@loomhq/lens 10.48.0 → 10.48.1

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.
@@ -1,8 +1,14 @@
1
- import Backdrop from '../backdrop/backdrop';
2
1
  import React from 'react';
3
- declare const ModalCardWrapper: import("@emotion/styled-base").StyledComponent<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, ModalCardProps, object>;
4
- export declare const ModalCard: ({ children, onCloseClick, maxWidth, ...props }: ModalCardProps & React.ComponentProps<typeof ModalCardWrapper>) => JSX.Element;
5
- declare const Modal: ({ children, isOpen, mainButton, secondaryButton, alternativeButton, title, onCloseClick, onBackgroundClick, onKeyDown, hasDividers, maxWidth, zIndex, ...props }: ModalProps & React.ComponentProps<typeof Backdrop>) => JSX.Element;
2
+ declare const ModalCardWrapper: import("@emotion/styled-base").StyledComponent<React.DetailedHTMLProps<React.DialogHTMLAttributes<HTMLDialogElement>, HTMLDialogElement>, ModalCardProps, object>;
3
+ export declare const ModalCard: ({ children, onCloseClick, isOpen, maxWidth, ref, ...props }: ModalCardProps & React.ComponentProps<typeof ModalCardWrapper>) => JSX.Element;
4
+ declare const Modal: React.ForwardRefExoticComponent<Pick<ModalProps & {
5
+ isOpen?: boolean;
6
+ children?: React.ReactNode;
7
+ zIndex?: number;
8
+ backgroundColor?: string;
9
+ } & React.ClassAttributes<HTMLDivElement> & React.HTMLAttributes<HTMLDivElement> & {
10
+ theme?: object;
11
+ }, "key" | "defaultChecked" | "defaultValue" | "suppressContentEditableWarning" | "suppressHydrationWarning" | "accessKey" | "className" | "contentEditable" | "contextMenu" | "dir" | "draggable" | "hidden" | "id" | "lang" | "placeholder" | "slot" | "spellCheck" | "style" | "tabIndex" | "title" | "translate" | "radioGroup" | "role" | "about" | "datatype" | "inlist" | "prefix" | "property" | "resource" | "typeof" | "vocab" | "autoCapitalize" | "autoCorrect" | "autoSave" | "color" | "itemProp" | "itemScope" | "itemType" | "itemID" | "itemRef" | "results" | "security" | "unselectable" | "inputMode" | "is" | "aria-activedescendant" | "aria-atomic" | "aria-autocomplete" | "aria-busy" | "aria-checked" | "aria-colcount" | "aria-colindex" | "aria-colspan" | "aria-controls" | "aria-current" | "aria-describedby" | "aria-details" | "aria-disabled" | "aria-dropeffect" | "aria-errormessage" | "aria-expanded" | "aria-flowto" | "aria-grabbed" | "aria-haspopup" | "aria-hidden" | "aria-invalid" | "aria-keyshortcuts" | "aria-label" | "aria-labelledby" | "aria-level" | "aria-live" | "aria-modal" | "aria-multiline" | "aria-multiselectable" | "aria-orientation" | "aria-owns" | "aria-placeholder" | "aria-posinset" | "aria-pressed" | "aria-readonly" | "aria-relevant" | "aria-required" | "aria-roledescription" | "aria-rowcount" | "aria-rowindex" | "aria-rowspan" | "aria-selected" | "aria-setsize" | "aria-sort" | "aria-valuemax" | "aria-valuemin" | "aria-valuenow" | "aria-valuetext" | "children" | "dangerouslySetInnerHTML" | "onCopy" | "onCopyCapture" | "onCut" | "onCutCapture" | "onPaste" | "onPasteCapture" | "onCompositionEnd" | "onCompositionEndCapture" | "onCompositionStart" | "onCompositionStartCapture" | "onCompositionUpdate" | "onCompositionUpdateCapture" | "onFocus" | "onFocusCapture" | "onBlur" | "onBlurCapture" | "onChange" | "onChangeCapture" | "onBeforeInput" | "onBeforeInputCapture" | "onInput" | "onInputCapture" | "onReset" | "onResetCapture" | "onSubmit" | "onSubmitCapture" | "onInvalid" | "onInvalidCapture" | "onLoad" | "onLoadCapture" | "onError" | "onErrorCapture" | "onKeyDown" | "onKeyDownCapture" | "onKeyPress" | "onKeyPressCapture" | "onKeyUp" | "onKeyUpCapture" | "onAbort" | "onAbortCapture" | "onCanPlay" | "onCanPlayCapture" | "onCanPlayThrough" | "onCanPlayThroughCapture" | "onDurationChange" | "onDurationChangeCapture" | "onEmptied" | "onEmptiedCapture" | "onEncrypted" | "onEncryptedCapture" | "onEnded" | "onEndedCapture" | "onLoadedData" | "onLoadedDataCapture" | "onLoadedMetadata" | "onLoadedMetadataCapture" | "onLoadStart" | "onLoadStartCapture" | "onPause" | "onPauseCapture" | "onPlay" | "onPlayCapture" | "onPlaying" | "onPlayingCapture" | "onProgress" | "onProgressCapture" | "onRateChange" | "onRateChangeCapture" | "onSeeked" | "onSeekedCapture" | "onSeeking" | "onSeekingCapture" | "onStalled" | "onStalledCapture" | "onSuspend" | "onSuspendCapture" | "onTimeUpdate" | "onTimeUpdateCapture" | "onVolumeChange" | "onVolumeChangeCapture" | "onWaiting" | "onWaitingCapture" | "onAuxClick" | "onAuxClickCapture" | "onClick" | "onClickCapture" | "onContextMenu" | "onContextMenuCapture" | "onDoubleClick" | "onDoubleClickCapture" | "onDrag" | "onDragCapture" | "onDragEnd" | "onDragEndCapture" | "onDragEnter" | "onDragEnterCapture" | "onDragExit" | "onDragExitCapture" | "onDragLeave" | "onDragLeaveCapture" | "onDragOver" | "onDragOverCapture" | "onDragStart" | "onDragStartCapture" | "onDrop" | "onDropCapture" | "onMouseDown" | "onMouseDownCapture" | "onMouseEnter" | "onMouseLeave" | "onMouseMove" | "onMouseMoveCapture" | "onMouseOut" | "onMouseOutCapture" | "onMouseOver" | "onMouseOverCapture" | "onMouseUp" | "onMouseUpCapture" | "onSelect" | "onSelectCapture" | "onTouchCancel" | "onTouchCancelCapture" | "onTouchEnd" | "onTouchEndCapture" | "onTouchMove" | "onTouchMoveCapture" | "onTouchStart" | "onTouchStartCapture" | "onPointerDown" | "onPointerDownCapture" | "onPointerMove" | "onPointerMoveCapture" | "onPointerUp" | "onPointerUpCapture" | "onPointerCancel" | "onPointerCancelCapture" | "onPointerEnter" | "onPointerEnterCapture" | "onPointerLeave" | "onPointerLeaveCapture" | "onPointerOver" | "onPointerOverCapture" | "onPointerOut" | "onPointerOutCapture" | "onGotPointerCapture" | "onGotPointerCaptureCapture" | "onLostPointerCapture" | "onLostPointerCaptureCapture" | "onScroll" | "onScrollCapture" | "onWheel" | "onWheelCapture" | "onAnimationStart" | "onAnimationStartCapture" | "onAnimationEnd" | "onAnimationEndCapture" | "onAnimationIteration" | "onAnimationIterationCapture" | "onTransitionEnd" | "onTransitionEndCapture" | "css" | "backgroundColor" | "maxWidth" | "zIndex" | "theme" | "isOpen" | "onCloseClick" | "hasDividers" | "mainButton" | "secondaryButton" | "alternativeButton" | "onBackgroundClick"> & React.RefAttributes<HTMLDialogElement>>;
6
12
  declare type ModalProps = {
7
13
  children?: React.ReactNode;
8
14
  isOpen?: boolean;
@@ -19,6 +25,7 @@ declare type ModalProps = {
19
25
  };
20
26
  declare type ModalCardProps = {
21
27
  children?: React.ReactNode;
28
+ isOpen?: boolean;
22
29
  onCloseClick?: React.ReactEventHandler;
23
30
  maxWidth?: number | string;
24
31
  };
@@ -9,11 +9,12 @@ var __rest = (this && this.__rest) || function (s, e) {
9
9
  }
10
10
  return t;
11
11
  };
