@campxdev/react-blueprint 0.1.23 → 0.1.25
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/.storybook/preview.tsx +0 -1
- package/package.json +2 -1
- package/src/components/DataDisplay/Avatar/Avatar.tsx +70 -0
- package/src/components/DataDisplay/Avatar/CircularAvatar.stories.tsx +27 -0
- package/src/components/DataDisplay/Avatar/SquareAvatar.stories.tsx +47 -0
- package/src/components/DataDisplay/SidePanel/SidePanel.stories.tsx +36 -0
- package/src/components/DataDisplay/SidePanel/SidePanel.tsx +9 -0
- package/src/components/{FeedBack → Feedback}/Spinner/Spinner.stories.tsx +2 -2
- package/src/components/Feedback/Tooltip/Tooltip.stories.tsx +44 -0
- package/src/components/Feedback/Tooltip/Tooltip.tsx +45 -0
- package/src/components/Icons/IconComponents/{TooltipIcon.tsx → BulbIcon.tsx} +4 -4
- package/src/components/Icons/IconComponents/CrossIcon.tsx +25 -0
- package/src/components/Icons/IconComponents/InfoIcon.tsx +1 -1
- package/src/components/Icons/export.ts +4 -2
- package/src/components/Input/Chips/Chips.stories.tsx +54 -0
- package/src/components/Input/Chips/Chips.tsx +44 -0
- package/src/components/Input/HelpButton/HelpButton.stories.tsx +21 -0
- package/src/components/Input/HelpButton/HelpButton.tsx +17 -0
- package/src/components/Input/LabelWrapper/LabelWrapper.tsx +1 -1
- package/src/components/Input/OtpInput/OtpInput.stories.tsx +20 -0
- package/src/components/Input/OtpInput/OtpInput.tsx +85 -0
- package/src/components/Input/RadioGroup/RadioGroup.stories.tsx +1 -3
- package/src/components/Input/RadioGroup/RadioGroup.tsx +2 -1
- package/src/components/Input/SearchBar/SearchBar.stories.tsx +51 -0
- package/src/components/Input/SearchBar/SearchBar.tsx +48 -0
- package/src/components/Input/SingleCheckBox/SIngleCheckBox.tsx +14 -1
- package/src/components/Input/SingleCheckBox/SingleCheckBox.stories.tsx +0 -1
- package/src/components/Input/SingleSelect/SingleSelect.stories.tsx +20 -1
- package/src/components/Input/SingleSelect/SingleSelect.tsx +86 -11
- package/src/components/Input/TextField/TextField.stories.tsx +20 -0
- package/src/components/Input/components/FetchingOptionsLoader.tsx +2 -2
- package/src/components/Layout/Header/AppHeader.stories.tsx +2 -1
- package/src/components/Layout/Header/AppHeader.tsx +6 -6
- package/src/components/Layout/Header/HeaderActions/HeaderActions.tsx +14 -21
- package/src/components/Layout/LayoutWrapper/LayoutWrapper.stories.tsx +1 -1
- package/src/components/Navigation/DropDownMenu/DropDownMenu.stories.tsx +3 -12
- package/src/components/export.ts +2 -0
- package/src/themes/colorTokens.ts +4 -4
- package/src/themes/commonTheme.ts +45 -1
- package/src/utils/campxAxios.ts +1 -3
- package/types/theme.d.ts +7 -0
- /package/src/components/{FeedBack → Feedback}/Spinner/Spinner.css +0 -0
- /package/src/components/{FeedBack → Feedback}/Spinner/Spinner.tsx +0 -0
- /package/src/components/{Modals → Navigation/DialogButton}/DialogButton.stories.tsx +0 -0
- /package/src/components/{Modals → Navigation/DialogButton}/DialogButton.tsx +0 -0
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
StackProps,
|
|
7
7
|
} from "@mui/material";
|
|
8
8
|
import { ReactNode } from "react";
|
|
9
|
+
import { Typography } from "../../DataDisplay/Typography/Typography";
|
|
9
10
|
import { Icons } from "../../export";
|
|
10
11
|
import { LabelWrapper } from "../LabelWrapper/LabelWrapper";
|
|
11
12
|
|
|
@@ -47,7 +48,7 @@ export const RadioGroup = ({
|
|
|
47
48
|
disabled={disabled || item.disabled}
|
|
48
49
|
/>
|
|
49
50
|
}
|
|
50
|
-
label={item.label}
|
|
51
|
+
label={<Typography variant="body2">{item.label}</Typography>}
|
|
51
52
|
/>
|
|
52
53
|
))}
|
|
53
54
|
</MuiRadioGroup>
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { Meta, StoryObj } from "@storybook/react/*";
|
|
2
|
+
import { SearchBar } from "./SearchBar";
|
|
3
|
+
|
|
4
|
+
const meta: Meta<typeof SearchBar> = {
|
|
5
|
+
title: "Input/SearchBar",
|
|
6
|
+
component: SearchBar,
|
|
7
|
+
argTypes: {
|
|
8
|
+
placeholder: {
|
|
9
|
+
description: "The placeholder text",
|
|
10
|
+
},
|
|
11
|
+
label: {
|
|
12
|
+
description: "Can be a ReactNode or String",
|
|
13
|
+
},
|
|
14
|
+
value: {
|
|
15
|
+
description: "Current value of the search input.",
|
|
16
|
+
},
|
|
17
|
+
onSearch: {
|
|
18
|
+
description: "Function to handle search",
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
export default meta;
|
|
23
|
+
|
|
24
|
+
type Story = StoryObj<typeof SearchBar>;
|
|
25
|
+
|
|
26
|
+
export const Primary: Story = {
|
|
27
|
+
args: {
|
|
28
|
+
onSearch: (value: string) => console.log(value),
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export const WithPlaceHolder: Story = {
|
|
33
|
+
args: {
|
|
34
|
+
...Primary.args,
|
|
35
|
+
placeholder: "Search By Name/Email",
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export const WithLabel: Story = {
|
|
40
|
+
args: {
|
|
41
|
+
...Primary.args,
|
|
42
|
+
label: "Searching Students",
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
export const WithValue: Story = {
|
|
47
|
+
args: {
|
|
48
|
+
...WithLabel.args,
|
|
49
|
+
value: "Chrome",
|
|
50
|
+
},
|
|
51
|
+
};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { Search } from "@mui/icons-material";
|
|
2
|
+
import { InputAdornment } from "@mui/material";
|
|
3
|
+
import { debounce } from "lodash";
|
|
4
|
+
import { ReactNode, useMemo, useState } from "react";
|
|
5
|
+
import { TextField, TextFieldProps } from "../TextField/TextField";
|
|
6
|
+
|
|
7
|
+
export type SearchBarProps = {
|
|
8
|
+
placeholder?: string;
|
|
9
|
+
label?: string | ReactNode;
|
|
10
|
+
value?: string;
|
|
11
|
+
onSearch: (value: string) => void;
|
|
12
|
+
} & TextFieldProps;
|
|
13
|
+
|
|
14
|
+
export const SearchBar = ({
|
|
15
|
+
placeholder = "Search",
|
|
16
|
+
label,
|
|
17
|
+
value = "",
|
|
18
|
+
onSearch,
|
|
19
|
+
...rest
|
|
20
|
+
}: SearchBarProps) => {
|
|
21
|
+
const [search, setSearch] = useState(value);
|
|
22
|
+
|
|
23
|
+
const debouncedSendRequest = useMemo(() => {
|
|
24
|
+
return debounce(onSearch, 300);
|
|
25
|
+
}, [onSearch]);
|
|
26
|
+
|
|
27
|
+
const handleChange = (e: any) => {
|
|
28
|
+
setSearch(e.target.value);
|
|
29
|
+
debouncedSendRequest(e.target.value);
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
return (
|
|
33
|
+
<TextField
|
|
34
|
+
placeholder={placeholder}
|
|
35
|
+
label={label}
|
|
36
|
+
value={search}
|
|
37
|
+
InputProps={{
|
|
38
|
+
endAdornment: (
|
|
39
|
+
<InputAdornment position="end">
|
|
40
|
+
<Search />
|
|
41
|
+
</InputAdornment>
|
|
42
|
+
),
|
|
43
|
+
}}
|
|
44
|
+
{...rest}
|
|
45
|
+
onChange={handleChange}
|
|
46
|
+
/>
|
|
47
|
+
);
|
|
48
|
+
};
|
|
@@ -2,8 +2,10 @@ import {
|
|
|
2
2
|
FormControlLabel,
|
|
3
3
|
Checkbox as MuiCheckbox,
|
|
4
4
|
CheckboxProps as MuiCheckboxProps,
|
|
5
|
+
useTheme,
|
|
5
6
|
} from "@mui/material";
|
|
6
7
|
import { ReactNode } from "react";
|
|
8
|
+
import { Typography } from "../../DataDisplay/Typography/Typography";
|
|
7
9
|
import { Icons } from "../../export";
|
|
8
10
|
|
|
9
11
|
export type CheckboxProps = {
|
|
@@ -14,8 +16,10 @@ export const SingleCheckBox = ({
|
|
|
14
16
|
checked,
|
|
15
17
|
label,
|
|
16
18
|
onChange,
|
|
19
|
+
required,
|
|
17
20
|
...rest
|
|
18
21
|
}: CheckboxProps) => {
|
|
22
|
+
const theme = useTheme();
|
|
19
23
|
return (
|
|
20
24
|
<FormControlLabel
|
|
21
25
|
control={
|
|
@@ -27,7 +31,16 @@ export const SingleCheckBox = ({
|
|
|
27
31
|
{...rest}
|
|
28
32
|
/>
|
|
29
33
|
}
|
|
30
|
-
label={
|
|
34
|
+
label={
|
|
35
|
+
<Typography variant="body2">
|
|
36
|
+
{label}
|
|
37
|
+
{required && (
|
|
38
|
+
<span style={{ color: `${theme.palette.highlight.main}` }}>
|
|
39
|
+
{" *"}
|
|
40
|
+
</span>
|
|
41
|
+
)}
|
|
42
|
+
</Typography>
|
|
43
|
+
}
|
|
31
44
|
/>
|
|
32
45
|
);
|
|
33
46
|
};
|
|
@@ -82,7 +82,6 @@ export const Default = {
|
|
|
82
82
|
args: {
|
|
83
83
|
required: true,
|
|
84
84
|
label: "Single Select",
|
|
85
|
-
options: topFilms,
|
|
86
85
|
},
|
|
87
86
|
};
|
|
88
87
|
export const Primary = {
|
|
@@ -102,3 +101,23 @@ export const WithAPIEndPoint = {
|
|
|
102
101
|
required: false,
|
|
103
102
|
},
|
|
104
103
|
};
|
|
104
|
+
|
|
105
|
+
export const SingleSelectWithValue = {
|
|
106
|
+
render: (args: SingleSelectProps) => <SingleSelect {...args} />,
|
|
107
|
+
args: {
|
|
108
|
+
label: "Select Select",
|
|
109
|
+
options: topFilms,
|
|
110
|
+
required: true,
|
|
111
|
+
value: 1994,
|
|
112
|
+
},
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
export const SingleSelectWithValueAndApi = {
|
|
116
|
+
render: (args: SingleSelectProps) => <SingleSelect {...args} />,
|
|
117
|
+
args: {
|
|
118
|
+
optionsApiEndPoint: "dropdowns/classrooms",
|
|
119
|
+
label: "Select Classroom",
|
|
120
|
+
required: true,
|
|
121
|
+
value: 1,
|
|
122
|
+
},
|
|
123
|
+
};
|
|
@@ -3,13 +3,14 @@ import {
|
|
|
3
3
|
Autocomplete as MuiAutocomplete,
|
|
4
4
|
Paper,
|
|
5
5
|
PaperProps,
|
|
6
|
-
TextField,
|
|
7
6
|
} from "@mui/material";
|
|
8
7
|
import axios from "axios";
|
|
9
|
-
import
|
|
8
|
+
import _ from "lodash";
|
|
9
|
+
import { useEffect, useReducer } from "react";
|
|
10
10
|
import { campxAxios } from "../../../utils/campxAxios";
|
|
11
11
|
import { Typography } from "../../DataDisplay/Typography/Typography";
|
|
12
|
-
import {
|
|
12
|
+
import { Spinner } from "../../Feedback/Spinner/Spinner";
|
|
13
|
+
import { TextField } from "../TextField/TextField";
|
|
13
14
|
import { FetchingOptionsLoader } from "../components/FetchingOptionsLoader";
|
|
14
15
|
import { OptionContainer } from "../styles";
|
|
15
16
|
|
|
@@ -21,13 +22,15 @@ function sleep(duration: number): Promise<void> {
|
|
|
21
22
|
});
|
|
22
23
|
}
|
|
23
24
|
|
|
24
|
-
export
|
|
25
|
-
options?: { label: string; subLabel?: string; value: any }[];
|
|
25
|
+
export type SingleSelectProps = {
|
|
26
|
+
options?: { label: string; subLabel?: string; value: any }[] | any[];
|
|
26
27
|
optionsApiEndPoint?: string;
|
|
27
28
|
useCampxAxios: boolean;
|
|
28
29
|
required?: boolean;
|
|
29
30
|
label?: string;
|
|
30
|
-
|
|
31
|
+
value?: any;
|
|
32
|
+
getValue?: (option: any) => any;
|
|
33
|
+
};
|
|
31
34
|
|
|
32
35
|
const CustomPaper = (props: PaperProps) => (
|
|
33
36
|
<Paper {...props}>
|
|
@@ -41,6 +44,8 @@ enum SingleSelectActionsTypes {
|
|
|
41
44
|
CLOSE = "close",
|
|
42
45
|
LOAD_INTERNAL_OPTIONS_START = "load_internal_options_start",
|
|
43
46
|
LOAD_INTERNAL_OPTIONS_END = "load_internal_options_end",
|
|
47
|
+
LOAD_INITIAL_INTERNAL_OPTIONS_START = "load_initial_internal_options_start",
|
|
48
|
+
LOAD_INITIAL_INTERNAL_OPTIONS_END = "load_initial_internal_options_end",
|
|
44
49
|
SET_NETWORK_ERROR = "set_network_error",
|
|
45
50
|
SET_INTERNAL_OPTIONS = "set_internal_options",
|
|
46
51
|
APPEND_INTERNAL_OPTIONS = "append_internal_options",
|
|
@@ -66,6 +71,12 @@ const singleSelectReducer = (
|
|
|
66
71
|
case SingleSelectActionsTypes.LOAD_INTERNAL_OPTIONS_END: {
|
|
67
72
|
return { ...state, loadingInternalOptions: false };
|
|
68
73
|
}
|
|
74
|
+
case SingleSelectActionsTypes.LOAD_INITIAL_INTERNAL_OPTIONS_START: {
|
|
75
|
+
return { ...state, loadingInitialInternalOptions: true };
|
|
76
|
+
}
|
|
77
|
+
case SingleSelectActionsTypes.LOAD_INITIAL_INTERNAL_OPTIONS_END: {
|
|
78
|
+
return { ...state, loadingInitialInternalOptions: false };
|
|
79
|
+
}
|
|
69
80
|
case SingleSelectActionsTypes.SET_NETWORK_ERROR: {
|
|
70
81
|
return { ...state, ...stateChanges };
|
|
71
82
|
}
|
|
@@ -73,6 +84,7 @@ const singleSelectReducer = (
|
|
|
73
84
|
return {
|
|
74
85
|
...state,
|
|
75
86
|
internalOptions: stateChanges.internalOptions,
|
|
87
|
+
internalOptionsMap: stateChanges.internalOptionsMap,
|
|
76
88
|
loadingInternalOptions: false,
|
|
77
89
|
};
|
|
78
90
|
}
|
|
@@ -80,6 +92,10 @@ const singleSelectReducer = (
|
|
|
80
92
|
return {
|
|
81
93
|
...state,
|
|
82
94
|
internalOptions: [...state.internalOptions, ...stateChanges.newOptions],
|
|
95
|
+
internalOptionsMap: {
|
|
96
|
+
...state.internalOptionsMap,
|
|
97
|
+
...stateChanges.internalOptionsMap,
|
|
98
|
+
},
|
|
83
99
|
loadingInternalOptions: false,
|
|
84
100
|
limit: state.limit,
|
|
85
101
|
offset: state.offset + 10,
|
|
@@ -102,11 +118,19 @@ export const SingleSelect = ({
|
|
|
102
118
|
useCampxAxios = true,
|
|
103
119
|
required = false,
|
|
104
120
|
label,
|
|
121
|
+
getValue,
|
|
122
|
+
value,
|
|
105
123
|
}: SingleSelectProps) => {
|
|
124
|
+
const generateOptionsMap = (options: any[]) => {
|
|
125
|
+
return _.keyBy(options ?? [], getValue ? getValue : (o) => o.value);
|
|
126
|
+
};
|
|
127
|
+
|
|
106
128
|
const [state, dispatch] = useReducer(singleSelectReducer, {
|
|
107
129
|
open: false,
|
|
108
130
|
loadingInternalOptions: false,
|
|
131
|
+
loadingInitialInternalOptions: false,
|
|
109
132
|
internalOptions: options ?? [],
|
|
133
|
+
internalOptionsMap: generateOptionsMap(options ?? []),
|
|
110
134
|
limit: 10,
|
|
111
135
|
offset: 0,
|
|
112
136
|
hasMore: true,
|
|
@@ -114,6 +138,7 @@ export const SingleSelect = ({
|
|
|
114
138
|
const {
|
|
115
139
|
open,
|
|
116
140
|
loadingInternalOptions,
|
|
141
|
+
loadingInitialInternalOptions,
|
|
117
142
|
internalOptions,
|
|
118
143
|
limit,
|
|
119
144
|
offset,
|
|
@@ -144,6 +169,7 @@ export const SingleSelect = ({
|
|
|
144
169
|
actionType: SingleSelectActionsTypes.SET_INTERNAL_OPTIONS,
|
|
145
170
|
stateChanges: {
|
|
146
171
|
internalOptions: options,
|
|
172
|
+
internalOptionsMap: generateOptionsMap(options),
|
|
147
173
|
},
|
|
148
174
|
});
|
|
149
175
|
} catch (e) {
|
|
@@ -165,7 +191,8 @@ export const SingleSelect = ({
|
|
|
165
191
|
if (
|
|
166
192
|
listboxNode.scrollTop + listboxNode.clientHeight >=
|
|
167
193
|
listboxNode.scrollHeight - 1 &&
|
|
168
|
-
hasMore
|
|
194
|
+
hasMore &&
|
|
195
|
+
optionsApiEndPoint
|
|
169
196
|
) {
|
|
170
197
|
dispatch({
|
|
171
198
|
actionType: SingleSelectActionsTypes.LOAD_INTERNAL_OPTIONS_START,
|
|
@@ -188,19 +215,67 @@ export const SingleSelect = ({
|
|
|
188
215
|
actionType: SingleSelectActionsTypes.APPEND_INTERNAL_OPTIONS,
|
|
189
216
|
stateChanges: {
|
|
190
217
|
newOptions: newOptions,
|
|
218
|
+
internalOptionsMap: generateOptionsMap(newOptions),
|
|
191
219
|
},
|
|
192
220
|
});
|
|
193
221
|
}
|
|
194
222
|
};
|
|
195
223
|
|
|
224
|
+
const fetchInitialOptions = async () => {
|
|
225
|
+
dispatch({
|
|
226
|
+
actionType: SingleSelectActionsTypes.LOAD_INITIAL_INTERNAL_OPTIONS_START,
|
|
227
|
+
});
|
|
228
|
+
try {
|
|
229
|
+
const res = await internalAxios.get(optionsApiEndPoint ?? "", {
|
|
230
|
+
params: { limit, offset, selectedValue: value },
|
|
231
|
+
});
|
|
232
|
+
dispatch({
|
|
233
|
+
actionType: SingleSelectActionsTypes.SET_INTERNAL_OPTIONS,
|
|
234
|
+
stateChanges: {
|
|
235
|
+
internalOptions: res.data,
|
|
236
|
+
internalOptionsMap: generateOptionsMap(res.data),
|
|
237
|
+
},
|
|
238
|
+
});
|
|
239
|
+
await sleep(1000);
|
|
240
|
+
} catch (e) {
|
|
241
|
+
dispatch({
|
|
242
|
+
actionType: SingleSelectActionsTypes.SET_NETWORK_ERROR,
|
|
243
|
+
stateChanges: { error: e },
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
};
|
|
247
|
+
|
|
248
|
+
useEffect(() => {
|
|
249
|
+
console.log("useEffect");
|
|
250
|
+
if (value && optionsApiEndPoint) {
|
|
251
|
+
fetchInitialOptions().finally(() => {
|
|
252
|
+
dispatch({
|
|
253
|
+
actionType:
|
|
254
|
+
SingleSelectActionsTypes.LOAD_INITIAL_INTERNAL_OPTIONS_END,
|
|
255
|
+
});
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
}, []);
|
|
259
|
+
|
|
260
|
+
if (loadingInitialInternalOptions) {
|
|
261
|
+
console.log("Rendered Loading");
|
|
262
|
+
return (
|
|
263
|
+
<TextField
|
|
264
|
+
label={label}
|
|
265
|
+
required={required}
|
|
266
|
+
InputProps={{
|
|
267
|
+
endAdornment: <Spinner />,
|
|
268
|
+
}}
|
|
269
|
+
/>
|
|
270
|
+
);
|
|
271
|
+
}
|
|
196
272
|
return (
|
|
197
273
|
<MuiAutocomplete
|
|
198
274
|
open={open}
|
|
199
|
-
|
|
275
|
+
autoFocus={true}
|
|
276
|
+
value={state.internalOptionsMap[value]}
|
|
200
277
|
renderInput={(params) => (
|
|
201
|
-
<
|
|
202
|
-
<TextField {...params} />
|
|
203
|
-
</LabelWrapper>
|
|
278
|
+
<TextField {...params} label={label} required={required} />
|
|
204
279
|
)}
|
|
205
280
|
PaperComponent={CustomPaper}
|
|
206
281
|
renderOption={(props, option: any) => {
|
|
@@ -3,6 +3,9 @@ import { Meta } from "@storybook/react";
|
|
|
3
3
|
|
|
4
4
|
// Make sure your TextField import is correct
|
|
5
5
|
import { TextField, TextFieldProps } from "./TextField";
|
|
6
|
+
import { ToolTipContent, Tooltip } from "../../Feedback/Tooltip/Tooltip";
|
|
7
|
+
import { InputAdornment as MuiInputAdornment } from "@mui/material";
|
|
8
|
+
import { InfoIcon } from "../../Icons/IconComponents/InfoIcon";
|
|
6
9
|
|
|
7
10
|
// Define the default export with Meta type including the component type
|
|
8
11
|
export default {
|
|
@@ -133,3 +136,20 @@ export const PassowrdInput = {
|
|
|
133
136
|
helperText: "Password should be alpha-numeric with special character",
|
|
134
137
|
},
|
|
135
138
|
};
|
|
139
|
+
|
|
140
|
+
export const InfoInput = {
|
|
141
|
+
render: (args: TextFieldProps) => <TextField {...args} />,
|
|
142
|
+
args: {
|
|
143
|
+
label: "Info",
|
|
144
|
+
required: true,
|
|
145
|
+
InputProps: {
|
|
146
|
+
endAdornment: (
|
|
147
|
+
<MuiInputAdornment position="end">
|
|
148
|
+
<Tooltip title={<ToolTipContent message={"This is the info tooltip !! This is the info tooltip !! This is the info tooltip !!"} />}>
|
|
149
|
+
<InfoIcon />
|
|
150
|
+
</Tooltip>
|
|
151
|
+
</MuiInputAdornment>
|
|
152
|
+
),
|
|
153
|
+
},
|
|
154
|
+
},
|
|
155
|
+
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Typography } from "../../DataDisplay/Typography/Typography";
|
|
2
|
-
import { Spinner } from "../../
|
|
2
|
+
import { Spinner } from "../../Feedback/Spinner/Spinner";
|
|
3
3
|
import { FetchingOptionsLoaderContainer } from "../styles";
|
|
4
4
|
|
|
5
5
|
export const FetchingOptionsLoader = ({ loading }: { loading: boolean }) => {
|
|
@@ -11,4 +11,4 @@ export const FetchingOptionsLoader = ({ loading }: { loading: boolean }) => {
|
|
|
11
11
|
</FetchingOptionsLoaderContainer>
|
|
12
12
|
)
|
|
13
13
|
);
|
|
14
|
-
};
|
|
14
|
+
};
|
|
@@ -4,6 +4,7 @@ import { DropdownMenuItem } from "../../Navigation/DropDownMenu/DropdownMenuItem
|
|
|
4
4
|
import { Icons } from "../../export";
|
|
5
5
|
import { AppHeader, AppHeaderProps } from "./AppHeader";
|
|
6
6
|
import { AppsMenu } from "./AppsMenu";
|
|
7
|
+
import HelpButton from "../../Input/HelpButton/HelpButton";
|
|
7
8
|
|
|
8
9
|
// Define the default export with Meta type including the component type
|
|
9
10
|
const meta: Meta<typeof AppHeader> = {
|
|
@@ -129,6 +130,7 @@ export const WithActions: Story = {
|
|
|
129
130
|
<IconButton>
|
|
130
131
|
<Icons.ExamResultIcon />
|
|
131
132
|
</IconButton>,
|
|
133
|
+
<HelpButton />,
|
|
132
134
|
],
|
|
133
135
|
userBoxActions: [
|
|
134
136
|
{ label: "Action 1", onClick: () => alert("Action 1 clicked") },
|
|
@@ -137,7 +139,6 @@ export const WithActions: Story = {
|
|
|
137
139
|
},
|
|
138
140
|
};
|
|
139
141
|
|
|
140
|
-
// Story with custom header actions
|
|
141
142
|
export const WithCustomHeaderActions: Story = {
|
|
142
143
|
render: (args: AppHeaderProps) => <AppHeader {...args} />,
|
|
143
144
|
args: {
|
|
@@ -10,11 +10,11 @@ import {
|
|
|
10
10
|
|
|
11
11
|
export interface AppHeaderProps {
|
|
12
12
|
actions?: ReactNode[];
|
|
13
|
-
appsMenu
|
|
14
|
-
clientLogo
|
|
13
|
+
appsMenu?: ReactNode;
|
|
14
|
+
clientLogo?: string;
|
|
15
15
|
cogWheelMenu?: ReactNode[];
|
|
16
16
|
customHeaderActions?: ReactNode;
|
|
17
|
-
fullName
|
|
17
|
+
fullName?: string;
|
|
18
18
|
designation?: string;
|
|
19
19
|
profileUrl?: string;
|
|
20
20
|
userBoxActions?: {
|
|
@@ -48,7 +48,7 @@ export const AppHeader = ({
|
|
|
48
48
|
<StyledContainer sx={containerSx}>
|
|
49
49
|
<Stack alignItems={"center"} gap={"10px"} flexDirection={"row"}>
|
|
50
50
|
{appsMenu}
|
|
51
|
-
<AppLogo clientLogo={clientLogo} imageSx={imageSx} />
|
|
51
|
+
<AppLogo clientLogo={clientLogo ?? ""} imageSx={imageSx} />
|
|
52
52
|
</Stack>
|
|
53
53
|
<StyledActionBox>
|
|
54
54
|
{customHeaderActions ? (
|
|
@@ -56,10 +56,10 @@ export const AppHeader = ({
|
|
|
56
56
|
) : (
|
|
57
57
|
<HeaderActions
|
|
58
58
|
cogWheelMenu={cogWheelMenu}
|
|
59
|
-
fullName={fullName}
|
|
59
|
+
fullName={fullName ?? ""}
|
|
60
60
|
designation={designation}
|
|
61
61
|
userBoxActions={userBoxActions}
|
|
62
|
-
profileUrl={profileUrl}
|
|
62
|
+
profileUrl={profileUrl ?? ""}
|
|
63
63
|
actions={actions}
|
|
64
64
|
profileSx={profileSx}
|
|
65
65
|
/>
|
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
import { Divider,
|
|
1
|
+
import { Divider, Stack } from "@mui/material";
|
|
2
2
|
import { ReactNode } from "react";
|
|
3
|
-
// import { IMenuItemProps } from '../../../DropDownButton/DropdownMenuItem'
|
|
4
|
-
// import InstitutionsDropDown from '../../../Institutions/InstitutionsDropdown'
|
|
5
|
-
import { Icons } from "../../../export";
|
|
6
3
|
import CogWheelMenu from "./CogWheelMenu";
|
|
7
4
|
import UserBox from "./UserBox";
|
|
8
5
|
|
|
@@ -17,7 +14,7 @@ export interface HeaderActionsProps {
|
|
|
17
14
|
}[];
|
|
18
15
|
profileUrl: string | undefined;
|
|
19
16
|
actions?: ReactNode[];
|
|
20
|
-
profileSx?: any;
|
|
17
|
+
profileSx?: any; // Making HelpButton prop optional
|
|
21
18
|
}
|
|
22
19
|
|
|
23
20
|
const HeaderActions = ({
|
|
@@ -30,28 +27,24 @@ const HeaderActions = ({
|
|
|
30
27
|
profileSx = {},
|
|
31
28
|
}: HeaderActionsProps) => {
|
|
32
29
|
return (
|
|
33
|
-
<Stack direction="row" gap={1} alignItems=
|
|
34
|
-
|
|
35
|
-
href={"https://campx.atlassian.net/servicedesk/customer/portal/2"}
|
|
36
|
-
target="_blank"
|
|
37
|
-
>
|
|
38
|
-
<Icons.HelpIcon />
|
|
39
|
-
</IconButton>
|
|
40
|
-
|
|
30
|
+
<Stack direction="row" gap={1} alignItems="center">
|
|
31
|
+
{/* Render other actions */}
|
|
41
32
|
{actions.map((action, index) => (
|
|
42
33
|
<>
|
|
43
|
-
<div>
|
|
44
|
-
<Divider
|
|
45
|
-
orientation="vertical"
|
|
46
|
-
variant="middle"
|
|
47
|
-
flexItem
|
|
48
|
-
sx={{ height: "20px" }}
|
|
49
|
-
/>
|
|
50
|
-
</div>
|
|
51
34
|
{action}
|
|
35
|
+
<Divider
|
|
36
|
+
orientation="vertical"
|
|
37
|
+
variant="middle"
|
|
38
|
+
flexItem
|
|
39
|
+
sx={{ height: "20px" }}
|
|
40
|
+
/>
|
|
52
41
|
</>
|
|
53
42
|
))}
|
|
43
|
+
|
|
44
|
+
{/* Render cogWheelMenu if provided */}
|
|
54
45
|
{cogWheelMenu?.length ? <CogWheelMenu menu={cogWheelMenu} /> : null}
|
|
46
|
+
|
|
47
|
+
{/* Render UserBox */}
|
|
55
48
|
<UserBox
|
|
56
49
|
fullName={fullName}
|
|
57
50
|
designation={designation}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Button, Stack } from "@mui/material";
|
|
2
2
|
import { Meta, StoryObj } from "@storybook/react";
|
|
3
|
-
import DialogButton from "../../
|
|
3
|
+
import DialogButton from "../../Navigation/DialogButton/DialogButton";
|
|
4
4
|
import { Icons } from "../../export";
|
|
5
5
|
import { PageContent } from "../PageContent/PageContent";
|
|
6
6
|
import { SideNavigation } from "../SideNavigation/SideNavigation";
|
|
@@ -50,17 +50,10 @@ export const Primary: Story = {
|
|
|
50
50
|
<DropdownMenuItem
|
|
51
51
|
icon={<Icons.HelpIcon />}
|
|
52
52
|
label={"Register"}
|
|
53
|
-
onClick={() => {
|
|
54
|
-
console.log("hi");
|
|
55
|
-
}}
|
|
53
|
+
onClick={() => {}}
|
|
56
54
|
/>,
|
|
57
55
|
|
|
58
|
-
<DropdownMenuItem
|
|
59
|
-
label={"Active Devices"}
|
|
60
|
-
onClick={() => {
|
|
61
|
-
console.log("hi");
|
|
62
|
-
}}
|
|
63
|
-
/>,
|
|
56
|
+
<DropdownMenuItem label={"Active Devices"} onClick={() => {}} />,
|
|
64
57
|
],
|
|
65
58
|
menuListProps: {
|
|
66
59
|
sx: { width: "20px" },
|
|
@@ -94,9 +87,7 @@ export const WithButtonLoading: Story = {
|
|
|
94
87
|
<DropdownMenuItem
|
|
95
88
|
icon={<Icons.HelpIcon />}
|
|
96
89
|
label={"Register"}
|
|
97
|
-
onClick={() => {
|
|
98
|
-
console.log("hi");
|
|
99
|
-
}}
|
|
90
|
+
onClick={() => {}}
|
|
100
91
|
/>,
|
|
101
92
|
],
|
|
102
93
|
},
|
package/src/components/export.ts
CHANGED
|
@@ -10,4 +10,6 @@ export * from "./Layout/LayoutWrapper/LayoutWrapper";
|
|
|
10
10
|
export * from "./Layout/PageContent/PageContent";
|
|
11
11
|
export * from "./Layout/SideNavigation/SideNavigation";
|
|
12
12
|
export * from "./Navigation/DropDownMenu/DropDownButton";
|
|
13
|
+
export * from "./Navigation/DropDownMenu/DropDownIcon";
|
|
13
14
|
export * from "./Navigation/DropDownMenu/DropDownMenu";
|
|
15
|
+
export * from "./Navigation/DropDownMenu/DropdownMenuItem";
|
|
@@ -21,10 +21,10 @@ export const LightColorTokens = {
|
|
|
21
21
|
main: "#88B053",
|
|
22
22
|
},
|
|
23
23
|
error: {
|
|
24
|
-
main: "F2353C",
|
|
24
|
+
main: "#F2353C",
|
|
25
25
|
},
|
|
26
26
|
warning: {
|
|
27
|
-
main: "ED9035",
|
|
27
|
+
main: "#ED9035",
|
|
28
28
|
},
|
|
29
29
|
info: {
|
|
30
30
|
main: "#4BAABE",
|
|
@@ -60,10 +60,10 @@ export const DarkColorTokens = {
|
|
|
60
60
|
main: "#88B053",
|
|
61
61
|
},
|
|
62
62
|
error: {
|
|
63
|
-
main: "F2353C",
|
|
63
|
+
main: "#F2353C",
|
|
64
64
|
},
|
|
65
65
|
warning: {
|
|
66
|
-
main: "ED9035",
|
|
66
|
+
main: "#ED9035",
|
|
67
67
|
},
|
|
68
68
|
info: {
|
|
69
69
|
main: "#4BAABE",
|