@performant-software/semantic-components 1.0.19-beta.0 → 1.0.19-beta.2
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/build/index.js +1 -1
- package/build/index.js.map +1 -1
- package/build/main.css +5 -0
- package/package.json +2 -2
- package/src/components/BreadcrumbItem.css +0 -0
- package/src/components/BreadcrumbItem.js +69 -0
- package/src/components/Breadcrumbs.css +4 -0
- package/src/components/Breadcrumbs.js +111 -0
- package/src/components/ItemsToggle.js +30 -17
- package/src/i18n/en.json +5 -0
- package/src/index.js +1 -0
- package/types/components/BreadcrumbItem.js.flow +69 -0
- package/types/components/Breadcrumbs.js.flow +111 -0
- package/types/components/ItemsToggle.js.flow +30 -17
- package/types/index.js.flow +1 -0
package/build/main.css
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@performant-software/semantic-components",
|
|
3
|
-
"version": "1.0.19-beta.
|
|
3
|
+
"version": "1.0.19-beta.2",
|
|
4
4
|
"description": "A package of shared components based on the Semantic UI Framework.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "./build/index.js",
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"build": "webpack --mode production && flow-copy-source -v src types"
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@performant-software/shared-components": "^1.0.19-beta.
|
|
15
|
+
"@performant-software/shared-components": "^1.0.19-beta.2",
|
|
16
16
|
"@react-google-maps/api": "^2.8.1",
|
|
17
17
|
"axios": "^0.26.1",
|
|
18
18
|
"i18next": "^19.4.4",
|
|
File without changes
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
|
|
3
|
+
import React, { useEffect, useState, type ComponentType } from 'react';
|
|
4
|
+
import { Breadcrumb, Loader } from 'semantic-ui-react';
|
|
5
|
+
|
|
6
|
+
type Props = {
|
|
7
|
+
active: boolean,
|
|
8
|
+
as?: ComponentType<any>,
|
|
9
|
+
id?: number,
|
|
10
|
+
label?: string,
|
|
11
|
+
name: string,
|
|
12
|
+
onLoad: (id: number, name: string) => Promise<any>,
|
|
13
|
+
url: string
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
const BreadcrumbItem: ComponentType<any> = (props: Props) => {
|
|
17
|
+
const [loading, setLoading] = useState(false);
|
|
18
|
+
const [name, setName] = useState(null);
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Sets or clears the name attribute on the state.
|
|
22
|
+
*/
|
|
23
|
+
useEffect(() => {
|
|
24
|
+
if (props.id) {
|
|
25
|
+
props
|
|
26
|
+
.onLoad(props.id, props.name)
|
|
27
|
+
.then((n) => setName(n))
|
|
28
|
+
.finally(() => setLoading(false));
|
|
29
|
+
|
|
30
|
+
setLoading(true);
|
|
31
|
+
} else {
|
|
32
|
+
setName(null);
|
|
33
|
+
}
|
|
34
|
+
}, [props.id, props.name]);
|
|
35
|
+
|
|
36
|
+
return (
|
|
37
|
+
<>
|
|
38
|
+
<Breadcrumb.Section
|
|
39
|
+
active={props.active && !props.id}
|
|
40
|
+
as={props.as}
|
|
41
|
+
to={`/${props.url}`}
|
|
42
|
+
>
|
|
43
|
+
{ props.label }
|
|
44
|
+
</Breadcrumb.Section>
|
|
45
|
+
{ props.id && (
|
|
46
|
+
<Breadcrumb.Divider
|
|
47
|
+
icon='right chevron'
|
|
48
|
+
/>
|
|
49
|
+
)}
|
|
50
|
+
{ loading && (
|
|
51
|
+
<Loader
|
|
52
|
+
active
|
|
53
|
+
inline
|
|
54
|
+
/>
|
|
55
|
+
)}
|
|
56
|
+
{ name && props.id && (
|
|
57
|
+
<Breadcrumb.Section
|
|
58
|
+
active={props.active}
|
|
59
|
+
as={props.as}
|
|
60
|
+
to={`/${props.url}/${props.id}`}
|
|
61
|
+
>
|
|
62
|
+
{ name }
|
|
63
|
+
</Breadcrumb.Section>
|
|
64
|
+
)}
|
|
65
|
+
</>
|
|
66
|
+
);
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
export default BreadcrumbItem;
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
|
|
3
|
+
import React, { useCallback, useMemo, type ComponentType } from 'react';
|
|
4
|
+
import { Breadcrumb } from 'semantic-ui-react';
|
|
5
|
+
import _ from 'underscore';
|
|
6
|
+
import BreadcrumbItem from './BreadcrumbItem';
|
|
7
|
+
import './Breadcrumbs.css';
|
|
8
|
+
|
|
9
|
+
const URL_DELIMITER = '/';
|
|
10
|
+
|
|
11
|
+
type Props = {
|
|
12
|
+
/**
|
|
13
|
+
* Alternate component to use to render the breadcrumb.
|
|
14
|
+
*/
|
|
15
|
+
as?: ComponentType<any>,
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* A key-value pair of types to labels to match the `pathname`.
|
|
19
|
+
*/
|
|
20
|
+
labels: { key: string, value: string },
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Callback fired to lookup the name of the passed breadcrumb item.
|
|
24
|
+
*/
|
|
25
|
+
onLoad: (id: number, name: string) => Promise<any>,
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* The URL for which to generate the breadcrumb.
|
|
29
|
+
*/
|
|
30
|
+
pathname: string
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* This component can be used to render a breadcrumb for the passed URL.
|
|
35
|
+
*/
|
|
36
|
+
const Breadcrumbs: ComponentType<any> = (props: Props) => {
|
|
37
|
+
/**
|
|
38
|
+
* Returns true if the passed string contains only digits.
|
|
39
|
+
*
|
|
40
|
+
* @type {function(*): boolean}
|
|
41
|
+
*/
|
|
42
|
+
const isNumeric = useCallback((str: string) => /^\d+$/.test(str), []);
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Sets the items to display based on the URL path.
|
|
46
|
+
*
|
|
47
|
+
* @type {[]}
|
|
48
|
+
*/
|
|
49
|
+
const items = useMemo(() => {
|
|
50
|
+
const value = [];
|
|
51
|
+
|
|
52
|
+
const path = props.pathname.split(URL_DELIMITER).splice(1);
|
|
53
|
+
|
|
54
|
+
for (let i = 0; i < path.length; i += 1) {
|
|
55
|
+
const key = path[i];
|
|
56
|
+
const id = path[i + 1];
|
|
57
|
+
const url = path.slice(0, i + 1).join(URL_DELIMITER);
|
|
58
|
+
|
|
59
|
+
/*
|
|
60
|
+
* If the item in the path is non-numeric, we'll add it as the item label.
|
|
61
|
+
* If the next item is numeric, we'll add it as the ID.
|
|
62
|
+
* If the next item is non-numeric, it'll be added as a separate label on the next iteration.
|
|
63
|
+
*/
|
|
64
|
+
if (!isNumeric(key)) {
|
|
65
|
+
const item = { key, url, id: undefined };
|
|
66
|
+
|
|
67
|
+
if (isNumeric(id)) {
|
|
68
|
+
item.id = id;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
value.push(item);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return value;
|
|
76
|
+
}, [props.pathname]);
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Returns true if there are more items to display.
|
|
80
|
+
*
|
|
81
|
+
* @type {function(*): boolean}
|
|
82
|
+
*/
|
|
83
|
+
const hasMore = useCallback((index: number) => index < (items.length - 1), [items]);
|
|
84
|
+
|
|
85
|
+
return (
|
|
86
|
+
<Breadcrumb
|
|
87
|
+
size='large'
|
|
88
|
+
>
|
|
89
|
+
{ _.map(items, (item, index) => (
|
|
90
|
+
<>
|
|
91
|
+
<BreadcrumbItem
|
|
92
|
+
active={!hasMore(index)}
|
|
93
|
+
as={props.as}
|
|
94
|
+
id={item.id}
|
|
95
|
+
label={props.labels[item.key]}
|
|
96
|
+
name={item.key}
|
|
97
|
+
onLoad={props.onLoad}
|
|
98
|
+
url={item.url}
|
|
99
|
+
/>
|
|
100
|
+
{ hasMore(index) && (
|
|
101
|
+
<Breadcrumb.Divider
|
|
102
|
+
icon='right chevron'
|
|
103
|
+
/>
|
|
104
|
+
)}
|
|
105
|
+
</>
|
|
106
|
+
))}
|
|
107
|
+
</Breadcrumb>
|
|
108
|
+
);
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
export default Breadcrumbs;
|
|
@@ -71,6 +71,15 @@ const useItemsToggle = (WrappedComponent: ComponentType<any>) => (
|
|
|
71
71
|
return sort && sort.text;
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
+
/**
|
|
75
|
+
* Returns true if the component should be hidden.
|
|
76
|
+
*
|
|
77
|
+
* @returns {boolean|*}
|
|
78
|
+
*/
|
|
79
|
+
isHidden() {
|
|
80
|
+
return this.props.hideToggle && _.isEmpty(this.props.sort);
|
|
81
|
+
}
|
|
82
|
+
|
|
74
83
|
/**
|
|
75
84
|
* Calls the onSort prop.
|
|
76
85
|
*
|
|
@@ -98,7 +107,7 @@ const useItemsToggle = (WrappedComponent: ComponentType<any>) => (
|
|
|
98
107
|
* @returns {*}
|
|
99
108
|
*/
|
|
100
109
|
render() {
|
|
101
|
-
const renderListHeader = this.
|
|
110
|
+
const renderListHeader = this.isHidden()
|
|
102
111
|
? undefined
|
|
103
112
|
: this.renderHeader.bind(this);
|
|
104
113
|
|
|
@@ -121,27 +130,31 @@ const useItemsToggle = (WrappedComponent: ComponentType<any>) => (
|
|
|
121
130
|
* @returns {*}
|
|
122
131
|
*/
|
|
123
132
|
renderHeader() {
|
|
124
|
-
if (this.
|
|
133
|
+
if (this.isHidden()) {
|
|
125
134
|
return null;
|
|
126
135
|
}
|
|
127
136
|
|
|
128
137
|
return (
|
|
129
138
|
<>
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
139
|
+
{ !this.props.hideToggle && (
|
|
140
|
+
<>
|
|
141
|
+
<Button
|
|
142
|
+
active={this.state.view === Views.list}
|
|
143
|
+
aria-label='List View'
|
|
144
|
+
basic
|
|
145
|
+
icon='list'
|
|
146
|
+
onClick={() => this.setState({ view: Views.list })}
|
|
147
|
+
/>
|
|
148
|
+
<Button
|
|
149
|
+
active={this.state.view === Views.grid}
|
|
150
|
+
aria-label='Grid View'
|
|
151
|
+
basic
|
|
152
|
+
icon='grid layout'
|
|
153
|
+
onClick={() => this.setState({ view: Views.grid })}
|
|
154
|
+
/>
|
|
155
|
+
</>
|
|
156
|
+
)}
|
|
157
|
+
{ !_.isEmpty(this.props.sort) && this.props.onSort && (
|
|
145
158
|
<Button.Group
|
|
146
159
|
basic
|
|
147
160
|
style={{
|
package/src/i18n/en.json
CHANGED
package/src/index.js
CHANGED
|
@@ -14,6 +14,7 @@ export { default as BibliographyForm } from './components/BibliographyForm';
|
|
|
14
14
|
export { default as BibliographyList } from './components/BibliographyList';
|
|
15
15
|
export { default as BibliographySearchInput } from './components/BibliographySearchInput';
|
|
16
16
|
export { default as BooleanIcon } from './components/BooleanIcon';
|
|
17
|
+
export { default as Breadcrumbs } from './components/Breadcrumbs';
|
|
17
18
|
export { default as CancelButton } from './components/CancelButton';
|
|
18
19
|
export { default as ColorButton } from './components/ColorButton';
|
|
19
20
|
export { default as ColorPickerModal } from './components/ColorPickerModal';
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
|
|
3
|
+
import React, { useEffect, useState, type ComponentType } from 'react';
|
|
4
|
+
import { Breadcrumb, Loader } from 'semantic-ui-react';
|
|
5
|
+
|
|
6
|
+
type Props = {
|
|
7
|
+
active: boolean,
|
|
8
|
+
as?: ComponentType<any>,
|
|
9
|
+
id?: number,
|
|
10
|
+
label?: string,
|
|
11
|
+
name: string,
|
|
12
|
+
onLoad: (id: number, name: string) => Promise<any>,
|
|
13
|
+
url: string
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
const BreadcrumbItem: ComponentType<any> = (props: Props) => {
|
|
17
|
+
const [loading, setLoading] = useState(false);
|
|
18
|
+
const [name, setName] = useState(null);
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Sets or clears the name attribute on the state.
|
|
22
|
+
*/
|
|
23
|
+
useEffect(() => {
|
|
24
|
+
if (props.id) {
|
|
25
|
+
props
|
|
26
|
+
.onLoad(props.id, props.name)
|
|
27
|
+
.then((n) => setName(n))
|
|
28
|
+
.finally(() => setLoading(false));
|
|
29
|
+
|
|
30
|
+
setLoading(true);
|
|
31
|
+
} else {
|
|
32
|
+
setName(null);
|
|
33
|
+
}
|
|
34
|
+
}, [props.id, props.name]);
|
|
35
|
+
|
|
36
|
+
return (
|
|
37
|
+
<>
|
|
38
|
+
<Breadcrumb.Section
|
|
39
|
+
active={props.active && !props.id}
|
|
40
|
+
as={props.as}
|
|
41
|
+
to={`/${props.url}`}
|
|
42
|
+
>
|
|
43
|
+
{ props.label }
|
|
44
|
+
</Breadcrumb.Section>
|
|
45
|
+
{ props.id && (
|
|
46
|
+
<Breadcrumb.Divider
|
|
47
|
+
icon='right chevron'
|
|
48
|
+
/>
|
|
49
|
+
)}
|
|
50
|
+
{ loading && (
|
|
51
|
+
<Loader
|
|
52
|
+
active
|
|
53
|
+
inline
|
|
54
|
+
/>
|
|
55
|
+
)}
|
|
56
|
+
{ name && props.id && (
|
|
57
|
+
<Breadcrumb.Section
|
|
58
|
+
active={props.active}
|
|
59
|
+
as={props.as}
|
|
60
|
+
to={`/${props.url}/${props.id}`}
|
|
61
|
+
>
|
|
62
|
+
{ name }
|
|
63
|
+
</Breadcrumb.Section>
|
|
64
|
+
)}
|
|
65
|
+
</>
|
|
66
|
+
);
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
export default BreadcrumbItem;
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
|
|
3
|
+
import React, { useCallback, useMemo, type ComponentType } from 'react';
|
|
4
|
+
import { Breadcrumb } from 'semantic-ui-react';
|
|
5
|
+
import _ from 'underscore';
|
|
6
|
+
import BreadcrumbItem from './BreadcrumbItem';
|
|
7
|
+
import './Breadcrumbs.css';
|
|
8
|
+
|
|
9
|
+
const URL_DELIMITER = '/';
|
|
10
|
+
|
|
11
|
+
type Props = {
|
|
12
|
+
/**
|
|
13
|
+
* Alternate component to use to render the breadcrumb.
|
|
14
|
+
*/
|
|
15
|
+
as?: ComponentType<any>,
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* A key-value pair of types to labels to match the `pathname`.
|
|
19
|
+
*/
|
|
20
|
+
labels: { key: string, value: string },
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Callback fired to lookup the name of the passed breadcrumb item.
|
|
24
|
+
*/
|
|
25
|
+
onLoad: (id: number, name: string) => Promise<any>,
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* The URL for which to generate the breadcrumb.
|
|
29
|
+
*/
|
|
30
|
+
pathname: string
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* This component can be used to render a breadcrumb for the passed URL.
|
|
35
|
+
*/
|
|
36
|
+
const Breadcrumbs: ComponentType<any> = (props: Props) => {
|
|
37
|
+
/**
|
|
38
|
+
* Returns true if the passed string contains only digits.
|
|
39
|
+
*
|
|
40
|
+
* @type {function(*): boolean}
|
|
41
|
+
*/
|
|
42
|
+
const isNumeric = useCallback((str: string) => /^\d+$/.test(str), []);
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Sets the items to display based on the URL path.
|
|
46
|
+
*
|
|
47
|
+
* @type {[]}
|
|
48
|
+
*/
|
|
49
|
+
const items = useMemo(() => {
|
|
50
|
+
const value = [];
|
|
51
|
+
|
|
52
|
+
const path = props.pathname.split(URL_DELIMITER).splice(1);
|
|
53
|
+
|
|
54
|
+
for (let i = 0; i < path.length; i += 1) {
|
|
55
|
+
const key = path[i];
|
|
56
|
+
const id = path[i + 1];
|
|
57
|
+
const url = path.slice(0, i + 1).join(URL_DELIMITER);
|
|
58
|
+
|
|
59
|
+
/*
|
|
60
|
+
* If the item in the path is non-numeric, we'll add it as the item label.
|
|
61
|
+
* If the next item is numeric, we'll add it as the ID.
|
|
62
|
+
* If the next item is non-numeric, it'll be added as a separate label on the next iteration.
|
|
63
|
+
*/
|
|
64
|
+
if (!isNumeric(key)) {
|
|
65
|
+
const item = { key, url, id: undefined };
|
|
66
|
+
|
|
67
|
+
if (isNumeric(id)) {
|
|
68
|
+
item.id = id;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
value.push(item);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return value;
|
|
76
|
+
}, [props.pathname]);
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Returns true if there are more items to display.
|
|
80
|
+
*
|
|
81
|
+
* @type {function(*): boolean}
|
|
82
|
+
*/
|
|
83
|
+
const hasMore = useCallback((index: number) => index < (items.length - 1), [items]);
|
|
84
|
+
|
|
85
|
+
return (
|
|
86
|
+
<Breadcrumb
|
|
87
|
+
size='large'
|
|
88
|
+
>
|
|
89
|
+
{ _.map(items, (item, index) => (
|
|
90
|
+
<>
|
|
91
|
+
<BreadcrumbItem
|
|
92
|
+
active={!hasMore(index)}
|
|
93
|
+
as={props.as}
|
|
94
|
+
id={item.id}
|
|
95
|
+
label={props.labels[item.key]}
|
|
96
|
+
name={item.key}
|
|
97
|
+
onLoad={props.onLoad}
|
|
98
|
+
url={item.url}
|
|
99
|
+
/>
|
|
100
|
+
{ hasMore(index) && (
|
|
101
|
+
<Breadcrumb.Divider
|
|
102
|
+
icon='right chevron'
|
|
103
|
+
/>
|
|
104
|
+
)}
|
|
105
|
+
</>
|
|
106
|
+
))}
|
|
107
|
+
</Breadcrumb>
|
|
108
|
+
);
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
export default Breadcrumbs;
|
|
@@ -71,6 +71,15 @@ const useItemsToggle = (WrappedComponent: ComponentType<any>) => (
|
|
|
71
71
|
return sort && sort.text;
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
+
/**
|
|
75
|
+
* Returns true if the component should be hidden.
|
|
76
|
+
*
|
|
77
|
+
* @returns {boolean|*}
|
|
78
|
+
*/
|
|
79
|
+
isHidden() {
|
|
80
|
+
return this.props.hideToggle && _.isEmpty(this.props.sort);
|
|
81
|
+
}
|
|
82
|
+
|
|
74
83
|
/**
|
|
75
84
|
* Calls the onSort prop.
|
|
76
85
|
*
|
|
@@ -98,7 +107,7 @@ const useItemsToggle = (WrappedComponent: ComponentType<any>) => (
|
|
|
98
107
|
* @returns {*}
|
|
99
108
|
*/
|
|
100
109
|
render() {
|
|
101
|
-
const renderListHeader = this.
|
|
110
|
+
const renderListHeader = this.isHidden()
|
|
102
111
|
? undefined
|
|
103
112
|
: this.renderHeader.bind(this);
|
|
104
113
|
|
|
@@ -121,27 +130,31 @@ const useItemsToggle = (WrappedComponent: ComponentType<any>) => (
|
|
|
121
130
|
* @returns {*}
|
|
122
131
|
*/
|
|
123
132
|
renderHeader() {
|
|
124
|
-
if (this.
|
|
133
|
+
if (this.isHidden()) {
|
|
125
134
|
return null;
|
|
126
135
|
}
|
|
127
136
|
|
|
128
137
|
return (
|
|
129
138
|
<>
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
139
|
+
{ !this.props.hideToggle && (
|
|
140
|
+
<>
|
|
141
|
+
<Button
|
|
142
|
+
active={this.state.view === Views.list}
|
|
143
|
+
aria-label='List View'
|
|
144
|
+
basic
|
|
145
|
+
icon='list'
|
|
146
|
+
onClick={() => this.setState({ view: Views.list })}
|
|
147
|
+
/>
|
|
148
|
+
<Button
|
|
149
|
+
active={this.state.view === Views.grid}
|
|
150
|
+
aria-label='Grid View'
|
|
151
|
+
basic
|
|
152
|
+
icon='grid layout'
|
|
153
|
+
onClick={() => this.setState({ view: Views.grid })}
|
|
154
|
+
/>
|
|
155
|
+
</>
|
|
156
|
+
)}
|
|
157
|
+
{ !_.isEmpty(this.props.sort) && this.props.onSort && (
|
|
145
158
|
<Button.Group
|
|
146
159
|
basic
|
|
147
160
|
style={{
|
package/types/index.js.flow
CHANGED
|
@@ -14,6 +14,7 @@ export { default as BibliographyForm } from './components/BibliographyForm';
|
|
|
14
14
|
export { default as BibliographyList } from './components/BibliographyList';
|
|
15
15
|
export { default as BibliographySearchInput } from './components/BibliographySearchInput';
|
|
16
16
|
export { default as BooleanIcon } from './components/BooleanIcon';
|
|
17
|
+
export { default as Breadcrumbs } from './components/Breadcrumbs';
|
|
17
18
|
export { default as CancelButton } from './components/CancelButton';
|
|
18
19
|
export { default as ColorButton } from './components/ColorButton';
|
|
19
20
|
export { default as ColorPickerModal } from './components/ColorPickerModal';
|