summaryrefslogtreecommitdiffstats
path: root/public/prism/prism-ebnf.min.js
blob: 43c59fd22e828e9e229e30b5815092b05451bdd8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
Prism.languages.ebnf = {
  comment: /\(\*[\s\S]*?\*\)/,
  string: { pattern: /"[^"\r\n]*"|'[^'\r\n]*'/, greedy: !0 },
  special: { pattern: /\?[^?\r\n]*\?/, greedy: !0, alias: 'class-name' },
  definition: {
    pattern: /^([\t ]*)[a-z]\w*(?:[ \t]+[a-z]\w*)*(?=\s*=)/im,
    lookbehind: !0,
    alias: ['rule', 'keyword'],
  },
  rule: /\b[a-z]\w*(?:[ \t]+[a-z]\w*)*\b/i,
  punctuation: /\([:/]|[:/]\)|[.,;()[\]{}]/,
  operator: /[-=|*/!]/,
};
/ .highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */ .highlight .ge { font-style: italic } /* Generic.Emph */ .highlight .gr { color: #aa0000 } /* Generic.Error */ .highlight .gh { color: #333333 } /* Generic.Heading */ .highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ .highlight .go { color: #888888 } /* Generic.Output */ .highlight .gp { color: #555555 } /* Generic.Prompt */ .highlight .gs { font-weight: bold } /* Generic.Strong */ .highlight .gu { color: #666666 } /* Generic.Subheading */ .highlight .gt { color: #aa0000 } /* Generic.Traceback */ .highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */ .highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */ .highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */ .highlight .kp { color: #008800 } /* Keyword.Pseudo */ .highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */ .highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */ .highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */ .highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */ .highlight .na { color: #336699 } /* Name.Attribute */ .highlight .nb { color: #003388 } /* Name.Builtin */ .highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */ .highlight .no { color: #003366; font-weight: bold } /* Name.Constant */ .highlight .nd { color: #555555 } /* Name.Decorator */ .highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */ .highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */ .highlight .nl { color: #336699; font-style: italic } /* Name.Label */ .highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */ .highlight .py { color: #336699; font-weight: bold } /* Name.Property */ .highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */ .highlight .nv { color: #336699 } /* Name.Variable */ .highlight .ow { color: #008800 } /* Operator.Word */ .highlight .w { color: #bbbbbb } /* Text.Whitespace */ .highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */ .highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */ .highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */ .highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */ .highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ .highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */ .highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */ .highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */ .highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */ .highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
/* eslint-disable max-statements */
import {
  type ChangeEvent,
  type FC,
  type FormEvent,
  type ReactNode,
  useState,
  useCallback,
  useMemo,
} from 'react';
import { useIntl } from 'react-intl';
import { Button, Form, Input, Label, Spinner, TextArea } from '../../../atoms';
import { LabelledField } from '../../../molecules';
import styles from './contact-form.module.scss';

export type ContactFormData = {
  email: string;
  message: string;
  name: string;
  object: string;
};

export type ContactFormProps = {
  /**
   * Set additional classnames to the form wrapper.
   */
  className?: string;
  /**
   * Pass a component to print a success/error message.
   */
  Notice?: ReactNode;
  /**
   * A callback function to send mail.
   */
  sendMail: (data: ContactFormData, reset: () => void) => Promise<void>;
};

/**
 * ContactForm component
 *
 * Render a contact form.
 */
export const ContactForm: FC<ContactFormProps> = ({
  className = '',
  Notice,
  sendMail,
}) => {
  const formClass = `${styles.form} ${className}`;
  const intl = useIntl();
  const emptyForm: ContactFormData = useMemo(() => {
    return {
      email: '',
      message: '',
      name: '',
      object: '',
    };
  }, []);
  const [data, setData] = useState(emptyForm);
  const [isSubmitting, setIsSubmitting] = useState<boolean>(false);

  /**
   * Reset all the form fields.
   */
  const resetForm = useCallback(() => {
    setData(emptyForm);
    setIsSubmitting(false);
  }, [emptyForm]);

  const updateForm = useCallback(
    (e: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
      switch (e.target.name) {
        case 'email':
          setData((prevData) => {
            return { ...prevData, email: e.target.value };
          });
          break;
        case 'message':
          setData((prevData) => {
            return { ...prevData, message: e.target.value };
          });
          break;
        case 'name':
          setData((prevData) => {
            return { ...prevData, name: e.target.value };
          });
          break;
        case 'object':
          setData((prevData) => {
            return { ...prevData, object: e.target.value };
          });
          break;
        default:
          break;
      }
    },
    []
  );

  const formName = intl.formatMessage({
    defaultMessage: 'Contact form',
    description: 'ContactForm: form accessible name',
    id: 'HFdzae',
  });

  const nameLabel = intl.formatMessage({
    defaultMessage: 'Name:',
    description: 'ContactForm: name label',
    id: '1dCuCx',
  });

  const emailLabel = intl.formatMessage({
    defaultMessage: 'Email:',
    description: 'ContactForm: email label',
    id: 'w4B5PA',
  });

  const objectLabel = intl.formatMessage({
    defaultMessage: 'Object:',
    description: 'ContactForm: object label',
    id: 's8/tyz',
  });

  const messageLabel = intl.formatMessage({
    defaultMessage: 'Message:',
    description: 'ContactForm: message label',
    id: 'yN5P+m',
  });

  const loadingMsg = intl.formatMessage({
    defaultMessage: 'Sending mail...',
    description: 'ContactForm: spinner message on submit',
    id: 'xaqaYQ',
  });

  const submitHandler = useCallback(
    async (e: FormEvent) => {
      e.preventDefault();
      setIsSubmitting(true);
      await sendMail(data, resetForm).then(() => setIsSubmitting(false));
    },
    [data, resetForm, sendMail]
  );

  return (
    <Form aria-label={formName} className={formClass} onSubmit={submitHandler}>
      <LabelledField
        className={styles.field}
        field={
          <Input
            id="contact-name"
            isRequired
            name="name"
            onChange={updateForm}
            type="text"
            value={data.name}
          />
        }
        label={
          <Label htmlFor="contact-name" isRequired>
            {nameLabel}
          </Label>
        }
      />
      <LabelledField
        className={styles.field}
        field={
          <Input
            id="contact-email"
            isRequired
            name="email"
            onChange={updateForm}
            type="email"
            value={data.email}
          />
        }
        label={
          <Label htmlFor="contact-email" isRequired>
            {emailLabel}
          </Label>
        }
      />
      <LabelledField
        className={styles.field}
        field={
          <Input
            id="contact-object"
            name="object"
            onChange={updateForm}
            type="text"
            value={data.object}
          />
        }
        label={<Label htmlFor="contact-object">{objectLabel}</Label>}
      />
      <LabelledField
        className={styles.field}
        field={
          <TextArea
            id="contact-message"
            isRequired
            name="message"
            onChange={updateForm}
            value={data.message}
          />
        }
        label={
          <Label htmlFor="contact-message" isRequired>
            {messageLabel}
          </Label>
        }
      />
      <Button type="submit" kind="primary" className={styles.button}>
        {intl.formatMessage({
          defaultMessage: 'Send',
          description: 'ContactForm: send button',
          id: 'VkAnvv',
        })}
      </Button>
      {isSubmitting ? <Spinner>{loadingMsg}</Spinner> : null}
      {Notice}
    </Form>
  );
};