@kwiz/fluentui 1.0.16 → 1.0.20
Sign up to get free protection for your applications and to get access to all the features.
- package/.github/workflows/npm-publish.yml +34 -0
- package/LICENSE +21 -21
- package/README.md +26 -26
- package/package.json +72 -72
- package/src/_modules/config.ts +9 -9
- package/src/_modules/constants.ts +3 -3
- package/src/controls/accordion.tsx +48 -48
- package/src/controls/button.tsx +169 -169
- package/src/controls/centered.tsx +22 -22
- package/src/controls/date.tsx +39 -39
- package/src/controls/dropdown.tsx +53 -52
- package/src/controls/error-boundary.tsx +41 -41
- package/src/controls/field-editor.tsx +40 -40
- package/src/controls/file-upload.tsx +67 -67
- package/src/controls/horizontal.tsx +34 -34
- package/src/controls/input.tsx +60 -60
- package/src/controls/kwizoverflow.tsx +103 -103
- package/src/controls/list.tsx +117 -117
- package/src/controls/loading.tsx +10 -10
- package/src/controls/please-wait.tsx +32 -32
- package/src/controls/prompt.tsx +96 -96
- package/src/controls/search.tsx +65 -65
- package/src/controls/section.tsx +51 -51
- package/src/controls/svg.tsx +120 -120
- package/src/controls/toolbar.tsx +48 -48
- package/src/controls/vertical-content.tsx +49 -49
- package/src/controls/vertical.tsx +34 -34
- package/src/helpers/context.ts +39 -39
- package/src/helpers/hooks.tsx +335 -335
- package/src/index.ts +26 -26
- package/src/styles/styles.ts +87 -87
- package/src/styles/theme.ts +90 -90
- package/dist/_modules/build.d.ts +0 -2
- package/dist/_modules/build.js +0 -3
- package/dist/_modules/build.js.map +0 -1
- package/dist/_modules/config.d.ts +0 -1
- package/dist/_modules/config.js +0 -9
- package/dist/_modules/config.js.map +0 -1
- package/dist/_modules/constants.d.ts +0 -2
- package/dist/_modules/constants.js +0 -3
- package/dist/_modules/constants.js.map +0 -1
- package/dist/_modules/exports-index.d.ts +0 -1
- package/dist/_modules/exports-index.js +0 -2
- package/dist/_modules/exports-index.js.map +0 -1
- package/dist/controls/accordion.d.ts +0 -13
- package/dist/controls/accordion.js +0 -27
- package/dist/controls/accordion.js.map +0 -1
- package/dist/controls/button.d.ts +0 -28
- package/dist/controls/button.js +0 -113
- package/dist/controls/button.js.map +0 -1
- package/dist/controls/centered.d.ts +0 -5
- package/dist/controls/centered.js +0 -14
- package/dist/controls/centered.js.map +0 -1
- package/dist/controls/date.d.ts +0 -8
- package/dist/controls/date.js +0 -32
- package/dist/controls/date.js.map +0 -1
- package/dist/controls/dropdown.d.ts +0 -29
- package/dist/controls/dropdown.js +0 -27
- package/dist/controls/dropdown.js.map +0 -1
- package/dist/controls/error-boundary.d.ts +0 -23
- package/dist/controls/error-boundary.js +0 -33
- package/dist/controls/error-boundary.js.map +0 -1
- package/dist/controls/exports-index.d.ts +0 -17
- package/dist/controls/exports-index.js +0 -18
- package/dist/controls/exports-index.js.map +0 -1
- package/dist/controls/field-editor.d.ts +0 -13
- package/dist/controls/field-editor.js +0 -15
- package/dist/controls/field-editor.js.map +0 -1
- package/dist/controls/file-upload.d.ts +0 -18
- package/dist/controls/file-upload.js +0 -41
- package/dist/controls/file-upload.js.map +0 -1
- package/dist/controls/horizontal.d.ts +0 -8
- package/dist/controls/horizontal.js +0 -23
- package/dist/controls/horizontal.js.map +0 -1
- package/dist/controls/input.d.ts +0 -13
- package/dist/controls/input.js +0 -43
- package/dist/controls/input.js.map +0 -1
- package/dist/controls/kwizoverflow.d.ts +0 -14
- package/dist/controls/kwizoverflow.js +0 -45
- package/dist/controls/kwizoverflow.js.map +0 -1
- package/dist/controls/list.d.ts +0 -21
- package/dist/controls/list.js +0 -72
- package/dist/controls/list.js.map +0 -1
- package/dist/controls/loading copy.d.ts +0 -5
- package/dist/controls/loading copy.js +0 -7
- package/dist/controls/loading copy.js.map +0 -1
- package/dist/controls/loading.d.ts +0 -5
- package/dist/controls/loading.js +0 -7
- package/dist/controls/loading.js.map +0 -1
- package/dist/controls/please-wait.d.ts +0 -18
- package/dist/controls/please-wait.js +0 -16
- package/dist/controls/please-wait.js.map +0 -1
- package/dist/controls/prompt.d.ts +0 -32
- package/dist/controls/prompt.js +0 -31
- package/dist/controls/prompt.js.map +0 -1
- package/dist/controls/search.d.ts +0 -13
- package/dist/controls/search.js +0 -47
- package/dist/controls/search.js.map +0 -1
- package/dist/controls/section.d.ts +0 -14
- package/dist/controls/section.js +0 -27
- package/dist/controls/section.js.map +0 -1
- package/dist/controls/svg.d.ts +0 -23
- package/dist/controls/svg.js +0 -45
- package/dist/controls/svg.js.map +0 -1
- package/dist/controls/toolbar.d.ts +0 -12
- package/dist/controls/toolbar.js +0 -23
- package/dist/controls/toolbar.js.map +0 -1
- package/dist/controls/vertical-content.d.ts +0 -6
- package/dist/controls/vertical-content.js +0 -37
- package/dist/controls/vertical-content.js.map +0 -1
- package/dist/controls/vertical.d.ts +0 -8
- package/dist/controls/vertical.js +0 -23
- package/dist/controls/vertical.js.map +0 -1
- package/dist/exports-index.d.ts +0 -3
- package/dist/exports-index.js +0 -4
- package/dist/exports-index.js.map +0 -1
- package/dist/helpers/context.d.ts +0 -26
- package/dist/helpers/context.js +0 -15
- package/dist/helpers/context.js.map +0 -1
- package/dist/helpers/hooks.d.ts +0 -62
- package/dist/helpers/hooks.js +0 -287
- package/dist/helpers/hooks.js.map +0 -1
- package/dist/index.d.ts +0 -25
- package/dist/index.js +0 -25
- package/dist/index.js.map +0 -1
- package/dist/styles/exports-index.d.ts +0 -2
- package/dist/styles/exports-index.js +0 -3
- package/dist/styles/exports-index.js.map +0 -1
- package/dist/styles/styles.d.ts +0 -19
- package/dist/styles/styles.js +0 -79
- package/dist/styles/styles.js.map +0 -1
- package/dist/styles/theme.d.ts +0 -6
- package/dist/styles/theme.js +0 -77
- package/dist/styles/theme.js.map +0 -1
@@ -1,104 +1,104 @@
|
|
1
|
-
import {
|
2
|
-
Menu, MenuButton, MenuItem, MenuList, MenuPopover, MenuTrigger, Overflow, OverflowItem,
|
3
|
-
useIsOverflowItemVisible, useOverflowMenu
|
4
|
-
} from "@fluentui/react-components";
|
5
|
-
import { MoreHorizontalFilled } from "@fluentui/react-icons";
|
6
|
-
import { isNumber } from '@kwiz/common';
|
7
|
-
|
8
|
-
interface IProps<ItemType> {
|
9
|
-
/** you cannot have a menu with trigger in overflow items. put those in groupWrapper controls before/after rendering children. */
|
10
|
-
items: ItemType[];
|
11
|
-
getKey: (item: ItemType, index: number) => string;
|
12
|
-
getPriority?: (item: ItemType, index: number) => number;
|
13
|
-
renderItem: (item: ItemType, index: number, overflow?: boolean) => JSX.Element;
|
14
|
-
groupWrapper?: (children: React.ReactNode) => JSX.Element;
|
15
|
-
menuRef?: React.RefObject<HTMLButtonElement>;
|
16
|
-
menuWrapper?: (children: React.ReactNode) => JSX.Element;
|
17
|
-
menuTrigger?: (ref: React.RefObject<HTMLButtonElement>, overflowCount: number) => JSX.Element;
|
18
|
-
className?: string;
|
19
|
-
}
|
20
|
-
const OverflowMenu = <ItemType,>(props: IProps<ItemType>) => {
|
21
|
-
const { ref, isOverflowing, overflowCount } =
|
22
|
-
useOverflowMenu<HTMLButtonElement>();
|
23
|
-
|
24
|
-
if (!isOverflowing) {
|
25
|
-
return null;
|
26
|
-
}
|
27
|
-
|
28
|
-
let menu = <Menu>
|
29
|
-
<MenuTrigger disableButtonEnhancement>
|
30
|
-
{props.menuTrigger
|
31
|
-
? props.menuTrigger(props.menuRef || ref, overflowCount)
|
32
|
-
: <MenuButton
|
33
|
-
icon={<MoreHorizontalFilled/>}
|
34
|
-
ref={props.menuRef || ref}
|
35
|
-
aria-label="More items"
|
36
|
-
appearance="subtle"
|
37
|
-
/>}
|
38
|
-
</MenuTrigger>
|
39
|
-
<MenuPopover>
|
40
|
-
<MenuList>
|
41
|
-
{props.items.map((item, index) => (
|
42
|
-
<OverflowMenuItem key={props.getKey(item, index)} {...props} item={item} index={index} />
|
43
|
-
))}
|
44
|
-
</MenuList>
|
45
|
-
</MenuPopover>
|
46
|
-
</Menu>;
|
47
|
-
|
48
|
-
return (
|
49
|
-
props.menuWrapper
|
50
|
-
? props.menuWrapper(menu)
|
51
|
-
: menu
|
52
|
-
);
|
53
|
-
}
|
54
|
-
|
55
|
-
const OverflowMenuItem = <ItemType,>(props: IProps<ItemType> & { item: ItemType, index: number }) => {
|
56
|
-
const isVisible = useIsOverflowItemVisible(props.getKey(props.item, props.index));
|
57
|
-
|
58
|
-
if (isVisible) {
|
59
|
-
return null;
|
60
|
-
}
|
61
|
-
|
62
|
-
return (
|
63
|
-
<MenuItem key={props.getKey(props.item, props.index)}>
|
64
|
-
{props.renderItem(props.item, props.index, true)}
|
65
|
-
</MenuItem>
|
66
|
-
);
|
67
|
-
};
|
68
|
-
export const KWIZOverflow = <ItemType,>(props: IProps<ItemType>) => {
|
69
|
-
let content: JSX.Element[] = [];
|
70
|
-
let addMenu = () => {
|
71
|
-
if (menuIndex >= 0)
|
72
|
-
content.splice(menuIndex, 0, <OverflowMenu key="overflow_menu" {...props} />);
|
73
|
-
else
|
74
|
-
content.push(<OverflowMenu key="overflow_menu" {...props} />);
|
75
|
-
};
|
76
|
-
|
77
|
-
let menuIndex = -1;
|
78
|
-
|
79
|
-
props.items.forEach((item, index) => {
|
80
|
-
//add the menu before the first item with priority
|
81
|
-
let priority = props.getPriority ? props.getPriority(item, index) : undefined;
|
82
|
-
if (isNumber(priority) && priority > 0)
|
83
|
-
menuIndex = index;
|
84
|
-
|
85
|
-
content.push(<OverflowItem key={props.getKey(item, index)} id={props.getKey(item, index)}
|
86
|
-
priority={priority}>
|
87
|
-
{props.renderItem(item, index)}
|
88
|
-
</OverflowItem>);
|
89
|
-
});
|
90
|
-
|
91
|
-
addMenu();
|
92
|
-
|
93
|
-
return (
|
94
|
-
<Overflow minimumVisible={2} padding={60} key={`overflow_${props.items.length}`}>
|
95
|
-
<div style={{ overflow: "hidden" }} className={props.className}>
|
96
|
-
{
|
97
|
-
props.groupWrapper
|
98
|
-
? props.groupWrapper(content)
|
99
|
-
: content
|
100
|
-
}
|
101
|
-
</div>
|
102
|
-
</Overflow>
|
103
|
-
)
|
1
|
+
import {
|
2
|
+
Menu, MenuButton, MenuItem, MenuList, MenuPopover, MenuTrigger, Overflow, OverflowItem,
|
3
|
+
useIsOverflowItemVisible, useOverflowMenu
|
4
|
+
} from "@fluentui/react-components";
|
5
|
+
import { MoreHorizontalFilled } from "@fluentui/react-icons";
|
6
|
+
import { isNumber } from '@kwiz/common';
|
7
|
+
|
8
|
+
interface IProps<ItemType> {
|
9
|
+
/** you cannot have a menu with trigger in overflow items. put those in groupWrapper controls before/after rendering children. */
|
10
|
+
items: ItemType[];
|
11
|
+
getKey: (item: ItemType, index: number) => string;
|
12
|
+
getPriority?: (item: ItemType, index: number) => number;
|
13
|
+
renderItem: (item: ItemType, index: number, overflow?: boolean) => JSX.Element;
|
14
|
+
groupWrapper?: (children: React.ReactNode) => JSX.Element;
|
15
|
+
menuRef?: React.RefObject<HTMLButtonElement>;
|
16
|
+
menuWrapper?: (children: React.ReactNode) => JSX.Element;
|
17
|
+
menuTrigger?: (ref: React.RefObject<HTMLButtonElement>, overflowCount: number) => JSX.Element;
|
18
|
+
className?: string;
|
19
|
+
}
|
20
|
+
const OverflowMenu = <ItemType,>(props: IProps<ItemType>) => {
|
21
|
+
const { ref, isOverflowing, overflowCount } =
|
22
|
+
useOverflowMenu<HTMLButtonElement>();
|
23
|
+
|
24
|
+
if (!isOverflowing) {
|
25
|
+
return null;
|
26
|
+
}
|
27
|
+
|
28
|
+
let menu = <Menu>
|
29
|
+
<MenuTrigger disableButtonEnhancement>
|
30
|
+
{props.menuTrigger
|
31
|
+
? props.menuTrigger(props.menuRef || ref, overflowCount)
|
32
|
+
: <MenuButton
|
33
|
+
icon={<MoreHorizontalFilled/>}
|
34
|
+
ref={props.menuRef || ref}
|
35
|
+
aria-label="More items"
|
36
|
+
appearance="subtle"
|
37
|
+
/>}
|
38
|
+
</MenuTrigger>
|
39
|
+
<MenuPopover>
|
40
|
+
<MenuList>
|
41
|
+
{props.items.map((item, index) => (
|
42
|
+
<OverflowMenuItem key={props.getKey(item, index)} {...props} item={item} index={index} />
|
43
|
+
))}
|
44
|
+
</MenuList>
|
45
|
+
</MenuPopover>
|
46
|
+
</Menu>;
|
47
|
+
|
48
|
+
return (
|
49
|
+
props.menuWrapper
|
50
|
+
? props.menuWrapper(menu)
|
51
|
+
: menu
|
52
|
+
);
|
53
|
+
}
|
54
|
+
|
55
|
+
const OverflowMenuItem = <ItemType,>(props: IProps<ItemType> & { item: ItemType, index: number }) => {
|
56
|
+
const isVisible = useIsOverflowItemVisible(props.getKey(props.item, props.index));
|
57
|
+
|
58
|
+
if (isVisible) {
|
59
|
+
return null;
|
60
|
+
}
|
61
|
+
|
62
|
+
return (
|
63
|
+
<MenuItem key={props.getKey(props.item, props.index)}>
|
64
|
+
{props.renderItem(props.item, props.index, true)}
|
65
|
+
</MenuItem>
|
66
|
+
);
|
67
|
+
};
|
68
|
+
export const KWIZOverflow = <ItemType,>(props: IProps<ItemType>) => {
|
69
|
+
let content: JSX.Element[] = [];
|
70
|
+
let addMenu = () => {
|
71
|
+
if (menuIndex >= 0)
|
72
|
+
content.splice(menuIndex, 0, <OverflowMenu key="overflow_menu" {...props} />);
|
73
|
+
else
|
74
|
+
content.push(<OverflowMenu key="overflow_menu" {...props} />);
|
75
|
+
};
|
76
|
+
|
77
|
+
let menuIndex = -1;
|
78
|
+
|
79
|
+
props.items.forEach((item, index) => {
|
80
|
+
//add the menu before the first item with priority
|
81
|
+
let priority = props.getPriority ? props.getPriority(item, index) : undefined;
|
82
|
+
if (isNumber(priority) && priority > 0)
|
83
|
+
menuIndex = index;
|
84
|
+
|
85
|
+
content.push(<OverflowItem key={props.getKey(item, index)} id={props.getKey(item, index)}
|
86
|
+
priority={priority}>
|
87
|
+
{props.renderItem(item, index)}
|
88
|
+
</OverflowItem>);
|
89
|
+
});
|
90
|
+
|
91
|
+
addMenu();
|
92
|
+
|
93
|
+
return (
|
94
|
+
<Overflow minimumVisible={2} padding={60} key={`overflow_${props.items.length}`}>
|
95
|
+
<div style={{ overflow: "hidden" }} className={props.className}>
|
96
|
+
{
|
97
|
+
props.groupWrapper
|
98
|
+
? props.groupWrapper(content)
|
99
|
+
: content
|
100
|
+
}
|
101
|
+
</div>
|
102
|
+
</Overflow>
|
103
|
+
)
|
104
104
|
};
|
package/src/controls/list.tsx
CHANGED
@@ -1,118 +1,118 @@
|
|
1
|
-
import { makeStyles, tokens } from '@fluentui/react-components';
|
2
|
-
import { LOGO_BLUE_SQUARE, LOGO_WHITE_SQUARE, isNullOrUndefined, isString } from '@kwiz/common';
|
3
|
-
import React from 'react';
|
4
|
-
import { KnownClassNames, mixins } from '../styles/styles';
|
5
|
-
import { Horizontal } from './horizontal';
|
6
|
-
import { Section } from './section';
|
7
|
-
import { Vertical } from './vertical';
|
8
|
-
|
9
|
-
const useStyles = makeStyles({
|
10
|
-
list: {
|
11
|
-
rowGap: 0
|
12
|
-
},
|
13
|
-
listItem: {
|
14
|
-
padding: tokens.spacingVerticalS,
|
15
|
-
':hover': {
|
16
|
-
backgroundColor: tokens.colorNeutralBackground1Hover
|
17
|
-
}
|
18
|
-
},
|
19
|
-
listItemSelected: {
|
20
|
-
backgroundColor: tokens.colorNeutralBackground1Selected
|
21
|
-
},
|
22
|
-
media: {
|
23
|
-
width: '32px',
|
24
|
-
fontSize: tokens.fontSizeBase600,
|
25
|
-
display: 'flex',
|
26
|
-
flexDirection: 'column',
|
27
|
-
justifyContent: 'center'
|
28
|
-
},
|
29
|
-
image: {
|
30
|
-
width: tokens.lineHeightBase600,
|
31
|
-
height: tokens.lineHeightBase600,
|
32
|
-
backgroundPosition: 'center center',
|
33
|
-
backgroundSize: 'cover',
|
34
|
-
borderRadius: tokens.borderRadiusCircular,
|
35
|
-
border: `1px solid ${tokens.colorNeutralStroke1}`
|
36
|
-
},
|
37
|
-
listItemBody: {
|
38
|
-
rowGap: 0,
|
39
|
-
width: 'calc(100% - 44px)'
|
40
|
-
},
|
41
|
-
listItemHeader: mixins.ellipsis,
|
42
|
-
listItemContent: {
|
43
|
-
...mixins.ellipsis,
|
44
|
-
fontSize: tokens.fontSizeBase200
|
45
|
-
},
|
46
|
-
listItemMedia: {
|
47
|
-
...mixins.ellipsis,
|
48
|
-
maxWidth: '20%',
|
49
|
-
'& svg': {
|
50
|
-
height: tokens.fontSizeBase300
|
51
|
-
},
|
52
|
-
'& button': {
|
53
|
-
padding: 0,
|
54
|
-
minWidth: 0,
|
55
|
-
minHeight: 0,
|
56
|
-
height: '14px'
|
57
|
-
}
|
58
|
-
},
|
59
|
-
listItemMediaNoTrim: {
|
60
|
-
overflow: 'visible',
|
61
|
-
maxWidth: 'fit-content'
|
62
|
-
},
|
63
|
-
listItemMultilineContent: {
|
64
|
-
whiteSpace: 'pre-line'
|
65
|
-
}
|
66
|
-
});
|
67
|
-
|
68
|
-
export interface iListItem {
|
69
|
-
key: string | number;
|
70
|
-
media?: JSX.Element | string;
|
71
|
-
header: string;
|
72
|
-
headerMedia?: JSX.Element | string;
|
73
|
-
content?: string | JSX.Element | (string | JSX.Element)[];
|
74
|
-
onClickOnMedia?: boolean;
|
75
|
-
onClick?: (event: React.MouseEvent<HTMLDivElement, MouseEvent>) => void;
|
76
|
-
selected?: boolean;
|
77
|
-
}
|
78
|
-
interface IProps {
|
79
|
-
selectable?: boolean;
|
80
|
-
items: iListItem[];
|
81
|
-
showAllHeaderMedia?: boolean;
|
82
|
-
/** allow multiline content */
|
83
|
-
multiline?: boolean;
|
84
|
-
dark?: boolean;
|
85
|
-
}
|
86
|
-
|
87
|
-
export const ListEx = (props: IProps) => {
|
88
|
-
|
89
|
-
const cssNames = useStyles();
|
90
|
-
|
91
|
-
const listItemElm = (item: iListItem) => <Horizontal key={item.key} css={[cssNames.listItem, item.selected && cssNames.listItemSelected]} onClick={item.onClick}>
|
92
|
-
{item.media && <Section css={[cssNames.media]} onClick={(e) => {
|
93
|
-
if (!item.onClickOnMedia)
|
94
|
-
e.stopPropagation();//media may have its on onclick
|
95
|
-
}}>{
|
96
|
-
isString(item.media)
|
97
|
-
? <div className={cssNames.image} style={{ backgroundImage: `url('${encodeURI(item.media)}'), url('${props.dark ? LOGO_WHITE_SQUARE : LOGO_BLUE_SQUARE}')` }}></div>
|
98
|
-
: item.media
|
99
|
-
}</Section>}
|
100
|
-
<Vertical main css={[cssNames.listItemBody]}>
|
101
|
-
<Horizontal main>
|
102
|
-
<Section main css={[cssNames.listItemHeader]}>{item.header}</Section>
|
103
|
-
{item.headerMedia && <Section onClick={(e) => {
|
104
|
-
e.stopPropagation();//media may have its on onclick
|
105
|
-
}} css={[cssNames.listItemMedia, props.showAllHeaderMedia && cssNames.listItemMediaNoTrim]}>{item.headerMedia}</Section>}
|
106
|
-
</Horizontal>
|
107
|
-
{!isNullOrUndefined(item.content)
|
108
|
-
? (Array.isArray(item.content) ? item.content : [item.content]).map((c, idx) => isNullOrUndefined(c) ? undefined : <Section key={idx} css={[cssNames.listItemContent, props.multiline ? cssNames.listItemMultilineContent : undefined]}>{c}</Section>)
|
109
|
-
: undefined}
|
110
|
-
</Vertical>
|
111
|
-
</Horizontal>;
|
112
|
-
|
113
|
-
return (
|
114
|
-
<Vertical css={[cssNames.list, KnownClassNames.list]}>
|
115
|
-
{props.items.map(item => listItemElm(item))}
|
116
|
-
</Vertical>
|
117
|
-
);
|
1
|
+
import { makeStyles, tokens } from '@fluentui/react-components';
|
2
|
+
import { LOGO_BLUE_SQUARE, LOGO_WHITE_SQUARE, isNullOrUndefined, isString } from '@kwiz/common';
|
3
|
+
import React from 'react';
|
4
|
+
import { KnownClassNames, mixins } from '../styles/styles';
|
5
|
+
import { Horizontal } from './horizontal';
|
6
|
+
import { Section } from './section';
|
7
|
+
import { Vertical } from './vertical';
|
8
|
+
|
9
|
+
const useStyles = makeStyles({
|
10
|
+
list: {
|
11
|
+
rowGap: 0
|
12
|
+
},
|
13
|
+
listItem: {
|
14
|
+
padding: tokens.spacingVerticalS,
|
15
|
+
':hover': {
|
16
|
+
backgroundColor: tokens.colorNeutralBackground1Hover
|
17
|
+
}
|
18
|
+
},
|
19
|
+
listItemSelected: {
|
20
|
+
backgroundColor: tokens.colorNeutralBackground1Selected
|
21
|
+
},
|
22
|
+
media: {
|
23
|
+
width: '32px',
|
24
|
+
fontSize: tokens.fontSizeBase600,
|
25
|
+
display: 'flex',
|
26
|
+
flexDirection: 'column',
|
27
|
+
justifyContent: 'center'
|
28
|
+
},
|
29
|
+
image: {
|
30
|
+
width: tokens.lineHeightBase600,
|
31
|
+
height: tokens.lineHeightBase600,
|
32
|
+
backgroundPosition: 'center center',
|
33
|
+
backgroundSize: 'cover',
|
34
|
+
borderRadius: tokens.borderRadiusCircular,
|
35
|
+
border: `1px solid ${tokens.colorNeutralStroke1}`
|
36
|
+
},
|
37
|
+
listItemBody: {
|
38
|
+
rowGap: 0,
|
39
|
+
width: 'calc(100% - 44px)'
|
40
|
+
},
|
41
|
+
listItemHeader: mixins.ellipsis,
|
42
|
+
listItemContent: {
|
43
|
+
...mixins.ellipsis,
|
44
|
+
fontSize: tokens.fontSizeBase200
|
45
|
+
},
|
46
|
+
listItemMedia: {
|
47
|
+
...mixins.ellipsis,
|
48
|
+
maxWidth: '20%',
|
49
|
+
'& svg': {
|
50
|
+
height: tokens.fontSizeBase300
|
51
|
+
},
|
52
|
+
'& button': {
|
53
|
+
padding: 0,
|
54
|
+
minWidth: 0,
|
55
|
+
minHeight: 0,
|
56
|
+
height: '14px'
|
57
|
+
}
|
58
|
+
},
|
59
|
+
listItemMediaNoTrim: {
|
60
|
+
overflow: 'visible',
|
61
|
+
maxWidth: 'fit-content'
|
62
|
+
},
|
63
|
+
listItemMultilineContent: {
|
64
|
+
whiteSpace: 'pre-line'
|
65
|
+
}
|
66
|
+
});
|
67
|
+
|
68
|
+
export interface iListItem {
|
69
|
+
key: string | number;
|
70
|
+
media?: JSX.Element | string;
|
71
|
+
header: string;
|
72
|
+
headerMedia?: JSX.Element | string;
|
73
|
+
content?: string | JSX.Element | (string | JSX.Element)[];
|
74
|
+
onClickOnMedia?: boolean;
|
75
|
+
onClick?: (event: React.MouseEvent<HTMLDivElement, MouseEvent>) => void;
|
76
|
+
selected?: boolean;
|
77
|
+
}
|
78
|
+
interface IProps {
|
79
|
+
selectable?: boolean;
|
80
|
+
items: iListItem[];
|
81
|
+
showAllHeaderMedia?: boolean;
|
82
|
+
/** allow multiline content */
|
83
|
+
multiline?: boolean;
|
84
|
+
dark?: boolean;
|
85
|
+
}
|
86
|
+
|
87
|
+
export const ListEx = (props: IProps) => {
|
88
|
+
|
89
|
+
const cssNames = useStyles();
|
90
|
+
|
91
|
+
const listItemElm = (item: iListItem) => <Horizontal key={item.key} css={[cssNames.listItem, item.selected && cssNames.listItemSelected]} onClick={item.onClick}>
|
92
|
+
{item.media && <Section css={[cssNames.media]} onClick={(e) => {
|
93
|
+
if (!item.onClickOnMedia)
|
94
|
+
e.stopPropagation();//media may have its on onclick
|
95
|
+
}}>{
|
96
|
+
isString(item.media)
|
97
|
+
? <div className={cssNames.image} style={{ backgroundImage: `url('${encodeURI(item.media)}'), url('${props.dark ? LOGO_WHITE_SQUARE : LOGO_BLUE_SQUARE}')` }}></div>
|
98
|
+
: item.media
|
99
|
+
}</Section>}
|
100
|
+
<Vertical main css={[cssNames.listItemBody]}>
|
101
|
+
<Horizontal main>
|
102
|
+
<Section main css={[cssNames.listItemHeader]}>{item.header}</Section>
|
103
|
+
{item.headerMedia && <Section onClick={(e) => {
|
104
|
+
e.stopPropagation();//media may have its on onclick
|
105
|
+
}} css={[cssNames.listItemMedia, props.showAllHeaderMedia && cssNames.listItemMediaNoTrim]}>{item.headerMedia}</Section>}
|
106
|
+
</Horizontal>
|
107
|
+
{!isNullOrUndefined(item.content)
|
108
|
+
? (Array.isArray(item.content) ? item.content : [item.content]).map((c, idx) => isNullOrUndefined(c) ? undefined : <Section key={idx} css={[cssNames.listItemContent, props.multiline ? cssNames.listItemMultilineContent : undefined]}>{c}</Section>)
|
109
|
+
: undefined}
|
110
|
+
</Vertical>
|
111
|
+
</Horizontal>;
|
112
|
+
|
113
|
+
return (
|
114
|
+
<Vertical css={[cssNames.list, KnownClassNames.list]}>
|
115
|
+
{props.items.map(item => listItemElm(item))}
|
116
|
+
</Vertical>
|
117
|
+
);
|
118
118
|
}
|
package/src/controls/loading.tsx
CHANGED
@@ -1,11 +1,11 @@
|
|
1
|
-
import { LOGO_ANIM_SMALL } from '@kwiz/common';
|
2
|
-
import { Centered } from './centered';
|
3
|
-
import React from 'react';
|
4
|
-
|
5
|
-
interface IProps {
|
6
|
-
}
|
7
|
-
export const Loading: React.FunctionComponent<IProps> = (props) => {
|
8
|
-
return (
|
9
|
-
<Centered><img src={LOGO_ANIM_SMALL} alt="loading" style={{ width: '15vw' }} /></Centered>
|
10
|
-
);
|
1
|
+
import { LOGO_ANIM_SMALL } from '@kwiz/common';
|
2
|
+
import { Centered } from './centered';
|
3
|
+
import React from 'react';
|
4
|
+
|
5
|
+
interface IProps {
|
6
|
+
}
|
7
|
+
export const Loading: React.FunctionComponent<IProps> = (props) => {
|
8
|
+
return (
|
9
|
+
<Centered><img src={LOGO_ANIM_SMALL} alt="loading" style={{ width: '15vw' }} /></Centered>
|
10
|
+
);
|
11
11
|
}
|
@@ -1,33 +1,33 @@
|
|
1
|
-
import { Field, ProgressBar } from '@fluentui/react-components';
|
2
|
-
import { isFunction } from '@kwiz/common';
|
3
|
-
import React from 'react';
|
4
|
-
import { IPrompterProps, Prompter } from './prompt';
|
5
|
-
|
6
|
-
interface IProps {
|
7
|
-
step?: number; max?: number;
|
8
|
-
/** do not wrap in a dialog */
|
9
|
-
contentOnly?: boolean;
|
10
|
-
cancelText?: string;
|
11
|
-
onCancel?: () => void;
|
12
|
-
label?: string;
|
13
|
-
}
|
14
|
-
export const PleaseWait: React.FunctionComponent<React.PropsWithChildren<IProps>> = (props) => {
|
15
|
-
const field = <Field validationMessage={props.label || "please wait..."} validationState="none">
|
16
|
-
<ProgressBar value={props.step} max={props.max} />
|
17
|
-
</Field>;
|
18
|
-
return (props.contentOnly
|
19
|
-
? field
|
20
|
-
: <Prompter hideOk
|
21
|
-
hideCancel={!isFunction(props.onCancel)}
|
22
|
-
cancelButtonText={props.cancelText || 'cancel'}
|
23
|
-
onCancel={props.onCancel}>{field}</Prompter>
|
24
|
-
);
|
25
|
-
}
|
26
|
-
|
27
|
-
export const PleaseWaitPrompt = (props: { message: string; step?: number; max?: number; }): IPrompterProps => ({
|
28
|
-
//title: 'please wait...',
|
29
|
-
hideOk: true, hideCancel: true,
|
30
|
-
children: <Field validationMessage={props.message} validationState="none">
|
31
|
-
<ProgressBar value={props.step} max={props.max} />
|
32
|
-
</Field>
|
1
|
+
import { Field, ProgressBar } from '@fluentui/react-components';
|
2
|
+
import { isFunction } from '@kwiz/common';
|
3
|
+
import React from 'react';
|
4
|
+
import { IPrompterProps, Prompter } from './prompt';
|
5
|
+
|
6
|
+
interface IProps {
|
7
|
+
step?: number; max?: number;
|
8
|
+
/** do not wrap in a dialog */
|
9
|
+
contentOnly?: boolean;
|
10
|
+
cancelText?: string;
|
11
|
+
onCancel?: () => void;
|
12
|
+
label?: string;
|
13
|
+
}
|
14
|
+
export const PleaseWait: React.FunctionComponent<React.PropsWithChildren<IProps>> = (props) => {
|
15
|
+
const field = <Field validationMessage={props.label || "please wait..."} validationState="none">
|
16
|
+
<ProgressBar value={props.step} max={props.max} />
|
17
|
+
</Field>;
|
18
|
+
return (props.contentOnly
|
19
|
+
? field
|
20
|
+
: <Prompter hideOk
|
21
|
+
hideCancel={!isFunction(props.onCancel)}
|
22
|
+
cancelButtonText={props.cancelText || 'cancel'}
|
23
|
+
onCancel={props.onCancel}>{field}</Prompter>
|
24
|
+
);
|
25
|
+
}
|
26
|
+
|
27
|
+
export const PleaseWaitPrompt = (props: { message: string; step?: number; max?: number; }): IPrompterProps => ({
|
28
|
+
//title: 'please wait...',
|
29
|
+
hideOk: true, hideCancel: true,
|
30
|
+
children: <Field validationMessage={props.message} validationState="none">
|
31
|
+
<ProgressBar value={props.step} max={props.max} />
|
32
|
+
</Field>
|
33
33
|
});
|