12
+ import FocusTrap from 'focus-trap-react';
12
13
  import { getColorValue, getRadius, getShadow, getSize, u, } from '../../utilities';
13
14
  import Backdrop from '../backdrop/backdrop';
14
15
  import Container from '../container/container';
15
16
  import IconButton from '../icon-button/icon-button';
16
- import React from 'react';
17
+ import React, { useEffect } from 'react';
17
18
  import Spacer from '../spacer/spacer';
18
19
  import { SvgClose } from '../icon/available-icons';
19
20
  import Text from '../text/text';
@@ -25,7 +26,7 @@ const ContentWrapper = styled.div `
25
26
  position: relative;
26
27
  max-height: ${modalCardHeight};
27
28
  `;
28
- const ModalCardWrapper = styled.div `
29
+ const ModalCardWrapper = styled.dialog `
29
30
  max-height: ${modalCardHeight};
30
31
  top: 15vh;
31
32
  background-color: ${getColorValue('overlay')};
@@ -35,6 +36,12 @@ const ModalCardWrapper = styled.div `
35
36
  margin: 0 auto;
36
37
  position: relative;
37
38
  overflow: auto;
39
+ // TODO: LNS-150: Bake dialog resets into native resets file
40
+ border: 0;
41
+ padding: 0;
42
+ &::backdrop {
43
+ background: var(--lns-color-overlay);
44
+ }
38
45
  `;
