@simplybusiness/mobius 4.9.2 → 4.10.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.
Files changed (50) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/cjs/components/Trust/Trust.js +56 -0
  3. package/dist/cjs/components/Trust/Trust.js.map +1 -0
  4. package/dist/cjs/components/Trust/TrustpilotProvider.js +31 -0
  5. package/dist/cjs/components/Trust/TrustpilotProvider.js.map +1 -0
  6. package/dist/cjs/components/Trust/constants.js +44 -0
  7. package/dist/cjs/components/Trust/constants.js.map +1 -0
  8. package/dist/cjs/components/Trust/getDefaultProps.js +34 -0
  9. package/dist/cjs/components/Trust/getDefaultProps.js.map +1 -0
  10. package/dist/cjs/components/Trust/index.js +21 -0
  11. package/dist/cjs/components/Trust/index.js.map +1 -0
  12. package/dist/cjs/components/Trust/types.js +7 -0
  13. package/dist/cjs/components/Trust/types.js.map +1 -0
  14. package/dist/cjs/components/index.js +1 -0
  15. package/dist/cjs/components/index.js.map +1 -1
  16. package/dist/cjs/tsconfig.tsbuildinfo +1 -1
  17. package/dist/esm/components/Trust/Trust.js +41 -0
  18. package/dist/esm/components/Trust/Trust.js.map +1 -0
  19. package/dist/esm/components/Trust/TrustpilotProvider.js +21 -0
  20. package/dist/esm/components/Trust/TrustpilotProvider.js.map +1 -0
  21. package/dist/esm/components/Trust/constants.js +20 -0
  22. package/dist/esm/components/Trust/constants.js.map +1 -0
  23. package/dist/esm/components/Trust/getDefaultProps.js +24 -0
  24. package/dist/esm/components/Trust/getDefaultProps.js.map +1 -0
  25. package/dist/esm/components/Trust/index.js +4 -0
  26. package/dist/esm/components/Trust/index.js.map +1 -0
  27. package/dist/esm/components/Trust/types.js +4 -0
  28. package/dist/esm/components/Trust/types.js.map +1 -0
  29. package/dist/esm/components/index.js +1 -0
  30. package/dist/esm/components/index.js.map +1 -1
  31. package/dist/types/components/Trust/Trust.d.ts +3 -0
  32. package/dist/types/components/Trust/Trust.stories.d.ts +7 -0
  33. package/dist/types/components/Trust/Trust.test.d.ts +1 -0
  34. package/dist/types/components/Trust/TrustpilotProvider.d.ts +4 -0
  35. package/dist/types/components/Trust/constants.d.ts +16 -0
  36. package/dist/types/components/Trust/getDefaultProps.d.ts +18 -0
  37. package/dist/types/components/Trust/index.d.ts +2 -0
  38. package/dist/types/components/Trust/types.d.ts +22 -0
  39. package/dist/types/components/index.d.ts +1 -0
  40. package/package.json +2 -2
  41. package/src/components/Trust/Trust.mdx +55 -0
  42. package/src/components/Trust/Trust.stories.tsx +48 -0
  43. package/src/components/Trust/Trust.test.tsx +8 -0
  44. package/src/components/Trust/Trust.tsx +62 -0
  45. package/src/components/Trust/TrustpilotProvider.tsx +20 -0
  46. package/src/components/Trust/constants.ts +21 -0
  47. package/src/components/Trust/getDefaultProps.ts +31 -0
  48. package/src/components/Trust/index.tsx +2 -0
  49. package/src/components/Trust/types.ts +28 -0
  50. package/src/components/index.tsx +1 -0
