pixel-react 1.0.6 → 1.0.8
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/.yarn/install-state.gz +0 -0
- package/lib/StyleGuide/ColorPalette/types.d.ts +2 -0
- package/lib/components/DragAndDrop/DragAndDrop.d.ts +9 -0
- package/lib/components/DragAndDrop/DragAndDrop.stories.d.ts +6 -0
- package/lib/components/DragAndDrop/DragAndDropList.d.ts +20 -0
- package/lib/components/DragAndDrop/index.d.ts +1 -0
- package/lib/components/Drawer/Drawer.d.ts +2 -1
- package/lib/components/GridLayout/types.d.ts +17 -0
- package/lib/components/Modal/Modal.d.ts +5 -0
- package/lib/components/Modal/Modal.stories.d.ts +7 -0
- package/lib/components/Modal/index.d.ts +1 -0
- package/lib/components/Modal/types.d.ts +26 -0
- package/lib/components/TableTree/TableTree.d.ts +1 -1
- package/lib/index.d.ts +29 -3
- package/lib/index.esm.js +4725 -80
- package/lib/index.esm.js.map +1 -1
- package/lib/index.js +4723 -77
- package/lib/index.js.map +1 -1
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +26 -23
- package/src/StyleGuide/ColorPalette/ColorPalette.scss +5 -0
- package/src/StyleGuide/ColorPalette/ColorPalette.tsx +10 -1
- package/src/StyleGuide/ColorPalette/colorPaletteList.ts +2 -2
- package/src/StyleGuide/ColorPalette/types.ts +2 -0
- package/src/assets/Themes/BaseTheme.scss +9 -8
- package/src/assets/Themes/DarkTheme.scss +1 -0
- package/src/assets/icons/collapse-icon.svg +6 -0
- package/src/assets/icons/copy-icon.svg +3 -0
- package/src/assets/icons/download-icon.svg +3 -0
- package/src/assets/icons/expand-icon.svg +6 -0
- package/src/assets/icons/license_info.svg +28 -0
- package/src/assets/icons/license_warning.svg +10 -0
- package/src/assets/icons/refresh-icon.svg +4 -0
- package/src/components/DatePicker/DatePicker.scss +3 -3
- package/src/components/DragAndDrop/DragAndDrop.d.ts +5 -0
- package/src/components/DragAndDrop/DragAndDrop.stories.tsx +25 -0
- package/src/components/DragAndDrop/DragAndDrop.ts +7 -0
- package/src/components/DragAndDrop/DragAndDropList.scss +69 -0
- package/src/components/DragAndDrop/DragAndDropList.tsx +150 -0
- package/src/components/DragAndDrop/index.ts +1 -0
- package/src/components/Drawer/Drawer.tsx +3 -7
- package/src/components/GridLayout/GridLayout.stories.tsx +13 -51
- package/src/components/GridLayout/GridLayout.tsx +9 -7
- package/src/components/GridLayout/types.ts +20 -0
- package/src/components/Icon/iconList.ts +14 -0
- package/src/components/Modal/Modal.stories.tsx +63 -0
- package/src/components/Modal/Modal.tsx +71 -0
- package/src/components/Modal/index.tsx +1 -0
- package/src/components/Modal/modal.scss +37 -0
- package/src/components/Modal/types.ts +37 -0
- package/src/components/TableTree/TableTree.tsx +1 -1
- package/src/components/ThemeProvider/ThemeProvider.tsx +11 -8
- package/src/index.ts +2 -5
@@ -0,0 +1,150 @@
|
|
1
|
+
import { useState } from 'react';
|
2
|
+
import DragAndDrop from './DragAndDrop';
|
3
|
+
const {
|
4
|
+
DNDCore: {
|
5
|
+
DndContext,
|
6
|
+
KeyboardSensor,
|
7
|
+
PointerSensor,
|
8
|
+
useSensor,
|
9
|
+
useSensors,
|
10
|
+
closestCorners,
|
11
|
+
},
|
12
|
+
DNDSortable: {
|
13
|
+
useSortable,
|
14
|
+
arrayMove,
|
15
|
+
sortableKeyboardCoordinates,
|
16
|
+
SortableContext,
|
17
|
+
verticalListSortingStrategy,
|
18
|
+
},
|
19
|
+
DNDUtilities: { CSS },
|
20
|
+
} = DragAndDrop;
|
21
|
+
import Typography from '../Typography';
|
22
|
+
|
23
|
+
import './DragAndDropList.scss';
|
24
|
+
|
25
|
+
interface TaskProps {
|
26
|
+
id: number;
|
27
|
+
title: string;
|
28
|
+
}
|
29
|
+
|
30
|
+
export const Task = ({ id, title }: TaskProps) => {
|
31
|
+
const { attributes, listeners, setNodeRef, transform, transition } =
|
32
|
+
useSortable({ id });
|
33
|
+
|
34
|
+
const style = {
|
35
|
+
transition,
|
36
|
+
transform: CSS.Transform.toString(transform),
|
37
|
+
};
|
38
|
+
|
39
|
+
return (
|
40
|
+
<div
|
41
|
+
ref={setNodeRef}
|
42
|
+
style={style}
|
43
|
+
{...attributes}
|
44
|
+
{...listeners}
|
45
|
+
className="task"
|
46
|
+
>
|
47
|
+
<Typography as='h1' fontSize={16} className='task-title'>{title}</Typography>
|
48
|
+
</div>
|
49
|
+
);
|
50
|
+
};
|
51
|
+
|
52
|
+
interface ColumnProps {
|
53
|
+
id: string;
|
54
|
+
tasks: { id: number; title: string }[];
|
55
|
+
}
|
56
|
+
|
57
|
+
export const Column: React.FC<ColumnProps> = ({ tasks }) => {
|
58
|
+
return (
|
59
|
+
<div className="column">
|
60
|
+
<SortableContext items={tasks} strategy={verticalListSortingStrategy}>
|
61
|
+
{tasks.map((task) => (
|
62
|
+
<Task key={task.id} id={task.id} title={task.title} />
|
63
|
+
))}
|
64
|
+
</SortableContext>
|
65
|
+
</div>
|
66
|
+
);
|
67
|
+
};
|
68
|
+
|
69
|
+
interface InputProps {
|
70
|
+
onSubmit: (input: string) => void;
|
71
|
+
}
|
72
|
+
|
73
|
+
export const Input: React.FC<InputProps> = ({ onSubmit }) => {
|
74
|
+
const [input, setInput] = useState('');
|
75
|
+
|
76
|
+
const handleSubmit = () => {
|
77
|
+
if (!input) return;
|
78
|
+
|
79
|
+
onSubmit(input);
|
80
|
+
|
81
|
+
setInput('');
|
82
|
+
};
|
83
|
+
|
84
|
+
return (
|
85
|
+
<div className="container">
|
86
|
+
<input
|
87
|
+
className="input"
|
88
|
+
type="text"
|
89
|
+
value={input}
|
90
|
+
onChange={(e) => setInput(e.target.value)}
|
91
|
+
/>
|
92
|
+
<button onClick={handleSubmit} className="button">
|
93
|
+
<Typography fontSize={14}>Add</Typography>
|
94
|
+
</button>
|
95
|
+
</div>
|
96
|
+
);
|
97
|
+
};
|
98
|
+
|
99
|
+
const DragAndDropList = () => {
|
100
|
+
const [tasks, setTasks] = useState([
|
101
|
+
{ id: 1, title: 'Add tests to homepage' },
|
102
|
+
{ id: 2, title: 'Fix styling in about section' },
|
103
|
+
{ id: 3, title: 'Learn how to center a div' },
|
104
|
+
]);
|
105
|
+
|
106
|
+
const addTask = (title: any) => {
|
107
|
+
setTasks((tasks) => [...tasks, { id: tasks.length + 1, title }]);
|
108
|
+
};
|
109
|
+
|
110
|
+
const sensors = useSensors(
|
111
|
+
useSensor(PointerSensor),
|
112
|
+
useSensor(KeyboardSensor, {
|
113
|
+
coordinateGetter: sortableKeyboardCoordinates,
|
114
|
+
})
|
115
|
+
);
|
116
|
+
|
117
|
+
const getTaskPos = (id: number): number =>
|
118
|
+
tasks.findIndex((task) => task.id === id);
|
119
|
+
|
120
|
+
const handleDragEnd = (event: any) => {
|
121
|
+
const { active, over } = event;
|
122
|
+
|
123
|
+
if (active.id === over.id) return;
|
124
|
+
|
125
|
+
setTasks((tasks) => {
|
126
|
+
const originalPos = getTaskPos(active.id);
|
127
|
+
const newPos = getTaskPos(over.id);
|
128
|
+
|
129
|
+
return arrayMove(tasks, originalPos, newPos);
|
130
|
+
});
|
131
|
+
};
|
132
|
+
|
133
|
+
return (
|
134
|
+
<div className="drag-and-drop-list">
|
135
|
+
<Typography fontSize={32} fontWeight="semi-bold">
|
136
|
+
Drag and Drop test ✅
|
137
|
+
</Typography>
|
138
|
+
<Input onSubmit={addTask} />
|
139
|
+
<DndContext
|
140
|
+
sensors={sensors}
|
141
|
+
collisionDetection={closestCorners}
|
142
|
+
onDragEnd={handleDragEnd}
|
143
|
+
>
|
144
|
+
<Column id="toDo" tasks={tasks} />
|
145
|
+
</DndContext>
|
146
|
+
</div>
|
147
|
+
);
|
148
|
+
};
|
149
|
+
|
150
|
+
export default DragAndDropList;
|
@@ -0,0 +1 @@
|
|
1
|
+
export * from './DragAndDrop';
|
@@ -3,11 +3,11 @@ import { DrawerProps } from './Types.js';
|
|
3
3
|
import Button from '../Button/Button.js';
|
4
4
|
import classNames from 'classnames';
|
5
5
|
import './Drawer.scss';
|
6
|
-
import { useContext, useEffect, useState } from 'react';
|
6
|
+
import { FC, useContext, useEffect, useState } from 'react';
|
7
7
|
import Icon from '../Icon';
|
8
8
|
import useEscapeKey from '../../hooks/keyboardevents/useEscKeyEvent.js';
|
9
9
|
import { ThemeContext } from '../ThemeProvider/ThemeProvider.js';
|
10
|
-
const Drawer = ({
|
10
|
+
const Drawer: FC<DrawerProps> = ({
|
11
11
|
isOpen = true,
|
12
12
|
children = 'Drawer content area',
|
13
13
|
onClose = () => {},
|
@@ -103,11 +103,7 @@ const Drawer = ({
|
|
103
103
|
<div className="ff-drawer-title">{title}</div>
|
104
104
|
</div>
|
105
105
|
{_isCloseModalButtonVisible && (
|
106
|
-
<Icon
|
107
|
-
name="close"
|
108
|
-
hoverEffect={false}
|
109
|
-
onClick={onClose}
|
110
|
-
/>
|
106
|
+
<Icon name="close" hoverEffect={false} onClick={onClose} />
|
111
107
|
)}
|
112
108
|
</div>
|
113
109
|
</div>
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import { Meta, StoryObj } from '@storybook/react';
|
2
2
|
import { Container, Row, Col } from './GridLayout';
|
3
|
-
import './GridLayoutStory.scss'
|
3
|
+
import './GridLayoutStory.scss';
|
4
4
|
|
5
5
|
const meta: Meta<typeof Container> = {
|
6
6
|
title: 'Components/GridLayout',
|
@@ -27,31 +27,21 @@ export const Grid: ContainerStory = {
|
|
27
27
|
<Container {...args}>
|
28
28
|
<Row>
|
29
29
|
<Col size={4}>
|
30
|
-
<div className=
|
31
|
-
Column 1
|
32
|
-
</div>
|
30
|
+
<div className="one">Column 1</div>
|
33
31
|
</Col>
|
34
32
|
<Col size={4}>
|
35
|
-
<div className=
|
36
|
-
Column 2
|
37
|
-
</div>
|
33
|
+
<div className="two">Column 2</div>
|
38
34
|
</Col>
|
39
35
|
<Col size={4}>
|
40
|
-
<div className=
|
41
|
-
Column 3
|
42
|
-
</div>
|
36
|
+
<div className="three">Column 3</div>
|
43
37
|
</Col>
|
44
38
|
</Row>
|
45
39
|
<Row>
|
46
40
|
<Col size={6}>
|
47
|
-
<div className=
|
48
|
-
Column 4
|
49
|
-
</div>
|
41
|
+
<div className="four">Column 4</div>
|
50
42
|
</Col>
|
51
43
|
<Col size={6}>
|
52
|
-
<div className=
|
53
|
-
Column 5
|
54
|
-
</div>
|
44
|
+
<div className="five">Column 5</div>
|
55
45
|
</Col>
|
56
46
|
</Row>
|
57
47
|
</Container>
|
@@ -67,57 +57,29 @@ export const Grid2: ContainerStory = {
|
|
67
57
|
<Container {...args}>
|
68
58
|
<Row gap="20px">
|
69
59
|
<Col size={3}>
|
70
|
-
<div
|
71
|
-
className='one'
|
72
|
-
>
|
73
|
-
Column 1 (size 3)
|
74
|
-
</div>
|
60
|
+
<div className="one">Column 1 (size 3)</div>
|
75
61
|
</Col>
|
76
62
|
<Col size={6}>
|
77
|
-
<div
|
78
|
-
className='two'
|
79
|
-
>
|
80
|
-
Column 2 (size 6)
|
81
|
-
</div>
|
63
|
+
<div className="two">Column 2 (size 6)</div>
|
82
64
|
</Col>
|
83
65
|
<Col size={3}>
|
84
|
-
<div
|
85
|
-
className='three'
|
86
|
-
>
|
87
|
-
Column 3 (size 3)
|
88
|
-
</div>
|
66
|
+
<div className="three">Column 3 (size 3)</div>
|
89
67
|
</Col>
|
90
68
|
</Row>
|
91
69
|
<Row gap="10px">
|
92
70
|
<Col size={4}>
|
93
|
-
<div
|
94
|
-
className='four'
|
95
|
-
>
|
96
|
-
Column 4 (size 4)
|
97
|
-
</div>
|
71
|
+
<div className="four">Column 4 (size 4)</div>
|
98
72
|
</Col>
|
99
73
|
<Col size={4}>
|
100
|
-
<div
|
101
|
-
className='five'
|
102
|
-
>
|
103
|
-
Column 5 (size 4)
|
104
|
-
</div>
|
74
|
+
<div className="five">Column 5 (size 4)</div>
|
105
75
|
</Col>
|
106
76
|
<Col size={4}>
|
107
|
-
<div
|
108
|
-
className='one'
|
109
|
-
>
|
110
|
-
Column 6 (size 4)
|
111
|
-
</div>
|
77
|
+
<div className="one">Column 6 (size 4)</div>
|
112
78
|
</Col>
|
113
79
|
</Row>
|
114
80
|
<Row gap="15px">
|
115
81
|
<Col size={12}>
|
116
|
-
<div
|
117
|
-
className='two'
|
118
|
-
>
|
119
|
-
Full-width column (size 12)
|
120
|
-
</div>
|
82
|
+
<div className="two">Full-width column (size 12)</div>
|
121
83
|
</Col>
|
122
84
|
</Row>
|
123
85
|
</Container>
|
@@ -2,29 +2,31 @@
|
|
2
2
|
import React from 'react';
|
3
3
|
import './GridLayout.scss';
|
4
4
|
import { ContainerProps, RowProps, ColProps } from './types';
|
5
|
+
import cx from 'classnames'
|
5
6
|
|
6
7
|
export const Container: React.FC<ContainerProps> = ({
|
7
8
|
children,
|
8
9
|
fluid = false,
|
9
10
|
gap = '0px',
|
11
|
+
className=''
|
10
12
|
}) => {
|
11
|
-
const
|
13
|
+
const containerClassName = fluid ? 'ff-container-fluid' : 'ff-container';
|
12
14
|
return (
|
13
|
-
<div className={className} style={{ gap }}>
|
15
|
+
<div className={cx(containerClassName,className)} style={{ gap }}>
|
14
16
|
{children}
|
15
17
|
</div>
|
16
18
|
);
|
17
19
|
};
|
18
20
|
|
19
|
-
export const Row: React.FC<RowProps> = ({ children, gap = '0px' }) => {
|
21
|
+
export const Row: React.FC<RowProps> = ({ children, gap = '0px',className='' }) => {
|
20
22
|
return (
|
21
|
-
<div className="ff-row" style={{ gap }}>
|
23
|
+
<div className={cx("ff-row",className)} style={{ gap }}>
|
22
24
|
{children}
|
23
25
|
</div>
|
24
26
|
);
|
25
27
|
};
|
26
28
|
|
27
|
-
export const Col: React.FC<ColProps> = ({ children, size = 12 }) => {
|
28
|
-
const
|
29
|
-
return <div className={className}>{children}</div>;
|
29
|
+
export const Col: React.FC<ColProps> = ({ children, size = 12,className='' }) => {
|
30
|
+
const colClassName = `ff-col-${size}`;
|
31
|
+
return <div className={cx(colClassName,className)}>{children}</div>;
|
30
32
|
};
|
@@ -25,6 +25,13 @@ export interface ContainerProps {
|
|
25
25
|
* @type {string}
|
26
26
|
*/
|
27
27
|
gap?: string;
|
28
|
+
|
29
|
+
/**
|
30
|
+
* Classname for Container
|
31
|
+
* @default ''
|
32
|
+
* @type {string}
|
33
|
+
*/
|
34
|
+
className?:string
|
28
35
|
}
|
29
36
|
|
30
37
|
export interface RowProps {
|
@@ -43,6 +50,12 @@ export interface RowProps {
|
|
43
50
|
* @type {string}
|
44
51
|
*/
|
45
52
|
gap?: string;
|
53
|
+
|
54
|
+
/**
|
55
|
+
* @default ''
|
56
|
+
* @type string
|
57
|
+
*/
|
58
|
+
className?:string
|
46
59
|
}
|
47
60
|
|
48
61
|
export interface ColProps {
|
@@ -61,4 +74,11 @@ export interface ColProps {
|
|
61
74
|
* @type {number}
|
62
75
|
*/
|
63
76
|
size?: number;
|
77
|
+
|
78
|
+
/**
|
79
|
+
* @default ''
|
80
|
+
* @type string
|
81
|
+
*
|
82
|
+
*/
|
83
|
+
className?: string;
|
64
84
|
}
|
@@ -45,6 +45,13 @@ import ImpactListIcon from '../../assets/icons/impactList.svg?react';
|
|
45
45
|
import InfoIcon from '../../assets/icons/info_icon.svg?react';
|
46
46
|
import CalendarIcon from '../../assets/icons/calendar_icon.svg?react';
|
47
47
|
import HideIcon from '../../assets/icons/hide_icon.svg?react';
|
48
|
+
import CollapseIcon from '../../assets/icons/collapse-icon.svg?react';
|
49
|
+
import ExpandIcon from '../../assets/icons/expand-icon.svg?react';
|
50
|
+
import CopyIcon from '../../assets/icons/copy-icon.svg?react';
|
51
|
+
import DownloadFile from '../../assets/icons/download-icon.svg?react';
|
52
|
+
import RefreshIcon from '../../assets/icons/refresh-icon.svg?react';
|
53
|
+
import LicenseInfo from '../../assets/icons/license_info.svg?react';
|
54
|
+
import LicenseWarning from '../../assets/icons/license_warning.svg?react';
|
48
55
|
//icons
|
49
56
|
Components['delete_info'] = DeleteInfoIcon;
|
50
57
|
Components['success'] = ToastSuccessIcon;
|
@@ -90,5 +97,12 @@ Components['add_variable'] = AddVariable;
|
|
90
97
|
Components['info'] = InfoIcon;
|
91
98
|
Components['calendar_icon'] = CalendarIcon;
|
92
99
|
Components['hide_icon'] = HideIcon;
|
100
|
+
Components['collapse_icon'] = CollapseIcon;
|
101
|
+
Components['refresh_icon'] = RefreshIcon;
|
102
|
+
Components['download_file'] = DownloadFile;
|
103
|
+
Components['copy_icon'] = CopyIcon;
|
104
|
+
Components['expand_icon'] = ExpandIcon;
|
105
|
+
Components['license_info'] = LicenseInfo;
|
106
|
+
Components['license_warning'] = LicenseWarning;
|
93
107
|
|
94
108
|
export default Components;
|
@@ -0,0 +1,63 @@
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
2
|
+
import Modal from './Modal';
|
3
|
+
import { useState } from 'react';
|
4
|
+
import Button from '../Button';
|
5
|
+
|
6
|
+
const meta: Meta<typeof Modal> = {
|
7
|
+
title: 'Components/Modal',
|
8
|
+
component: Modal,
|
9
|
+
parameters: {
|
10
|
+
layout: 'centered',
|
11
|
+
},
|
12
|
+
tags: ['autodocs'],
|
13
|
+
};
|
14
|
+
|
15
|
+
type Story = StoryObj<typeof Modal>;
|
16
|
+
|
17
|
+
export const DefaultModalStory: Story = {
|
18
|
+
args: {
|
19
|
+
isOpen: true,
|
20
|
+
contentLabel: 'modal',
|
21
|
+
ariaHideApp: true,
|
22
|
+
isHeaderDisplayed: true,
|
23
|
+
headerContent: <h2>title</h2>,
|
24
|
+
children: <h2>Hello</h2>,
|
25
|
+
isFooterDisplayed:true,
|
26
|
+
footerContent: <Button variant="primary" label="continue" />,
|
27
|
+
},
|
28
|
+
};
|
29
|
+
|
30
|
+
export const Controlled: Story = {
|
31
|
+
render: () => {
|
32
|
+
const [openModal, setModal] = useState(false);
|
33
|
+
return (
|
34
|
+
<>
|
35
|
+
<Button
|
36
|
+
variant="primary"
|
37
|
+
onClick={() => {
|
38
|
+
setModal(true);
|
39
|
+
}}
|
40
|
+
>
|
41
|
+
Show Modal
|
42
|
+
</Button>
|
43
|
+
{openModal && (
|
44
|
+
<Modal
|
45
|
+
overlayClassName="custom-overlay"
|
46
|
+
isOpen={openModal}
|
47
|
+
onClose={() => {
|
48
|
+
setModal(false);
|
49
|
+
}}
|
50
|
+
headerContent={<div>title</div>}
|
51
|
+
isHeaderDisplayed={true}
|
52
|
+
children={<div>Hello</div>}
|
53
|
+
ariaHideApp={true}
|
54
|
+
isFooterDisplayed={true}
|
55
|
+
footerContent={<Button variant="primary" label='continue'/>}
|
56
|
+
/>
|
57
|
+
)}
|
58
|
+
</>
|
59
|
+
);
|
60
|
+
},
|
61
|
+
};
|
62
|
+
|
63
|
+
export default meta;
|
@@ -0,0 +1,71 @@
|
|
1
|
+
import React, { useContext, useEffect } from 'react';
|
2
|
+
import { createPortal } from 'react-dom';
|
3
|
+
import './modal.scss';
|
4
|
+
import { ModalProps } from './types';
|
5
|
+
import { ThemeContext } from '../ThemeProvider/ThemeProvider';
|
6
|
+
|
7
|
+
|
8
|
+
const Modal: React.FC<ModalProps> = ({
|
9
|
+
isOpen,
|
10
|
+
onClose,
|
11
|
+
contentLabel,
|
12
|
+
isHeaderDisplayed,
|
13
|
+
headerContent,
|
14
|
+
footerContent,
|
15
|
+
contentClassName,
|
16
|
+
isFooterDisplayed,
|
17
|
+
overlayClassName,
|
18
|
+
shouldCloseOnEsc = true,
|
19
|
+
ariaHideApp = true,
|
20
|
+
shouldCloseOnOverlayClick = true,
|
21
|
+
children,
|
22
|
+
}) => {
|
23
|
+
useEffect(() => {
|
24
|
+
const handleKeyDown = (e: KeyboardEvent) => {
|
25
|
+
if (e.key === 'Escape' && shouldCloseOnEsc) {
|
26
|
+
onClose();
|
27
|
+
}
|
28
|
+
};
|
29
|
+
|
30
|
+
if (isOpen) {
|
31
|
+
document.addEventListener('keydown', handleKeyDown);
|
32
|
+
if (ariaHideApp) {
|
33
|
+
document.body.style.overflow = 'hidden';
|
34
|
+
}
|
35
|
+
}
|
36
|
+
return () => {
|
37
|
+
document.removeEventListener('keydown', handleKeyDown);
|
38
|
+
if (ariaHideApp) {
|
39
|
+
document.body.style.overflow = '';
|
40
|
+
}
|
41
|
+
};
|
42
|
+
}, [isOpen, onClose, ariaHideApp, shouldCloseOnEsc]);
|
43
|
+
|
44
|
+
if (!isOpen) return null;
|
45
|
+
const themeContext = useContext(ThemeContext);
|
46
|
+
const currentTheme = themeContext?.currentTheme;
|
47
|
+
|
48
|
+
return createPortal(
|
49
|
+
<div
|
50
|
+
className={`ff-modal-overlay ${overlayClassName || ''}`}
|
51
|
+
onClick={shouldCloseOnOverlayClick ? onClose : undefined}
|
52
|
+
>
|
53
|
+
<div
|
54
|
+
className={`ff-modal-content ${currentTheme} ${contentClassName || ''}`}
|
55
|
+
onClick={(e) => e.stopPropagation()}
|
56
|
+
aria-label={contentLabel}
|
57
|
+
>
|
58
|
+
{isHeaderDisplayed && (
|
59
|
+
<div className="ff-modal-header">{headerContent}</div>
|
60
|
+
)}
|
61
|
+
{children}
|
62
|
+
</div>
|
63
|
+
{isFooterDisplayed && (
|
64
|
+
<div className="ff-modal-footer">{footerContent}</div>
|
65
|
+
)}
|
66
|
+
</div>,
|
67
|
+
document.body
|
68
|
+
);
|
69
|
+
};
|
70
|
+
|
71
|
+
export default Modal;
|
@@ -0,0 +1 @@
|
|
1
|
+
export { default } from './Modal';
|
@@ -0,0 +1,37 @@
|
|
1
|
+
@use '../../assets/styles/mixins' as *;
|
2
|
+
.ff-modal-overlay {
|
3
|
+
position: fixed;
|
4
|
+
top: 0;
|
5
|
+
left: 0;
|
6
|
+
width: 100%;
|
7
|
+
height: 100%;
|
8
|
+
background: var(--background-modal-color);
|
9
|
+
@include center-content;
|
10
|
+
flex-direction: column;
|
11
|
+
}
|
12
|
+
|
13
|
+
.ff-modal-content {
|
14
|
+
background: var(--ff-mini-modal-border);
|
15
|
+
position: relative;
|
16
|
+
max-width: 549px;
|
17
|
+
width: 100%;
|
18
|
+
border-radius: 12px 12px 0 0;
|
19
|
+
padding: 16px;
|
20
|
+
.ff-modal-header {
|
21
|
+
height: 32px;
|
22
|
+
width: 448px;
|
23
|
+
}
|
24
|
+
}
|
25
|
+
.ff-modal-footer {
|
26
|
+
background-color: var(--expandable-menu-option-bg);
|
27
|
+
max-width: 549px;
|
28
|
+
width: 100%;
|
29
|
+
height: 32px;
|
30
|
+
border-radius: 0 0 12px 12px;
|
31
|
+
display: flex;
|
32
|
+
flex-direction: row;
|
33
|
+
justify-content: end;
|
34
|
+
align-items: center;
|
35
|
+
gap: 8px;
|
36
|
+
padding: 4px 16px;
|
37
|
+
}
|
@@ -0,0 +1,37 @@
|
|
1
|
+
import { ReactNode } from "react";
|
2
|
+
|
3
|
+
export interface ModalProps {
|
4
|
+
isOpen: boolean;
|
5
|
+
onClose: () => void;
|
6
|
+
|
7
|
+
/*** label value for aria-label */
|
8
|
+
contentLabel?: string;
|
9
|
+
|
10
|
+
/*** default header will be provided with title and close icon. */
|
11
|
+
isHeaderDisplayed: boolean;
|
12
|
+
|
13
|
+
/*** Title to be displayed in the header when defaultHeader is true*/
|
14
|
+
headerTitle?: string;
|
15
|
+
|
16
|
+
/*** Custom class names for the modal content */
|
17
|
+
contentClassName?: string;
|
18
|
+
|
19
|
+
/*** Custom class name for the overlay */
|
20
|
+
overlayClassName?: string;
|
21
|
+
|
22
|
+
/*** Whether the modal should close when the 'Escape' key is pressed */
|
23
|
+
shouldCloseOnEsc?: boolean;
|
24
|
+
|
25
|
+
/*** Whether to hide the app from screen readers when the modal is open */
|
26
|
+
ariaHideApp?: boolean; //for screen readers
|
27
|
+
|
28
|
+
/*** Whether the modal should close when clicking outside of it (on the overlay) */
|
29
|
+
shouldCloseOnOverlayClick?: boolean;
|
30
|
+
// shouldFocusAfterRender?: boolean;
|
31
|
+
// shouldReturnFocusAfterClose?: boolean;
|
32
|
+
headerContent?: string | ReactNode;
|
33
|
+
footerContent?: ReactNode;
|
34
|
+
/***Content to be displayed inside the modal */
|
35
|
+
children: ReactNode;
|
36
|
+
isFooterDisplayed: boolean;
|
37
|
+
}
|
@@ -1,12 +1,12 @@
|
|
1
1
|
/* eslint-disable */
|
2
2
|
// @ts-nocheck
|
3
|
-
import './TableTree.scss';
|
4
3
|
import React, { ReactNode, useLayoutEffect, useRef, useState } from 'react';
|
5
4
|
import { prepareData } from '../../utils/TableCell/TableCell';
|
6
5
|
import Icon from '../Icon';
|
7
6
|
import { checkEmpty } from '../../utils/checkEmpty/checkEmpty';
|
8
7
|
|
9
8
|
import Checkbox from '../Checkbox';
|
9
|
+
import './TableTree.scss';
|
10
10
|
|
11
11
|
interface ColumnDataProps {
|
12
12
|
name: string;
|
@@ -1,21 +1,24 @@
|
|
1
|
-
import React, { createContext, useState } from 'react';
|
1
|
+
import React, { createContext, useState, useEffect } from 'react';
|
2
2
|
import { ThemeContextType, ThemeProviderProps, Theme } from './types';
|
3
3
|
import '../../assets/Themes/Theme.scss';
|
4
4
|
|
5
5
|
const ThemeContext = createContext<ThemeContextType | undefined>(undefined);
|
6
6
|
|
7
7
|
const ThemeProvider: React.FC<ThemeProviderProps> = ({ children, theme }) => {
|
8
|
-
const [currentTheme, setCurrentTheme] = useState<Theme>(
|
9
|
-
theme || 'ff-light-theme'
|
10
|
-
);
|
8
|
+
const [currentTheme, setCurrentTheme] = useState<Theme>(theme || 'ff-light-theme');
|
11
9
|
|
12
10
|
const applyTheme = (newTheme: Theme) => setCurrentTheme(newTheme);
|
13
11
|
|
12
|
+
useEffect(() => {
|
13
|
+
document.body.className = currentTheme;
|
14
|
+
return () => {
|
15
|
+
document.body.className = '';
|
16
|
+
};
|
17
|
+
}, [currentTheme]);
|
18
|
+
|
14
19
|
return (
|
15
|
-
<ThemeContext.Provider
|
16
|
-
|
17
|
-
>
|
18
|
-
<div className={currentTheme}>{children}</div>
|
20
|
+
<ThemeContext.Provider value={{ currentTheme, setCurrentTheme, applyTheme }}>
|
21
|
+
{children}
|
19
22
|
</ThemeContext.Provider>
|
20
23
|
);
|
21
24
|
};
|