summaryrefslogtreecommitdiffstats
path: root/public/prism/prism-qore.js
Commit message (Expand)AuthorAgeFilesLines
* chore: add prismjs for syntax highlightingArmand Philippot2021-12-301-0/+23
id='n5' href='#n5'>5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
import {
  useId,
  type CSSProperties,
  type HTMLAttributes,
  type ForwardRefRenderFunction,
  forwardRef,
} from 'react';
import { Label } from '../../forms';
import styles from './progress-bar.module.scss';

export type ProgressBarProps = Omit<
  HTMLAttributes<HTMLDivElement>,
  'children'
> & {
  /**
   * Current value.
   */
  current: number;
  /**
   * Should the progress bar be centered inside its parent?
   *
   * @default false
   */
  isCentered?: boolean;
  /**
   * Should the progress bar indicate a loading state?
   *
   * @default false
   */
  isLoading?: boolean;
  /**
   * The progress bar label.
   */
  label: string;
  /**
   * Maximal value.
   */
  max: number;
};

const ProgressBarWithRef: ForwardRefRenderFunction<
  HTMLDivElement,
  ProgressBarProps
> = (
  {
    className = '',
    current,
    isCentered = false,
    isLoading = false,
    label,
    max,
    ...props
  },
  ref
) => {
  const wrapperClass = [
    styles.wrapper,
    styles[isCentered ? 'wrapper--centered' : ''],
    className,
  ].join(' ');
  const progressClass = `${styles.progress} ${
    styles[isLoading ? 'progress--loading' : '']
  }`;
  const progressBarId = useId();
  const progressValueFallback = `${current}/${max}`;
  // eslint-disable-next-line @typescript-eslint/no-magic-numbers -- Percent
  const progressPercent = `${((max - current) / max) * 100}%`;

  return (
    <div {...props} className={wrapperClass} ref={ref}>
      <Label
        className={styles.label}
        htmlFor={progressBarId}
        // eslint-disable-next-line react/jsx-no-literals -- Size allowed
        size="md"
      >
        {label}
      </Label>
      <div
        className={progressClass}
        style={{ '--currentProgress': `-${progressPercent}` } as CSSProperties}
      >
        <progress
          aria-valuemin={0}
          aria-valuemax={max}
          aria-valuenow={current}
          id={progressBarId}
          max={max}
          value={isLoading ? undefined : current}
        >
          {progressValueFallback}
        </progress>
        <div aria-hidden className={styles.progress__bar} />
      </div>
    </div>
  );
};

/**
 * ProgressBar component
 *
 * Render a progress bar.
 */
export const ProgressBar = forwardRef(ProgressBarWithRef);