@gewest13/shared

v2.11.57

Published

Gewest13 Library Shared Components is a curated repository of reusable UI assets used by Gewest13. Designed to enhance development efficiency and promote consistency, these components serve as valuable resources for streamlining application creation.

Downloads

88

Readme

Gewest13 components

Gewest13 Library Shared Components is a curated repository of reusable UI assets used by Gewest13. Designed to enhance development efficiency and promote consistency, these components serve as valuable resources for streamlining application creation.

Table of Contents

  1. Components

  2. Hooks

  3. Functions

  4. Utils

  5. All CSS imports

Components

Components can be imported individually, or you have the option to import all components at once using the root file index.js. Additionally, you can include the main CSS file named index.css, which is situated within @gewest13/components/dist/index.css. However, for optimal organization, it is recommended to import each CSS file separately for the specific components you are utilizing.

ColumnsContainer

Recommended import:

import { ColumnsContainer } from '@gewest13/components';

Css import:

import '@gewest13/components/dist/ColumnsContainer.css';

Example:

<ColumnsContainer
  // Optionally, specify a custom grid container
  Container={Container}
  // Define the columns in your grid layout
  columns={[
    {
      // Define the grid columns for different screen sizes
      grids: { 
        desktop: { column: '3 / 5' }, 
        tablet: { column: '3 / 5' }, 
        mobile: { column: '4 / -4' }
      },
      // Specify the component to render inside the column
      component: (
        <Typography mobileMargin={[0, 0, 40, 0]} size="typo-24" tag="h3">
          {heading}
        </Typography>
      ),
    }
  ]}
/>

Image

Recommended import:

import { Image } from '@gewest13/components';

Css import:

import '@gewest13/components/dist/Image.css';

Recommended use:

// src/shared/Image/Image.tsx
import React from 'react';

import { Image as SharedImage } from '@gewest13/components/dist/Image';

import { vwsizes } from 'config';

export default function Image(props: React.ComponentProps<typeof SharedImage>) {
  return (
    <SharedImage
      vwSizes={vwsizes}
      {...props}
    />
  );
}

Example:

<Image
  src={{
    desktop: { mediaItemUrl: 'placeholder.jpg', altText: 'placeholder' },
    tablet: { mediaItemUrl: 'placeholder.jpg', altText: 'placeholder' },
    mobile: { mediaItemUrl: 'placeholder.jpg', altText: 'placeholder' },
  }}
  ratios={{ desktop: [1680, 1800], tablet: [840, 900], mobile: [432, 720] }}
/>

RecaptchaV3

Recommended import:

import { RecaptchaV3, getToken } from '@gewest13/components';

Example:

// Recaptcha is the recaptcha site key from the google recaptcha admin
<RecaptchaV3 recaptcha={recaptcha} />

SharedForm

Recommended import:

import { SharedForm } from '@gewest13/components';

Important:

⚠️ To use this shared form you should first import the wpMail function.

Example:

<SharedForm
  // Best practice to spread props from wordpress
  Container={<form className="example" />}
  confirmationSubject="Confirmation Subject"
  confirmationPreviewText="Confirmation Preview Text"
  // Or render a template on the server on build
  confirmationEmail="<p>Hey {{firstName}}</p>"
  dataReceiverSubject="Data Receiver Subject"
  dataReceiverPreviewText="Data Receiver Preview Text"
  dataReceiverEmail="<p>First name: {{firstName}}</p>"
  mailReceiver={[{databaseId: 3, databaseId: 2, databaseId: 1}]}
  mailSender={{ databaseId: 4 }}
  recaptcha_site_key={recaptcha}
  onSubmit={handleFormSubmit}
  onSuccessfulSubmit={handleSuccessfulSubmit}
  onFailedSubmit={handleFailedSubmit}
  debug={true}
>
  <label htmlFor="textInput">
    Enter Text:
    <input
      type="text"
      id="textInput"
      value=""
    />
  </label>
  {/* Add other form elements as needed */}
</SharedForm>

Swiper

Recommended import:

import { Swiper, SwiperCard } from '@gewest13/components';

Css import:

import '@gewest13/components/dist/Swiper.css';

Example:

<SharedSwiper>
  {slides && slides.map((slide, index) => (
    // Add width and height here
    <SwiperCard className={styles.slideCard} key={index}>
      {slide}
    </SwiperCard>
  ))}
</SharedSwiper>

Video

Recommended import:

import { Video, VideoComponent, FullVideo } from '@gewest13/components';

Css import:

import '@gewest13/components/dist/Video.css';

Example:

<Video
  src={{mediaItemUrl: 'placeholder.jpg', altText: 'placeholder'}}
  ratio={[1600, 900]}
/>  

<VideoComponent
  src={{
    desktop: { mediaItemUrl: 'placeholder.jpg', altText: 'placeholder' },
    tablet: { mediaItemUrl: 'placeholder.jpg', altText: 'placeholder' },
    mobile: { mediaItemUrl: 'placeholder.jpg', altText: 'placeholder' },
  }}
  ratios={{ desktop: [1680, 1800], tablet: [840, 900], mobile: [432, 720] }}
/>