@@ -0,0 +1,41 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { forwardRef, useEffect, useRef } from "react";
3
+ import classNames from "classnames/dedupe";
4
+ import { getDefaultProps } from "./getDefaultProps";
5
+ import { REQUIRED_TRUSTPILOT_CLASS_NAME, TRUSTPILOT_WIDGET } from "./constants";
6
+ import { mergeRefs } from "../../utils";
7
+ export const Trust = /*#__PURE__*/ forwardRef((props, ref)=>{
8
+ const { elementType: Element = "div", variant, theme, ...otherProps } = props;
9
+ const trustRef = useRef(null);
10
+ const { link, ...defaultProps } = getDefaultProps(props);
11
+ const { className: variantClassName } = TRUSTPILOT_WIDGET[variant];
12
+ const themeClassName = theme.charAt(0).toUpperCase() + theme.slice(1);
13
+ const classes = classNames("mobius", "mobius/Trust", REQUIRED_TRUSTPILOT_CLASS_NAME, {
14
+ [`mobius/TrustTheme${themeClassName}`]: theme,
15
+ [`mobius/TrustVariant${variantClassName}`]: variant
16
+ }, otherProps.className);
17
+ useEffect(()=>{
18
+ // If window.Trustpilot is available it means that we need to load the TrustBox from our ref.
19
+ if (trustRef.current && window.Trustpilot && window.Trustpilot.loadFromElement) {
20
+ window.Trustpilot.loadFromElement(trustRef.current, true);
21
+ }
22
+ }, []);
23
+ return /*#__PURE__*/ _jsx(Element, {
24
+ ref: mergeRefs([
25
+ trustRef,
26
+ ref
27
+ ]),
28
+ ...defaultProps,
29
+ ...otherProps,
30
+ className: classes,
31
+ children: /*#__PURE__*/ _jsx("a", {
32
+ href: link,
33
+ target: "_blank",
34
+ rel: "noopener noreferrer",
35
+ className: "mobius/TrustLink",
36
+ children: "Trustpilot"
37
+ })
38
+ });
39
+ });
40
+
41
+ //# sourceMappingURL=Trust.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/components/Trust/Trust.tsx"],"sourcesContent":["import { forwardRef, useEffect, useRef } from \"react\";\nimport classNames from \"classnames/dedupe\";\nimport { ForwardedRefComponent } from \"../../types/components\";\nimport { TrustElementType, TrustProps, TrustRef } from \"./types\";\nimport { getDefaultProps } from \"./getDefaultProps\";\nimport { REQUIRED_TRUSTPILOT_CLASS_NAME, TRUSTPILOT_WIDGET } from \"./constants\";\nimport { mergeRefs } from \"../../utils\";\n\nexport const Trust: ForwardedRefComponent<TrustProps, TrustElementType> =\n forwardRef((props: TrustProps, ref: TrustRef) => {\n const {\n elementType: Element = \"div\",\n variant,\n theme,\n ...otherProps\n } = props;\n const trustRef = useRef(null);\n\n const { link, ...defaultProps } = getDefaultProps(props);\n const { className: variantClassName } = TRUSTPILOT_WIDGET[variant];\n const themeClassName = theme.charAt(0).toUpperCase() + theme.slice(1);\n\n const classes = classNames(\n \"mobius\",\n \"mobius/Trust\",\n REQUIRED_TRUSTPILOT_CLASS_NAME,\n {\n [`mobius/TrustTheme${themeClassName}`]: theme,\n [`mobius/TrustVariant${variantClassName}`]: variant,\n },\n otherProps.className,\n );\n\n useEffect(() => {\n // If window.Trustpilot is available it means that we need to load the TrustBox from our ref.\n if (\n trustRef.current &&\n window.Trustpilot &&\n window.Trustpilot.loadFromElement\n ) {\n window.Trustpilot.loadFromElement(trustRef.current, true);\n }\n }, []);\n\n return (\n <Element\n ref={mergeRefs([trustRef, ref])}\n {...defaultProps}\n {...otherProps}\n className={classes}\n >\n <a\n href={link}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"mobius/TrustLink\"\n >\n Trustpilot\n </a>\n </Element>\n );\n });\n"],"names":["forwardRef","useEffect","useRef","classNames","getDefaultProps","REQUIRED_TRUSTPILOT_CLASS_NAME","TRUSTPILOT_WIDGET","mergeRefs","Trust","props","ref","elementType","Element","variant","theme","otherProps","trustRef","link","defaultProps","className","variantClassName","themeClassName","charAt","toUpperCase","slice","classes","current","window","Trustpilot","loadFromElement","a","href","target","rel"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":";AAAA,SAASA,UAAU,EAAEC,SAAS,EAAEC,MAAM,QAAQ,QAAQ;AACtD,OAAOC,gBAAgB,oBAAoB;AAG3C,SAASC,eAAe,QAAQ,oBAAoB;AACpD,SAASC,8BAA8B,EAAEC,iBAAiB,QAAQ,cAAc;AAChF,SAASC,SAAS,QAAQ,cAAc;AAExC,OAAO,MAAMC,sBACXR,WAAW,CAACS,OAAmBC;IAC7B,MAAM,EACJC,aAAaC,UAAU,KAAK,EAC5BC,OAAO,EACPC,KAAK,EACL,GAAGC,YACJ,GAAGN;IACJ,MAAMO,WAAWd,OAAO;IAExB,MAAM,EAAEe,IAAI,EAAE,GAAGC,cAAc,GAAGd,gBAAgBK;IAClD,MAAM,EAAEU,WAAWC,gBAAgB,EAAE,GAAGd,iBAAiB,CAACO,QAAQ;IAClE,MAAMQ,iBAAiBP,MAAMQ,MAAM,CAAC,GAAGC,WAAW,KAAKT,MAAMU,KAAK,CAAC;IAEnE,MAAMC,UAAUtB,WACd,UACA,gBACAE,gCACA;QACE,CAAC,CAAC,iBAAiB,EAAEgB,eAAe,CAAC,CAAC,EAAEP;QACxC,CAAC,CAAC,mBAAmB,EAAEM,iBAAiB,CAAC,CAAC,EAAEP;IAC9C,GACAE,WAAWI,SAAS;IAGtBlB,UAAU;QACR,6FAA6F;QAC7F,IACEe,SAASU,OAAO,IAChBC,OAAOC,UAAU,IACjBD,OAAOC,UAAU,CAACC,eAAe,EACjC;YACAF,OAAOC,UAAU,CAACC,eAAe,CAACb,SAASU,OAAO,EAAE;QACtD;IACF,GAAG,EAAE;IAEL,qBACE,KAACd;QACCF,KAAKH,UAAU;YAACS;YAAUN;SAAI;QAC7B,GAAGQ,YAAY;QACf,GAAGH,UAAU;QACdI,WAAWM;kBAEX,cAAA,KAACK;YACCC,MAAMd;YACNe,QAAO;YACPC,KAAI;YACJd,WAAU;sBACX;;;AAKP,GAAG"}
@@ -0,0 +1,21 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useEffect } from "react";
3
+ export const TrustpilotProvider = ({ children })=>{
4
+ useEffect(()=>{
5
+ // Required to load Trustpilot widgets
6
+ const script = document.createElement("script");
7
+ script.type = "text/javascript";
8
+ script.className = "optanon-category-C0002";
9
+ script.src = "//widget.trustpilot.com/bootstrap/v5/tp.widget.bootstrap.min.js";
10
+ script.async = true;
11
+ document.head.appendChild(script);
12
+ return ()=>{
13
+ document.head.removeChild(script);
14
+ };
15
+ }, []);
16
+ return /*#__PURE__*/ _jsx("div", {
17
+ children: children
18
+ });
19
+ };
20
+
21
+ //# sourceMappingURL=TrustpilotProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/components/Trust/TrustpilotProvider.tsx"],"sourcesContent":["import { ReactNode, useEffect } from \"react\";\n\nexport const TrustpilotProvider = ({ children }: { children: ReactNode }) => {\n useEffect(() => {\n // Required to load Trustpilot widgets\n const script = document.createElement(\"script\");\n script.type = \"text/javascript\";\n script.className = \"optanon-category-C0002\";\n script.src =\n \"//widget.trustpilot.com/bootstrap/v5/tp.widget.bootstrap.min.js\";\n script.async = true;\n document.head.appendChild(script);\n\n return () => {\n document.head.removeChild(script);\n };\n }, []);\n\n return <div>{children}</div>;\n};\n"],"names":["useEffect","TrustpilotProvider","children","script","document","createElement","type","className","src","async","head","appendChild","removeChild","div"],"rangeMappings":";;;;;;;;;;;;;;;;;;","mappings":";AAAA,SAAoBA,SAAS,QAAQ,QAAQ;AAE7C,OAAO,MAAMC,qBAAqB,CAAC,EAAEC,QAAQ,EAA2B;IACtEF,UAAU;QACR,sCAAsC;QACtC,MAAMG,SAASC,SAASC,aAAa,CAAC;QACtCF,OAAOG,IAAI,GAAG;QACdH,OAAOI,SAAS,GAAG;QACnBJ,OAAOK,GAAG,GACR;QACFL,OAAOM,KAAK,GAAG;QACfL,SAASM,IAAI,CAACC,WAAW,CAACR;QAE1B,OAAO;YACLC,SAASM,IAAI,CAACE,WAAW,CAACT;QAC5B;IACF,GAAG,EAAE;IAEL,qBAAO,KAACU;kBAAKX;;AACf,EAAE"}
@@ -0,0 +1,20 @@
1
+ export const REQUIRED_TRUSTPILOT_CLASS_NAME = "trustpilot-widget";
2
+ export const SIMPLYBUSINESS_UNIT_ID = "5ca35a3da72b330001954cef";
3
+ export const TRUSTPILOT_LINKS = {
4
+ "en-US": "https://www.trustpilot.com/review/simplybusiness.com",
5
+ "en-GB": "https://www.trustpilot.com/review/simplybusiness.co.uk"
6
+ };
7
+ export const TRUSTPILOT_WIDGET = {
8
+ // Keys based on actual widget names
9
+ // https://support.trustpilot.com/hc/en-us/articles/360019826379-TrustBox-widget-overview
10
+ "micro-combo": {
11
+ templateId: "5419b6ffb0d04a076446a9af",
12
+ className: "MicroCombo"
13
+ },
14
+ mini: {
15
+ templateId: "53aa8807dec7e10d38f59f32",
16
+ className: "Mini"
17
+ }
18
+ };
19
+
20
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/components/Trust/constants.ts"],"sourcesContent":["export const REQUIRED_TRUSTPILOT_CLASS_NAME = \"trustpilot-widget\";\n\nexport const SIMPLYBUSINESS_UNIT_ID = \"5ca35a3da72b330001954cef\";\n\nexport const TRUSTPILOT_LINKS = {\n \"en-US\": \"https://www.trustpilot.com/review/simplybusiness.com\",\n \"en-GB\": \"https://www.trustpilot.com/review/simplybusiness.co.uk\",\n};\n\nexport const TRUSTPILOT_WIDGET = {\n // Keys based on actual widget names\n // https://support.trustpilot.com/hc/en-us/articles/360019826379-TrustBox-widget-overview\n \"micro-combo\": {\n templateId: \"5419b6ffb0d04a076446a9af\",\n className: \"MicroCombo\",\n },\n mini: {\n templateId: \"53aa8807dec7e10d38f59f32\",\n className: \"Mini\",\n },\n};\n"],"names":["REQUIRED_TRUSTPILOT_CLASS_NAME","SIMPLYBUSINESS_UNIT_ID","TRUSTPILOT_LINKS","TRUSTPILOT_WIDGET","templateId","className","mini"],"rangeMappings":";;;;;;;;;;;;;;;;;","mappings":"AAAA,OAAO,MAAMA,iCAAiC,oBAAoB;AAElE,OAAO,MAAMC,yBAAyB,2BAA2B;AAEjE,OAAO,MAAMC,mBAAmB;IAC9B,SAAS;IACT,SAAS;AACX,EAAE;AAEF,OAAO,MAAMC,oBAAoB;IAC/B,oCAAoC;IACpC,yFAAyF;IACzF,eAAe;QACbC,YAAY;QACZC,WAAW;IACb;IACAC,MAAM;QACJF,YAAY;QACZC,WAAW;IACb;AACF,EAAE"}
@@ -0,0 +1,24 @@
1
+ import { SIMPLYBUSINESS_UNIT_ID, TRUSTPILOT_LINKS, TRUSTPILOT_WIDGET } from "./constants";
2
+ export const getDefaultProps = (props)=>{
3
+ const { locale, variant, height, width, theme, stars } = props;
4
+ const { templateId } = TRUSTPILOT_WIDGET[variant];
5
+ const link = TRUSTPILOT_LINKS[locale];
6
+ const sharedProps = {
7
+ "data-businessunit-id": SIMPLYBUSINESS_UNIT_ID,
8
+ "data-locale": locale,
9
+ "data-template-id": templateId,
10
+ "data-theme": theme,
11
+ "data-style-width": width || "100%",
12
+ link
13
+ };
14
+ if (variant === "micro-combo") {
15
+ return {
16
+ "data-style-height": height || "40px",
17
+ "data-stars": stars,
18
+ ...sharedProps
19
+ };
20
+ }
21
+ return sharedProps;
22
+ };
23
+
24
+ //# sourceMappingURL=getDefaultProps.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/components/Trust/getDefaultProps.ts"],"sourcesContent":["import {\n SIMPLYBUSINESS_UNIT_ID,\n TRUSTPILOT_LINKS,\n TRUSTPILOT_WIDGET,\n} from \"./constants\";\nimport { TrustProps } from \"./types\";\n\nexport const getDefaultProps = (props: TrustProps) => {\n const { locale, variant, height, width, theme, stars } = props;\n const { templateId } = TRUSTPILOT_WIDGET[variant];\n const link = TRUSTPILOT_LINKS[locale];\n\n const sharedProps = {\n \"data-businessunit-id\": SIMPLYBUSINESS_UNIT_ID,\n \"data-locale\": locale,\n \"data-template-id\": templateId,\n \"data-theme\": theme,\n \"data-style-width\": width || \"100%\",\n link,\n };\n\n if (variant === \"micro-combo\") {\n return {\n \"data-style-height\": height || \"40px\",\n \"data-stars\": stars,\n ...sharedProps,\n };\n }\n\n return sharedProps;\n};\n"],"names":["SIMPLYBUSINESS_UNIT_ID","TRUSTPILOT_LINKS","TRUSTPILOT_WIDGET","getDefaultProps","props","locale","variant","height","width","theme","stars","templateId","link","sharedProps"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;","mappings":"AAAA,SACEA,sBAAsB,EACtBC,gBAAgB,EAChBC,iBAAiB,QACZ,cAAc;AAGrB,OAAO,MAAMC,kBAAkB,CAACC;IAC9B,MAAM,EAAEC,MAAM,EAAEC,OAAO,EAAEC,MAAM,EAAEC,KAAK,EAAEC,KAAK,EAAEC,KAAK,EAAE,GAAGN;IACzD,MAAM,EAAEO,UAAU,EAAE,GAAGT,iBAAiB,CAACI,QAAQ;IACjD,MAAMM,OAAOX,gBAAgB,CAACI,OAAO;IAErC,MAAMQ,cAAc;QAClB,wBAAwBb;QACxB,eAAeK;QACf,oBAAoBM;QACpB,cAAcF;QACd,oBAAoBD,SAAS;QAC7BI;IACF;IAEA,IAAIN,YAAY,eAAe;QAC7B,OAAO;YACL,qBAAqBC,UAAU;YAC/B,cAAcG;YACd,GAAGG,WAAW;QAChB;IACF;IAEA,OAAOA;AACT,EAAE"}
@@ -0,0 +1,4 @@
1
+ export * from "./Trust";
2
+ export * from "./types";
3
+
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/components/Trust/index.tsx"],"sourcesContent":["export * from \"./Trust\";\nexport * from \"./types\";\n"],"names":[],"rangeMappings":";","mappings":"AAAA,cAAc,UAAU;AACxB,cAAc,UAAU"}
@@ -0,0 +1,4 @@
1
+ window.Trustpilot = window.Trustpilot || {};
2
+ export { };
3
+
4
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/components/Trust/types.ts"],"sourcesContent":["import { Ref, RefAttributes } from \"react\";\nimport { DOMProps } from \"../../types/dom\";\nimport { TRUSTPILOT_WIDGET } from \"./constants\";\n\ndeclare global {\n interface Window {\n Trustpilot: any;\n }\n}\n\nwindow.Trustpilot = window.Trustpilot || {};\n\nexport type TrustElementType = HTMLDivElement;\n\nexport interface TrustProps extends DOMProps, RefAttributes<TrustElementType> {\n /** Custom class name for setting specific CSS */\n className?: string;\n elementType?: string | React.ElementType;\n locale: \"en-US\" | \"en-GB\";\n variant: keyof typeof TRUSTPILOT_WIDGET;\n templateId?: string;\n height?: string;\n width?: string;\n theme: \"dark\" | \"light\";\n stars?: string;\n}\n\nexport type TrustRef = Ref<TrustElementType>;\n"],"names":["window","Trustpilot"],"rangeMappings":";","mappings":"AAUAA,OAAOC,UAAU,GAAGD,OAAOC,UAAU,IAAI,CAAC;AAiB1C,WAA6C"}
@@ -37,6 +37,7 @@ export * from "./TextArea";
37
37
  export * from "./TextAreaInput";
