@cruk/cruk-react-components 7.2.1 → 7.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/index.css
CHANGED
|
@@ -2815,18 +2815,12 @@ button {
|
|
|
2815
2815
|
display: none;
|
|
2816
2816
|
}
|
|
2817
2817
|
|
|
2818
|
-
&[data-is-animated="true"]
|
|
2818
|
+
&[data-is-animated="true"],
|
|
2819
|
+
&[data-is-animated="true"]::backdrop {
|
|
2819
2820
|
transition-behavior: allow-discrete;
|
|
2820
2821
|
transition-property: all;
|
|
2821
2822
|
transition-duration: 0.3s;
|
|
2822
2823
|
transition-timing-function: ease-in-out;
|
|
2823
|
-
|
|
2824
|
-
&::backdrop {
|
|
2825
|
-
transition-behavior: allow-discrete;
|
|
2826
|
-
transition-property: all;
|
|
2827
|
-
transition-duration: 0.3s;
|
|
2828
|
-
transition-timing-function: ease-in-out;
|
|
2829
|
-
}
|
|
2830
2824
|
}
|
|
2831
2825
|
|
|
2832
2826
|
&[open] {
|
|
@@ -2851,9 +2845,11 @@ button {
|
|
|
2851
2845
|
|
|
2852
2846
|
.close-button {
|
|
2853
2847
|
float: right;
|
|
2854
|
-
margin-
|
|
2848
|
+
margin-top: calc(var(--spacing-xs, 1rem) * -1);
|
|
2849
|
+
margin-right: calc(var(--spacing-xs, 0.5rem) * -1);
|
|
2855
2850
|
font-size: 1.2rem;
|
|
2856
2851
|
padding: 0;
|
|
2852
|
+
outline-offset: -0.5rem;
|
|
2857
2853
|
}
|
|
2858
2854
|
}
|
|
2859
2855
|
|
|
@@ -2965,14 +2961,23 @@ button {
|
|
|
2965
2961
|
}
|
|
2966
2962
|
|
|
2967
2963
|
.component-popover {
|
|
2968
|
-
|
|
2969
|
-
|
|
2970
|
-
|
|
2971
|
-
|
|
2972
|
-
|
|
2973
|
-
|
|
2974
|
-
|
|
2975
|
-
|
|
2964
|
+
[popovertarget] {
|
|
2965
|
+
--anchor-name: --popovertarget;
|
|
2966
|
+
position: relative;
|
|
2967
|
+
|
|
2968
|
+
/* Tether arrow */
|
|
2969
|
+
&::before {
|
|
2970
|
+
content: "";
|
|
2971
|
+
position: absolute;
|
|
2972
|
+
box-sizing: border-box;
|
|
2973
|
+
width: 1rem;
|
|
2974
|
+
height: 1rem;
|
|
2975
|
+
rotate: 45deg;
|
|
2976
|
+
transform-origin: center center center;
|
|
2977
|
+
background-color: var(--clr-popover-background, #fff);
|
|
2978
|
+
border: 1px solid var(--clr-cruk-grey-300, #c6c6c6);
|
|
2979
|
+
display: none;
|
|
2980
|
+
opacity: 0;
|
|
2976
2981
|
}
|
|
2977
2982
|
}
|
|
2978
2983
|
|
|
@@ -2996,43 +3001,30 @@ button {
|
|
|
2996
3001
|
opacity: 0;
|
|
2997
3002
|
}
|
|
2998
3003
|
|
|
2999
|
-
[
|
|
3000
|
-
|
|
3001
|
-
|
|
3002
|
-
|
|
3003
|
-
|
|
3004
|
+
&[data-is-animated="true"] {
|
|
3005
|
+
[popover],
|
|
3006
|
+
[popovertarget]::before {
|
|
3007
|
+
/* allows display none to block with animation*/
|
|
3008
|
+
transition-behavior: allow-discrete;
|
|
3009
|
+
transition-property: all;
|
|
3010
|
+
transition-duration: 0.2s;
|
|
3011
|
+
transition-timing-function: ease-in-out;
|
|
3004
3012
|
}
|
|
3005
3013
|
}
|
|
3006
3014
|
|
|
3007
|
-
|
|
3008
|
-
|
|
3009
|
-
|
|
3015
|
+
/* Animate popover */
|
|
3016
|
+
/* Animate tether arrow attached to button */
|
|
3017
|
+
[popover]:popover-open,
|
|
3018
|
+
[popovertarget]:has(+ :popover-open)::before {
|
|
3019
|
+
display: block;
|
|
3020
|
+
opacity: 1;
|
|
3010
3021
|
|
|
3011
|
-
|
|
3012
|
-
content: "";
|
|
3013
|
-
position: absolute;
|
|
3014
|
-
box-sizing: border-box;
|
|
3015
|
-
width: 1rem;
|
|
3016
|
-
height: 1rem;
|
|
3017
|
-
rotate: 45deg;
|
|
3018
|
-
transform-origin: center center center;
|
|
3019
|
-
background-color: var(--clr-popover-background, #fff);
|
|
3020
|
-
border: 1px solid var(--clr-cruk-grey-300, #c6c6c6);
|
|
3021
|
-
display: none;
|
|
3022
|
+
@starting-style {
|
|
3022
3023
|
opacity: 0;
|
|
3023
3024
|
}
|
|
3024
3025
|
}
|
|
3025
3026
|
|
|
3026
|
-
|
|
3027
|
-
&::before {
|
|
3028
|
-
display: block;
|
|
3029
|
-
opacity: 1;
|
|
3030
|
-
@starting-style {
|
|
3031
|
-
opacity: 0;
|
|
3032
|
-
}
|
|
3033
|
-
}
|
|
3034
|
-
}
|
|
3035
|
-
|
|
3027
|
+
/* Positioning variants*/
|
|
3036
3028
|
&[data-position="top"],
|
|
3037
3029
|
&:not([data-position]) {
|
|
3038
3030
|
[popover] {
|
|
@@ -3061,7 +3053,7 @@ button {
|
|
|
3061
3053
|
position-area: left;
|
|
3062
3054
|
position-try-fallbacks: --right, --top, --bottom;
|
|
3063
3055
|
}
|
|
3064
|
-
[popovertarget]
|
|
3056
|
+
[popovertarget]::before {
|
|
3065
3057
|
left: -0.5rem;
|
|
3066
3058
|
top: calc(50% - 0.5rem);
|
|
3067
3059
|
}
|
|
@@ -3072,11 +3064,14 @@ button {
|
|
|
3072
3064
|
position-area: right;
|
|
3073
3065
|
position-try-fallbacks: --left, --top, --bottom;
|
|
3074
3066
|
}
|
|
3075
|
-
[popovertarget]
|
|
3067
|
+
[popovertarget]::before {
|
|
3076
3068
|
right: -0.5rem;
|
|
3077
3069
|
top: calc(50% - 0.5rem);
|
|
3078
3070
|
}
|
|
3079
3071
|
}
|
|
3072
|
+
|
|
3073
|
+
/* anchor name only works within this wrapping class */
|
|
3074
|
+
anchor-scope: --popovertarget;
|
|
3080
3075
|
}
|
|
3081
3076
|
|
|
3082
3077
|
@position-try --bottom {
|
|
@@ -7,28 +7,26 @@ import React, { type HTMLAttributes, type ReactNode } from "react";
|
|
|
7
7
|
* - Modals are unmounted when closed.
|
|
8
8
|
* - Modal's "trap" focus in them, ensuring the keyboard navigation cycles through the modal, and not the rest of the page.
|
|
9
9
|
* ## Accessibility
|
|
10
|
-
* - Once the Modal is appeared on the screen, the focus must be within the Modal container which will enable the screen readers to be able to navigate within the Modal.
|
|
10
|
+
* - Once the Modal is appeared on the screen, the focus must be within the Modal container which will enable the screen readers to be able to navigate within the Modal.
|
|
11
|
+
* You may wish to hide the close button so that a user must click on another button to confirm a choice before the modal is closed. However closing with the 'ESC' key must always work,
|
|
12
|
+
* so the props which contains the function that allows the modal to close itself 'closeFunction' is always required.
|
|
11
13
|
*/
|
|
12
|
-
export declare function Modal({ modalName,
|
|
14
|
+
export declare function Modal({ modalName, startOpen, isAnimated, closeFunction, showCloseButton, children, ref: outerRef, style, ...htmlAttributes }: HTMLAttributes<HTMLDialogElement> & {
|
|
13
15
|
/** modal name used for aria-label */
|
|
14
16
|
modalName: string;
|
|
17
|
+
/** set if the modal start open */
|
|
18
|
+
startOpen: boolean;
|
|
15
19
|
/** callback function called on modal close */
|
|
16
20
|
closeFunction?: () => void;
|
|
17
21
|
/** flag to reveal close button with cross in the top right of modal */
|
|
18
22
|
showCloseButton?: boolean;
|
|
19
|
-
/** set max width of modal */
|
|
20
|
-
maxWidth?: string;
|
|
21
|
-
/** set space from top of view port that modal appears */
|
|
22
|
-
top?: string;
|
|
23
|
-
/** children components */
|
|
24
|
-
children?: ReactNode;
|
|
25
|
-
/** width of modal */
|
|
26
|
-
width?: string;
|
|
27
23
|
/** turn on animate in modal */
|
|
28
24
|
isAnimated?: boolean;
|
|
29
|
-
/**
|
|
30
|
-
|
|
25
|
+
/** children components inside modal */
|
|
26
|
+
children?: ReactNode;
|
|
31
27
|
/** ref to the dialog element */
|
|
32
28
|
ref?: React.RefObject<HTMLDialogElement | null>;
|
|
29
|
+
/** additional style attributes for the dialog element */
|
|
30
|
+
style?: React.CSSProperties;
|
|
33
31
|
}): React.JSX.Element;
|
|
34
32
|
export default Modal;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{__rest as e,__assign as o}from"../../../node_modules/tslib/tslib.es6.js";import n,{useRef as t,useEffect as
|
|
1
|
+
import{__rest as e,__assign as o}from"../../../node_modules/tslib/tslib.es6.js";import n,{useRef as t,useEffect as l}from"react";import{faClose as r}from"../../../node_modules/@fortawesome/free-solid-svg-icons/index.js";import{IconFa as i}from"../IconFa/index.js";import{Button as a}from"../Button/index.js";function s(s){var c=s.modalName,d=s.startOpen,u=void 0===d||d,m=s.isAnimated,f=void 0===m||m,p=s.closeFunction,v=s.showCloseButton,y=s.children,w=s.ref,b=s.style,h=e(s,["modalName","startOpen","isAnimated","closeFunction","showCloseButton","children","ref","style"]),E=t(null),g=null!=w?w:E,j=n.useCallback(function(){var e,o;(null===(e=g.current)||void 0===e?void 0:e.hasAttribute("open"))&&(console.log("closing modal"),null===(o=g.current)||void 0===o||o.close(),p&&p())},[p,g]);return l(function(){var e=function(e){"Escape"===e.key&&j()};if("undefined"!=typeof window)return document.body.style.overflow="hidden",document.addEventListener("keydown",e),function(){"undefined"!=typeof window&&(document.body.style.overflow="unset",document.removeEventListener("keydown",e))}},[j]),l(function(){u&&g&&g.current&&g.current.showModal()},[u,g]),n.createElement(n.Fragment,null,n.createElement("dialog",o({ref:g,className:["component-modal","spacing-props","colour-props"].join(" "),"aria-modal":"true","aria-label":c,open:!1,"data-is-animated":f,style:b},h),v||p?n.createElement(a,{className:"component-button close-button","aria-label":"close",appearance:"tertiary",onClick:function(){j()}},n.createElement(i,{faIcon:r})):null,y))}export{s as Modal};
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../../src/components/Modal/index.tsx"],"sourcesContent":["import React, {\n type HTMLAttributes,\n type ReactNode,\n useEffect,\n useRef,\n} from \"react\";\nimport { faClose } from \"@fortawesome/free-solid-svg-icons\";\n\nimport { IconFa } from \"../IconFa\";\n\nimport Button from \"../Button\";\n\n/**\n *\n * Use a modal to display content over top of the rest of the site which must be interacted with before the user can continue.\n * ## How modals work\n * - Modals are positioned over everything else in the document and remove scroll from the \"body\" tag so that modal content scrolls instead.\n * - Modals are unmounted when closed.\n * - Modal's \"trap\" focus in them, ensuring the keyboard navigation cycles through the modal, and not the rest of the page.\n * ## Accessibility\n * - Once the Modal is appeared on the screen, the focus must be within the Modal container which will enable the screen readers to be able to navigate within the Modal
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../../src/components/Modal/index.tsx"],"sourcesContent":["import React, {\n type HTMLAttributes,\n type ReactNode,\n useEffect,\n useRef,\n} from \"react\";\nimport { faClose } from \"@fortawesome/free-solid-svg-icons\";\n\nimport { IconFa } from \"../IconFa\";\n\nimport Button from \"../Button\";\n\n/**\n *\n * Use a modal to display content over top of the rest of the site which must be interacted with before the user can continue.\n * ## How modals work\n * - Modals are positioned over everything else in the document and remove scroll from the \"body\" tag so that modal content scrolls instead.\n * - Modals are unmounted when closed.\n * - Modal's \"trap\" focus in them, ensuring the keyboard navigation cycles through the modal, and not the rest of the page.\n * ## Accessibility\n * - Once the Modal is appeared on the screen, the focus must be within the Modal container which will enable the screen readers to be able to navigate within the Modal.\n * You may wish to hide the close button so that a user must click on another button to confirm a choice before the modal is closed. However closing with the 'ESC' key must always work,\n * so the props which contains the function that allows the modal to close itself 'closeFunction' is always required.\n */\nexport function Modal({\n modalName,\n startOpen = true,\n isAnimated = true,\n closeFunction,\n showCloseButton,\n children,\n ref: outerRef,\n style,\n ...htmlAttributes\n}: HTMLAttributes<HTMLDialogElement> & {\n /** modal name used for aria-label */\n modalName: string;\n /** set if the modal start open */\n startOpen: boolean;\n /** callback function called on modal close */\n closeFunction?: () => void;\n /** flag to reveal close button with cross in the top right of modal */\n showCloseButton?: boolean;\n /** turn on animate in modal */\n isAnimated?: boolean;\n /** children components inside modal */\n children?: ReactNode;\n /** ref to the dialog element */\n ref?: React.RefObject<HTMLDialogElement | null>;\n /** additional style attributes for the dialog element */\n style?: React.CSSProperties;\n}) {\n const innerRef = useRef<HTMLDialogElement>(null);\n const ref = outerRef ?? innerRef;\n\n const doClose = React.useCallback((): void => {\n if (!ref.current?.hasAttribute(\"open\")) return;\n console.log(\"closing modal\");\n ref.current?.close();\n if (closeFunction) {\n closeFunction();\n }\n }, [closeFunction, ref]);\n\n useEffect(() => {\n const closeByEsc = (event: KeyboardEvent): void => {\n if (event.key === \"Escape\") {\n doClose();\n }\n };\n if (typeof window === `undefined`) {\n return undefined;\n }\n document.body.style.overflow = \"hidden\";\n document.addEventListener(\"keydown\", closeByEsc);\n\n return () => {\n if (typeof window === `undefined`) {\n return;\n }\n document.body.style.overflow = \"unset\";\n document.removeEventListener(\"keydown\", closeByEsc);\n };\n }, [doClose]);\n\n useEffect(() => {\n if (startOpen && ref && ref.current) {\n ref.current.showModal();\n }\n }, [startOpen, ref]);\n\n return (\n <>\n <dialog\n ref={ref}\n className={[\"component-modal\", \"spacing-props\", \"colour-props\"].join(\n \" \",\n )}\n aria-modal=\"true\"\n aria-label={modalName}\n open={false}\n data-is-animated={isAnimated}\n style={style}\n {...htmlAttributes}\n >\n {showCloseButton || closeFunction ? (\n <Button\n className=\"component-button close-button\"\n aria-label=\"close\"\n appearance=\"tertiary\"\n onClick={() => {\n doClose();\n }}\n >\n <IconFa faIcon={faClose} />\n </Button>\n ) : null}\n {children}\n </dialog>\n </>\n );\n}\n\nexport default Modal;\n"],"names":["Modal","_a","modalName","_b","startOpen","_c","isAnimated","closeFunction","showCloseButton","children","outerRef","ref","style","htmlAttributes","__rest","innerRef","useRef","doClose","React","useCallback","current","hasAttribute","console","log","close","useEffect","closeByEsc","event","key","window","document","body","overflow","addEventListener","removeEventListener","showModal","createElement","Fragment","__assign","className","join","open","Button","appearance","onClick","IconFa","faIcon","faClose"],"mappings":"oTAwBM,SAAUA,EAAMC,GACpB,IAAAC,EAASD,EAAAC,UACTC,EAAAF,EAAAG,UAAAA,OAAS,IAAAD,GAAOA,EAChBE,EAAAJ,EAAAK,WAAAA,OAAU,IAAAD,GAAOA,EACjBE,EAAaN,EAAAM,cACbC,EAAeP,EAAAO,gBACfC,aACKC,EAAQT,EAAAU,IACbC,EAAKX,EAAAW,MACFC,EAAcC,EAAAb,EATG,mGA4Bdc,EAAWC,EAA0B,MACrCL,EAAMD,QAAAA,EAAYK,EAElBE,EAAUC,EAAMC,YAAY,oBAChB,QAAXlB,EAAAU,EAAIS,eAAO,IAAAnB,OAAA,EAAAA,EAAEoB,aAAa,WAC/BC,QAAQC,IAAI,iBACD,QAAXpB,EAAAQ,EAAIS,mBAAOjB,GAAAA,EAAEqB,QACTjB,GACFA,IAEJ,EAAG,CAACA,EAAeI,IA6BnB,OA3BAc,EAAU,WACR,IAAMC,EAAa,SAACC,GACA,WAAdA,EAAMC,KACRX,GAEJ,EACA,GAAsB,oBAAXY,OAMX,OAHAC,SAASC,KAAKnB,MAAMoB,SAAW,SAC/BF,SAASG,iBAAiB,UAAWP,GAE9B,WACiB,oBAAXG,SAGXC,SAASC,KAAKnB,MAAMoB,SAAW,QAC/BF,SAASI,oBAAoB,UAAWR,GAC1C,CACF,EAAG,CAACT,IAEJQ,EAAU,WACJrB,GAAaO,GAAOA,EAAIS,SAC1BT,EAAIS,QAAQe,WAEhB,EAAG,CAAC/B,EAAWO,IAGbO,EAAAkB,cAAAlB,EAAAmB,SAAA,KACEnB,EAAAkB,cAAA,SAAAE,EAAA,CACE3B,IAAKA,EACL4B,UAAW,CAAC,kBAAmB,gBAAiB,gBAAgBC,KAC9D,KACD,aACU,OAAM,aACLtC,EACZuC,MAAM,EAAK,mBACOnC,EAClBM,MAAOA,GACHC,GAEHL,GAAmBD,EAClBW,EAAAkB,cAACM,EAAM,CACLH,UAAU,gCAA+B,aAC9B,QACXI,WAAW,WACXC,QAAS,WACP3B,GACF,GAEAC,EAAAkB,cAACS,EAAM,CAACC,OAAQC,KAEhB,KACHtC,GAIT"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cruk/cruk-react-components",
|
|
3
|
-
"version": "7.2.
|
|
3
|
+
"version": "7.2.2",
|
|
4
4
|
"description": "React components implementing CRUK, RFL, SU2C & Bowelbabe designs",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"publishConfig": {
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
"@rollup/plugin-commonjs": "^29.0.0",
|
|
50
50
|
"@rollup/plugin-node-resolve": "^15.2.3",
|
|
51
51
|
"@rollup/plugin-terser": "^0.4.4",
|
|
52
|
-
"@rollup/plugin-typescript": "^
|
|
52
|
+
"@rollup/plugin-typescript": "^12.0.0",
|
|
53
53
|
"@swc/core": "1.9.3",
|
|
54
54
|
"@storybook/addon-a11y": "^10",
|
|
55
55
|
"@storybook/addon-docs": "^10",
|