@ndlib/component-library 0.0.36 → 0.0.37
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/components/composites/EmptyState/EmptyState.stories.d.ts +1 -0
- package/dist/components/composites/EmptyState/EmptyState.stories.js +8 -2
- package/dist/components/composites/EmptyState/EmptyState.test.js +1 -1
- package/dist/components/composites/EmptyState/index.d.ts +1 -0
- package/dist/components/composites/EmptyState/index.js +2 -2
- package/dist/components/composites/Modal/Modal.stories.d.ts +6 -0
- package/dist/components/composites/Modal/Modal.stories.js +33 -0
- package/dist/components/composites/Modal/index.d.ts +17 -0
- package/dist/components/composites/Modal/index.js +52 -0
- package/dist/components/elements/Button/index.js +1 -1
- package/dist/components/elements/Fields/CheckboxGroup/CheckboxGroup.stories.d.ts +1 -0
- package/dist/components/elements/Fields/CheckboxGroup/CheckboxGroup.stories.js +3 -0
- package/dist/components/elements/Fields/CheckboxGroup/index.d.ts +3 -1
- package/dist/components/elements/Fields/CheckboxGroup/index.js +29 -14
- package/dist/components/elements/Fields/Select/index.d.ts +3 -3
- package/dist/components/elements/text/ReadMore/index.js +1 -1
- package/dist/components/providers/componentConfig.d.ts +3 -0
- package/dist/components/providers/componentConfig.js +3 -0
- package/dist/components/providers/dialogs.d.ts +9 -0
- package/dist/components/providers/dialogs.js +32 -0
- package/dist/components/providers/media.d.ts +8 -0
- package/dist/components/providers/media.js +43 -0
- package/dist/components/providers/ui.js +3 -2
- package/dist/index.d.ts +3 -1
- package/dist/index.js +3 -1
- package/dist/theme/custom.d.ts +2 -1
- package/dist/theme/custom.js +1 -0
- package/package.json +3 -1
- package/dist/utils/hooks/useMediaQuery.d.ts +0 -4
- package/dist/utils/hooks/useMediaQuery.js +0 -29
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { EMPTY_STATE_SIZE, EmptyState } from '.';
|
|
3
3
|
import NotInterestedIcon from '@mui/icons-material/NotInterested';
|
|
4
|
+
import { Link } from '../../elements/Link';
|
|
5
|
+
import { FONT_SIZE } from '../../../theme/typography';
|
|
4
6
|
const meta = {
|
|
5
7
|
title: 'Composites/EmptyState',
|
|
6
8
|
component: EmptyState,
|
|
@@ -16,7 +18,11 @@ export const Small = {
|
|
|
16
18
|
args: {},
|
|
17
19
|
};
|
|
18
20
|
export const CustomMessage = {
|
|
19
|
-
render: () => _jsx(EmptyState, {
|
|
21
|
+
render: () => _jsx(EmptyState, { children: "Custom message" }),
|
|
22
|
+
args: {},
|
|
23
|
+
};
|
|
24
|
+
export const JsxMessage = {
|
|
25
|
+
render: () => (_jsxs(EmptyState, { children: ["Something is wrong.", ' ', _jsx(Link, Object.assign({ to: "/", sx: { fontSize: FONT_SIZE.MD } }, { children: "Click here to fix." }))] })),
|
|
20
26
|
args: {},
|
|
21
27
|
};
|
|
22
28
|
export const CustomIcon = {
|
|
@@ -6,7 +6,7 @@ const MOCK_ICON_TEST_ID = 'mock-icon';
|
|
|
6
6
|
const MockIcon = () => _jsx("div", { "data-testid": MOCK_ICON_TEST_ID });
|
|
7
7
|
describe('EmptyState', () => {
|
|
8
8
|
it('renders passed message', () => {
|
|
9
|
-
const { getByText } = render(_jsx(EmptyState, {
|
|
9
|
+
const { getByText } = render(_jsx(EmptyState, { children: TEST_MESSAGE }));
|
|
10
10
|
expect(getByText(TEST_MESSAGE)).toBeDefined();
|
|
11
11
|
});
|
|
12
12
|
it('renders default message if no message passed', () => {
|
|
@@ -26,7 +26,7 @@ export var EMPTY_STATE_SIZE;
|
|
|
26
26
|
})(EMPTY_STATE_SIZE || (EMPTY_STATE_SIZE = {}));
|
|
27
27
|
export const DEFAULT_MESSAGE = 'No results found.';
|
|
28
28
|
export const EmptyState = (_a) => {
|
|
29
|
-
var { icon,
|
|
29
|
+
var { omitIcon, icon, children, size: sizeProp, sx } = _a, rest = __rest(_a, ["omitIcon", "icon", "children", "size", "sx"]);
|
|
30
30
|
const size = sizeProp || EMPTY_STATE_SIZE.LG;
|
|
31
|
-
return (_jsxs(Column, Object.assign({ sx: Object.assign({ width: '100%', alignItems: 'center', justifyContent: 'center', mt: size === EMPTY_STATE_SIZE.SM ? 3 : 5 }, sx) }, rest, { children: [_jsx(Row, { children: _jsx(Icon, { icon: icon || SearchOffIcon, size: size === EMPTY_STATE_SIZE.SM ? FONT_SIZE.ML : FONT_SIZE.XL, color: COLOR.GRAY }) }), _jsx(Row, Object.assign({ sx: { mt: size === EMPTY_STATE_SIZE.SM ? 0 : 1 } }, { children: _jsx(Paragraph, Object.assign({ sx: { color: COLOR.GRAY }, size: size === EMPTY_STATE_SIZE.SM ? PARAGRAPH_SIZE.MD : PARAGRAPH_SIZE.LG }, { children:
|
|
31
|
+
return (_jsxs(Column, Object.assign({ sx: Object.assign({ width: '100%', alignItems: 'center', justifyContent: 'center', mt: size === EMPTY_STATE_SIZE.SM ? 3 : 5 }, sx) }, rest, { children: [_jsx(Row, { children: omitIcon ? null : (_jsx(Icon, { icon: icon || SearchOffIcon, size: size === EMPTY_STATE_SIZE.SM ? FONT_SIZE.ML : FONT_SIZE.XL, color: COLOR.GRAY })) }), _jsx(Row, Object.assign({ sx: { mt: size === EMPTY_STATE_SIZE.SM ? 0 : 1 } }, { children: _jsx(Paragraph, Object.assign({ sx: { color: COLOR.GRAY }, size: size === EMPTY_STATE_SIZE.SM ? PARAGRAPH_SIZE.MD : PARAGRAPH_SIZE.LG }, { children: children || DEFAULT_MESSAGE })) }))] })));
|
|
32
32
|
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Modal } from '.';
|
|
3
|
+
import { Button } from '../../elements/Button';
|
|
4
|
+
import { Paragraph } from '../../elements/text/Paragraph';
|
|
5
|
+
import { useDialog } from '../../providers/dialogs';
|
|
6
|
+
import { useTheme } from '../../../theme';
|
|
7
|
+
const meta = {
|
|
8
|
+
title: 'Composites/Modal',
|
|
9
|
+
component: Modal,
|
|
10
|
+
tags: ['autodocs'],
|
|
11
|
+
};
|
|
12
|
+
export default meta;
|
|
13
|
+
const ModalExample = () => {
|
|
14
|
+
const modalId = 'modal-example';
|
|
15
|
+
const { open, close, state } = useDialog(modalId);
|
|
16
|
+
const theme = useTheme();
|
|
17
|
+
return (_jsxs(_Fragment, { children: [_jsx(Button, Object.assign({ onClick: open, sx: { position: 'relative', zIndex: theme.zIndex.DROPDOWN } }, { children: "Open Modal" })), _jsx(Modal, Object.assign({ isOpen: state.isOpen, heading: "Heading", close: close, actions: [
|
|
18
|
+
{
|
|
19
|
+
label: 'Secondary',
|
|
20
|
+
isPrimary: false,
|
|
21
|
+
onClick: () => { },
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
label: 'Primary',
|
|
25
|
+
isPrimary: true,
|
|
26
|
+
onClick: () => { },
|
|
27
|
+
},
|
|
28
|
+
] }, { children: _jsx(Paragraph, { children: "Modal body goes here" }) }))] }));
|
|
29
|
+
};
|
|
30
|
+
export const Default = {
|
|
31
|
+
render: () => _jsx(ModalExample, {}),
|
|
32
|
+
args: {},
|
|
33
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { StyledElementProps } from '../../../theme';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
type ModalProps = StyledElementProps<HTMLDivElement, {
|
|
4
|
+
isOpen: boolean;
|
|
5
|
+
close: () => void;
|
|
6
|
+
heading: string;
|
|
7
|
+
hideHeading?: boolean;
|
|
8
|
+
footer?: React.ReactNode;
|
|
9
|
+
actions?: ModalAction[];
|
|
10
|
+
}>;
|
|
11
|
+
type ModalAction = {
|
|
12
|
+
label: string;
|
|
13
|
+
isPrimary?: boolean;
|
|
14
|
+
onClick: () => void;
|
|
15
|
+
};
|
|
16
|
+
export declare const Modal: React.FC<ModalProps>;
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
2
|
+
var t = {};
|
|
3
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
4
|
+
t[p] = s[p];
|
|
5
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
6
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
7
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
8
|
+
t[p[i]] = s[p[i]];
|
|
9
|
+
}
|
|
10
|
+
return t;
|
|
11
|
+
};
|
|
12
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
13
|
+
import _ReactModal from 'react-modal';
|
|
14
|
+
import { importedDefaultComponentShim } from '../../../utils/misc';
|
|
15
|
+
import { useTheme } from '../../../theme';
|
|
16
|
+
import { GROUP_TYPE, Group } from '../../elements/Group';
|
|
17
|
+
import { Row } from '../../elements/layout/Row';
|
|
18
|
+
import { HEADING_SIZE, Heading } from '../../elements/text/Heading';
|
|
19
|
+
import { BUTTON_TYPE, Button } from '../../elements/Button';
|
|
20
|
+
import { COLOR } from '../../../theme/colors';
|
|
21
|
+
import { TYPOGRAPHY_TYPE } from '../../../theme/typography';
|
|
22
|
+
import { useMediaQuery } from '../../providers/media';
|
|
23
|
+
import { useComponentConfig } from '../../providers/componentConfig';
|
|
24
|
+
const ReactModal = importedDefaultComponentShim(_ReactModal);
|
|
25
|
+
export const Modal = (_a) => {
|
|
26
|
+
var { children, heading, hideHeading, isOpen, footer, actions, close } = _a, props = __rest(_a, ["children", "heading", "hideHeading", "isOpen", "footer", "actions", "close"]);
|
|
27
|
+
const { breakpoint } = useMediaQuery();
|
|
28
|
+
const { modal } = useComponentConfig();
|
|
29
|
+
const theme = useTheme();
|
|
30
|
+
return (_jsx(ReactModal, Object.assign({ isOpen: isOpen, shouldFocusAfterRender: true, appElement: modal.appElement, onRequestClose: close }, props, { style: {
|
|
31
|
+
overlay: {
|
|
32
|
+
backgroundColor: 'rgba(0, 0, 0, 0.5)',
|
|
33
|
+
zIndex: theme.zIndex.MODAL,
|
|
34
|
+
},
|
|
35
|
+
content: {
|
|
36
|
+
padding: 0,
|
|
37
|
+
minWidth: breakpoint === 0 ? 'calc(100% - 1rem)' : '500px',
|
|
38
|
+
top: '50%',
|
|
39
|
+
left: '50%',
|
|
40
|
+
right: 'auto',
|
|
41
|
+
bottom: 'auto',
|
|
42
|
+
marginRight: '-50%',
|
|
43
|
+
transform: 'translate(-50%, -50%)',
|
|
44
|
+
},
|
|
45
|
+
} }, { children: _jsxs(Group, Object.assign({ type: GROUP_TYPE.REGION, sx: { my: 0 } }, { children: [!hideHeading && (_jsxs(Row, Object.assign({ justify: "space-between", align: "center", sx: {
|
|
46
|
+
p: 3,
|
|
47
|
+
borderBottom: 'solid 1px',
|
|
48
|
+
borderColor: COLOR.LIGHT_GRAY,
|
|
49
|
+
} }, { children: [_jsx(Heading, Object.assign({ size: HEADING_SIZE.SM, typography: TYPOGRAPHY_TYPE.CONTROL_MEDIUM }, { children: heading })), _jsx(Button, Object.assign({ type: BUTTON_TYPE.TEXT, onClick: close }, { children: "Close" }))] }))), _jsx(Row, Object.assign({ sx: { p: 3 } }, { children: children })), _jsxs(Row, Object.assign({ sx: { borderTop: 'solid 1px', borderColor: COLOR.LIGHT_GRAY, p: 3 } }, { children: [footer, actions !== undefined && (_jsx(Row, Object.assign({ sx: { width: '100%', justifyContent: 'flex-end' } }, { children: actions.map((action, index) => (_jsx(Button, Object.assign({ type: action.isPrimary ? BUTTON_TYPE.DEFAULT : BUTTON_TYPE.OUTLINE, onClick: action.onClick, sx: {
|
|
50
|
+
mr: index < actions.length - 1 ? 1 : 0,
|
|
51
|
+
} }, { children: action.label }), index))) })))] }))] })) })));
|
|
52
|
+
};
|
|
@@ -21,3 +21,6 @@ const StatefulCheckboxGroup = (props) => {
|
|
|
21
21
|
export const Default = {
|
|
22
22
|
render: () => (_jsx(Row, { children: _jsx(StatefulCheckboxGroup, {}) })),
|
|
23
23
|
};
|
|
24
|
+
export const Columns = {
|
|
25
|
+
render: () => (_jsx(Row, { children: _jsx(StatefulCheckboxGroup, { columns: 2 }) })),
|
|
26
|
+
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { StyledElementProps } from '../../../../theme';
|
|
2
|
+
import { StyledElementProps, StylesProp } from '../../../../theme';
|
|
3
3
|
import { Key } from '../option';
|
|
4
4
|
type Option = {
|
|
5
5
|
value: Key;
|
|
@@ -9,6 +9,8 @@ type CheckboxGroupProps = StyledElementProps<HTMLDivElement, {
|
|
|
9
9
|
onChange: (value: Set<Key>) => void;
|
|
10
10
|
options: Option[];
|
|
11
11
|
checkedOptions?: Set<Key>;
|
|
12
|
+
columnStyles: StylesProp;
|
|
13
|
+
columns?: number;
|
|
12
14
|
}, string>;
|
|
13
15
|
export declare const CheckboxGroup: React.FC<CheckboxGroupProps>;
|
|
14
16
|
export {};
|
|
@@ -10,6 +10,7 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
10
10
|
return t;
|
|
11
11
|
};
|
|
12
12
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
13
|
+
import { useMemo } from 'react';
|
|
13
14
|
import { Row } from '../../layout/Row';
|
|
14
15
|
import { Checkbox } from '../Checkbox';
|
|
15
16
|
import { Label } from '../../text/Label';
|
|
@@ -18,18 +19,32 @@ import { GROUP_TYPE } from '../../Group';
|
|
|
18
19
|
import { Column } from '../../layout/Column';
|
|
19
20
|
import { TYPOGRAPHY_TYPE, getTypographyStyles, } from '../../../../theme/typography';
|
|
20
21
|
export const CheckboxGroup = (_a) => {
|
|
21
|
-
var { options, checkedOptions, onChange } = _a, rest = __rest(_a, ["options", "checkedOptions", "onChange"]);
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
22
|
+
var { options, checkedOptions, columns: columnsProp, columnStyles, onChange } = _a, rest = __rest(_a, ["options", "checkedOptions", "columns", "columnStyles", "onChange"]);
|
|
23
|
+
const columns = columnsProp || 1;
|
|
24
|
+
const optionsByColumn = useMemo(() => {
|
|
25
|
+
// place first i/n items into first column, next i/n items into second column, etc.
|
|
26
|
+
const optionsByColumn = [];
|
|
27
|
+
for (let i = 0; i < options.length; i++) {
|
|
28
|
+
const maxPerColumn = Math.ceil(options.length / columns);
|
|
29
|
+
const columnIndex = Math.floor(i / maxPerColumn);
|
|
30
|
+
if (optionsByColumn[columnIndex] === undefined) {
|
|
31
|
+
optionsByColumn[columnIndex] = [];
|
|
32
|
+
}
|
|
33
|
+
optionsByColumn[columnIndex].push(options[i]);
|
|
34
|
+
}
|
|
35
|
+
return optionsByColumn;
|
|
36
|
+
}, [options, columns]);
|
|
37
|
+
return (_jsx(Row, Object.assign({}, rest, { children: optionsByColumn.map((options, index) => (_jsx(Column, Object.assign({ grow: 1, sx: Object.assign({ mr: 4 }, columnStyles) }, { children: options.map((option) => (_jsx(Group, Object.assign({ type: GROUP_TYPE.RAW }, { children: ({ labelTargetId }) => (_jsxs(Row, Object.assign({ sx: {
|
|
38
|
+
mb: 3,
|
|
39
|
+
alignItems: 'center',
|
|
40
|
+
} }, { children: [_jsx(Checkbox, { onChange: (checked) => {
|
|
41
|
+
const updatedSet = new Set(checkedOptions || []);
|
|
42
|
+
if (checked) {
|
|
43
|
+
updatedSet.add(option.value);
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
updatedSet.delete(option.value);
|
|
47
|
+
}
|
|
48
|
+
onChange(updatedSet);
|
|
49
|
+
}, checked: !!(checkedOptions === null || checkedOptions === void 0 ? void 0 : checkedOptions.has(option.value)), id: labelTargetId, sx: { mr: 2 } }), _jsx(Label, Object.assign({ sx: Object.assign({ cursor: 'pointer' }, getTypographyStyles(TYPOGRAPHY_TYPE.CONDENSED_TEXT_MEDIUM)) }, { children: option.label }))] }))) }), option.value))) }), index))) })));
|
|
35
50
|
};
|
|
@@ -3,15 +3,15 @@ import { StyledElementProps } from '../../../../theme';
|
|
|
3
3
|
import { INPUT_SIZE } from '../TextInput';
|
|
4
4
|
import { BasicOption, Key, RenderOption, RenderOptionLabel } from '../option';
|
|
5
5
|
type SelectProps<Value extends Key, Option extends BasicOption<Value>> = StyledElementProps<HTMLSelectElement, {
|
|
6
|
-
placeholder
|
|
6
|
+
placeholder?: string;
|
|
7
7
|
size?: INPUT_SIZE;
|
|
8
8
|
leftIcon?: React.FC<any>;
|
|
9
9
|
value: Value;
|
|
10
10
|
label?: string;
|
|
11
11
|
onSelectOption: (value: Value) => void;
|
|
12
12
|
options: Option[];
|
|
13
|
-
renderOption
|
|
14
|
-
renderOptionLabel
|
|
13
|
+
renderOption?: RenderOption<Value, Option>;
|
|
14
|
+
renderOptionLabel?: RenderOptionLabel<Option>;
|
|
15
15
|
}, string>;
|
|
16
16
|
export declare function Select<Value extends Key, Option extends BasicOption<Value>>({ size: sizeParam, placeholder, leftIcon, value, label, onSelectOption, options, renderOption, renderOptionLabel: renderOptionLabelParam, sx, }: SelectProps<Value, Option>): import("react/jsx-runtime").JSX.Element;
|
|
17
17
|
export {};
|
|
@@ -15,7 +15,7 @@ import React, { useState } from 'react';
|
|
|
15
15
|
import { useTheme } from '../../../../theme';
|
|
16
16
|
import { COLOR, colors } from '../../../../theme/colors';
|
|
17
17
|
import { getTypographyStyles, } from '../../../../theme/typography';
|
|
18
|
-
import { useMediaQuery } from '
|
|
18
|
+
import { useMediaQuery } from '../../../providers/media';
|
|
19
19
|
const ReadMoreLink = (props) => {
|
|
20
20
|
// const theme = useTheme()
|
|
21
21
|
const bg = colors[props.bg || COLOR.BACKGROUND];
|
|
@@ -8,6 +8,9 @@ export type ComponentConfig = {
|
|
|
8
8
|
internalLinkComponent: React.FC<LinkComponentProps>;
|
|
9
9
|
externalLinkComponent: React.FC<LinkComponentProps>;
|
|
10
10
|
};
|
|
11
|
+
modal: {
|
|
12
|
+
appElement: HTMLElement | undefined;
|
|
13
|
+
};
|
|
11
14
|
};
|
|
12
15
|
export type ComponentConfigParam = DeepPartial<ComponentConfig>;
|
|
13
16
|
export type LinkComponentProps = StyledElementProps<HTMLAnchorElement, {
|
|
@@ -25,6 +25,9 @@ const defaultComponentConfig = {
|
|
|
25
25
|
internalLinkComponent: DefaultLink,
|
|
26
26
|
externalLinkComponent: DefaultLink,
|
|
27
27
|
},
|
|
28
|
+
modal: {
|
|
29
|
+
appElement: undefined,
|
|
30
|
+
},
|
|
28
31
|
};
|
|
29
32
|
export const ComponentConfigContext = createContext(defaultComponentConfig);
|
|
30
33
|
export const useComponentConfig = () => useContext(ComponentConfigContext);
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import React from 'react';
|
|
3
|
+
const DialogContext = React.createContext({
|
|
4
|
+
open: () => { },
|
|
5
|
+
close: () => { },
|
|
6
|
+
dialogs: {},
|
|
7
|
+
});
|
|
8
|
+
export const DialogsProvider = ({ children }) => {
|
|
9
|
+
const [dialogs, setDialogs] = React.useState({});
|
|
10
|
+
const open = (key) => {
|
|
11
|
+
setDialogs(Object.assign(Object.assign({}, dialogs), { [key]: { isOpen: true } }));
|
|
12
|
+
};
|
|
13
|
+
const close = (key) => {
|
|
14
|
+
setDialogs(Object.assign(Object.assign({}, dialogs), { [key]: { isOpen: false } }));
|
|
15
|
+
};
|
|
16
|
+
return (_jsx(DialogContext.Provider, Object.assign({ value: {
|
|
17
|
+
dialogs,
|
|
18
|
+
open,
|
|
19
|
+
close,
|
|
20
|
+
} }, { children: children })));
|
|
21
|
+
};
|
|
22
|
+
export const useDialog = (id) => {
|
|
23
|
+
const dialogs = React.useContext(DialogContext);
|
|
24
|
+
const open = () => dialogs.open(id);
|
|
25
|
+
const close = () => dialogs.close(id);
|
|
26
|
+
const state = dialogs.dialogs[id] || { isOpen: false };
|
|
27
|
+
return {
|
|
28
|
+
open,
|
|
29
|
+
close,
|
|
30
|
+
state,
|
|
31
|
+
};
|
|
32
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import React, { PropsWithChildren } from 'react';
|
|
2
|
+
type MediaContextType = {
|
|
3
|
+
screenSize: number;
|
|
4
|
+
breakpoint: number;
|
|
5
|
+
};
|
|
6
|
+
export declare const MediaSizeProvider: React.FC<PropsWithChildren>;
|
|
7
|
+
export declare const useMediaQuery: () => MediaContextType;
|
|
8
|
+
export {};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { createContext, useContext, useEffect, useMemo, useState, } from 'react';
|
|
3
|
+
import { useTheme } from '../../theme';
|
|
4
|
+
const MediaContext = createContext({
|
|
5
|
+
screenSize: -1,
|
|
6
|
+
breakpoint: -1,
|
|
7
|
+
});
|
|
8
|
+
export const MediaSizeProvider = ({ children, }) => {
|
|
9
|
+
const [renderCount, setRenderCount] = useState(0);
|
|
10
|
+
const theme = useTheme();
|
|
11
|
+
const breakpoints = theme.breakpoints.map((bp) => parseInt(bp.slice(0, -2)), [theme]);
|
|
12
|
+
const { screenSize, breakpoint } = useMemo(() => {
|
|
13
|
+
if (typeof window === 'undefined') {
|
|
14
|
+
return {
|
|
15
|
+
screenSize: -1,
|
|
16
|
+
breakpoint: -1,
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
const screenSize = window.innerWidth;
|
|
20
|
+
const closestBreakpoint = breakpoints.findIndex((bp) => screenSize < bp);
|
|
21
|
+
const breakpoint = closestBreakpoint === -1 ? breakpoints.length : closestBreakpoint;
|
|
22
|
+
return {
|
|
23
|
+
screenSize,
|
|
24
|
+
breakpoint,
|
|
25
|
+
};
|
|
26
|
+
}, [renderCount, breakpoints]); // eslint-disable-line react-hooks/exhaustive-deps
|
|
27
|
+
useEffect(() => {
|
|
28
|
+
if (typeof window === 'undefined')
|
|
29
|
+
return;
|
|
30
|
+
const rerenderOnResize = () => {
|
|
31
|
+
setRenderCount((renderCount) => renderCount + 1);
|
|
32
|
+
};
|
|
33
|
+
window.addEventListener('resize', rerenderOnResize);
|
|
34
|
+
return () => {
|
|
35
|
+
window.removeEventListener('resize', rerenderOnResize);
|
|
36
|
+
};
|
|
37
|
+
}, []);
|
|
38
|
+
return (_jsx(MediaContext.Provider, Object.assign({ value: {
|
|
39
|
+
breakpoint,
|
|
40
|
+
screenSize,
|
|
41
|
+
} }, { children: children })));
|
|
42
|
+
};
|
|
43
|
+
export const useMediaQuery = () => useContext(MediaContext);
|
|
@@ -5,7 +5,8 @@ import { ThemeProvider } from '../../theme/';
|
|
|
5
5
|
import { AlertsProvider } from './alerts';
|
|
6
6
|
import { FontLoader } from '../../FontLoader';
|
|
7
7
|
import { GlobalStyles } from '../../theme/GlobalStyles';
|
|
8
|
+
import { DialogsProvider } from './dialogs';
|
|
9
|
+
import { MediaSizeProvider } from './media';
|
|
8
10
|
export const UiProvider = ({ env, components, alertsConfig, children, loadFonts, loadGlobalStyles, }) => {
|
|
9
|
-
|
|
10
|
-
return (_jsxs(EnvironmentProvider, Object.assign({ env: env }, { children: [_jsx(ComponentConfigProvider, Object.assign({ config: components || {} }, { children: _jsx(ThemeProvider, { children: _jsx(AlertsProvider, Object.assign({}, alertsConfig, { children: children })) }) })), loadGlobalStyles && _jsx(GlobalStyles, {}), loadFonts && _jsx(FontLoader, {})] })));
|
|
11
|
+
return (_jsxs(EnvironmentProvider, Object.assign({ env: env }, { children: [_jsx(ThemeProvider, { children: _jsx(MediaSizeProvider, { children: _jsx(ComponentConfigProvider, Object.assign({ config: components || {} }, { children: _jsx(DialogsProvider, { children: _jsx(AlertsProvider, Object.assign({}, alertsConfig, { children: children })) }) })) }) }), loadGlobalStyles && _jsx(GlobalStyles, {}), loadFonts && _jsx(FontLoader, {})] })));
|
|
11
12
|
};
|
package/dist/index.d.ts
CHANGED
|
@@ -32,8 +32,10 @@ export { Card, CARD_SIZE, CARD_LAYOUT } from './components/composites/Card';
|
|
|
32
32
|
export { NavMenu } from './components/composites/NavMenu';
|
|
33
33
|
export { EmptyState, EMPTY_STATE_SIZE, } from './components/composites/EmptyState';
|
|
34
34
|
export { DropdownLinks } from './components/composites/DropdownLinks';
|
|
35
|
+
export { Modal } from './components/composites/Modal';
|
|
35
36
|
export { UiProvider } from './components/providers/ui';
|
|
36
37
|
export { MenuProvider, useMenu } from './components/providers/menu';
|
|
37
38
|
export { useAlerts, AlertsProvider, ALERT_DOMAIN, } from './components/providers/alerts';
|
|
39
|
+
export { MediaSizeProvider, useMediaQuery } from './components/providers/media';
|
|
40
|
+
export { DialogsProvider, useDialog } from './components/providers/dialogs';
|
|
38
41
|
export { useHover } from './utils/hooks/useHover';
|
|
39
|
-
export { useMediaQuery } from './utils/hooks/useMediaQuery';
|
package/dist/index.js
CHANGED
|
@@ -32,8 +32,10 @@ export { Card, CARD_SIZE, CARD_LAYOUT } from './components/composites/Card';
|
|
|
32
32
|
export { NavMenu } from './components/composites/NavMenu';
|
|
33
33
|
export { EmptyState, EMPTY_STATE_SIZE, } from './components/composites/EmptyState';
|
|
34
34
|
export { DropdownLinks } from './components/composites/DropdownLinks';
|
|
35
|
+
export { Modal } from './components/composites/Modal';
|
|
35
36
|
export { UiProvider } from './components/providers/ui';
|
|
36
37
|
export { MenuProvider, useMenu } from './components/providers/menu';
|
|
37
38
|
export { useAlerts, AlertsProvider, ALERT_DOMAIN, } from './components/providers/alerts';
|
|
39
|
+
export { MediaSizeProvider, useMediaQuery } from './components/providers/media';
|
|
40
|
+
export { DialogsProvider, useDialog } from './components/providers/dialogs';
|
|
38
41
|
export { useHover } from './utils/hooks/useHover';
|
|
39
|
-
export { useMediaQuery } from './utils/hooks/useMediaQuery';
|
package/dist/theme/custom.d.ts
CHANGED
package/dist/theme/custom.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ndlib/component-library",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.37",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"files": [
|
|
@@ -54,6 +54,7 @@
|
|
|
54
54
|
"@types/react": "^18.0.28",
|
|
55
55
|
"@types/react-datepicker": "^4.15.0",
|
|
56
56
|
"@types/react-dom": "^18.0.11",
|
|
57
|
+
"@types/react-modal": "^3.16.0",
|
|
57
58
|
"@types/sanitize-html": "^2.9.0",
|
|
58
59
|
"@typescript-eslint/eslint-plugin": "^5.57.1",
|
|
59
60
|
"@typescript-eslint/parser": "^5.57.1",
|
|
@@ -82,6 +83,7 @@
|
|
|
82
83
|
"@floating-ui/react": "^0.24.5",
|
|
83
84
|
"react-datepicker": "^4.16.0",
|
|
84
85
|
"react-markdown": "^8.0.7",
|
|
86
|
+
"react-modal": "^3.16.1",
|
|
85
87
|
"rehype-raw": "^6.1.1",
|
|
86
88
|
"sanitize-html": "^2.11.0"
|
|
87
89
|
}
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { useEffect, useState } from 'react';
|
|
2
|
-
import { useTheme } from '../../theme';
|
|
3
|
-
export const useMediaQuery = () => {
|
|
4
|
-
const [screenSize, setScreenSize] = useState(typeof window !== 'undefined' ? window.innerWidth : 0);
|
|
5
|
-
const [breakpoint, setBreakpoint] = useState(undefined);
|
|
6
|
-
const theme = useTheme();
|
|
7
|
-
const breakpoints = theme.breakpoints.map((bp) => parseInt(bp.slice(0, -2)), [theme]);
|
|
8
|
-
useEffect(() => {
|
|
9
|
-
if (typeof window === 'undefined')
|
|
10
|
-
return;
|
|
11
|
-
const handleResize = () => {
|
|
12
|
-
const screenSize = window.innerWidth;
|
|
13
|
-
let closestBreakpoint = breakpoints.findIndex((bp) => screenSize < bp);
|
|
14
|
-
closestBreakpoint =
|
|
15
|
-
closestBreakpoint === -1 ? breakpoints.length : closestBreakpoint;
|
|
16
|
-
setBreakpoint(closestBreakpoint);
|
|
17
|
-
setScreenSize(screenSize);
|
|
18
|
-
};
|
|
19
|
-
window.addEventListener('resize', handleResize);
|
|
20
|
-
handleResize();
|
|
21
|
-
return () => {
|
|
22
|
-
window.removeEventListener('resize', handleResize);
|
|
23
|
-
};
|
|
24
|
-
}, []); // eslint-disable-line react-hooks/exhaustive-deps
|
|
25
|
-
return {
|
|
26
|
-
screenSize,
|
|
27
|
-
breakpoint,
|
|
28
|
-
};
|
|
29
|
-
};
|