38
38
  export * from "./TextField";
39
39
  export * from "./Title";
40
+ export * from "./Trust";
40
41
  export * from "./VisuallyHidden";
41
42
 
42
43
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/index.tsx"],"sourcesContent":["export * from \"./Accordion\";\nexport * from \"./Alert\";\nexport * from \"./Box\";\nexport * from \"./Breadcrumbs\";\nexport * from \"./Button\";\nexport * from \"./Checkbox\";\nexport * from \"./Container\";\nexport * from \"./Divider\";\nexport * from \"./Drawer\";\nexport * from \"./DropdownMenu\";\nexport * from \"./ErrorMessage\";\nexport * from \"./Fieldset\";\nexport * from \"./Flex\";\nexport * from \"./Grid\";\nexport * from \"./Icon\";\nexport * from \"./Image\";\nexport * from \"./Label\";\nexport * from \"./Link\";\nexport * from \"./LinkButton\";\nexport * from \"./List\";\nexport * from \"./LoadingIndicator\";\nexport * from \"./Logo\";\nexport * from \"./Modal\";\nexport * from \"./NumberField\";\nexport * from \"./Option\";\nexport * from \"./PasswordField\";\nexport * from \"./Popover\";\nexport * from \"./Progress\";\nexport * from \"./Radio\";\nexport * from \"./Segment\";\nexport * from \"./Select\";\nexport * from \"./Slider\";\nexport * from \"./SVG\";\nexport * from \"./Table\";\nexport * from \"./Text\";\nexport * from \"./TextArea\";\nexport * from \"./TextAreaInput\";\nexport * from \"./TextField\";\nexport * from \"./Title\";\nexport * from \"./VisuallyHidden\";\n"],"names":[],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAAA,cAAc,cAAc;AAC5B,cAAc,UAAU;AACxB,cAAc,QAAQ;AACtB,cAAc,gBAAgB;AAC9B,cAAc,WAAW;AACzB,cAAc,aAAa;AAC3B,cAAc,cAAc;AAC5B,cAAc,YAAY;AAC1B,cAAc,WAAW;AACzB,cAAc,iBAAiB;AAC/B,cAAc,iBAAiB;AAC/B,cAAc,aAAa;AAC3B,cAAc,SAAS;AACvB,cAAc,SAAS;AACvB,cAAc,SAAS;AACvB,cAAc,UAAU;AACxB,cAAc,UAAU;AACxB,cAAc,SAAS;AACvB,cAAc,eAAe;AAC7B,cAAc,SAAS;AACvB,cAAc,qBAAqB;AACnC,cAAc,SAAS;AACvB,cAAc,UAAU;AACxB,cAAc,gBAAgB;AAC9B,cAAc,WAAW;AACzB,cAAc,kBAAkB;AAChC,cAAc,YAAY;AAC1B,cAAc,aAAa;AAC3B,cAAc,UAAU;AACxB,cAAc,YAAY;AAC1B,cAAc,WAAW;AACzB,cAAc,WAAW;AACzB,cAAc,QAAQ;AACtB,cAAc,UAAU;AACxB,cAAc,SAAS;AACvB,cAAc,aAAa;AAC3B,cAAc,kBAAkB;AAChC,cAAc,cAAc;AAC5B,cAAc,UAAU;AACxB,cAAc,mBAAmB"}
1
+ {"version":3,"sources":["../../../src/components/index.tsx"],"sourcesContent":["export * from \"./Accordion\";\nexport * from \"./Alert\";\nexport * from \"./Box\";\nexport * from \"./Breadcrumbs\";\nexport * from \"./Button\";\nexport * from \"./Checkbox\";\nexport * from \"./Container\";\nexport * from \"./Divider\";\nexport * from \"./Drawer\";\nexport * from \"./DropdownMenu\";\nexport * from \"./ErrorMessage\";\nexport * from \"./Fieldset\";\nexport * from \"./Flex\";\nexport * from \"./Grid\";\nexport * from \"./Icon\";\nexport * from \"./Image\";\nexport * from \"./Label\";\nexport * from \"./Link\";\nexport * from \"./LinkButton\";\nexport * from \"./List\";\nexport * from \"./LoadingIndicator\";\nexport * from \"./Logo\";\nexport * from \"./Modal\";\nexport * from \"./NumberField\";\nexport * from \"./Option\";\nexport * from \"./PasswordField\";\nexport * from \"./Popover\";\nexport * from \"./Progress\";\nexport * from \"./Radio\";\nexport * from \"./Segment\";\nexport * from \"./Select\";\nexport * from \"./Slider\";\nexport * from \"./SVG\";\nexport * from \"./Table\";\nexport * from \"./Text\";\nexport * from \"./TextArea\";\nexport * from \"./TextAreaInput\";\nexport * from \"./TextField\";\nexport * from \"./Title\";\nexport * from \"./Trust\";\nexport * from \"./VisuallyHidden\";\n"],"names":[],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAAA,cAAc,cAAc;AAC5B,cAAc,UAAU;AACxB,cAAc,QAAQ;AACtB,cAAc,gBAAgB;AAC9B,cAAc,WAAW;AACzB,cAAc,aAAa;AAC3B,cAAc,cAAc;AAC5B,cAAc,YAAY;AAC1B,cAAc,WAAW;AACzB,cAAc,iBAAiB;AAC/B,cAAc,iBAAiB;AAC/B,cAAc,aAAa;AAC3B,cAAc,SAAS;AACvB,cAAc,SAAS;AACvB,cAAc,SAAS;AACvB,cAAc,UAAU;AACxB,cAAc,UAAU;AACxB,cAAc,SAAS;AACvB,cAAc,eAAe;AAC7B,cAAc,SAAS;AACvB,cAAc,qBAAqB;AACnC,cAAc,SAAS;AACvB,cAAc,UAAU;AACxB,cAAc,gBAAgB;AAC9B,cAAc,WAAW;AACzB,cAAc,kBAAkB;AAChC,cAAc,YAAY;AAC1B,cAAc,aAAa;AAC3B,cAAc,UAAU;AACxB,cAAc,YAAY;AAC1B,cAAc,WAAW;AACzB,cAAc,WAAW;AACzB,cAAc,QAAQ;AACtB,cAAc,UAAU;AACxB,cAAc,SAAS;AACvB,cAAc,aAAa;AAC3B,cAAc,kBAAkB;AAChC,cAAc,cAAc;AAC5B,cAAc,UAAU;AACxB,cAAc,UAAU;AACxB,cAAc,mBAAmB"}
@@ -0,0 +1,3 @@
1
+ import { ForwardedRefComponent } from "../../types/components";
2
+ import { TrustElementType, TrustProps } from "./types";
3
+ export declare const Trust: ForwardedRefComponent<TrustProps, TrustElementType>;
@@ -0,0 +1,7 @@
1
+ import type { Meta, StoryObj } from "@storybook/react";
2
+ import { Trust } from "..";
3
+ type StoryType = StoryObj<typeof Trust>;
4
+ declare const meta: Meta<typeof Trust>;
5
+ export declare const MicroCombo: StoryType;
6
+ export declare const Mini: StoryType;
7
+ export default meta;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,4 @@
1
+ import { ReactNode } from "react";
2
+ export declare const TrustpilotProvider: ({ children }: {
3
+ children: ReactNode;
4
+ }) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,16 @@
1
+ export declare const REQUIRED_TRUSTPILOT_CLASS_NAME = "trustpilot-widget";
2
+ export declare const SIMPLYBUSINESS_UNIT_ID = "5ca35a3da72b330001954cef";
3
+ export declare const TRUSTPILOT_LINKS: {
4
+ "en-US": string;
5
+ "en-GB": string;
6
+ };
7
+ export declare const TRUSTPILOT_WIDGET: {
8
+ "micro-combo": {
9
+ templateId: string;
10
+ className: string;
11
+ };
12
+ mini: {
13
+ templateId: string;
14
+ className: string;
15
+ };
16
+ };
@@ -0,0 +1,18 @@
1
+ import { TrustProps } from "./types";
2
+ export declare const getDefaultProps: (props: TrustProps) => {
3
+ "data-businessunit-id": string;
4
+ "data-locale": "en-GB" | "en-US";
5
+ "data-template-id": string;
6
+ "data-theme": "dark" | "light";
7
+ "data-style-width": string;
8
+ link: string;
9
+ } | {
10
+ "data-businessunit-id": string;
11
+ "data-locale": "en-GB" | "en-US";
12
+ "data-template-id": string;
13
+ "data-theme": "dark" | "light";
14
+ "data-style-width": string;
15
+ link: string;
16
+ "data-style-height": string;
17
+ "data-stars": string | undefined;
18
+ };
@@ -0,0 +1,2 @@
1
+ export * from "./Trust";
2
+ export * from "./types";
@@ -0,0 +1,22 @@
1
+ import { Ref, RefAttributes } from "react";
2
+ import { DOMProps } from "../../types/dom";
3
+ import { TRUSTPILOT_WIDGET } from "./constants";
4
+ declare global {
5
+ interface Window {
6
+ Trustpilot: any;
7
+ }
8
+ }
9
+ export type TrustElementType = HTMLDivElement;
10
+ export interface TrustProps extends DOMProps, RefAttributes<TrustElementType> {
11
+ /** Custom class name for setting specific CSS */
12
+ className?: string;
13
+ elementType?: string | React.ElementType;
14
+ locale: "en-US" | "en-GB";
15
+ variant: keyof typeof TRUSTPILOT_WIDGET;
16
+ templateId?: string;
17
+ height?: string;
18
+ width?: string;
19
+ theme: "dark" | "light";
20
+ stars?: string;
21
+ }
22
+ export type TrustRef = Ref<TrustElementType>;
@@ -37,4 +37,5 @@ export * from "./TextArea";
37
37
  export * from "./TextAreaInput";
38
38
  export * from "./TextField";
39
39
  export * from "./Title";
40
+ export * from "./Trust";
40
41
  export * from "./VisuallyHidden";
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@simplybusiness/mobius",
3
3
  "license": "UNLICENSED",
4
- "version": "4.9.2",
4
+ "version": "4.10.0",
5
5
  "description": "Core library of Mobius react components",
6
6
  "repository": {
7
7
  "type": "git",
@@ -86,7 +86,7 @@
86
86
  },
87
87
  "dependencies": {
88
88
  "@floating-ui/react": "^0.26.16",
89
- "@simplybusiness/icons": "^4.9.0",
89
+ "@simplybusiness/icons": "^4.10.0",
90
90
  "classnames": "^2.5.1",
91
91
  "dialog-polyfill": "^0.5.6",
92
92
  "lodash.debounce": "^4.0.8",
@@ -0,0 +1,55 @@
1
+ import { Meta, ArgTypes, Story } from "@storybook/addon-docs";
2
+ import * as TrustStories from "./Trust.stories";
3
+ import { Trust } from "./Trust";
4
+
5
+ <Meta of={TrustStories} />
6
+
7
+ # Trust
8
+
9
+ The `Trust` component is used for to display review summary from Trustpilot.
10
+
11
+ ## Install
12
+
13
+ ```bash
14
+ yarn add @simplybusiness/mobius
15
+ ```
16
+
17
+ ## Usage
18
+
19
+ ```js
20
+ import { Trust } from "@simplybusiness/mobius";
21
+ ```
22
+
23
+ ## MicroCombo
24
+
25
+ <Story of={TrustStories.MicroCombo} />
26
+
27
+ ## Mini
28
+
29
+ <Story of={TrustStories.Mini} />
30
+
31
+ ## Props
32
+
33
+ <ArgTypes of={Trust} />
34
+
35
+ ## Component HTML Structure and Class names
36
+
37
+ The following HTML is rendered for a Trust:
38
+
39
+ ```html
40
+ <div
41
+ class="mobius mobius/Trust mobius/TrustThemeDark mobius/TrustVariantMicroCombo"
42
+ >
43
+ <a
44
+ href="https://www.trustpilot.com/review/simplybusiness.com"
45
+ target="_blank"
46
+ rel="noopener noreferrer"
47
+ >
48
+ Trustpilot
49
+ </a>
50
+ </div>
51
+ ```
52
+
53
+ ---
54
+
55
+ [See on Github](https://github.com/simplybusiness/mobius/tree/master/packages/mobius/src/components/Trust) | [Give feedback](https://simplybusiness.atlassian.net/CreateIssue.jspa?issuetype=10103&pid=10609) | [Get support](https://simplybusiness.slack.com/archives/C016CC0NDNE)
@@ -0,0 +1,48 @@
1
+ import type { Meta, StoryObj } from "@storybook/react";
2
+ import { Trust, type TrustProps } from "..";
3
+ import { excludeControls } from "../../utils";
4
+ import { TrustpilotProvider } from "./TrustpilotProvider";
5
+
6
+ type StoryType = StoryObj<typeof Trust>;
7
+
8
+ const meta: Meta<typeof Trust> = {
9
+ title: "Components/Trust",
10
+ component: Trust,
11
+ argTypes: excludeControls(
12
+ "className",
13
+ "locale",
14
+ "variant",
15
+ "theme",
16
+ "width",
17
+ "height",
18
+ "templateId",
19
+ "stars",
20
+ ),
21
+ decorators: [
22
+ Story => (
23
+ <TrustpilotProvider>
24
+ <Story />
25
+ </TrustpilotProvider>
26
+ ),
27
+ ],
28
+ };
29
+
30
+ export const MicroCombo: StoryType = {
31
+ render: (args: TrustProps) => <Trust {...args} />,
32
+ args: {
33
+ locale: "en-US",
34
+ variant: "micro-combo",
35
+ theme: "light",
36
+ },
37
+ };
38
+
39
+ export const Mini: StoryType = {
40
+ render: (args: TrustProps) => <Trust {...args} />,
41
+ args: {
42
+ locale: "en-US",
43
+ variant: "mini",
44
+ theme: "light",
45
+ },
46
+ };
47
+
48
+ export default meta;
@@ -0,0 +1,8 @@
1
+ import { render } from "@testing-library/react";
2
+ import { Trust } from ".";
3
+
4
+ describe("Trust", () => {
5
+ it("should render without errors", () => {
6
+ render(<Trust locale="en-US" variant="micro-combo" theme="dark" />);
7
+ });
8
+ });
@@ -0,0 +1,62 @@
1
+ import { forwardRef, useEffect, useRef } from "react";
2
+ import classNames from "classnames/dedupe";
3
+ import { ForwardedRefComponent } from "../../types/components";
4
+ import { TrustElementType, TrustProps, TrustRef } from "./types";
5
+ import { getDefaultProps } from "./getDefaultProps";
6
+ import { REQUIRED_TRUSTPILOT_CLASS_NAME, TRUSTPILOT_WIDGET } from "./constants";
7
+ import { mergeRefs } from "../../utils";
8
+
9
+ export const Trust: ForwardedRefComponent<TrustProps, TrustElementType> =
10
+ forwardRef((props: TrustProps, ref: TrustRef) => {
11
+ const {
12
+ elementType: Element = "div",
13
+ variant,
14
+ theme,
15
+ ...otherProps
16
+ } = props;
17
+ const trustRef = useRef(null);
18
+
19
+ const { link, ...defaultProps } = getDefaultProps(props);
20
+ const { className: variantClassName } = TRUSTPILOT_WIDGET[variant];
21
+ const themeClassName = theme.charAt(0).toUpperCase() + theme.slice(1);
22
+
23
+ const classes = classNames(
24
+ "mobius",
25
+ "mobius/Trust",
26
+ REQUIRED_TRUSTPILOT_CLASS_NAME,
27
+ {
28
+ [`mobius/TrustTheme${themeClassName}`]: theme,
29
+ [`mobius/TrustVariant${variantClassName}`]: variant,
30
+ },
31
+ otherProps.className,
32
+ );
33
+
34
+ useEffect(() => {
35
+ // If window.Trustpilot is available it means that we need to load the TrustBox from our ref.
36
+ if (
37
+ trustRef.current &&
38
+ window.Trustpilot &&
39
+ window.Trustpilot.loadFromElement
40
+ ) {
41
+ window.Trustpilot.loadFromElement(trustRef.current, true);
42
+ }
43
+ }, []);
44
+
45
+ return (
46
+ <Element
47
+ ref={mergeRefs([trustRef, ref])}
48
+ {...defaultProps}
49
+ {...otherProps}
50
+ className={classes}
51
+ >
52
+ <a
53
+ href={link}
54
+ target="_blank"
55
+ rel="noopener noreferrer"
56
+ className="mobius/TrustLink"
57
+ >
58
+ Trustpilot
59
+ </a>
60
+ </Element>
61
+ );
62
+ });
@@ -0,0 +1,20 @@
1
+ import { ReactNode, useEffect } from "react";
2
+
3
+ export const TrustpilotProvider = ({ children }: { children: ReactNode }) => {
4
+ useEffect(() => {
5
+ // Required to load Trustpilot widgets
6
+ const script = document.createElement("script");
7
+ script.type = "text/javascript";
8
+ script.className = "optanon-category-C0002";
9
+ script.src =
10
+ "//widget.trustpilot.com/bootstrap/v5/tp.widget.bootstrap.min.js";
11
+ script.async = true;
12
+ document.head.appendChild(script);
13
+
14
+ return () => {
15
+ document.head.removeChild(script);
16
+ };
17
+ }, []);
18
+
19
+ return <div>{children}</div>;
20
+ };
@@ -0,0 +1,21 @@
1
+ export const REQUIRED_TRUSTPILOT_CLASS_NAME = "trustpilot-widget";
2
+
3
+ export const SIMPLYBUSINESS_UNIT_ID = "5ca35a3da72b330001954cef";
4
+
5
+ export const TRUSTPILOT_LINKS = {
6
+ "en-US": "https://www.trustpilot.com/review/simplybusiness.com",
7
+ "en-GB": "https://www.trustpilot.com/review/simplybusiness.co.uk",
8
+ };
9
+
10
+ export const TRUSTPILOT_WIDGET = {
11
+ // Keys based on actual widget names
12
+ // https://support.trustpilot.com/hc/en-us/articles/360019826379-TrustBox-widget-overview
13
+ "micro-combo": {
14
+ templateId: "5419b6ffb0d04a076446a9af",
15
+ className: "MicroCombo",
16
+ },
17
+ mini: {
18
+ templateId: "53aa8807dec7e10d38f59f32",
19
+ className: "Mini",
20
+ },
21
+ };
@@ -0,0 +1,31 @@
1
+ import {
2
+ SIMPLYBUSINESS_UNIT_ID,
3
+ TRUSTPILOT_LINKS,
4
+ TRUSTPILOT_WIDGET,
5
+ } from "./constants";
6
+ import { TrustProps } from "./types";
7
+
8
+ export const getDefaultProps = (props: TrustProps) => {
9
+ const { locale, variant, height, width, theme, stars } = props;
10
+ const { templateId } = TRUSTPILOT_WIDGET[variant];
11
+ const link = TRUSTPILOT_LINKS[locale];
12
+
13
+ const sharedProps = {
14
+ "data-businessunit-id": SIMPLYBUSINESS_UNIT_ID,
15
+ "data-locale": locale,
16
+ "data-template-id": templateId,
17
+ "data-theme": theme,
18
+ "data-style-width": width || "100%",
19
+ link,
20
+ };
21
+
22
+ if (variant === "micro-combo") {
23
+ return {
24
+ "data-style-height": height || "40px",
25
+ "data-stars": stars,
26
+ ...sharedProps,
27
+ };
28
+ }
29
+
30
+ return sharedProps;
31
+ };
@@ -0,0 +1,2 @@
1
+ export * from "./Trust";
2
+ export * from "./types";
@@ -0,0 +1,28 @@
1
+ import { Ref, RefAttributes } from "react";
2
+ import { DOMProps } from "../../types/dom";
3
+ import { TRUSTPILOT_WIDGET } from "./constants";
4
+
5
+ declare global {
6
+ interface Window {
7
+ Trustpilot: any;
8
+ }
9
+ }
10
+
11
+ window.Trustpilot = window.Trustpilot || {};
12
+
13
+ export type TrustElementType = HTMLDivElement;
14
+
15
+ export interface TrustProps extends DOMProps, RefAttributes<TrustElementType> {
16
+ /** Custom class name for setting specific CSS */
17
+ className?: string;
18
+ elementType?: string | React.ElementType;
19
+ locale: "en-US" | "en-GB";
20
+ variant: keyof typeof TRUSTPILOT_WIDGET;
21
+ templateId?: string;
22
+ height?: string;
23
+ width?: string;
24
+ theme: "dark" | "light";
25
+ stars?: string;
26
+ }
27
+
28
+ export type TrustRef = Ref<TrustElementType>;
@@ -37,4 +37,5 @@ export * from "./TextArea";
37
37
  export * from "./TextAreaInput";
38
38
  export * from "./TextField";
39
39
  export * from "./Title";
40
+ export * from "./Trust";
40
41
  export * from "./VisuallyHidden";