@kwiz/fluentui 1.0.73 → 1.0.75
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/.github/workflows/npm-publish.yml +24 -24
- package/LICENSE +21 -21
- package/README.md +53 -53
- package/dist/@types/forwardRef.d.ts +0 -0
- package/dist/@types/forwardRef.js +1 -0
- package/dist/@types/forwardRef.js.map +1 -0
- package/dist/controls/error-boundary copy.d.ts +23 -0
- package/dist/controls/error-boundary copy.js +33 -0
- package/dist/controls/error-boundary copy.js.map +1 -0
- package/dist/controls/menu.js +2 -2
- package/dist/controls/menu.js.map +1 -1
- package/dist/controls/search.js +19 -11
- package/dist/controls/search.js.map +1 -1
- package/dist/controls/svg.js +21 -21
- package/dist/controls/svg.js.map +1 -1
- package/dist/helpers/common.d.ts +4 -0
- package/dist/helpers/common.js +2 -0
- package/dist/helpers/common.js.map +1 -0
- package/dist/helpers/context.d.ts +26 -0
- package/dist/helpers/context.js +15 -0
- package/dist/helpers/context.js.map +1 -0
- package/dist/helpers/drag-drop/exports.d.ts +12 -0
- package/dist/helpers/drag-drop/exports.js +3 -0
- package/dist/helpers/drag-drop/exports.js.map +1 -0
- package/dist/helpers/exports.d.ts +7 -0
- package/dist/helpers/exports.js +8 -0
- package/dist/helpers/exports.js.map +1 -0
- package/dist/helpers/use-editable-control.d.ts +1 -1
- package/dist/helpers/use-editable-control.js.map +1 -1
- package/package.json +85 -84
- package/src/_modules/config.ts +9 -9
- package/src/_modules/constants.ts +3 -3
- package/src/controls/ColorPickerDialog.tsx +83 -83
- package/src/controls/accordion.tsx +62 -62
- package/src/controls/button.tsx +180 -180
- package/src/controls/canvas/CustomEventTargetBase.ts +32 -32
- package/src/controls/canvas/DrawPad.tsx +296 -296
- package/src/controls/canvas/DrawPadManager.ts +694 -694
- package/src/controls/canvas/bezier.ts +109 -109
- package/src/controls/canvas/point.ts +44 -44
- package/src/controls/card-list.tsx +31 -31
- package/src/controls/card.tsx +77 -77
- package/src/controls/centered.tsx +14 -14
- package/src/controls/date.tsx +87 -87
- package/src/controls/diagram-picker.tsx +96 -96
- package/src/controls/divider.tsx +15 -15
- package/src/controls/dropdown.tsx +66 -66
- package/src/controls/error-boundary.tsx +41 -41
- package/src/controls/field-editor.tsx +42 -42
- package/src/controls/file-upload.tsx +155 -155
- package/src/controls/horizontal.tsx +48 -48
- package/src/controls/html-editor/editor.tsx +182 -182
- package/src/controls/index.ts +33 -33
- package/src/controls/input.tsx +160 -160
- package/src/controls/kwizoverflow.tsx +106 -106
- package/src/controls/list.tsx +119 -119
- package/src/controls/loading.tsx +10 -10
- package/src/controls/menu.tsx +173 -173
- package/src/controls/merge-text.tsx +126 -126
- package/src/controls/please-wait.tsx +32 -32
- package/src/controls/progress-bar.tsx +109 -109
- package/src/controls/prompt.tsx +121 -121
- package/src/controls/qrcode.tsx +36 -36
- package/src/controls/search.tsx +71 -61
- package/src/controls/section.tsx +133 -133
- package/src/controls/svg.tsx +138 -138
- package/src/controls/toolbar.tsx +46 -46
- package/src/controls/vertical-content.tsx +49 -49
- package/src/controls/vertical.tsx +42 -42
- package/src/helpers/block-nav.tsx +88 -88
- package/src/helpers/context-const.ts +29 -29
- package/src/helpers/context-export.tsx +77 -77
- package/src/helpers/context-internal.ts +13 -13
- package/src/helpers/drag-drop/drag-drop-container.tsx +53 -53
- package/src/helpers/drag-drop/drag-drop-context-internal.tsx +9 -9
- package/src/helpers/drag-drop/drag-drop-context.tsx +61 -61
- package/src/helpers/drag-drop/drag-drop.types.ts +21 -21
- package/src/helpers/drag-drop/index.ts +12 -12
- package/src/helpers/drag-drop/readme.md +75 -75
- package/src/helpers/drag-drop/use-draggable.ts +47 -47
- package/src/helpers/drag-drop/use-droppable.ts +38 -38
- package/src/helpers/forwardRef.ts +7 -7
- package/src/helpers/hooks-events.ts +149 -149
- package/src/helpers/hooks.tsx +141 -141
- package/src/helpers/index.ts +8 -8
- package/src/helpers/use-alerts.tsx +74 -74
- package/src/helpers/use-editable-control.tsx +37 -37
- package/src/helpers/use-toast.tsx +29 -29
- package/src/index.ts +2 -2
- package/src/styles/index.ts +1 -1
- package/src/styles/styles.ts +104 -104
- package/src/styles/theme.ts +90 -90
@@ -1,126 +1,126 @@
|
|
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
|
+
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 +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
|
});
|
@@ -1,110 +1,110 @@
|
|
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
|
-
);
|
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
110
|
});
|