39
46
  const CloseIconSection = styled.div `
40
47
  position: absolute;
@@ -87,18 +94,38 @@ const ModalCardChildrenSection = styled.div `
87
94
  }
88
95
  `;
89
96
  export const ModalCard = (_a) => {
90
- var { children, onCloseClick, maxWidth = 60 } = _a, props = __rest(_a, ["children", "onCloseClick", "maxWidth"]);
91
- return (React.createElement(ModalCardWrapper, Object.assign({ maxWidth: maxWidth, onClick: e => e.stopPropagation() }, props),
92
- onCloseClick && (React.createElement(CloseIconSection, null,
93
- React.createElement(IconButton, { altText: "Close", icon: React.createElement(SvgClose, null), onClick: onCloseClick }))),
94
- React.createElement(ModalCardChildrenSection, null, children)));
97
+ // TODO: LNS-151: Abstract into useKeyDown hook for reuse
98
+ var { children, onCloseClick, isOpen, maxWidth = 60, ref } = _a, props = __rest(_a, ["children", "onCloseClick", "isOpen", "maxWidth", "ref"]);
99
+ useEffect(() => {
100
+ if (!isOpen) {
101
+ return;
102
+ }
103
+ const keyListener = e => {
104
+ if (e.key === 'Escape') {
105
+ e.preventDefault();
106
+ onCloseClick(e);
107
+ }
108
+ };
109
+ window.addEventListener('keydown', keyListener);
110
+ return () => {
111
+ window.removeEventListener('keydown', keyListener);
112
+ };
113
+ }, [isOpen, onCloseClick]);
114
+ return (React.createElement(FocusTrap, { active: isOpen },
115
+ React.createElement(ModalCardWrapper, Object.assign({ open: isOpen, maxWidth: maxWidth, onClick: e => e.stopPropagation(), ref: ref }, props),
116
+ onCloseClick && (React.createElement(CloseIconSection, null,
117
+ React.createElement(IconButton, { altText: "Close", icon: React.createElement(SvgClose, null), onClick: onCloseClick }))),
118
+ React.createElement(ModalCardChildrenSection, null, children))));
95
119
  };
96
- const Modal = (_a) => {
120
+ const Modal = React.forwardRef((_a, ref) => {
97
121
  var { children, isOpen, mainButton, secondaryButton, alternativeButton, title, onCloseClick, onBackgroundClick, onKeyDown, hasDividers, maxWidth = 60, zIndex = 1000 } = _a, props = __rest(_a, ["children", "isOpen", "mainButton", "secondaryButton", "alternativeButton", "title", "onCloseClick", "onBackgroundClick", "onKeyDown", "hasDividers", "maxWidth", "zIndex"]);
98
122
  const hasButtons = mainButton || secondaryButton || alternativeButton ? true : false;
99
123
  return (React.createElement(Backdrop, Object.assign({ isOpen: isOpen, zIndex: zIndex }, props),
100
124
  React.createElement(Container, { height: "100%", onClick: onBackgroundClick, onKeyDown: onKeyDown },
101
- React.createElement(ModalCard, Object.assign({ maxWidth: maxWidth, onCloseClick: onCloseClick }, props),
125
+ React.createElement(ModalCard, { ref: ref,
126
+ // TODO: LNS-148: Add aria labelling for screenreader support
127
+ // ariaLabelledBy={title}
128
+ isOpen: isOpen, maxWidth: maxWidth, onCloseClick: onCloseClick },
102
129
  React.createElement(ContentWrapper, { rows: `${title ? 'auto ' : ''} ${children ? '1fr ' : ''} ${hasButtons ? 'auto' : ''}` },
103
130
  title && (React.createElement(TitleSection, { bottom: children
104
131
  ? 'var(--lns-space-medium)'
@@ -110,5 +137,5 @@ const Modal = (_a) => {
110
137
  React.createElement(RightButtonsSection, null,
111
138
  secondaryButton && (React.createElement(Spacer, { right: "small", isInline: true }, secondaryButton)),
112
139
  mainButton))))))));
113
- };
140
+ });
114
141
  export default Modal;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@loomhq/lens",
3
- "version": "10.48.0",
3
+ "version": "10.48.1",
4
4
  "scripts": {
5
5
  "dev": "next",
6
6
  "build:next": "next build",
@@ -26,6 +26,7 @@
26
26
  "dependencies": {
27
27
  "@floating-ui/react-dom": "^0.6.3",
28
28
  "downshift": "^5.4.7",
29
+ "focus-trap-react": "^10.0.0",
29
30
  "lodash": "^4.17.21",
30
31
  "react-color": "^2.19.3",
31
32
  "react-laag": "^2.0.3",