<FullVideo 
  ref={videoRef} 
  disableFullScreenHandling 
  srcFull={fullVideo} 
  className={styles.video} 
  ratios={{ desktop: [1680, 945] }} 
  src={{ desktop: videoLoop }}
>
  {fullVideo && (
    <button onClick={() => videoRef.current.playFullScreen()}>Play movie</button>
  )}
</FullVideo>

SharedTypography

Example:

'use client';

import React, { forwardRef, ForwardedRef } from 'react';

import { SharedTypography, TypographyImperativeHandle } from '@gewest13/components/dist/SharedTypography';

import { vwsizes } from 'config';

import styles from './Typography.module.scss';

export interface TTypography {
  size: TfontSizes;
  className?: string;
}

const Typography = forwardRef((props: React.ComponentProps<typeof SharedTypography> & TTypography, ref: ForwardedRef<TypographyImperativeHandle>) => {
  const { className, size, ...rest } = props;

  return (
    <SharedTypography
      {...rest}
      ref={ref}
      className={`${styles[`typography--${size}`]} ${className || ''}`}
      vwSizes={vwsizes}
    />
  );
});

export default Typography;

Hooks

useWindowSize

Description for the useWindowSize hook.

Functions

createContainer

Description for the createContainer function.

draftModeWordpress

Recommended import:

import { draftModeWordpress } from '@gewest13/components';

Example:

// Path: app/api/preview/route.ts
import { WORDPRESS_API_URL } from 'config';
import { draftModeWordpress } from '@gewest13/components';

export async function GET(req: any) {
  // When going to /api/preview?uri=1234
  // uri should be the databaseId of the post
  return draftModeWordpress({
    req,
    api_url: WORDPRESS_API_URL,
  });
}
// Path: inside the root on app level ~/middleware.ts
import { NextRequest, NextResponse } from 'next/server';

export const config = {
  matcher: ['/api/preview'],
};

export async function middleware(req: NextRequest) {
  const basicAuth = req.headers.get('authorization');
  const url = req.nextUrl;

  if (basicAuth) {
    const authValue = basicAuth.split(' ')[1];
    const [user, pwd] = atob(authValue).split(':');

    return NextResponse.rewrite(`${url}&username=${user}&password=${encodeURIComponent(pwd)}`);
  }

  return NextResponse.rewrite(url, { status: 401 });
}
// Path src/components/LivePreview/LivePreview.tsx
// This also should be a shared component
'use client';

import React, { Suspense, startTransition, useEffect, useState } from 'react';

import getPage from '@/lib/get-page';

import Components from '@/shared/Components/Components';
import Hero from '@/shared/Hero/Hero';

function getCookie(name: string) {
  const nameEQ = `${name}=`;
  const ca = document.cookie.split(';');
  // eslint-disable-next-line no-plusplus
  for (let i = 0; i < ca.length; i++) {
    let c = ca[i];
    while (c.charAt(0) === ' ') c = c.substring(1, c.length);
    if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length, c.length);
  }
  return null;
}

export default function LivePreview(data: any) {
  const [draftData, setDraftData] = useState(null) as any;
  const { draftMode, id } = data;
  const { acfComponents, acfHero } = draftData || data;

  useEffect(() => {
    if (!draftMode) return undefined;

    const authToken = getCookie('token');

    if (!authToken) return undefined;

    const intervalId = setInterval(async () => {
      const pageData = await getPage({ id });

      startTransition(() => {
        setDraftData(pageData);
      });
    }, 2000);

    return () => {
      clearInterval(intervalId);
    };
  }, []);

  return (
    <Suspense fallback={null}>
      <Hero acfHero={acfHero} />
      <Components acfComponents={acfComponents} />
    </Suspense>
  );
}

fetchWordpress

Description for the fetchWordpress function.

grid

Description for the grid function.

margin

Description for the margin function.

ratios

Description for the ratios function.

vwsize

Description for the vwsize function.

wpMail

Recommended import:

import { wpMail } from '@gewest13/components';

Example:

// Path: app/api/mail/route.ts
import { WORDPRESS_API_URL } from 'config';
import { testWpMail, postWpMail } from '@gewest13/components';

export async function GET(req: any) {
  return testWpMail({
    req,
    api_url: WORDPRESS_API_URL,
    // NEVER EXPOSE THIS IN
    wordpress_username: process.env.WORDPRESS_USERNAME!,
    wordpress_password: process.env.WORDPRESS_PASSWORD!,
  });
}

export async function POST(req: any) {
  return postWpMail({
    req,
    api_url: WORDPRESS_API_URL,
    wordpress_username: process.env.WORDPRESS_USERNAME!,
    wordpress_password: process.env.WORDPRESS_PASSWORD!,
  });
}

Utils

lerp

Description

CSS

Comment out not needed css imports inside layout or app

import '@gewest13/components/dist/ColumnsContainer/ColumnsContainer.css';
import '@gewest13/components/dist/Image/Image.css';
import '@gewest13/components/dist/SharedFormConfirmation/SharedFormConfirmation.css';
import '@gewest13/components/dist/Swiper/Swiper.css';
import '@gewest13/components/dist/Video/Video.css';