@nulogy/components 16.0.4 → 16.2.0
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/dist/main.js +15330 -15857
- package/dist/main.js.map +1 -1
- package/dist/main.module.js +15352 -15880
- package/dist/main.module.js.map +1 -1
- package/dist/src/BottomSheet/BottomSheet.styled.d.ts +2 -2
- package/dist/src/Button/IconicButton.js +7 -12
- package/dist/src/Layout/Sidebar.story.d.ts +1 -1
- package/dist/src/Layout/Sidebar.story.js +23 -10
- package/dist/src/Modal/Modal.d.ts +11 -7
- package/dist/src/Modal/Modal.js +36 -34
- package/dist/src/Modal/Modal.story.d.ts +0 -1
- package/dist/src/Modal/Modal.story.js +10 -9
- package/dist/src/Table/stories/BaseTable.story.d.ts +1 -0
- package/dist/src/Table/stories/BaseTable.story.js +15 -0
- package/dist/src/Table/stories/Table.story.js +13 -0
- package/dist/src/TopBar/TopBar.styled.d.ts +2 -2
- package/package.json +7 -7
|
@@ -3,13 +3,13 @@ import type { AnimationProps } from "framer-motion";
|
|
|
3
3
|
import type { HeightProps, LayoutProps, MaxHeightProps, MaxWidthProps, SpaceProps, WidthProps } from "styled-system";
|
|
4
4
|
declare const Overlay: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<Omit<Omit<Omit<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & {
|
|
5
5
|
ref?: import("react").Ref<HTMLDivElement>;
|
|
6
|
-
}, "as" | keyof import("@reach/dialog").
|
|
6
|
+
}, "as" | keyof import("@reach/dialog").DialogInnerProps> & import("@reach/dialog").DialogInnerProps & {
|
|
7
7
|
as?: "div";
|
|
8
8
|
} & import("framer-motion").MotionProps, "ref"> & import("react").RefAttributes<HTMLElement | SVGElement>, "ref"> & {
|
|
9
9
|
ref?: import("react").Ref<HTMLElement | SVGElement>;
|
|
10
10
|
}, never>> & string & Omit<import("framer-motion").CustomDomComponent<Omit<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & {
|
|
11
11
|
ref?: import("react").Ref<HTMLDivElement>;
|
|
12
|
-
}, "as" | keyof import("@reach/dialog").
|
|
12
|
+
}, "as" | keyof import("@reach/dialog").DialogInnerProps> & import("@reach/dialog").DialogInnerProps & {
|
|
13
13
|
as?: "div";
|
|
14
14
|
}>, keyof import("react").Component<any, {}, any>>;
|
|
15
15
|
interface SheetProps extends DialogContentProps, AnimationProps, WidthProps, MaxWidthProps, HeightProps, MaxHeightProps, SpaceProps, LayoutProps {
|
|
@@ -2,7 +2,6 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import React from "react";
|
|
3
3
|
import { styled } from "styled-components";
|
|
4
4
|
import { space, variant } from "styled-system";
|
|
5
|
-
import { Manager, Reference, Popper } from "react-popper-2";
|
|
6
5
|
import { transparentize } from "polished";
|
|
7
6
|
import icons from "@nulogy/icons";
|
|
8
7
|
import { Icon } from "../Icon";
|
|
@@ -20,7 +19,7 @@ const IconWrapper = styled.span(({ theme, size }) => ({
|
|
|
20
19
|
}));
|
|
21
20
|
const HoverText = styled.div(({ theme }) => ({
|
|
22
21
|
whiteSpace: "nowrap",
|
|
23
|
-
|
|
22
|
+
fontSize: theme.fontSizes.small,
|
|
24
23
|
lineHeight: theme.lineHeights.smallTextCompressed,
|
|
25
24
|
color: theme.colors.whiteGrey,
|
|
26
25
|
backgroundColor: transparentize(0.15, theme.colors.blackBlue),
|
|
@@ -28,6 +27,11 @@ const HoverText = styled.div(({ theme }) => ({
|
|
|
28
27
|
marginTop: theme.space.half,
|
|
29
28
|
padding: `${theme.space.half} ${theme.space.x1}`,
|
|
30
29
|
pointerEvents: "none",
|
|
30
|
+
position: "absolute",
|
|
31
|
+
top: "100%",
|
|
32
|
+
left: "50%",
|
|
33
|
+
transform: "translateX(-50%)",
|
|
34
|
+
zIndex: 1,
|
|
31
35
|
}));
|
|
32
36
|
const WrapperButton = styled.button(({ disabled, hoverBackgroundColor, theme }) => ({
|
|
33
37
|
background: "transparent",
|
|
@@ -90,16 +94,7 @@ const WrapperButton = styled.button(({ disabled, hoverBackgroundColor, theme })
|
|
|
90
94
|
}), space);
|
|
91
95
|
const IconicButton = React.forwardRef(({ children, color = "darkBlue", hoverBackgroundColor = "lightBlue", icon, labelHidden, className, iconSize = "x3", fontSize, tooltip, variant, ...props }, forwardedRef) => {
|
|
92
96
|
const componentVariant = useComponentVariant(variant);
|
|
93
|
-
return (_jsxs(WrapperButton, { ref: forwardedRef, "aria-label": props["aria-label"] ? props["aria-label"] : typeof children === "string" ? children : undefined, className: className, hoverBackgroundColor: hoverBackgroundColor, variant: componentVariant, ...props, children: [
|
|
94
|
-
{
|
|
95
|
-
name: "preventOverflow",
|
|
96
|
-
enabled: true,
|
|
97
|
-
options: {
|
|
98
|
-
padding: 8,
|
|
99
|
-
rootBoundary: "viewport",
|
|
100
|
-
},
|
|
101
|
-
},
|
|
102
|
-
], children: ({ ref, style }) => labelHidden || tooltip ? (_jsx(HoverText, { ref: ref, style: style, children: tooltip ? tooltip : children })) : null })] }), children &&
|
|
97
|
+
return (_jsxs(WrapperButton, { ref: forwardedRef, "aria-label": props["aria-label"] ? props["aria-label"] : typeof children === "string" ? children : undefined, className: className, hoverBackgroundColor: hoverBackgroundColor, variant: componentVariant, ...props, children: [_jsx(IconWrapper, { size: iconSize, children: _jsx(Icon, { size: iconSize, icon: icon, color: color }) }), (labelHidden || tooltip) && _jsx(HoverText, { children: tooltip ?? children }), children &&
|
|
103
98
|
!labelHidden &&
|
|
104
99
|
(typeof children === "string" || typeof children === "number" ? (_jsx(Text, { fontSize: fontSize, mr: "half", ml: "half", color: color, children: children })) : (children))] }));
|
|
105
100
|
});
|
|
@@ -13,7 +13,7 @@ export default _default;
|
|
|
13
13
|
type Story = StoryObj<typeof Sidebar>;
|
|
14
14
|
export declare const _Sidebar: () => import("react/jsx-runtime").JSX.Element;
|
|
15
15
|
export declare const WithoutOverlay: () => import("react/jsx-runtime").JSX.Element;
|
|
16
|
-
export declare const OpenByDefault:
|
|
16
|
+
export declare const OpenByDefault: Story;
|
|
17
17
|
export declare const WithCustomOffset: Story;
|
|
18
18
|
export declare const DontCloseOnOutsideClick: () => import("react/jsx-runtime").JSX.Element;
|
|
19
19
|
export declare const WithoutCloseButton: () => import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { useState, useRef } from "react";
|
|
3
|
+
import { expect, userEvent, waitFor, within } from "storybook/test";
|
|
3
4
|
import { ApplicationFrame, Breadcrumbs, Link, Page, Sidebar, Select, PrimaryButton, Box, Textarea, Heading3, Navigation, } from "..";
|
|
4
5
|
import { useUrlProps } from "../utils/testing/useUrlProps";
|
|
5
6
|
export default {
|
|
@@ -33,16 +34,28 @@ export const WithoutOverlay = () => {
|
|
|
33
34
|
};
|
|
34
35
|
return (_jsx(ApplicationFrame, { navBar: _jsx(Navigation, {}), overflowX: "hidden", children: _jsxs(Page, { breadcrumbs: _jsxs(Breadcrumbs, { children: [_jsx(Link, { href: "/", children: "Home" }), _jsx(Link, { href: "/", children: "Materials" })] }), title: "Materials Overview", children: [_jsxs(Box, { minWidth: "300px", children: [_jsx(PrimaryButton, { onClick: toggleSidebar, ref: triggerRef, id: "openSidebarTrigger", children: "Open Sidebar" }), _jsxs(Box, { height: "3000px", width: "100%", bg: "lightBlue", mt: "x3", p: "x2", children: ["Space for more content", _jsx("input", {})] })] }), _jsx(ExampleSidebar, { isOpen: isOpen, onClose: closeSidebar, triggerRef: triggerRef, "aria-controls": "openSidebarTrigger", overlay: false })] }) }));
|
|
35
36
|
};
|
|
36
|
-
export const OpenByDefault =
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
37
|
+
export const OpenByDefault = {
|
|
38
|
+
play: async ({ canvasElement, step }) => {
|
|
39
|
+
await step("overlay is visible when sidebar is open", async () => {
|
|
40
|
+
await expect(canvasElement.querySelector("[data-testid='sidebar-overlay']")).toBeTruthy();
|
|
41
|
+
});
|
|
42
|
+
await step("close button dismisses the sidebar", async () => {
|
|
43
|
+
const canvas = within(canvasElement);
|
|
44
|
+
await userEvent.click(canvas.getByLabelText("Close"));
|
|
45
|
+
await waitFor(() => expect(canvasElement.querySelector("[data-testid='sidebar-overlay']")).toBeNull());
|
|
46
|
+
});
|
|
47
|
+
},
|
|
48
|
+
render: () => {
|
|
49
|
+
const [isOpen, setIsOpen] = useState(true);
|
|
50
|
+
const triggerRef = useRef(null);
|
|
51
|
+
const toggleSidebar = () => {
|
|
52
|
+
setIsOpen(!isOpen);
|
|
53
|
+
};
|
|
54
|
+
const closeSidebar = () => {
|
|
55
|
+
setIsOpen(false);
|
|
56
|
+
};
|
|
57
|
+
return (_jsx(ApplicationFrame, { navBar: _jsx(Navigation, {}), overflowX: "hidden", children: _jsxs(Page, { breadcrumbs: _jsxs(Breadcrumbs, { children: [_jsx(Link, { href: "/", children: "Home" }), _jsx(Link, { href: "/", children: "Materials" })] }), title: "Materials Overview", children: [_jsxs(Box, { minWidth: "300px", children: [_jsx(PrimaryButton, { onClick: toggleSidebar, ref: triggerRef, id: "openSidebarTrigger", children: "Open Sidebar" }), _jsx(Box, { height: "3000px", width: "100%", bg: "lightBlue", mt: "x3", p: "x2", children: "Space for more content" })] }), _jsx(ExampleSidebar, { isOpen: isOpen, onClose: closeSidebar, triggerRef: triggerRef, "aria-controls": "openSidebarTrigger" })] }) }));
|
|
58
|
+
},
|
|
46
59
|
};
|
|
47
60
|
const WithCustomOffsetComponent = (args) => {
|
|
48
61
|
const [isOpen, setIsOpen] = useState(true);
|
|
@@ -1,27 +1,31 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
|
|
2
|
+
interface ModalProps {
|
|
3
3
|
children?: React.ReactNode;
|
|
4
4
|
isOpen?: boolean;
|
|
5
5
|
title?: string;
|
|
6
6
|
ariaLabel?: string;
|
|
7
|
-
onRequestClose?: (
|
|
7
|
+
onRequestClose?: () => void;
|
|
8
8
|
closeAriaLabel?: string;
|
|
9
|
-
onAfterOpen?: (
|
|
9
|
+
onAfterOpen?: () => void;
|
|
10
10
|
shouldFocusAfterRender?: boolean;
|
|
11
11
|
shouldReturnFocusAfterClose?: boolean;
|
|
12
12
|
ariaDescribedBy?: string;
|
|
13
13
|
maxWidth?: string;
|
|
14
|
+
/** @deprecated No-op. Radix handles portal class automatically. */
|
|
14
15
|
portalClassName?: string;
|
|
16
|
+
/** @deprecated No-op. Use className for the modal content element. */
|
|
15
17
|
overlayClassName?: string;
|
|
16
18
|
className?: string;
|
|
17
19
|
id?: string;
|
|
20
|
+
/** @deprecated No-op. Radix handles aria-modal automatically. */
|
|
18
21
|
appElement?: JSX.Element;
|
|
22
|
+
/** @deprecated No-op. Radix handles aria hiding automatically. */
|
|
19
23
|
ariaHideApp?: boolean;
|
|
20
24
|
footerContent?: React.ReactNode;
|
|
21
|
-
parentSelector?: (
|
|
22
|
-
}
|
|
23
|
-
declare function Modal({ isOpen, shouldFocusAfterRender, shouldReturnFocusAfterClose, maxWidth,
|
|
25
|
+
parentSelector?: () => HTMLElement;
|
|
26
|
+
}
|
|
27
|
+
declare function Modal({ isOpen, shouldFocusAfterRender, shouldReturnFocusAfterClose, maxWidth, children, title, onRequestClose, onAfterOpen, ariaLabel, ariaDescribedBy, className, id, footerContent, closeAriaLabel, parentSelector, portalClassName: _portalClassName, overlayClassName: _overlayClassName, appElement: _appElement, ariaHideApp: _ariaHideApp, }: ModalProps): import("react/jsx-runtime").JSX.Element;
|
|
24
28
|
declare namespace Modal {
|
|
25
|
-
var setAppElement:
|
|
29
|
+
var setAppElement: (_appElement?: string | HTMLElement) => void;
|
|
26
30
|
}
|
|
27
31
|
export default Modal;
|
package/dist/src/Modal/Modal.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
import ReactModal from "react-modal";
|
|
2
|
+
import { styled, useTheme } from "styled-components";
|
|
3
|
+
import * as Dialog from "@radix-ui/react-dialog";
|
|
5
4
|
import { transparentize } from "polished";
|
|
6
5
|
import { Heading2 } from "../Type";
|
|
7
6
|
import { useScrollLock } from "../utils/useScrollLock";
|
|
@@ -9,67 +8,70 @@ import ModalContent from "./ModalContent";
|
|
|
9
8
|
import ModalFooter from "./ModalFooter";
|
|
10
9
|
import ModalHeader from "./ModalHeader";
|
|
11
10
|
import ModalCloseButton from "./ModalCloseButton";
|
|
12
|
-
const
|
|
11
|
+
const StyledDialogOverlay = styled(Dialog.Overlay)(({ theme }) => ({
|
|
13
12
|
position: "fixed",
|
|
14
|
-
|
|
15
|
-
left: 0,
|
|
16
|
-
right: 0,
|
|
17
|
-
bottom: 0,
|
|
18
|
-
display: "flex",
|
|
19
|
-
justifyContent: "center",
|
|
20
|
-
alignItems: "center",
|
|
13
|
+
inset: 0,
|
|
21
14
|
backgroundColor: transparentize(0.5, theme.colors.blackBlue),
|
|
22
15
|
zIndex: theme.zIndices.overlay,
|
|
23
|
-
});
|
|
24
|
-
const
|
|
25
|
-
maxWidth,
|
|
26
|
-
}), ({ theme }) => ({
|
|
16
|
+
}));
|
|
17
|
+
const StyledDialogContent = styled(Dialog.Content)(({ theme, $maxWidth }) => ({
|
|
27
18
|
"&:focus": {
|
|
28
19
|
outline: "none",
|
|
29
20
|
},
|
|
30
21
|
display: "flex",
|
|
31
22
|
flexDirection: "column",
|
|
32
|
-
position: "
|
|
33
|
-
top:
|
|
34
|
-
left:
|
|
35
|
-
|
|
36
|
-
bottom: 0,
|
|
23
|
+
position: "fixed",
|
|
24
|
+
top: "50%",
|
|
25
|
+
left: "50%",
|
|
26
|
+
transform: "translate(-50%, -50%)",
|
|
37
27
|
backgroundColor: theme.colors.white,
|
|
38
28
|
borderRadius: theme.radii.medium,
|
|
39
29
|
boxShadow: theme.shadows.large,
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
height: "auto",
|
|
30
|
+
width: `calc(100% - ${theme.space.x4})`,
|
|
31
|
+
maxWidth: $maxWidth,
|
|
43
32
|
maxHeight: `calc(100vh - ${theme.space.x8})`,
|
|
44
|
-
|
|
33
|
+
height: "auto",
|
|
34
|
+
overflow: "hidden",
|
|
45
35
|
padding: 0,
|
|
36
|
+
zIndex: theme.zIndices.overlay,
|
|
46
37
|
[`@media only screen and (max-width: ${theme.breakpoints.small})`]: {
|
|
47
|
-
width: "100%",
|
|
48
38
|
maxWidth: "100%",
|
|
39
|
+
width: "100%",
|
|
49
40
|
},
|
|
50
41
|
"*": {
|
|
51
42
|
boxSizing: "border-box",
|
|
52
43
|
},
|
|
53
44
|
color: theme.colors.black,
|
|
45
|
+
fontFamily: theme.fonts.base,
|
|
54
46
|
fontSize: theme.fontSizes.base,
|
|
55
47
|
lineHeight: theme.lineHeights.base,
|
|
56
48
|
WebkitFontSmoothing: "antialiased",
|
|
57
49
|
MozOsxFontSmoothing: "grayscale",
|
|
58
50
|
}));
|
|
59
|
-
function Modal({ isOpen = true, shouldFocusAfterRender = true, shouldReturnFocusAfterClose = true, maxWidth = "624px",
|
|
51
|
+
function Modal({ isOpen = true, shouldFocusAfterRender = true, shouldReturnFocusAfterClose = true, maxWidth = "624px", children, title, onRequestClose, onAfterOpen, ariaLabel, ariaDescribedBy, className, id, footerContent, closeAriaLabel, parentSelector,
|
|
52
|
+
// accepted but unused (no-ops):
|
|
53
|
+
portalClassName: _portalClassName, overlayClassName: _overlayClassName, appElement: _appElement, ariaHideApp: _ariaHideApp, }) {
|
|
60
54
|
const modalHasHeader = Boolean(onRequestClose || title);
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
55
|
+
return (_jsx(Dialog.Root, { open: isOpen, onOpenChange: (open) => {
|
|
56
|
+
if (open)
|
|
57
|
+
onAfterOpen?.();
|
|
58
|
+
else
|
|
59
|
+
onRequestClose?.();
|
|
60
|
+
}, children: _jsxs(Dialog.Portal, { container: parentSelector?.(), children: [_jsx(StyledDialogOverlay, {}), _jsx(StyledDialogContent, { "$maxWidth": maxWidth, "aria-label": !title ? ariaLabel : undefined, "aria-labelledby": title ? "modal-title" : undefined, "aria-describedby": ariaDescribedBy, className: className, id: id, onOpenAutoFocus: (e) => {
|
|
61
|
+
if (!shouldFocusAfterRender)
|
|
62
|
+
e.preventDefault();
|
|
63
|
+
}, onCloseAutoFocus: (e) => {
|
|
64
|
+
if (!shouldReturnFocusAfterClose)
|
|
65
|
+
e.preventDefault();
|
|
66
|
+
}, children: _jsx(ModalWrapper, { closeAriaLabel: closeAriaLabel, modalHasHeader: modalHasHeader, title: title, onRequestClose: onRequestClose, footerContent: footerContent, children: children }) })] }) }));
|
|
68
67
|
}
|
|
69
68
|
function ModalWrapper({ modalHasHeader, title, onRequestClose, closeAriaLabel, children, footerContent, }) {
|
|
70
69
|
const theme = useTheme();
|
|
71
70
|
useScrollLock();
|
|
72
71
|
return (_jsxs(_Fragment, { children: [modalHasHeader && (_jsxs(ModalHeader, { hasCloseButton: Boolean(onRequestClose), children: [title ? (_jsx(Heading2, { id: "modal-title", mb: "none", children: title })) : (_jsx("div", { style: { height: theme.space.x4 } })), onRequestClose && _jsx(ModalCloseButton, { onClick: onRequestClose, "aria-label": closeAriaLabel })] })), _jsx(ModalContent, { hasFooter: !!footerContent, children: children }), footerContent && _jsx(ModalFooter, { children: footerContent })] }));
|
|
73
72
|
}
|
|
74
|
-
Modal.setAppElement =
|
|
73
|
+
Modal.setAppElement = (_appElement) => {
|
|
74
|
+
console.warn("[NDS] Modal.setAppElement() is deprecated and has no effect. " +
|
|
75
|
+
"The Modal component now uses @radix-ui/react-dialog, which handles aria-modal automatically.");
|
|
76
|
+
};
|
|
75
77
|
export default Modal;
|
|
@@ -10,7 +10,6 @@ declare const _default: {
|
|
|
10
10
|
export default _default;
|
|
11
11
|
type Story = StoryObj<typeof NDSModal>;
|
|
12
12
|
export declare const Default: Story;
|
|
13
|
-
export declare const WithCloseButton: Story;
|
|
14
13
|
export declare const WithScrollingContent: Story;
|
|
15
14
|
export declare const WithScrollingContentWithoutFooterContent: Story;
|
|
16
15
|
export declare const WithNoTitle: Story;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { expect, userEvent, within } from "storybook/test";
|
|
2
3
|
import { useState } from "react";
|
|
3
4
|
import { Modal as NDSModal, Button, QuietButton, PrimaryButton, ButtonGroup, Form, Input, Select, Text, DatePicker, } from "../index";
|
|
4
5
|
if (process.env.NODE_ENV !== "test")
|
|
@@ -28,15 +29,6 @@ export const Default = {
|
|
|
28
29
|
onRequestClose: () => { },
|
|
29
30
|
},
|
|
30
31
|
};
|
|
31
|
-
export const WithCloseButton = {
|
|
32
|
-
args: {
|
|
33
|
-
children: "Content Content Content",
|
|
34
|
-
title: "Modal Title",
|
|
35
|
-
footerContent: ModalButtons,
|
|
36
|
-
onRequestClose: () => { },
|
|
37
|
-
},
|
|
38
|
-
name: "with close button",
|
|
39
|
-
};
|
|
40
32
|
export const WithScrollingContent = {
|
|
41
33
|
args: {
|
|
42
34
|
title: "Modal Title",
|
|
@@ -108,6 +100,15 @@ export const WithParentSelector = {
|
|
|
108
100
|
export const ExampleControlledModal = {
|
|
109
101
|
render: () => _jsx(ModalExample, {}),
|
|
110
102
|
name: "example controlled modal",
|
|
103
|
+
play: async ({ canvasElement }) => {
|
|
104
|
+
const canvas = within(canvasElement);
|
|
105
|
+
const body = within(document.body);
|
|
106
|
+
await userEvent.click(canvas.getByRole("button", { name: "Open Modal" }));
|
|
107
|
+
const dialog = await body.findByRole("dialog");
|
|
108
|
+
expect(dialog).toBeVisible();
|
|
109
|
+
await userEvent.keyboard("{Escape}");
|
|
110
|
+
expect(body.queryByRole("dialog")).not.toBeInTheDocument();
|
|
111
|
+
},
|
|
111
112
|
};
|
|
112
113
|
const ModalExample = () => {
|
|
113
114
|
const [isOpen, setIsOpen] = useState(false);
|
|
@@ -10,6 +10,7 @@ export declare const WithData: Story;
|
|
|
10
10
|
export declare const WithNoData: Story;
|
|
11
11
|
export declare const WithStickyHeader: Story;
|
|
12
12
|
export declare const WithLotsOfRowsAndColumns: Story;
|
|
13
|
+
export declare const WithLoading: Story;
|
|
13
14
|
export declare const WithCustomColumnWidths: () => import("react/jsx-runtime").JSX.Element;
|
|
14
15
|
export declare const WithACustomCellComponent: () => import("react/jsx-runtime").JSX.Element;
|
|
15
16
|
export declare const WithCellAlignment: () => import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { action } from "storybook/actions";
|
|
3
|
+
import { expect, within } from "storybook/test";
|
|
3
4
|
import { Box, DropdownButton, DropdownMenu, Button, Text, Flex } from "../..";
|
|
4
5
|
import { getMockRows, mockColumns } from "../Table.mock-utils";
|
|
5
6
|
import { Table } from "..";
|
|
@@ -300,6 +301,20 @@ export const WithLotsOfRowsAndColumns = {
|
|
|
300
301
|
},
|
|
301
302
|
},
|
|
302
303
|
};
|
|
304
|
+
export const WithLoading = {
|
|
305
|
+
args: {
|
|
306
|
+
columns,
|
|
307
|
+
rows: rowData,
|
|
308
|
+
loading: true,
|
|
309
|
+
},
|
|
310
|
+
name: "with loading state",
|
|
311
|
+
play: async ({ canvasElement }) => {
|
|
312
|
+
const canvas = within(canvasElement);
|
|
313
|
+
await expect(canvas.getByText("Loading...")).toBeInTheDocument();
|
|
314
|
+
const rows = canvasElement.querySelectorAll("tbody tr");
|
|
315
|
+
await expect(rows).toHaveLength(1);
|
|
316
|
+
},
|
|
317
|
+
};
|
|
303
318
|
export const WithCustomColumnWidths = () => _jsx(Table, { columns: columnsWithWidths, rows: rowDataWithWidths });
|
|
304
319
|
export const WithACustomCellComponent = () => (_jsx(Table, { columns: getColumnsWithCellRenderer(dropdownCellRenderer), rows: rowData }));
|
|
305
320
|
export const WithCellAlignment = () => _jsx(Table, { columns: columnsWithAlignment, rows: rowData });
|
|
@@ -242,6 +242,19 @@ export const WithEverything = {
|
|
|
242
242
|
},
|
|
243
243
|
};
|
|
244
244
|
export const WithOnHoverActions = {
|
|
245
|
+
play: async ({ canvasElement, step }) => {
|
|
246
|
+
const canvas = within(canvasElement);
|
|
247
|
+
await step("reveals row actions when mouse enters a row", async () => {
|
|
248
|
+
const rows = canvas.getAllByTestId("table-row");
|
|
249
|
+
await userEvent.hover(rows[0]);
|
|
250
|
+
await waitFor(() => expect(within(rows[0]).getByRole("button")).toBeInTheDocument());
|
|
251
|
+
});
|
|
252
|
+
await step("hides row actions when mouse leaves the row", async () => {
|
|
253
|
+
const rows = canvas.getAllByTestId("table-row");
|
|
254
|
+
await userEvent.unhover(rows[0]);
|
|
255
|
+
await waitFor(() => expect(within(rows[0]).queryByRole("button")).not.toBeInTheDocument());
|
|
256
|
+
});
|
|
257
|
+
},
|
|
245
258
|
render: (args) => {
|
|
246
259
|
const rowDataWithHovers = [
|
|
247
260
|
{
|
|
@@ -11,13 +11,13 @@ declare const StyledBackLink: import("styled-components/dist/types").IStyledComp
|
|
|
11
11
|
declare const StyledPageTitle: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").LiHTMLAttributes<HTMLLIElement>, HTMLLIElement>, never>> & string;
|
|
12
12
|
declare const Overlay: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<Omit<Omit<Omit<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & {
|
|
13
13
|
ref?: import("react").Ref<HTMLDivElement>;
|
|
14
|
-
}, "as" | keyof import("@reach/dialog").
|
|
14
|
+
}, "as" | keyof import("@reach/dialog").DialogInnerProps> & import("@reach/dialog").DialogInnerProps & {
|
|
15
15
|
as?: "div";
|
|
16
16
|
} & import("framer-motion").MotionProps, "ref"> & import("react").RefAttributes<HTMLElement | SVGElement>, "ref"> & {
|
|
17
17
|
ref?: import("react").Ref<HTMLElement | SVGElement>;
|
|
18
18
|
}, never>> & string & Omit<import("framer-motion").CustomDomComponent<Omit<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & {
|
|
19
19
|
ref?: import("react").Ref<HTMLDivElement>;
|
|
20
|
-
}, "as" | keyof import("@reach/dialog").
|
|
20
|
+
}, "as" | keyof import("@reach/dialog").DialogInnerProps> & import("@reach/dialog").DialogInnerProps & {
|
|
21
21
|
as?: "div";
|
|
22
22
|
}>, keyof import("react").Component<any, {}, any>>;
|
|
23
23
|
declare const TileLink: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").AnchorHTMLAttributes<HTMLAnchorElement>, HTMLAnchorElement>, never>> & string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nulogy/components",
|
|
3
|
-
"version": "16.0
|
|
3
|
+
"version": "16.2.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Component library for the Nulogy Design System - http://nulogy.design",
|
|
6
6
|
"private": false,
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"build:verify": "node scripts/verify-build.js",
|
|
17
17
|
"build:watch": "vite build --watch",
|
|
18
18
|
"build:storybook": "storybook build --stats-json",
|
|
19
|
-
"warn:prepush": "echo \"Make sure you also run all the other CI steps before pushing by running 'pnpm
|
|
19
|
+
"warn:prepush": "echo \"Make sure you also run all the other CI steps before pushing by running 'pnpm check'\"",
|
|
20
20
|
"check": "pnpm warn:prepush && pnpm check:types && pnpm check:lint && pnpm check:format",
|
|
21
21
|
"check:types": "tsc",
|
|
22
22
|
"check:lint": "eslint '**/*.{js,ts,jsx,tsx}'",
|
|
@@ -70,7 +70,7 @@
|
|
|
70
70
|
"devDependencies": {
|
|
71
71
|
"@apollo/client": "^4.1.6",
|
|
72
72
|
"@eslint/js": "^9.0.0",
|
|
73
|
-
"@nulogy/icons": "^4.
|
|
73
|
+
"@nulogy/icons": "^4.39.0",
|
|
74
74
|
"@semantic-release/changelog": "^6.0.2",
|
|
75
75
|
"@semantic-release/commit-analyzer": "^9.0.2",
|
|
76
76
|
"@semantic-release/git": "^10.0.1",
|
|
@@ -84,7 +84,7 @@
|
|
|
84
84
|
"@testing-library/react": "^16.0.0",
|
|
85
85
|
"@types/css-mediaquery": "^0.1.4",
|
|
86
86
|
"@types/deep-equal": "^1.0.4",
|
|
87
|
-
"@types/node": "^
|
|
87
|
+
"@types/node": "^25.3.5",
|
|
88
88
|
"@types/react": "^18.0.0",
|
|
89
89
|
"@types/react-dom": "^18.0.0",
|
|
90
90
|
"@typescript-eslint/eslint-plugin": "^8.49.0",
|
|
@@ -125,9 +125,10 @@
|
|
|
125
125
|
"dependencies": {
|
|
126
126
|
"@emotion/is-prop-valid": "^1.3.1",
|
|
127
127
|
"@nulogy/tokens": "^6.1.1",
|
|
128
|
+
"@radix-ui/react-dialog": "^1.1.0",
|
|
128
129
|
"@radix-ui/react-navigation-menu": "^1.1.4",
|
|
129
|
-
"@radix-ui/react-tooltip": "1.
|
|
130
|
-
"@reach/dialog": "0.
|
|
130
|
+
"@radix-ui/react-tooltip": "1.2.8",
|
|
131
|
+
"@reach/dialog": "0.18.0",
|
|
131
132
|
"@styled-system/prop-types": "^5.1.4",
|
|
132
133
|
"@styled-system/theme-get": "^5.1.2",
|
|
133
134
|
"@types/react-window": "^1.8.8",
|
|
@@ -144,7 +145,6 @@
|
|
|
144
145
|
"react-i18next": "^12.3.1",
|
|
145
146
|
"react-modal": "^3.14.4",
|
|
146
147
|
"react-popper": "1.3.11",
|
|
147
|
-
"react-popper-2": "npm:react-popper@2.2.4",
|
|
148
148
|
"react-resize-detector": "^9.1.0",
|
|
149
149
|
"react-select": "^5.9.0",
|
|
150
150
|
"react-window": "^1.8.11",
|