Skip to content

Commit

Permalink
feat(ffe-modals-react): basic modal
Browse files Browse the repository at this point in the history
  • Loading branch information
Peter Hellstrand committed Jun 20, 2024
1 parent 0301171 commit 41bb0a4
Show file tree
Hide file tree
Showing 7 changed files with 115 additions and 4 deletions.
1 change: 1 addition & 0 deletions packages/ffe-modals-react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"test:watch": "ffe-buildtool jest --watch"
},
"dependencies": {
"@sb1/ffe-icons-react": "^10.0.5",
"@sb1/ffe-modals": "^0.1.3"
},
"devDependencies": {
Expand Down
30 changes: 30 additions & 0 deletions packages/ffe-modals-react/src/CloseButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import React from 'react';
import classnames from 'classnames';
import { Icon } from '@sb1/ffe-icons-react';
import { Locale } from './types';
import { txt } from './texts';

const closeIcon =
'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgLTk2MCA5NjAgOTYwIiB3aWR0aD0iMjQiPjxwYXRoIGQ9Ik00ODAtNDM3Ljg0NyAyNzcuMDc2LTIzNC45MjRxLTguMzA3IDguMzA4LTIwLjg4NCA4LjUtMTIuNTc2LjE5My0yMS4yNjgtOC41LTguNjkzLTguNjkyLTguNjkzLTIxLjA3NnQ4LjY5My0yMS4wNzZMNDM3Ljg0Ny00ODAgMjM0LjkyNC02ODIuOTI0cS04LjMwOC04LjMwNy04LjUtMjAuODg0LS4xOTMtMTIuNTc2IDguNS0yMS4yNjggOC42OTItOC42OTMgMjEuMDc2LTguNjkzdDIxLjA3NiA4LjY5M0w0ODAtNTIyLjE1M2wyMDIuOTI0LTIwMi45MjNxOC4zMDctOC4zMDggMjAuODg0LTguNSAxMi41NzYtLjE5MyAyMS4yNjggOC41IDguNjkzIDguNjkyIDguNjkzIDIxLjA3NnQtOC42OTMgMjEuMDc2TDUyMi4xNTMtNDgwbDIwMi45MjMgMjAyLjkyNHE4LjMwOCA4LjMwNyA4LjUgMjAuODg0LjE5MyAxMi41NzYtOC41IDIxLjI2OC04LjY5MiA4LjY5My0yMS4wNzYgOC42OTN0LTIxLjA3Ni04LjY5M0w0ODAtNDM3Ljg0N1oiLz48L3N2Zz4=';

interface CloseButtonProps
extends Omit<React.ComponentPropsWithoutRef<'button'>, 'type'> {
locale: Locale;
}

export const CloseButton: React.FC<CloseButtonProps> = ({
className,
locale,
...rest
}) => {
return (
<button
type="button"
className={classnames('ffe-modal__close')}
aria-label={txt[locale].close}
{...rest}
>
<Icon fileUrl={closeIcon} size="md" />
</button>
);
};
64 changes: 60 additions & 4 deletions packages/ffe-modals-react/src/Modal.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,63 @@
import React from 'react';
import React, { useImperativeHandle, useRef } from 'react';
import classnames from 'classnames';
import { CloseButton } from './CloseButton';
import { Locale } from './types';

export interface ModalProps {}
export interface ModalProps extends React.ComponentPropsWithoutRef<'dialog'> {
/** Id of modal heading */
ariaLabelledby: string;
/** Id of modal heading */
locale?: Locale;
}

export const Modal: React.FC<ModalProps> = () => {
return null;
export type ModalHandle = {
readonly open: () => void;
readonly close: () => void;
};

export const Modal = React.forwardRef<ModalHandle, ModalProps>(
(
{
children,
onClick,
ariaLabelledby,
className,
locale = 'nb',
...rest
},
ref,
) => {
const modalRef = useRef<HTMLDialogElement>(null);

useImperativeHandle(ref, () => ({
open: () => {
modalRef.current?.showModal();
},
close: () => {
modalRef.current?.close();
},
}));

return (
// eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions
<dialog
{...rest}
ref={modalRef}
className={classnames('ffe-body', 'ffe-modal', className)}
aria-labelledby={ariaLabelledby}
onClick={event => {
const target = event.target as HTMLDialogElement;
if (target.nodeName === 'DIALOG') {
target.close();
}
onClick?.(event);
}}
>
<div className="ffe-modal__body">
<CloseButton onClick={() => modalRef.current?.close()} />
{children}
</div>
</dialog>
);
},
);
11 changes: 11 additions & 0 deletions packages/ffe-modals-react/src/ModalBlock.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import React from 'react';
import classnames from 'classnames';

export const ModalBlock: React.FC<React.ComponentPropsWithoutRef<'div'>> = ({
className,
...rest
}) => {
return (
<div className={classnames('ffe-modal__block', className)} {...rest} />
);
};
1 change: 1 addition & 0 deletions packages/ffe-modals-react/src/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export { Modal } from './Modal';
export { ModalBlock } from './ModalBlock';
11 changes: 11 additions & 0 deletions packages/ffe-modals-react/src/texts.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
const nb = {
close: 'Lukk',
} as const;
const nn = {
close: 'Lukk',
} as const;
const en = {
close: 'Close',
} as const;

export const txt = { nb, nn, en };
1 change: 1 addition & 0 deletions packages/ffe-modals-react/src/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export type Locale = 'nb' | 'nn' | 'en';

0 comments on commit 41bb0a4

Please sign in to comment.