import classNames from 'classnames'; import * as Icons from 'react-feather'; import { nanoid } from 'nanoid'; import { useState, useEffect, useCallback } from 'react'; import Link from 'next/link'; // Normalize how we work with the subtext as an array[] export function normalizeSubtext(subtext) { if (!Array.isArray(subtext)) { subtext = [subtext]; } return subtext; } // Simple method to normalize string as slug export function normalizeSlug(key) { return String(key.toLowerCase()).split(' ').join('-'); } // Normalize how we listen for media queries // Intentionally `null` default value -- will throw Error export function useMatchMedia(mediaQuery = null) { if (!mediaQuery) { throw new Error(`Jambonz UI "useMatchMedia" requires valid Media Query: ${mediaQuery} was passed.`); } const [mobile, setMobile] = useState(false); const handleMedia = useCallback((e) => { setMobile(e.matches); }, [setMobile]); useEffect(() => { const mql = window.matchMedia(mediaQuery); mql.addEventListener('change', handleMedia); setMobile(mql.matches); return function cleanup() { mql.removeEventListener('change', handleMedia); }; }, [handleMedia, setMobile, mediaQuery]); return mobile; } // Normalize for our mobile media query export function useMobileMedia() { return useMatchMedia('(max-width: 896px)'); } export function H1({ children }) { return

{children}

; } export function H2({ children }) { return

{children}

; } export function H3({ children }) { return

{children}

; } export function H4({ children }) { return

{children}

; } export function H5({ children }) { return
{children}
; } export function H6({ children }) { return
{children}
; } export function P({children}) { return

{children}

; } export function M({ children }) { return
{children}
; } export function MS({ children }) { return
{children}
; } export function MXS({ children }) { return
{children}
; } export function Latest({ data }) { const classes = { 'latest': true, [`latest--${data.label}`]: true, 'pad': true, 'bg-pink': true, }; return (

{data.headline}

{/* Use dangerouslySetInnerHTML to render inline links from YAML data */} {normalizeSubtext(data.subtext).map((subtext) => { return
; })}
); } export function Hero({ data, subStyle }) { const classes = { 'hero': true, 'pad': true, }; if (subStyle) { classes[`hero--${subStyle}`] = true; } return (

{data.headline}

{normalizeSubtext(data.subtext).map((subtext) => { return
{subtext}
; })}
{data.cta && (
)}
); } // Extra {props} get passed to the element export function Button({ children, href, mainStyle = 'fill', subStyle = null, ...props }) { const classes = { 'btn': true, [`btn--${mainStyle}`]: true, }; if (subStyle) { classes[`btn--${mainStyle}--${subStyle}`] = true; } return ( {children} ); } // Extra {props} get passed to the feather Component // See react-feather for all 286 icons available // https://github.com/feathericons/react-feather export function Icon({ name, mainStyle = 'inline', subStyle = null, ...props }) { const Component = Icons[name]; const classes = { 'icon': true, [`icon--${mainStyle}`]: true, }; if (subStyle) { classes[`icon--${mainStyle}--${subStyle}`] = true; } if (!Component) { return null; } // Stylized icon if (mainStyle !== 'inline') { return (
); } // Inline icon return ; } export function TextLayout({ data }) { return (
); }