@kwiz/fluentui 1.0.78 → 1.0.80

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.
Files changed (92) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +53 -53
  3. package/dist/controls/button.d.ts +4 -1
  4. package/dist/controls/button.js +37 -1
  5. package/dist/controls/button.js.map +1 -1
  6. package/dist/controls/qrcode.js +0 -6
  7. package/dist/controls/qrcode.js.map +1 -1
  8. package/dist/controls/svg.js +21 -21
  9. package/dist/controls/svg.js.map +1 -1
  10. package/package.json +85 -85
  11. package/.dependency-cruiser.js +0 -399
  12. package/.github/workflows/npm-publish.yml +0 -24
  13. package/dist/@types/forwardRef.d.ts +0 -0
  14. package/dist/@types/forwardRef.js +0 -1
  15. package/dist/@types/forwardRef.js.map +0 -1
  16. package/dist/controls/error-boundary copy.d.ts +0 -23
  17. package/dist/controls/error-boundary copy.js +0 -33
  18. package/dist/controls/error-boundary copy.js.map +0 -1
  19. package/dist/helpers/common.d.ts +0 -4
  20. package/dist/helpers/common.js +0 -2
  21. package/dist/helpers/common.js.map +0 -1
  22. package/dist/helpers/context.d.ts +0 -26
  23. package/dist/helpers/context.js +0 -15
  24. package/dist/helpers/context.js.map +0 -1
  25. package/dist/helpers/drag-drop/exports.d.ts +0 -12
  26. package/dist/helpers/drag-drop/exports.js +0 -3
  27. package/dist/helpers/drag-drop/exports.js.map +0 -1
  28. package/dist/helpers/exports.d.ts +0 -7
  29. package/dist/helpers/exports.js +0 -8
  30. package/dist/helpers/exports.js.map +0 -1
  31. package/src/_modules/config.ts +0 -9
  32. package/src/_modules/constants.ts +0 -3
  33. package/src/controls/ColorPickerDialog.tsx +0 -84
  34. package/src/controls/accordion.tsx +0 -62
  35. package/src/controls/button.tsx +0 -181
  36. package/src/controls/canvas/CustomEventTargetBase.ts +0 -33
  37. package/src/controls/canvas/DrawPad.tsx +0 -297
  38. package/src/controls/canvas/DrawPadManager.ts +0 -695
  39. package/src/controls/canvas/bezier.ts +0 -110
  40. package/src/controls/canvas/point.ts +0 -45
  41. package/src/controls/card-list.tsx +0 -32
  42. package/src/controls/card.tsx +0 -78
  43. package/src/controls/centered.tsx +0 -15
  44. package/src/controls/date.tsx +0 -88
  45. package/src/controls/diagram-picker.tsx +0 -97
  46. package/src/controls/divider.tsx +0 -16
  47. package/src/controls/dropdown.tsx +0 -67
  48. package/src/controls/error-boundary.tsx +0 -42
  49. package/src/controls/field-editor.tsx +0 -43
  50. package/src/controls/file-upload.tsx +0 -156
  51. package/src/controls/horizontal.tsx +0 -49
  52. package/src/controls/html-editor/editor.tsx +0 -182
  53. package/src/controls/index.ts +0 -33
  54. package/src/controls/input.tsx +0 -161
  55. package/src/controls/kwizoverflow.tsx +0 -107
  56. package/src/controls/list.tsx +0 -120
  57. package/src/controls/loading.tsx +0 -11
  58. package/src/controls/menu.tsx +0 -196
  59. package/src/controls/merge-text.tsx +0 -126
  60. package/src/controls/please-wait.tsx +0 -33
  61. package/src/controls/progress-bar.tsx +0 -110
  62. package/src/controls/prompt.tsx +0 -122
  63. package/src/controls/qrcode.tsx +0 -37
  64. package/src/controls/search.tsx +0 -72
  65. package/src/controls/section.tsx +0 -134
  66. package/src/controls/svg.tsx +0 -139
  67. package/src/controls/toolbar.tsx +0 -47
  68. package/src/controls/vertical-content.tsx +0 -50
  69. package/src/controls/vertical.tsx +0 -43
  70. package/src/helpers/block-nav.tsx +0 -89
  71. package/src/helpers/context-const.ts +0 -30
  72. package/src/helpers/context-export.tsx +0 -78
  73. package/src/helpers/context-internal.ts +0 -14
  74. package/src/helpers/drag-drop/drag-drop-container.tsx +0 -54
  75. package/src/helpers/drag-drop/drag-drop-context-internal.tsx +0 -10
  76. package/src/helpers/drag-drop/drag-drop-context.tsx +0 -62
  77. package/src/helpers/drag-drop/drag-drop.types.ts +0 -21
  78. package/src/helpers/drag-drop/index.ts +0 -12
  79. package/src/helpers/drag-drop/readme.md +0 -76
  80. package/src/helpers/drag-drop/use-draggable.ts +0 -48
  81. package/src/helpers/drag-drop/use-droppable.ts +0 -39
  82. package/src/helpers/forwardRef.ts +0 -7
  83. package/src/helpers/hooks-events.ts +0 -150
  84. package/src/helpers/hooks.tsx +0 -175
  85. package/src/helpers/index.ts +0 -8
  86. package/src/helpers/use-alerts.tsx +0 -75
  87. package/src/helpers/use-editable-control.tsx +0 -38
  88. package/src/helpers/use-toast.tsx +0 -30
  89. package/src/index.ts +0 -3
  90. package/src/styles/index.ts +0 -1
  91. package/src/styles/styles.ts +0 -105
  92. package/src/styles/theme.ts +0 -91
