@patternfly/react-data-view 1.0.0-prerelease.4 → 5.0.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/cjs/DataView/DataView.test.d.ts +1 -0
- package/dist/cjs/DataView/DataView.test.js +23 -0
- package/dist/cjs/DataViewToolbar/DataViewToolbar.d.ts +5 -3
- package/dist/cjs/DataViewToolbar/DataViewToolbar.js +3 -2
- package/dist/cjs/DataViewToolbar/DataViewToolbar.test.d.ts +1 -0
- package/dist/cjs/DataViewToolbar/DataViewToolbar.test.js +14 -0
- package/dist/cjs/Hooks/index.d.ts +1 -0
- package/dist/cjs/Hooks/index.js +1 -0
- package/dist/cjs/Hooks/pagination.d.ts +3 -0
- package/dist/cjs/Hooks/selection.d.ts +11 -0
- package/dist/cjs/Hooks/selection.js +26 -0
- package/dist/cjs/Hooks/selection.test.d.ts +1 -0
- package/dist/cjs/Hooks/selection.test.js +55 -0
- package/dist/esm/DataView/DataView.test.d.ts +1 -0
- package/dist/esm/DataView/DataView.test.js +18 -0
- package/dist/esm/DataViewToolbar/DataViewToolbar.d.ts +5 -3
- package/dist/esm/DataViewToolbar/DataViewToolbar.js +3 -2
- package/dist/esm/DataViewToolbar/DataViewToolbar.test.d.ts +1 -0
- package/dist/esm/DataViewToolbar/DataViewToolbar.test.js +9 -0
- package/dist/esm/Hooks/index.d.ts +1 -0
- package/dist/esm/Hooks/index.js +1 -0
- package/dist/esm/Hooks/pagination.d.ts +3 -0
- package/dist/esm/Hooks/selection.d.ts +11 -0
- package/dist/esm/Hooks/selection.js +22 -0
- package/dist/esm/Hooks/selection.test.d.ts +1 -0
- package/dist/esm/Hooks/selection.test.js +53 -0
- package/generate-fed-package-json.js +7 -8
- package/generate-index.js +2 -2
- package/package.json +8 -8
- package/patternfly-docs/content/extensions/data-view/examples/{DataViewToolbar/DataViewToolbar.md → Components/Components.md} +9 -5
- package/patternfly-docs/content/extensions/data-view/examples/Components/DataViewToolbarExample.tsx +20 -0
- package/patternfly-docs/content/extensions/data-view/examples/Functionality/Functionality.md +77 -0
- package/patternfly-docs/content/extensions/data-view/examples/{DataView/DataViewPredefinedLayoutExample.tsx → Functionality/PaginationExample.tsx} +2 -2
- package/patternfly-docs/content/extensions/data-view/examples/Functionality/SelectionExample.tsx +88 -0
- package/patternfly-docs/content/extensions/data-view/examples/{DataView/DataViewLayoutExample.tsx → Layout/AbstractLayoutExample.tsx} +4 -3
- package/patternfly-docs/content/extensions/data-view/examples/{DataView/DataView.md → Layout/Layout.md} +8 -6
- package/patternfly-docs/content/extensions/data-view/examples/Layout/PredefinedLayoutExample.tsx +120 -0
- package/patternfly-docs/pages/index.js +1 -1
- package/release.config.js +6 -2
- package/src/DataView/DataView.test.tsx +22 -0
- package/src/DataView/__snapshots__/DataView.test.tsx.snap +134 -0
- package/src/DataViewToolbar/DataViewToolbar.test.tsx +11 -0
- package/src/DataViewToolbar/DataViewToolbar.tsx +12 -5
- package/src/DataViewToolbar/__snapshots__/DataViewToolbar.test.tsx.snap +542 -0
- package/src/Hooks/index.ts +1 -0
- package/src/Hooks/pagination.ts +3 -0
- package/src/Hooks/selection.test.tsx +52 -0
- package/src/Hooks/selection.ts +32 -0
- package/patternfly-docs/content/extensions/data-view/examples/DataViewToolbar/DataViewToolbarExample.tsx +0 -7
- package/patternfly-docs/content/extensions/data-view/examples/Hooks/Hooks.md +0 -20
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const react_1 = __importDefault(require("react"));
|
|
7
|
+
const react_2 = require("@testing-library/react");
|
|
8
|
+
const DataView_1 = __importDefault(require("./DataView"));
|
|
9
|
+
const layoutItemStyling = {
|
|
10
|
+
width: '100%',
|
|
11
|
+
height: '5rem',
|
|
12
|
+
padding: 'var(--pf-v5-global--spacer--md)',
|
|
13
|
+
borderStyle: 'dashed',
|
|
14
|
+
borderWidth: '2px',
|
|
15
|
+
};
|
|
16
|
+
describe('DataView component', () => {
|
|
17
|
+
test('should render correctly', () => {
|
|
18
|
+
expect((0, react_2.render)(react_1.default.createElement(DataView_1.default, null,
|
|
19
|
+
react_1.default.createElement("div", { style: layoutItemStyling }, "Header"),
|
|
20
|
+
react_1.default.createElement("div", { style: Object.assign(Object.assign({}, layoutItemStyling), { borderTopWidth: 0, borderBottomWidth: 0 }) }, "Data representation"),
|
|
21
|
+
react_1.default.createElement("div", { style: layoutItemStyling }, "Footer")))).toMatchSnapshot();
|
|
22
|
+
});
|
|
23
|
+
});
|
|
@@ -1,11 +1,13 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
export interface DataViewToolbarProps {
|
|
1
|
+
import React, { PropsWithChildren } from 'react';
|
|
2
|
+
export interface DataViewToolbarProps extends PropsWithChildren {
|
|
3
3
|
/** Toolbar className */
|
|
4
4
|
className?: string;
|
|
5
5
|
/** Custom OUIA ID */
|
|
6
6
|
ouiaId?: string;
|
|
7
|
+
/** React component to display bulk select */
|
|
8
|
+
bulkSelect?: React.ReactNode;
|
|
7
9
|
/** React component to display pagination */
|
|
8
10
|
pagination?: React.ReactNode;
|
|
9
11
|
}
|
|
10
|
-
export declare const DataViewToolbar: React.FC<
|
|
12
|
+
export declare const DataViewToolbar: React.FC<DataViewToolbarProps>;
|
|
11
13
|
export default DataViewToolbar;
|
|
@@ -18,10 +18,11 @@ exports.DataViewToolbar = void 0;
|
|
|
18
18
|
const react_1 = __importDefault(require("react"));
|
|
19
19
|
const react_core_1 = require("@patternfly/react-core");
|
|
20
20
|
const DataViewToolbar = (_a) => {
|
|
21
|
-
var { className, ouiaId = 'DataViewToolbar', pagination, children } = _a, props = __rest(_a, ["className", "ouiaId", "pagination", "children"]);
|
|
21
|
+
var { className, ouiaId = 'DataViewToolbar', bulkSelect, pagination, children } = _a, props = __rest(_a, ["className", "ouiaId", "bulkSelect", "pagination", "children"]);
|
|
22
22
|
return (react_1.default.createElement(react_core_1.Toolbar, Object.assign({ ouiaId: ouiaId, className: className }, props),
|
|
23
23
|
react_1.default.createElement(react_core_1.ToolbarContent, null,
|
|
24
|
-
|
|
24
|
+
bulkSelect && (react_1.default.createElement(react_core_1.ToolbarItem, { "data-ouia-component-id": `${ouiaId}-bulk-select` }, bulkSelect)),
|
|
25
|
+
pagination && (react_1.default.createElement(react_core_1.ToolbarItem, { variant: react_core_1.ToolbarItemVariant.pagination, "data-ouia-component-id": `${ouiaId}-pagination` }, pagination)),
|
|
25
26
|
children)));
|
|
26
27
|
};
|
|
27
28
|
exports.DataViewToolbar = DataViewToolbar;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const react_1 = __importDefault(require("react"));
|
|
7
|
+
const react_2 = require("@testing-library/react");
|
|
8
|
+
const DataViewToolbar_1 = __importDefault(require("./DataViewToolbar"));
|
|
9
|
+
const react_core_1 = require("@patternfly/react-core");
|
|
10
|
+
describe('DataViewToolbar component', () => {
|
|
11
|
+
test('should render correctly', () => {
|
|
12
|
+
expect((0, react_2.render)(react_1.default.createElement(DataViewToolbar_1.default, { pagination: react_1.default.createElement(react_core_1.Pagination, { page: 1, perPage: 10 }) }))).toMatchSnapshot();
|
|
13
|
+
});
|
|
14
|
+
});
|
package/dist/cjs/Hooks/index.js
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
export interface UseDataViewPaginationProps {
|
|
2
|
+
/** Initial page */
|
|
2
3
|
page?: number;
|
|
4
|
+
/** Items per page */
|
|
3
5
|
perPage: number;
|
|
4
6
|
}
|
|
5
7
|
export interface DataViewPaginationProps extends UseDataViewPaginationProps {
|
|
8
|
+
/** Current page number */
|
|
6
9
|
page: number;
|
|
7
10
|
}
|
|
8
11
|
export declare const useDataViewPagination: ({ page, perPage }: UseDataViewPaginationProps) => {
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface UseDataViewSelectionProps {
|
|
2
|
+
/** Array of initially selected entries */
|
|
3
|
+
initialSelected?: (any)[];
|
|
4
|
+
/** Function to compare items when checking if entry is selected */
|
|
5
|
+
matchOption?: (item: any, another: any) => boolean;
|
|
6
|
+
}
|
|
7
|
+
export declare const useDataViewSelection: (props: UseDataViewSelectionProps) => {
|
|
8
|
+
selected: any[];
|
|
9
|
+
onSelect: (isSelecting: boolean, items?: any[] | any) => void;
|
|
10
|
+
isSelected: (item: any) => boolean;
|
|
11
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.useDataViewSelection = void 0;
|
|
4
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
5
|
+
const react_1 = require("react");
|
|
6
|
+
const useDataViewSelection = (props) => {
|
|
7
|
+
var _a;
|
|
8
|
+
const [selected, setSelected] = (0, react_1.useState)((_a = props.initialSelected) !== null && _a !== void 0 ? _a : []);
|
|
9
|
+
const matchOption = props.matchOption ? props.matchOption : (option, another) => (option === another);
|
|
10
|
+
const onSelect = (isSelecting, items) => {
|
|
11
|
+
isSelecting ?
|
|
12
|
+
setSelected(prev => {
|
|
13
|
+
const newSelectedItems = [...prev];
|
|
14
|
+
(Array.isArray(items) ? items : [items]).forEach(newItem => !prev.some(prevItem => matchOption(prevItem, newItem)) && newSelectedItems.push(newItem));
|
|
15
|
+
return newSelectedItems;
|
|
16
|
+
})
|
|
17
|
+
: setSelected(items ? prev => prev.filter(prevSelected => !(Array.isArray(items) ? items : [items]).some(item => matchOption(item, prevSelected))) : []);
|
|
18
|
+
};
|
|
19
|
+
const isSelected = (item) => (props === null || props === void 0 ? void 0 : props.matchOption) ? Boolean(selected.find(selected => matchOption(selected, item))) : selected.includes(item);
|
|
20
|
+
return {
|
|
21
|
+
selected,
|
|
22
|
+
onSelect,
|
|
23
|
+
isSelected
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
exports.useDataViewSelection = useDataViewSelection;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import '@testing-library/jest-dom';
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
require("@testing-library/jest-dom");
|
|
13
|
+
const react_1 = require("@testing-library/react");
|
|
14
|
+
const selection_1 = require("./selection");
|
|
15
|
+
describe('useDataViewSelection', () => {
|
|
16
|
+
it('should get initial state correctly - no initialSelected', () => {
|
|
17
|
+
const { result } = (0, react_1.renderHook)(() => (0, selection_1.useDataViewSelection)({}));
|
|
18
|
+
expect(result.current).toEqual({
|
|
19
|
+
selected: [],
|
|
20
|
+
onSelect: expect.any(Function),
|
|
21
|
+
isSelected: expect.any(Function),
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
it('should get initial state correctly - with initialSelected', () => {
|
|
25
|
+
const initialSelected = [{ id: 1, name: 'test1' }];
|
|
26
|
+
const { result } = (0, react_1.renderHook)(() => (0, selection_1.useDataViewSelection)({ initialSelected }));
|
|
27
|
+
expect(result.current).toEqual({
|
|
28
|
+
selected: initialSelected,
|
|
29
|
+
onSelect: expect.any(Function),
|
|
30
|
+
isSelected: expect.any(Function),
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
it('should select items correctly - objects', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
34
|
+
const initialSelected = [{ id: 1, name: 'test1' }];
|
|
35
|
+
const { result } = (0, react_1.renderHook)(() => (0, selection_1.useDataViewSelection)({ initialSelected }));
|
|
36
|
+
yield (0, react_1.act)(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
37
|
+
result.current.onSelect(true, { id: 2, name: 'test2' });
|
|
38
|
+
}));
|
|
39
|
+
expect(result.current.selected).toEqual([...initialSelected, { id: 2, name: 'test2' }]);
|
|
40
|
+
}));
|
|
41
|
+
it('should deselect items correctly - strings', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
42
|
+
const initialSelected = ['test1', 'test2'];
|
|
43
|
+
const { result } = (0, react_1.renderHook)(() => (0, selection_1.useDataViewSelection)({ initialSelected }));
|
|
44
|
+
yield (0, react_1.act)(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
45
|
+
result.current.onSelect(false, 'test2');
|
|
46
|
+
}));
|
|
47
|
+
expect(result.current.selected).toEqual(['test1']);
|
|
48
|
+
}));
|
|
49
|
+
it('should check if item is selected correctly - objects', () => {
|
|
50
|
+
const initialSelected = [{ id: 1, name: 'test1' }, { id: 2, name: 'test2' }];
|
|
51
|
+
const { result } = (0, react_1.renderHook)(() => (0, selection_1.useDataViewSelection)({ initialSelected, matchOption: (a, b) => a.id === b.id }));
|
|
52
|
+
expect(result.current.isSelected({ id: 1, name: 'test1' })).toBe(true);
|
|
53
|
+
expect(result.current.isSelected({ id: 3, name: 'test2' })).toBe(false);
|
|
54
|
+
});
|
|
55
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { render } from '@testing-library/react';
|
|
3
|
+
import DataView from './DataView';
|
|
4
|
+
const layoutItemStyling = {
|
|
5
|
+
width: '100%',
|
|
6
|
+
height: '5rem',
|
|
7
|
+
padding: 'var(--pf-v5-global--spacer--md)',
|
|
8
|
+
borderStyle: 'dashed',
|
|
9
|
+
borderWidth: '2px',
|
|
10
|
+
};
|
|
11
|
+
describe('DataView component', () => {
|
|
12
|
+
test('should render correctly', () => {
|
|
13
|
+
expect(render(React.createElement(DataView, null,
|
|
14
|
+
React.createElement("div", { style: layoutItemStyling }, "Header"),
|
|
15
|
+
React.createElement("div", { style: Object.assign(Object.assign({}, layoutItemStyling), { borderTopWidth: 0, borderBottomWidth: 0 }) }, "Data representation"),
|
|
16
|
+
React.createElement("div", { style: layoutItemStyling }, "Footer")))).toMatchSnapshot();
|
|
17
|
+
});
|
|
18
|
+
});
|
|
@@ -1,11 +1,13 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
export interface DataViewToolbarProps {
|
|
1
|
+
import React, { PropsWithChildren } from 'react';
|
|
2
|
+
export interface DataViewToolbarProps extends PropsWithChildren {
|
|
3
3
|
/** Toolbar className */
|
|
4
4
|
className?: string;
|
|
5
5
|
/** Custom OUIA ID */
|
|
6
6
|
ouiaId?: string;
|
|
7
|
+
/** React component to display bulk select */
|
|
8
|
+
bulkSelect?: React.ReactNode;
|
|
7
9
|
/** React component to display pagination */
|
|
8
10
|
pagination?: React.ReactNode;
|
|
9
11
|
}
|
|
10
|
-
export declare const DataViewToolbar: React.FC<
|
|
12
|
+
export declare const DataViewToolbar: React.FC<DataViewToolbarProps>;
|
|
11
13
|
export default DataViewToolbar;
|
|
@@ -12,10 +12,11 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
12
12
|
import React from 'react';
|
|
13
13
|
import { Toolbar, ToolbarContent, ToolbarItem, ToolbarItemVariant } from '@patternfly/react-core';
|
|
14
14
|
export const DataViewToolbar = (_a) => {
|
|
15
|
-
var { className, ouiaId = 'DataViewToolbar', pagination, children } = _a, props = __rest(_a, ["className", "ouiaId", "pagination", "children"]);
|
|
15
|
+
var { className, ouiaId = 'DataViewToolbar', bulkSelect, pagination, children } = _a, props = __rest(_a, ["className", "ouiaId", "bulkSelect", "pagination", "children"]);
|
|
16
16
|
return (React.createElement(Toolbar, Object.assign({ ouiaId: ouiaId, className: className }, props),
|
|
17
17
|
React.createElement(ToolbarContent, null,
|
|
18
|
-
|
|
18
|
+
bulkSelect && (React.createElement(ToolbarItem, { "data-ouia-component-id": `${ouiaId}-bulk-select` }, bulkSelect)),
|
|
19
|
+
pagination && (React.createElement(ToolbarItem, { variant: ToolbarItemVariant.pagination, "data-ouia-component-id": `${ouiaId}-pagination` }, pagination)),
|
|
19
20
|
children)));
|
|
20
21
|
};
|
|
21
22
|
export default DataViewToolbar;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { render } from '@testing-library/react';
|
|
3
|
+
import DataViewToolbar from './DataViewToolbar';
|
|
4
|
+
import { Pagination } from '@patternfly/react-core';
|
|
5
|
+
describe('DataViewToolbar component', () => {
|
|
6
|
+
test('should render correctly', () => {
|
|
7
|
+
expect(render(React.createElement(DataViewToolbar, { pagination: React.createElement(Pagination, { page: 1, perPage: 10 }) }))).toMatchSnapshot();
|
|
8
|
+
});
|
|
9
|
+
});
|
package/dist/esm/Hooks/index.js
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
export interface UseDataViewPaginationProps {
|
|
2
|
+
/** Initial page */
|
|
2
3
|
page?: number;
|
|
4
|
+
/** Items per page */
|
|
3
5
|
perPage: number;
|
|
4
6
|
}
|
|
5
7
|
export interface DataViewPaginationProps extends UseDataViewPaginationProps {
|
|
8
|
+
/** Current page number */
|
|
6
9
|
page: number;
|
|
7
10
|
}
|
|
8
11
|
export declare const useDataViewPagination: ({ page, perPage }: UseDataViewPaginationProps) => {
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface UseDataViewSelectionProps {
|
|
2
|
+
/** Array of initially selected entries */
|
|
3
|
+
initialSelected?: (any)[];
|
|
4
|
+
/** Function to compare items when checking if entry is selected */
|
|
5
|
+
matchOption?: (item: any, another: any) => boolean;
|
|
6
|
+
}
|
|
7
|
+
export declare const useDataViewSelection: (props: UseDataViewSelectionProps) => {
|
|
8
|
+
selected: any[];
|
|
9
|
+
onSelect: (isSelecting: boolean, items?: any[] | any) => void;
|
|
10
|
+
isSelected: (item: any) => boolean;
|
|
11
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
+
import { useState } from "react";
|
|
3
|
+
export const useDataViewSelection = (props) => {
|
|
4
|
+
var _a;
|
|
5
|
+
const [selected, setSelected] = useState((_a = props.initialSelected) !== null && _a !== void 0 ? _a : []);
|
|
6
|
+
const matchOption = props.matchOption ? props.matchOption : (option, another) => (option === another);
|
|
7
|
+
const onSelect = (isSelecting, items) => {
|
|
8
|
+
isSelecting ?
|
|
9
|
+
setSelected(prev => {
|
|
10
|
+
const newSelectedItems = [...prev];
|
|
11
|
+
(Array.isArray(items) ? items : [items]).forEach(newItem => !prev.some(prevItem => matchOption(prevItem, newItem)) && newSelectedItems.push(newItem));
|
|
12
|
+
return newSelectedItems;
|
|
13
|
+
})
|
|
14
|
+
: setSelected(items ? prev => prev.filter(prevSelected => !(Array.isArray(items) ? items : [items]).some(item => matchOption(item, prevSelected))) : []);
|
|
15
|
+
};
|
|
16
|
+
const isSelected = (item) => (props === null || props === void 0 ? void 0 : props.matchOption) ? Boolean(selected.find(selected => matchOption(selected, item))) : selected.includes(item);
|
|
17
|
+
return {
|
|
18
|
+
selected,
|
|
19
|
+
onSelect,
|
|
20
|
+
isSelected
|
|
21
|
+
};
|
|
22
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import '@testing-library/jest-dom';
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import '@testing-library/jest-dom';
|
|
11
|
+
import { renderHook, act } from '@testing-library/react';
|
|
12
|
+
import { useDataViewSelection } from './selection';
|
|
13
|
+
describe('useDataViewSelection', () => {
|
|
14
|
+
it('should get initial state correctly - no initialSelected', () => {
|
|
15
|
+
const { result } = renderHook(() => useDataViewSelection({}));
|
|
16
|
+
expect(result.current).toEqual({
|
|
17
|
+
selected: [],
|
|
18
|
+
onSelect: expect.any(Function),
|
|
19
|
+
isSelected: expect.any(Function),
|
|
20
|
+
});
|
|
21
|
+
});
|
|
22
|
+
it('should get initial state correctly - with initialSelected', () => {
|
|
23
|
+
const initialSelected = [{ id: 1, name: 'test1' }];
|
|
24
|
+
const { result } = renderHook(() => useDataViewSelection({ initialSelected }));
|
|
25
|
+
expect(result.current).toEqual({
|
|
26
|
+
selected: initialSelected,
|
|
27
|
+
onSelect: expect.any(Function),
|
|
28
|
+
isSelected: expect.any(Function),
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
it('should select items correctly - objects', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
32
|
+
const initialSelected = [{ id: 1, name: 'test1' }];
|
|
33
|
+
const { result } = renderHook(() => useDataViewSelection({ initialSelected }));
|
|
34
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
35
|
+
result.current.onSelect(true, { id: 2, name: 'test2' });
|
|
36
|
+
}));
|
|
37
|
+
expect(result.current.selected).toEqual([...initialSelected, { id: 2, name: 'test2' }]);
|
|
38
|
+
}));
|
|
39
|
+
it('should deselect items correctly - strings', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
40
|
+
const initialSelected = ['test1', 'test2'];
|
|
41
|
+
const { result } = renderHook(() => useDataViewSelection({ initialSelected }));
|
|
42
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
43
|
+
result.current.onSelect(false, 'test2');
|
|
44
|
+
}));
|
|
45
|
+
expect(result.current.selected).toEqual(['test1']);
|
|
46
|
+
}));
|
|
47
|
+
it('should check if item is selected correctly - objects', () => {
|
|
48
|
+
const initialSelected = [{ id: 1, name: 'test1' }, { id: 2, name: 'test2' }];
|
|
49
|
+
const { result } = renderHook(() => useDataViewSelection({ initialSelected, matchOption: (a, b) => a.id === b.id }));
|
|
50
|
+
expect(result.current.isSelected({ id: 1, name: 'test1' })).toBe(true);
|
|
51
|
+
expect(result.current.isSelected({ id: 3, name: 'test2' })).toBe(false);
|
|
52
|
+
});
|
|
53
|
+
});
|
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
const fse = require('fs-extra');
|
|
2
|
-
const
|
|
2
|
+
const { globSync } = require('glob');
|
|
3
3
|
const path = require('path');
|
|
4
4
|
|
|
5
5
|
const root = process.cwd();
|
|
6
6
|
|
|
7
|
-
const sourceFiles =
|
|
8
|
-
.sync(`${root}/src/*/`)
|
|
7
|
+
const sourceFiles = globSync(`${root}/src/*/`)
|
|
9
8
|
.map((name) => name.replace(/\/$/, ''));
|
|
10
9
|
|
|
11
|
-
const indexTypings =
|
|
10
|
+
const indexTypings = globSync(`${root}/src/index.d.ts`);
|
|
12
11
|
|
|
13
12
|
const ENV_AGNOSTIC_ROOT = `${root}/dist/dynamic`
|
|
14
13
|
|
|
@@ -23,9 +22,9 @@ async function copyTypings(files, dest) {
|
|
|
23
22
|
|
|
24
23
|
async function createPackage(file) {
|
|
25
24
|
const fileName = file.split('/').pop();
|
|
26
|
-
const esmSource =
|
|
27
|
-
const cjsSource =
|
|
28
|
-
const typingsSource =
|
|
25
|
+
const esmSource = globSync(`${root}/dist/esm/${fileName}/**/index.js`)[0];
|
|
26
|
+
const cjsSource = globSync(`${root}/dist/cjs/${fileName}/**/index.js`)[0];
|
|
27
|
+
const typingsSource = globSync(`${root}/dist/esm/${fileName}/**/index.d.ts`)[0]
|
|
29
28
|
/**
|
|
30
29
|
* Prevent creating package.json for directories with no JS files (like CSS directories)
|
|
31
30
|
*/
|
|
@@ -46,7 +45,7 @@ async function createPackage(file) {
|
|
|
46
45
|
main: cjsRelative,
|
|
47
46
|
module: esmRelative,
|
|
48
47
|
};
|
|
49
|
-
const typings =
|
|
48
|
+
const typings = globSync(`${root}/src/${fileName}/*.d.ts`);
|
|
50
49
|
const cmds = [];
|
|
51
50
|
content.typings = tsRelative;
|
|
52
51
|
cmds.push(copyTypings(typings, `${root}/dist/${fileName}`));
|
package/generate-index.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
const fse = require('fs-extra');
|
|
2
|
-
const
|
|
2
|
+
const { globSync } = require('glob');
|
|
3
3
|
const path = require('path');
|
|
4
4
|
|
|
5
5
|
const root = process.cwd();
|
|
6
6
|
|
|
7
7
|
const ENV_AGNOSTIC_ROOT = `${root}/src`
|
|
8
8
|
|
|
9
|
-
const sourceFiles =
|
|
9
|
+
const sourceFiles = globSync(path.resolve(__dirname, './src/*/index.ts'))
|
|
10
10
|
|
|
11
11
|
async function generateIndex(files) {
|
|
12
12
|
// ensure the dynamic root exists
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@patternfly/react-data-view",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "5.0.0",
|
|
4
4
|
"description": "Data view used for Red Hat projects.",
|
|
5
5
|
"main": "dist/cjs/index.js",
|
|
6
6
|
"module": "dist/esm/index.js",
|
|
@@ -27,13 +27,13 @@
|
|
|
27
27
|
},
|
|
28
28
|
"homepage": "https://github.com/patternfly/react-data-view#readme",
|
|
29
29
|
"publishConfig": {
|
|
30
|
-
"access": "public"
|
|
31
|
-
"tag": "prerelease"
|
|
30
|
+
"access": "public"
|
|
32
31
|
},
|
|
33
32
|
"dependencies": {
|
|
34
|
-
"@patternfly/react-core": "^
|
|
35
|
-
"@patternfly/react-icons": "^
|
|
36
|
-
"@patternfly/react-table": "^
|
|
33
|
+
"@patternfly/react-core": "^5.3.3",
|
|
34
|
+
"@patternfly/react-icons": "^5.3.1",
|
|
35
|
+
"@patternfly/react-table": "^5.3.3",
|
|
36
|
+
"@patternfly/react-component-groups": "^5.3.0-prerelease.2",
|
|
37
37
|
"react-jss": "^10.10.0",
|
|
38
38
|
"clsx": "^2.1.1"
|
|
39
39
|
},
|
|
@@ -43,8 +43,8 @@
|
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
45
|
"@patternfly/patternfly-a11y": "^4.3.1",
|
|
46
|
-
"@patternfly/documentation-framework": "
|
|
47
|
-
"@patternfly/patternfly": "^
|
|
46
|
+
"@patternfly/documentation-framework": "5.16.9",
|
|
47
|
+
"@patternfly/patternfly": "^5.3.1",
|
|
48
48
|
"@types/react": "^18.3.1",
|
|
49
49
|
"@types/react-dom": "^18.3.0",
|
|
50
50
|
"@types/react-router-dom": "^5.3.3",
|
|
@@ -5,21 +5,25 @@ section: extensions
|
|
|
5
5
|
subsection: Data view
|
|
6
6
|
# Sidenav secondary level section
|
|
7
7
|
# should be the same for all markdown files
|
|
8
|
-
id:
|
|
8
|
+
id: Components
|
|
9
9
|
# Tab (react | react-demos | html | html-demos | design-guidelines | accessibility)
|
|
10
10
|
source: react
|
|
11
11
|
# If you use typescript, the name of the interface to display props for
|
|
12
12
|
# These are found through the sourceProps function provided in patternfly-docs.source.js
|
|
13
|
+
sortValue: 4
|
|
13
14
|
propComponents: ['DataViewToolbar']
|
|
14
|
-
sourceLink: https://github.com/patternfly/react-data-view/blob/main/packages/module/patternfly-docs/content/extensions/data-view/examples/
|
|
15
|
+
sourceLink: https://github.com/patternfly/react-data-view/blob/main/packages/module/patternfly-docs/content/extensions/data-view/examples/Components/Components.md
|
|
15
16
|
---
|
|
17
|
+
import { BulkSelect } from '@patternfly/react-component-groups';
|
|
16
18
|
import DataViewToolbar from '@patternfly/react-data-view/dist/dynamic/DataViewToolbar';
|
|
17
19
|
|
|
18
|
-
|
|
20
|
+
## Data view toolbar
|
|
19
21
|
|
|
20
|
-
|
|
22
|
+
The **data view toolbar** component renders a default opinionated data view toolbar above or below the data section.
|
|
23
|
+
|
|
24
|
+
Data view toolbar can contain a `pagination`, `bulkSelect` or any other children content passed. The preffered way of passing children toolbar items is using the [toolbar item](/components/toolbar#toolbar-items) component.
|
|
21
25
|
|
|
22
|
-
|
|
26
|
+
### Basic example
|
|
23
27
|
|
|
24
28
|
```js file="./DataViewToolbarExample.tsx"
|
|
25
29
|
|
package/patternfly-docs/content/extensions/data-view/examples/Components/DataViewToolbarExample.tsx
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Pagination } from '@patternfly/react-core';
|
|
3
|
+
import { BulkSelect } from '@patternfly/react-component-groups';
|
|
4
|
+
import DataViewToolbar from '@patternfly/react-data-view/dist/dynamic/DataViewToolbar';
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
export const BasicExample: React.FunctionComponent = () => (
|
|
8
|
+
<DataViewToolbar
|
|
9
|
+
pagination={
|
|
10
|
+
<Pagination page={1} perPage={10} />
|
|
11
|
+
}
|
|
12
|
+
bulkSelect={
|
|
13
|
+
<BulkSelect
|
|
14
|
+
selectedCount={0}
|
|
15
|
+
pageCount={5}
|
|
16
|
+
onSelect={() => null}
|
|
17
|
+
/>
|
|
18
|
+
}
|
|
19
|
+
/>
|
|
20
|
+
)
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
---
|
|
2
|
+
# Sidenav top-level section
|
|
3
|
+
# should be the same for all markdown files
|
|
4
|
+
section: extensions
|
|
5
|
+
subsection: Data view
|
|
6
|
+
# Sidenav secondary level section
|
|
7
|
+
# should be the same for all markdown files
|
|
8
|
+
id: Functionality
|
|
9
|
+
# Tab (react | react-demos | html | html-demos | design-guidelines | accessibility)
|
|
10
|
+
source: react
|
|
11
|
+
# If you use typescript, the name of the interface to display props for
|
|
12
|
+
# These are found through the sourceProps function provided in patternfly-docs.source.js
|
|
13
|
+
sortValue: 3
|
|
14
|
+
sourceLink: https://github.com/patternfly/react-data-view/blob/main/packages/module/patternfly-docs/content/extensions/data-view/examples/Functionality/Functionality.md
|
|
15
|
+
---
|
|
16
|
+
import { useMemo } from 'react';
|
|
17
|
+
import { useDataViewPagination, useDataViewSelection } from '@patternfly/react-data-view/dist/dynamic/Hooks';
|
|
18
|
+
import { DataView } from '@patternfly/react-data-view/dist/dynamic/DataView';
|
|
19
|
+
import { BulkSelect, BulkSelectValue } from '@patternfly/react-component-groups/dist/dynamic/BulkSelect';
|
|
20
|
+
import { DataViewToolbar } from '@patternfly/react-data-view/dist/dynamic/DataViewToolbar';
|
|
21
|
+
|
|
22
|
+
This is a list of functionality you can use to manage data displayed in the **data view**.
|
|
23
|
+
|
|
24
|
+
# Pagination
|
|
25
|
+
Allows to display data records on multiple pages and display the pagination state.
|
|
26
|
+
|
|
27
|
+
### Toolbar usage
|
|
28
|
+
Data view toolbar can display a pagination using the `pagination` property accepting a React node. You can also pass a custom `ouiaId` for testing purposes.
|
|
29
|
+
|
|
30
|
+
### Pagination state
|
|
31
|
+
|
|
32
|
+
The `useDataViewPagination` hook manages the pagination state of the data view.
|
|
33
|
+
|
|
34
|
+
**Initial values:**
|
|
35
|
+
- `perPage` initial value
|
|
36
|
+
- (optional) `page` initial value
|
|
37
|
+
|
|
38
|
+
The retrieved values are named to match the PatternFly [pagination](/components/pagination) component props, so you can easily spread them.
|
|
39
|
+
|
|
40
|
+
**Return values:**
|
|
41
|
+
- current `page` number
|
|
42
|
+
- `onSetPage` to modify current page
|
|
43
|
+
- items `perPage` value
|
|
44
|
+
- `onPerPageSelect` to modify per page value
|
|
45
|
+
|
|
46
|
+
### Pagination example
|
|
47
|
+
```js file="./PaginationExample.tsx"
|
|
48
|
+
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
# Selection
|
|
52
|
+
Allows to select data records inside the data view and show the selection state.
|
|
53
|
+
|
|
54
|
+
### Toolbar usage
|
|
55
|
+
Data view toolbar can display a bulk selection component using the `bulkSelect` property accepting a React node. You can make use of a predefined [bulk select](/extensions/component-groups/bulk-select) from the [component groups](/extensions/component-groups/about-component-groups) extension.
|
|
56
|
+
|
|
57
|
+
### Selection state
|
|
58
|
+
|
|
59
|
+
The `useDataViewSelection` hook manages the selection state of the data view.
|
|
60
|
+
|
|
61
|
+
**Initial values:**
|
|
62
|
+
- (optional) `initialSelected` array of record's identifiers selected by default
|
|
63
|
+
- (optional) `matchOption` function to check if given record is selected
|
|
64
|
+
|
|
65
|
+
*When no `matchOption` is passed, the `Array.prototype.includes()` operation is performed on the `selected` array.*
|
|
66
|
+
|
|
67
|
+
**Return values:**
|
|
68
|
+
- `selected` array of currently selected records
|
|
69
|
+
- `isSelected` function returning the selection state for given record
|
|
70
|
+
- `onSelect` callback to modify the selection state and accepting `isSelecting` flag indicating if records are changing to selected or deselected and `items` containing affected records
|
|
71
|
+
|
|
72
|
+
### Selection example
|
|
73
|
+
|
|
74
|
+
```js file="./SelectionExample.tsx"
|
|
75
|
+
|
|
76
|
+
```
|
|
77
|
+
|
|
@@ -45,7 +45,7 @@ export const BasicExample: React.FunctionComponent = () => {
|
|
|
45
45
|
|
|
46
46
|
return (
|
|
47
47
|
<DataView>
|
|
48
|
-
<DataViewToolbar pagination={<Pagination
|
|
48
|
+
<DataViewToolbar ouiaId='DataViewHeader' pagination={<Pagination perPageOptions={perPageOptions} itemCount={repositories.length} {...pagination} />} />
|
|
49
49
|
<Table aria-label="Repositories table" ouiaId={ouiaId}>
|
|
50
50
|
<Thead data-ouia-component-id={`${ouiaId}-thead`}>
|
|
51
51
|
<Tr ouiaId={`${ouiaId}-tr-head`}>
|
|
@@ -60,6 +60,6 @@ export const BasicExample: React.FunctionComponent = () => {
|
|
|
60
60
|
))}
|
|
61
61
|
</Tbody>
|
|
62
62
|
</Table>
|
|
63
|
-
<DataViewToolbar pagination={<Pagination isCompact
|
|
63
|
+
<DataViewToolbar ouiaId='DataViewFooter' pagination={<Pagination isCompact perPageOptions={perPageOptions} itemCount={repositories.length} {...pagination} />} />
|
|
64
64
|
</DataView>
|
|
65
65
|
)}
|