@@ -1,120 +0,0 @@
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 { useKWIZFluentContext } from '../helpers/context-internal';
5
- import { KnownClassNames, mixins } from '../styles/styles';
6
- import { Horizontal } from './horizontal';
7
- import { Section } from './section';
8
- import { Vertical } from './vertical';
9
-
10
- const useStyles = makeStyles({
11
- list: {
12
- rowGap: 0
13
- },
14
- listItem: {
15
- padding: tokens.spacingVerticalS,
16
- ':hover': {
17
- backgroundColor: tokens.colorNeutralBackground1Hover
18
- }
19
- },
20
- listItemSelected: {
21
- backgroundColor: tokens.colorNeutralBackground1Selected
22
- },
23
- media: {
24
- width: '32px',
25
- fontSize: tokens.fontSizeBase600,
26
- display: 'flex',
27
- flexDirection: 'column',
28
- justifyContent: 'center'
29
- },
30
- image: {
31
- width: tokens.lineHeightBase600,
32
- height: tokens.lineHeightBase600,
33
- backgroundPosition: 'center center',
34
- backgroundSize: 'cover',
35
- borderRadius: tokens.borderRadiusCircular,
36
- border: `1px solid ${tokens.colorNeutralStroke1}`
37
- },
38
- listItemBody: {
39
- rowGap: 0,
40
- width: 'calc(100% - 44px)'
41
- },
42
- listItemHeader: mixins.ellipsis,
43
- listItemContent: {
44
- ...mixins.ellipsis,
45
- fontSize: tokens.fontSizeBase200
46
- },
47
- listItemMedia: {
48
- ...mixins.ellipsis,
49
- maxWidth: '20%',
50
- '& svg': {
51
- height: tokens.fontSizeBase300
52
- },
53
- '& button': {
54
- padding: 0,
55
- minWidth: 0,
56
- minHeight: 0,
57
- height: '14px'
58
- }
59
- },
60
- listItemMediaNoTrim: {
61
- overflow: 'visible',
62
- maxWidth: 'fit-content'
63
- },
64
- listItemMultilineContent: {
65
- whiteSpace: 'pre-line'
66
- }
67
- });
68
-
69
- export interface iListItem {
70
- key: string | number;
71
- media?: JSX.Element | string;
72
- header: string;
73
- headerMedia?: JSX.Element | string;
74
- content?: string | JSX.Element | (string | JSX.Element)[];
75
- onClickOnMedia?: boolean;
76
- onClick?: (event: React.MouseEvent<HTMLDivElement, MouseEvent>) => void;
77
- selected?: boolean;
78
- }
79
- interface IProps {
80
- selectable?: boolean;
81
- items: iListItem[];
82
- showAllHeaderMedia?: boolean;
83
- /** allow multiline content */
84
- multiline?: boolean;
85
- dark?: boolean;
86
- }
87
-
88
- export const ListEx = (props: IProps) => {
89
- const ctx = useKWIZFluentContext();
90
- const cssNames = useStyles();
91
- const isDark = ctx.dark === true || props.dark === true;
92
-
93
- const listItemElm = (item: iListItem) => <Horizontal key={item.key} css={[cssNames.listItem, item.selected && cssNames.listItemSelected]} onClick={item.onClick}>
94
- {item.media && <Section css={[cssNames.media]} onClick={(e) => {
95
- if (!item.onClickOnMedia)
96
- e.stopPropagation();//media may have its on onclick
97
- }}>{
98
- isString(item.media)
99
- ? <div className={cssNames.image} style={{ backgroundImage: `url('${encodeURI(item.media)}'), url('${isDark ? LOGO_WHITE_SQUARE : LOGO_BLUE_SQUARE}')` }}></div>
100
- : item.media
101
- }</Section>}
102
- <Vertical main css={[cssNames.listItemBody]}>
103
- <Horizontal main>
104
- <Section main css={[cssNames.listItemHeader]}>{item.header}</Section>
105
- {item.headerMedia && <Section onClick={(e) => {
106
- e.stopPropagation();//media may have its on onclick
107
- }} css={[cssNames.listItemMedia, props.showAllHeaderMedia && cssNames.listItemMediaNoTrim]}>{item.headerMedia}</Section>}
108
- </Horizontal>
109
- {!isNullOrUndefined(item.content)
110
- ? (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>)
111
- : undefined}
112
- </Vertical>
113
- </Horizontal>;
114
-
115
- return (
116
- <Vertical css={[cssNames.list, KnownClassNames.list]}>
117
- {props.items.map(item => listItemElm(item))}
118
- </Vertical>
119
- );
120
- }
@@ -1,11 +0,0 @@
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
- }
@@ -1,196 +0,0 @@
1
- import { Menu, MenuDivider, MenuGroup, MenuGroupHeader, MenuItem, MenuList, MenuListProps, MenuPopover, menuPopoverClassNames, MenuPopoverProps, MenuProps, MenuTrigger } from '@fluentui/react-components';
2
- import { IDictionary, isNotEmptyArray, isNotEmptyString, isNullOrEmptyString, isNullOrUndefined, isNumber, isString, isUndefined, jsonClone, stopEvent } from '@kwiz/common';
3
- import React from 'react';
4
- import { useClickableDiv, useStateEX } from '../helpers';
5
- import { useKWIZFluentContext } from '../helpers/context-internal';
6
- import { ButtonEX, ButtonEXProps } from './button';
7
- import { DividerEX } from './divider';
8
- import { Horizontal } from './horizontal';
9
- import { Search } from './search';
10
-
11
- interface iMenuItemEXItem {
12
- type?: "item";
13
- title: string;
14
- onClick: () => void;
15
- disabled?: boolean;
16
- icon?: JSX.Element;
17
- items?: iMenuItemEX[];
18
- checked?: boolean;
19
- }
20
- interface iMenuItemEXSeparator {
21
- type: "separator";
22
- }
23
- interface iMenuItemEXGroup {
24
- type: "group";
25
- title: string;
26
- //can't nest groups
27
- items: (iMenuItemEX & { type?: "separator" | "item" })[];
28
- }
29
- export type iMenuItemEX = iMenuItemEXItem | iMenuItemEXSeparator | iMenuItemEXGroup;
30
-
31
- interface IProps {
32
- menuProps?: MenuProps;
33
- menuPopOverProps?: MenuPopoverProps;
34
- menuListProps?: MenuListProps;
35
- trigger: JSX.Element | string | ButtonEXProps;
36
- items: iMenuItemEX[];
37
- /** default 8 null/false to disable */
38
- filterThreshold?: number | false;
39
- /** default 8, null/false to disable */
40
- pageSize?: number | false;
41
- }
42
- export const MenuEx: React.FunctionComponent<React.PropsWithChildren<IProps>> = (props) => {
43
- const ctx = useKWIZFluentContext();
44
- const [startIndexPerLevel, setStartIndexPerLevel] = useStateEX<IDictionary<number>>({});
45
- const [filterPerLevel, setFilterPerLevel] = useStateEX<IDictionary<string>>({});
46
- let pageSize: number = isUndefined(props.pageSize) ? 8 : isNumber(props.pageSize) ? props.pageSize : 99999999999;
47
- let filterThreshold: number = isUndefined(props.filterThreshold) ? 8 : isNumber(props.filterThreshold) ? props.filterThreshold : 99999999999;
48
-
49
- //when hovering over sub menu the parent would close - have menu trigger keep open on the parent level
50
- const [keepOpen, setKeepOpen] = useStateEX<IDictionary<boolean>>({});
51
- const [opened, setOpened] = useStateEX<IDictionary<boolean>>({});
52
-
53
- const clickableDiv = useClickableDiv();
54
-
55
- React.useEffect(() => {
56
- window.setTimeout(() => {
57
- var menus = document.querySelectorAll(`.${menuPopoverClassNames.root}`);
58
- menus.forEach((menu: HTMLDivElement) => {
59
- var rect = menu.getBoundingClientRect();
60
- if (rect.bottom > document.documentElement.clientHeight) {
61
- menu.style.overflow = "auto";
62
- menu.style.height = `${rect.height - (rect.bottom - document.documentElement.clientHeight)}px`;
63
- }
64
- });
65
- }, 100);
66
- }, [opened]);
67
-
68
- function renderItems(items: iMenuItemEX[], level: number) {
69
- const myLevelFilter = filterPerLevel[level];
70
-
71
- const showItem = (i: iMenuItemEX) => {
72
- //get rid of empty/null items
73
- let show = !isNullOrUndefined(i) && (isNotEmptyString(i.type) || isNotEmptyString((i as iMenuItemEXItem).title));
74
- if (show && isNotEmptyString(myLevelFilter)) {
75
- if (i.type === "separator") show = false;
76
- else if (i.type === "group") {
77
- //only show group if 1 or more results are in it
78
- return i.items.filter(sub => showItem(sub)).length > 0;
79
- }
80
- else
81
- show = i.title.toLowerCase().indexOf(myLevelFilter) >= 0;
82
- }
83
- return show;
84
- }
85
-
86
- //inject group items into this level - so we share the filter/next functionality. it looks wierd if filter/paging is done per group if they are displayed inline.
87
- items = items.map(i => i.type === "group" && isNotEmptyArray(i.items) ? [i, ...i.items] : i)
88
- .flat()
89
- //filter empty item or based on text filter
90
- .filter(i => showItem(i));
91
-
92
- let menuItems = items.map((item, index) => {
93
- switch (item.type) {
94
- case "group":
95
- //todo: technically group items should be nested inside the group for better screen reder support
96
- return <MenuGroup key={index}>
97
- <MenuGroupHeader>{item.title}</MenuGroupHeader>
98
- </MenuGroup>;
99
- case "separator":
100
- return <MenuDivider key={index} />;
101
- case "item":
102
- default:
103
- const openKey = `${level}|${index}`;
104
- const menuItem = <MenuItem key={index} icon={item.icon}
105
- disabled={item.disabled}
106
- onClick={item.onClick}
107
- >{item.title}</MenuItem>;
108
- return isNotEmptyArray(item.items)
109
- ? <Menu key={index} mountNode={ctx.mountNode} open={opened[openKey] || false} onOpenChange={(e, data) => {
110
- if (data.open) {
111
- setOpened({ ...opened, [openKey]: true });
112
- setKeepOpen({ ...keepOpen, [level]: true });
113
- }
114
- else if (!keepOpen[openKey]) {
115
- setOpened({ ...opened, [openKey]: false });
116
- setKeepOpen({ ...keepOpen, [level]: false });
117
- }
118
- }}>
119
- <MenuTrigger disableButtonEnhancement>
120
- {menuItem}
121
- </MenuTrigger>
122
- <MenuPopover>
123
- <MenuList>
124
- {renderItems(item.items, level + 1)}
125
- </MenuList>
126
- </MenuPopover>
127
- </Menu>
128
- : menuItem;
129
- }
130
- });
131
-
132
- const paged = menuItems.length > pageSize;
133
- const filtered = menuItems.length > filterThreshold || !isNullOrEmptyString(myLevelFilter);
134
-
135
- if (paged) {
136
- let start = startIndexPerLevel[level];
137
- if (isNullOrUndefined(start)) start = 0;
138
- let hasMore = menuItems.length > start + pageSize;
139
- menuItems = menuItems.slice(start, start + pageSize);
140
- if (start > 0) {
141
- menuItems.splice(0, 0, <DividerEX key="$prev" title='Previous'
142
- {...clickableDiv}
143
- onClick={() => {
144
- const s = jsonClone(startIndexPerLevel);
145
- s[level] = start - pageSize;
146
- setStartIndexPerLevel(s);
147
- }}
148
- >previous</DividerEX>);
149
- }
150
- if (hasMore)
151
- menuItems.push(<DividerEX key="$next" title='Next'
152
- {...clickableDiv}
153
- onClick={() => {
154
- const s = jsonClone(startIndexPerLevel);
155
- s[level] = start + pageSize;
156
- setStartIndexPerLevel(s);
157
- }}
158
- >next</DividerEX>);
159
- }
160
- if (filtered) {
161
- //just filter - no paging
162
- menuItems.splice(0, 0, <Horizontal key='$search'>
163
- <Search defaultValue={myLevelFilter || ""} onChangeDeferred={(newValue) => {
164
- const s = jsonClone(filterPerLevel);
165
- s[level] = newValue ? newValue.toLowerCase() : "";
166
- setFilterPerLevel(s);
167
- }} />
168
- </Horizontal>);
169
- }
170
- return menuItems;
171
- }
172
-
173
- return (
174
- <Menu mountNode={ctx.mountNode} {...props.menuProps} open={opened[0] || false} onOpenChange={(e, data) => {
175
- if (data.open) setOpened({ ...opened, 0: true });
176
- else if (!keepOpen[0]) setOpened({ ...opened, 0: false });
177
- }}>
178
- <MenuTrigger disableButtonEnhancement>
179
- {isString(props.trigger)
180
- ? <ButtonEX title={props.trigger} onClick={(e) => {
181
- stopEvent(e);
182
- }} />
183
- : isString((props.trigger as ButtonEXProps).title)
184
- ? <ButtonEX {...(props.trigger as ButtonEXProps)} onClick={(e) => {
185
- stopEvent(e);
186
- }} />
187
- : props.trigger as JSX.Element}
188
- </MenuTrigger>
189
- <MenuPopover {...props.menuPopOverProps}>
190
- <MenuList {...props.menuListProps}>
191
- {renderItems(props.items, 0)}
192
- </MenuList>
193
- </MenuPopover>
194
- </Menu>
195
- );
196
- }
@@ -1,126 +0,0 @@
1
- import { Drawer, DrawerBody, DrawerHeader, DrawerHeaderTitle, Field, Label, makeStyles, Radio, tokens } from '@fluentui/react-components';
2
- import { DismissRegular, SaveRegular } from '@fluentui/react-icons';
3
- import { isNullOrUndefined, waitFor } from '@kwiz/common';
4
- import { DefaultDarkColors, DefaultLightColors, MisMerge2 } from '@mismerge/react';
5
- import * as React from 'react';
6
-
7
- import '@mismerge/core/dark.css';
8
- import '@mismerge/core/styles.css';
9
- import { useStateEX, useWindowSize } from '../helpers';
10
- import { useKWIZFluentContext } from '../helpers/context-internal';
11
- import { ButtonEX, ButtonEXPrimarySubtle } from './button';
12
- import { Horizontal } from './horizontal';
13
- import { Section } from './section';
14
- import { Vertical } from './vertical';
15
-
16
- const useStyles = makeStyles({
17
- root: {
18
- // position: 'fixed',
19
- // top: 0,
20
- // left: 0,
21
- // right: 0,
22
- // bottom: 0,
23
- // backgroundColor: tokens.colorNeutralBackground1,
24
- // zIndex: 10,
25
- "& .mismerge": {
26
- // height: "100%",
27
- "--background": tokens.colorNeutralBackground1,
28
- //line number background
29
- "--primary-100": tokens.colorNeutralBackground2,
30
- //selection background
31
- "--selection": tokens.colorNeutralBackground1Selected,
32
- //scrollbar hover
33
- "--primary-300": tokens.colorNeutralBackground1Hover,
34
- //border / scroll
35
- "--primary-200": tokens.colorNeutralStroke1,
36
- //line number color
37
- "--primary-400": tokens.colorNeutralForeground2,
38
- //button hover color
39
- "--primary-500": tokens.colorNeutralForeground1Hover,
40
- //main text color
41
- "--primary-600": tokens.colorNeutralForeground1,
42
- "& TEXTAREA": {
43
- lineHeight: "20px"
44
- }
45
- }
46
- },
47
- menu: {
48
- justifyContent: "space-between"
49
- }
50
- });
51
-
52
- interface IProps {
53
- title: string;
54
- description?: string;
55
- lhsTitle: string;
56
- lhsValue: string;
57
- rhsTitle: string;
58
- rhsValue: string;
59
- dark?: boolean;
60
- save: (merged: string) => void;
61
- cancel: () => void;
62
- }
63
- export const MergeText: React.FunctionComponent<React.PropsWithChildren<IProps>> = (props) => {
64
- const classes = useStyles();
65
- const ctx = useKWIZFluentContext();
66
-
67
- let size = useWindowSize();
68
- let wrapper = React.useRef<HTMLDivElement>();
69
- let [lhs, setLhs] = useStateEX(props.lhsValue || "", {
70
- skipUpdateIfSame: true, onChange: (v, changed) => {
71
- if (changed) setKeep("left"); return v;
72
- }
73
- });
74
- let [rhs, setRhs] = useStateEX(props.rhsValue || "", {
75
- skipUpdateIfSame: true, onChange: (v, changed) => {
76
- if (changed) setKeep("right"); return v;
77
- }
78
- });
79
- let [keep, setKeep] = useStateEX<"cancel" | "left" | "right">("cancel");
80
-
81
- React.useEffect(() => {
82
- if (wrapper.current) {
83
- waitFor(() => !isNullOrUndefined(wrapper.current.querySelector(".mismerge"))).then(() => {
84
- let mismerge = wrapper.current.querySelector(".mismerge") as HTMLDivElement;
85
- if (mismerge)
86
- mismerge.style.height = `${mismerge.offsetParent.clientHeight - mismerge.offsetTop - 10}px`;
87
- });
88
- }
89
- }, [wrapper.current, size.height]);
90
-
91
- return <Drawer type='overlay' open size='full' className={classes.root} mountNode={ctx.mountNode}>
92
- <DrawerHeader>
93
- <DrawerHeaderTitle action={<ButtonEX icon={<DismissRegular />} title="Close" onClick={props.cancel} />}>
94
- {props.title}
95
- </DrawerHeaderTitle>
96
- </DrawerHeader>
97
- <DrawerBody>
98
- <Vertical>
99
- {props.description && <Label>{props.description}</Label>}
100
- <Field label="Which version would you like to keep?"
101
- hint="Merge the changes to either side and save. Close this panel to keep editing the page without saving">
102
- <Horizontal css={[classes.menu]}>
103
- <Horizontal nogap>
104
- <Radio value="left" label={props.lhsTitle} checked={keep === "left"} onClick={() => setKeep("left")} />
105
- <ButtonEXPrimarySubtle showTitleWithIcon dontCenterText icon={<SaveRegular />} disabled={keep !== "left"} title={`Save ${props.lhsTitle.toLowerCase()}`} onClick={() => props.save(lhs)} />
106
- </Horizontal>
107
- <Horizontal nogap>
108
- <Radio value="right" label={props.rhsTitle} checked={keep === "right"} onClick={() => setKeep("right")} />
109
- <ButtonEXPrimarySubtle showTitleWithIcon dontCenterText icon={<SaveRegular />} disabled={keep !== "right"} title={`Save ${props.rhsTitle.toLowerCase()}`} onClick={() => props.save(rhs)} />
110
- </Horizontal>
111
- </Horizontal>
112
- </Field>
113
- <Section main ref={wrapper}>
114
- <MisMerge2
115
- lhs={lhs}
116
- rhs={rhs}
117
- lhsEditable rhsEditable
118
- onLhsChange={v => setLhs(v)}
119
- onRhsChange={v => setRhs(v)}
120
- colors={props.dark ? DefaultDarkColors : DefaultLightColors}
121
- />
122
- </Section>
123
- </Vertical>
124
- </DrawerBody>
125
- </Drawer>;
126
- }
@@ -1,33 +0,0 @@
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
- });
@@ -1,110 +0,0 @@
1
- import { DividerProps, makeStyles, mergeClasses, ProgressBar, tokens } from '@fluentui/react-components';
2
- import { CheckmarkRegular, FluentIcon } from '@fluentui/react-icons';
3
- import { isFunction, isNotEmptyString } from '@kwiz/common';
4
- import React from 'react';
5
- import { KnownClassNames } from '../styles/styles';
6
- import { Horizontal } from './horizontal';
7
- import { Section } from './section';
8
- import { Vertical } from './vertical';
9
-
10
- const useStyles = makeStyles({
11
- root: {
12
- position: "relative"
13
- },
14
- stepNumber: {
15
- border: `2px solid ${tokens.colorNeutralStroke1}`,
16
- borderRadius: tokens.borderRadiusCircular,
17
- width: '24px',
18
- height: '24px',
19
- position: 'relative',
20
- display: 'inline-flex',
21
- alignItems: 'center',
22
- justifyContent: 'center',
23
- backgroundColor: tokens.colorNeutralBackground1,
24
- },
25
- stepLabel: {
26
- backgroundColor: tokens.colorNeutralBackground1,
27
- position: "absolute",
28
- top: '-10px',
29
- left: 0,
30
- right: 0,
31
- "& > span": {
32
- whiteSpace: "nowrap",
33
- overflow: "hidden",
34
- textOverflow: "ellipsis",
35
- display: "inline-block"
36
- }
37
- },
38
- stepNumberCurrent: {
39
- border: `2px solid ${tokens.colorBrandBackground}`,
40
- },
41
- stepNumberCompleted: {
42
- border: `2px solid ${tokens.colorBrandBackground}`,
43
- backgroundColor: tokens.colorBrandBackground,
44
- color: tokens.colorNeutralBackground1,
45
- },
46
- stepNumberClickable: {
47
- cursor: "pointer"
48
- },
49
- stepTitle: {
50
- fontSize: tokens.fontSizeBase400,
51
- lineHeight: tokens.lineHeightBase400,
52
- },
53
- progressBar: {
54
- position: "absolute",
55
- top: "14px"
56
- },
57
- stepSpacer: {
58
- position: "relative"
59
- }
60
- });
61
- interface IProps extends DividerProps {
62
- steps: number;
63
- step: number;
64
- stepLabel?: string;
65
- css?: string[];
66
- /** optional, send an icon instead of the step number */
67
- stepIcons?: FluentIcon[];
68
- onStepClick?: (step: number) => void;
69
- }
70
- export const ProgressBarEX = React.forwardRef<HTMLDivElement, (React.PropsWithChildren<IProps>)>((props, ref) => {
71
- const classes = useStyles();
72
-
73
- let stepLabels: JSX.Element[] = [];
74
- for (let i = 0; i < props.steps; i++) {
75
- const stepClasses = [classes.stepNumber];
76
- let addLabel = false;
77
- let canClick = false;
78
- if (props.step === i) {
79
- stepClasses.push(classes.stepNumberCurrent);
80
- if (isNotEmptyString(props.stepLabel))
81
- addLabel = true;
82
- }
83
- else if (props.step > i) {
84
- stepClasses.push(classes.stepNumberCompleted);
85
- canClick = isFunction(props.onStepClick);
86
- if (canClick)
87
- stepClasses.push(classes.stepNumberClickable);
88
- }
89
- let StepIcon = props.stepIcons?.[i];
90
- stepLabels.push(<Section key={`step${i}`} css={stepClasses} onClick={canClick ? () => props.onStepClick(i) : undefined}>{StepIcon ? <StepIcon /> : `${i + 1}`}</Section>);
91
- stepLabels.push(<Section main key={`step${i}Spacer`} css={[classes.stepSpacer]}>
92
- {addLabel && <Horizontal key="label" hCentered css={[classes.stepLabel, KnownClassNames.progressBarStepLabel]}>
93
- <span>{props.stepLabel}</span>
94
- </Horizontal>}
95
- </Section>);
96
-
97
- }
98
-
99
- let StepIcon = props.stepIcons?.[props.steps];
100
- //add last submit step
101
- stepLabels.push(<span key='stepSubmit' className={mergeClasses(classes.stepNumber, props.step === props.steps && classes.stepNumberCompleted)}>{StepIcon ? <StepIcon /> : <CheckmarkRegular />}</span>);
102
-
103
- return (
104
- <Vertical css={[classes.root, ...(props.css || [])]}>
105
- {/* progress bar first so labels will cover it without the need for zindex */}
106
- <ProgressBar className={classes.progressBar} value={(props.step * 2) + 1} max={props.steps * 2} />
107
- <Horizontal css={[classes.stepTitle]}>{...stepLabels}</Horizontal>
108
- </Vertical >
109
- );
110
- });