@bigmath-ui-library/core 2.0.4
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/LICENSE +7 -0
- package/LICENSE.md +1 -0
- package/README.md +42 -0
- package/dist/cjs/index.css +11 -0
- package/dist/cjs/index.js +134365 -0
- package/dist/esm/index.css +11 -0
- package/dist/esm/index.js +134258 -0
- package/package.json +58 -0
- package/rollup.config.js +73 -0
- package/src/BMClassnameSetup.ts +3 -0
- package/src/assets/icons/Calendar.svg +6 -0
- package/src/assets/icons/Close.svg +40 -0
- package/src/assets/icons/Default-Loading-Circles.svg +31 -0
- package/src/assets/icons/alert.svg +6 -0
- package/src/assets/icons/aws.svg +19 -0
- package/src/assets/icons/caret-down.svg +3 -0
- package/src/assets/icons/check.svg +6 -0
- package/src/assets/icons/circle-check-solid.svg +7 -0
- package/src/assets/icons/circle-check.svg +6 -0
- package/src/assets/icons/circle-selected.svg +3 -0
- package/src/assets/icons/circle-unselected.svg +3 -0
- package/src/assets/icons/close-basic.svg +3 -0
- package/src/assets/icons/close_collapse.svg +3 -0
- package/src/assets/icons/copy.svg +3 -0
- package/src/assets/icons/drag.svg +3 -0
- package/src/assets/icons/expand-more.svg +3 -0
- package/src/assets/icons/failed-solid.svg +7 -0
- package/src/assets/icons/globe.svg +3 -0
- package/src/assets/icons/google-cloud.svg +6 -0
- package/src/assets/icons/in-active.svg +4 -0
- package/src/assets/icons/info-solid.svg +6 -0
- package/src/assets/icons/info.svg +6 -0
- package/src/assets/icons/k8s.svg +4 -0
- package/src/assets/icons/lock-locked.svg +5 -0
- package/src/assets/icons/microsoft-azure.svg +9 -0
- package/src/assets/icons/onprem.svg +3 -0
- package/src/assets/icons/pencil.svg +3 -0
- package/src/assets/icons/search.svg +6 -0
- package/src/assets/icons/shield.svg +4 -0
- package/src/assets/icons/star.svg +3 -0
- package/src/assets/icons/success-tick.svg +3 -0
- package/src/assets/icons/timer.svg +3 -0
- package/src/assets/icons/visibility-off.svg +6 -0
- package/src/assets/icons/visibility.svg +6 -0
- package/src/assets/icons/warning.svg +6 -0
- package/src/bma/components/BMButton/BMButton.tsx +34 -0
- package/src/bma/components/BMButton/index.ts +1 -0
- package/src/bma/components/BMInput/BMInput.tsx +13 -0
- package/src/bma/components/BMInput/BMInputField.tsx +7 -0
- package/src/bma/components/BMInput/BMSearch.tsx +6 -0
- package/src/bma/components/BMInput/index.ts +3 -0
- package/src/bma/index.ts +3 -0
- package/src/bma/package.json +4 -0
- package/src/bma/theme/BMAutocomplete.ts +12 -0
- package/src/bma/theme/BMInput.ts +46 -0
- package/src/bma/theme/theme.ts +15 -0
- package/src/bma/theme/themeUtils.ts +10 -0
- package/src/components/BMAccordion/BMAccordion.tsx +150 -0
- package/src/components/BMAccordion/index.ts +1 -0
- package/src/components/BMAddSection/BMAddSection.tsx +38 -0
- package/src/components/BMAddSection/index.ts +1 -0
- package/src/components/BMAlert/BMAlert.tsx +168 -0
- package/src/components/BMAlert/index.ts +1 -0
- package/src/components/BMAutoComplete/BMAutoComplete.tsx +86 -0
- package/src/components/BMAutoComplete/index.ts +1 -0
- package/src/components/BMAvatar/BMAvatar.tsx +45 -0
- package/src/components/BMAvatar/index.ts +1 -0
- package/src/components/BMButton/BMButton.tsx +46 -0
- package/src/components/BMButton/BMButtonGroup.tsx +46 -0
- package/src/components/BMButton/BMSplitButton.tsx +72 -0
- package/src/components/BMButton/index.ts +3 -0
- package/src/components/BMCheckbox/BMCheckbox.tsx +44 -0
- package/src/components/BMCheckbox/BMCheckboxField.tsx +41 -0
- package/src/components/BMCheckbox/index.ts +2 -0
- package/src/components/BMCloudSelect/BMCloudList.tsx +43 -0
- package/src/components/BMCloudSelect/BMCloudSelect.tsx +109 -0
- package/src/components/BMCloudSelect/BMCloudSelectField.tsx +46 -0
- package/src/components/BMCloudSelect/index.ts +3 -0
- package/src/components/BMCodeBlock/BMCodeBlock.tsx +233 -0
- package/src/components/BMCodeBlock/index.ts +1 -0
- package/src/components/BMDatePicker/BMDatePicker.tsx +187 -0
- package/src/components/BMDatePicker/index.ts +1 -0
- package/src/components/BMDropdown/BMDropdown.tsx +107 -0
- package/src/components/BMDropdown/index.ts +1 -0
- package/src/components/BMForm/BMFormControlLabel.tsx +23 -0
- package/src/components/BMForm/BMLabel.tsx +24 -0
- package/src/components/BMForm/index.ts +2 -0
- package/src/components/BMHelloBanner/BMHelloBanner.tsx +68 -0
- package/src/components/BMHelloBanner/index.ts +1 -0
- package/src/components/BMInput/BMInput.tsx +31 -0
- package/src/components/BMInput/BMInputEditableCode.tsx +120 -0
- package/src/components/BMInput/BMInputField.tsx +37 -0
- package/src/components/BMInput/BMSearch.tsx +17 -0
- package/src/components/BMInput/BMStripeInput.tsx +24 -0
- package/src/components/BMInput/index.ts +5 -0
- package/src/components/BMLoadingBox/BMLoadingBox.tsx +45 -0
- package/src/components/BMLoadingBox/index.ts +1 -0
- package/src/components/BMMaps/BMMapMarker.css +12 -0
- package/src/components/BMMaps/BMMapMarker.tsx +68 -0
- package/src/components/BMMaps/BMMaps.tsx +129 -0
- package/src/components/BMMaps/MapIcons.tsx +83 -0
- package/src/components/BMMaps/icons/GeoPartition.svg +19 -0
- package/src/components/BMMaps/icons/GeoPartitionHover.svg +20 -0
- package/src/components/BMMaps/icons/MasterPreferred.svg +19 -0
- package/src/components/BMMaps/icons/MasterPreferredHover.svg +20 -0
- package/src/components/BMMaps/icons/ReadReplica.svg +18 -0
- package/src/components/BMMaps/icons/ReadReplicaHover.svg +19 -0
- package/src/components/BMMaps/icons/RegionNotSelected.svg +18 -0
- package/src/components/BMMaps/icons/RegionNotSelectedHover.svg +19 -0
- package/src/components/BMMaps/icons/RegionPreferred.svg +18 -0
- package/src/components/BMMaps/icons/RegionPreferredHover.svg +19 -0
- package/src/components/BMMaps/icons/RegionSelected.svg +18 -0
- package/src/components/BMMaps/icons/RegionSelectedHover.svg +19 -0
- package/src/components/BMMaps/index.ts +5 -0
- package/src/components/BMMaps/legend/MapLegend.tsx +80 -0
- package/src/components/BMMaps/markerTypes.ts +8 -0
- package/src/components/BMModal/BMModal.tsx +313 -0
- package/src/components/BMModal/index.ts +1 -0
- package/src/components/BMMultiEntry/BMMultiEntry.tsx +328 -0
- package/src/components/BMMultiEntry/BMMultiEntryField.tsx +47 -0
- package/src/components/BMMultiEntry/index.ts +2 -0
- package/src/components/BMMultiLevelStepper/BMMultiLevelStepper.tsx +191 -0
- package/src/components/BMMultiLevelStepper/index.ts +1 -0
- package/src/components/BMPagination/BMPagination.tsx +64 -0
- package/src/components/BMPagination/index.ts +1 -0
- package/src/components/BMPassword/BMPassword.tsx +37 -0
- package/src/components/BMPassword/BMPasswordField.tsx +50 -0
- package/src/components/BMPassword/index.ts +2 -0
- package/src/components/BMProgress/BMProgress.tsx +43 -0
- package/src/components/BMProgress/index.ts +1 -0
- package/src/components/BMRadio/BMRadio.tsx +162 -0
- package/src/components/BMRadio/BMRadioGroupField.tsx +40 -0
- package/src/components/BMRadio/index.ts +2 -0
- package/src/components/BMSelect/BMSelect.tsx +70 -0
- package/src/components/BMSelect/BMSelectField.tsx +47 -0
- package/src/components/BMSelect/index.ts +2 -0
- package/src/components/BMSlider/BMSlider.tsx +16 -0
- package/src/components/BMSlider/index.ts +1 -0
- package/src/components/BMSmartStatus/BMSmartStatus.tsx +185 -0
- package/src/components/BMSmartStatus/index.tsx +1 -0
- package/src/components/BMStatus/BMStatus.tsx +98 -0
- package/src/components/BMStatus/index.ts +1 -0
- package/src/components/BMTable/BMTable.tsx +131 -0
- package/src/components/BMTable/index.ts +1 -0
- package/src/components/BMTabs/BMTabs.tsx +50 -0
- package/src/components/BMTabs/index.ts +1 -0
- package/src/components/BMTag/BMTag.tsx +47 -0
- package/src/components/BMTag/index.ts +1 -0
- package/src/components/BMTagv2/BMTagv2.tsx +250 -0
- package/src/components/BMTagv2/index.ts +1 -0
- package/src/components/BMToggle/BMMultiToggleButton.tsx +99 -0
- package/src/components/BMToggle/BMToggle.tsx +35 -0
- package/src/components/BMToggle/BMToggleField.tsx +28 -0
- package/src/components/BMToggle/index.ts +3 -0
- package/src/components/BMTooltip/BMTooltip.tsx +52 -0
- package/src/components/BMTooltip/index.ts +1 -0
- package/src/components/BMWarning/BMWarning.tsx +39 -0
- package/src/components/BMWarning/index.ts +1 -0
- package/src/components/GenericFailure/GenericFailure.tsx +28 -0
- package/src/components/GenericFailure/index.ts +1 -0
- package/src/components/NoAccess/NoAccess.tsx +40 -0
- package/src/components/NoAccess/NoAccessActionTooltip.tsx +53 -0
- package/src/components/NoAccess/NoPermissionModal.tsx +55 -0
- package/src/components/NoAccess/index.ts +3 -0
- package/src/components/index.ts +34 -0
- package/src/index.ts +9 -0
- package/src/theme/BMAutoComplete.ts +152 -0
- package/src/theme/BMAvatar.ts +5 -0
- package/src/theme/BMButton.ts +132 -0
- package/src/theme/BMButtonGroup.ts +49 -0
- package/src/theme/BMCheckbox.ts +16 -0
- package/src/theme/BMFormHelperText.ts +19 -0
- package/src/theme/BMInput.ts +120 -0
- package/src/theme/BMMaps.ts +9 -0
- package/src/theme/BMRadio.ts +10 -0
- package/src/theme/BMTabs.ts +79 -0
- package/src/theme/BMTag.ts +28 -0
- package/src/theme/BMToggle.ts +50 -0
- package/src/theme/BMTooltip.ts +34 -0
- package/src/theme/theme.ts +326 -0
- package/src/theme/variables.ts +152 -0
- package/src/types/custom.d.ts +9 -0
- package/src/types/svg.d.ts +5 -0
- package/stories/BMAButton.stories.tsx +67 -0
- package/stories/BMAccordion.stories.tsx +55 -0
- package/stories/BMAddSection.stories.tsx +40 -0
- package/stories/BMAlert.stories.tsx +33 -0
- package/stories/BMAutoComplete.stories.tsx +65 -0
- package/stories/BMAvatar.stories.tsx +76 -0
- package/stories/BMButton.stories.tsx +57 -0
- package/stories/BMButton2.stories.tsx +131 -0
- package/stories/BMCheckbox.stories.tsx +23 -0
- package/stories/BMCloudSelectField.stories.tsx +40 -0
- package/stories/BMCodeBlock.stories.tsx +57 -0
- package/stories/BMDatePicker.stories.tsx +88 -0
- package/stories/BMDropdown.stories.tsx +84 -0
- package/stories/BMGroupButton.stories.tsx +53 -0
- package/stories/BMHelloBanner.stories.tsx +33 -0
- package/stories/BMInput.stories.tsx +184 -0
- package/stories/BMInputEditableCode.stories.tsx +86 -0
- package/stories/BMInputField.stories.tsx +50 -0
- package/stories/BMLoadingBox.stories.tsx +45 -0
- package/stories/BMMaps.stories.tsx +29 -0
- package/stories/BMModal.stories.tsx +218 -0
- package/stories/BMMultiEntry.stories.tsx +93 -0
- package/stories/BMMultiLevelStepper.stories.tsx +87 -0
- package/stories/BMPagination.stories.tsx +41 -0
- package/stories/BMPassword.stories.tsx +133 -0
- package/stories/BMProgress.stories.tsx +60 -0
- package/stories/BMRadio.stories.tsx +71 -0
- package/stories/BMSelect.stories.tsx +160 -0
- package/stories/BMSlider.stories.tsx +74 -0
- package/stories/BMSmartStatus.stories.tsx +98 -0
- package/stories/BMSplitButton.stories.tsx +32 -0
- package/stories/BMStatus.stories.tsx +29 -0
- package/stories/BMTable.stories.tsx +350 -0
- package/stories/BMTabs.stories.tsx +25 -0
- package/stories/BMTag.stories.tsx +63 -0
- package/stories/BMTagv2.stories.tsx +288 -0
- package/stories/BMToggle.stories.tsx +123 -0
- package/stories/BMTooltip.stories.tsx +59 -0
- package/stories/BMTypography.stories.tsx +79 -0
- package/stories/BMWarning.stories.tsx +55 -0
- package/stories/GenericFailure.stories.tsx +47 -0
- package/stories/NoAccess.stories.tsx +19 -0
- package/stories/NoAccessActionTooltip.stories.tsx +50 -0
- package/stories/NoPermissionModal.stories.tsx +46 -0
- package/tsconfig.base.json +21 -0
- package/tsconfig.build.json +23 -0
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import React, { FC, useState } from "react";
|
|
2
|
+
import { AdapterDateFns } from "@mui/x-date-pickers/AdapterDateFns";
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
DatePicker,
|
|
6
|
+
PickersTextField,
|
|
7
|
+
LocalizationProvider,
|
|
8
|
+
PickersTextFieldProps,
|
|
9
|
+
} from "@mui/x-date-pickers";
|
|
10
|
+
|
|
11
|
+
import {
|
|
12
|
+
Box,
|
|
13
|
+
Theme,
|
|
14
|
+
styled,
|
|
15
|
+
SxProps,
|
|
16
|
+
useTheme,
|
|
17
|
+
IconButton,
|
|
18
|
+
Typography,
|
|
19
|
+
PopperProps,
|
|
20
|
+
InputAdornment,
|
|
21
|
+
} from "@mui/material";
|
|
22
|
+
|
|
23
|
+
import CalendarIcon from "../../assets/icons/Calendar.svg";
|
|
24
|
+
|
|
25
|
+
interface BMDatePickerProps
|
|
26
|
+
extends Omit<React.ComponentProps<typeof DatePicker>, "onChange" | "value"> {
|
|
27
|
+
label?: string;
|
|
28
|
+
value: Date | null;
|
|
29
|
+
onChange: (date: Date | null) => void;
|
|
30
|
+
readOnly?: boolean;
|
|
31
|
+
openOnInputClick?: boolean;
|
|
32
|
+
dataTestid: string;
|
|
33
|
+
placeholder?: string;
|
|
34
|
+
shouldDisableDate?: (day: Date) => boolean;
|
|
35
|
+
bottomNoteText?: React.ReactNode;
|
|
36
|
+
className?: string;
|
|
37
|
+
popoverProps?: Partial<PopperProps>;
|
|
38
|
+
format?: string;
|
|
39
|
+
disabled?: boolean;
|
|
40
|
+
labelSx?: SxProps<Theme>;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const BottomNote = styled(Box)(({ theme }) => ({
|
|
44
|
+
marginTop: theme.spacing(0.5),
|
|
45
|
+
color: theme.palette.text.secondary,
|
|
46
|
+
fontSize: theme.typography.caption.fontSize,
|
|
47
|
+
}));
|
|
48
|
+
|
|
49
|
+
const StyledDatePickerWrapper = styled(Box)(({ theme }) => ({
|
|
50
|
+
display: "flex",
|
|
51
|
+
flexDirection: "column",
|
|
52
|
+
gap: theme.spacing(0.5),
|
|
53
|
+
}));
|
|
54
|
+
|
|
55
|
+
export const BMDatePicker: FC<BMDatePickerProps> = ({
|
|
56
|
+
label,
|
|
57
|
+
value,
|
|
58
|
+
onChange,
|
|
59
|
+
readOnly = false,
|
|
60
|
+
openOnInputClick = false,
|
|
61
|
+
placeholder,
|
|
62
|
+
minDate,
|
|
63
|
+
maxDate,
|
|
64
|
+
shouldDisableDate,
|
|
65
|
+
bottomNoteText,
|
|
66
|
+
className,
|
|
67
|
+
dataTestid = "bm-datepicker",
|
|
68
|
+
popoverProps,
|
|
69
|
+
labelSx,
|
|
70
|
+
format = "yyyy-MM-dd",
|
|
71
|
+
disabled = false,
|
|
72
|
+
...props
|
|
73
|
+
}) => {
|
|
74
|
+
const theme = useTheme();
|
|
75
|
+
const [open, setOpen] = useState(false);
|
|
76
|
+
|
|
77
|
+
// Open only if input click allowed and not disabled/readOnly
|
|
78
|
+
const handleInputClick = () => {
|
|
79
|
+
if (openOnInputClick && !disabled && !readOnly) {
|
|
80
|
+
setOpen(true);
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
// Open calendar when calendar icon clicked
|
|
85
|
+
const handleCalendarIconClick = () => {
|
|
86
|
+
if (!disabled && !readOnly) {
|
|
87
|
+
setOpen(true);
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
const CustomPickerTextField = React.forwardRef<
|
|
92
|
+
HTMLDivElement,
|
|
93
|
+
PickersTextFieldProps
|
|
94
|
+
>((props, ref) => {
|
|
95
|
+
return (
|
|
96
|
+
<PickersTextField
|
|
97
|
+
{...props}
|
|
98
|
+
ref={ref}
|
|
99
|
+
onClick={openOnInputClick ? handleInputClick : () => {}}
|
|
100
|
+
data-testid={dataTestid}
|
|
101
|
+
// @ts-ignore - InputProps is deprecated in MUI v6 but needed for compatibility
|
|
102
|
+
InputProps={{
|
|
103
|
+
...(props as any).InputProps,
|
|
104
|
+
readOnly: false,
|
|
105
|
+
endAdornment: (
|
|
106
|
+
<InputAdornment position="end">
|
|
107
|
+
<IconButton
|
|
108
|
+
size="small"
|
|
109
|
+
onClick={handleCalendarIconClick}
|
|
110
|
+
disabled={disabled || readOnly}
|
|
111
|
+
tabIndex={-1}
|
|
112
|
+
aria-label="open calendar"
|
|
113
|
+
>
|
|
114
|
+
<CalendarIcon />
|
|
115
|
+
</IconButton>
|
|
116
|
+
</InputAdornment>
|
|
117
|
+
),
|
|
118
|
+
sx: {
|
|
119
|
+
cursor: openOnInputClick ? "pointer" : "default",
|
|
120
|
+
"&.MuiOutlinedInput-root": {
|
|
121
|
+
borderRadius: 1,
|
|
122
|
+
paddingLeft: 1,
|
|
123
|
+
paddingRight: 1,
|
|
124
|
+
"& fieldset": {
|
|
125
|
+
borderColor: theme.palette.grey[300],
|
|
126
|
+
},
|
|
127
|
+
"&:hover fieldset": {
|
|
128
|
+
borderColor: theme.palette.primary[300],
|
|
129
|
+
},
|
|
130
|
+
"&.Mui-focused fieldset": {
|
|
131
|
+
borderColor: theme.palette.primary.main,
|
|
132
|
+
boxShadow: `0 0 0 2px ${theme.palette.primary.main}40`,
|
|
133
|
+
},
|
|
134
|
+
},
|
|
135
|
+
"& input": {
|
|
136
|
+
paddingTop: theme.spacing(1.5),
|
|
137
|
+
paddingBottom: theme.spacing(1.5),
|
|
138
|
+
},
|
|
139
|
+
},
|
|
140
|
+
}}
|
|
141
|
+
size="small"
|
|
142
|
+
fullWidth
|
|
143
|
+
/>
|
|
144
|
+
);
|
|
145
|
+
});
|
|
146
|
+
CustomPickerTextField.displayName = "CustomPickerTextField";
|
|
147
|
+
|
|
148
|
+
return (
|
|
149
|
+
<LocalizationProvider dateAdapter={AdapterDateFns}>
|
|
150
|
+
<StyledDatePickerWrapper className={className}>
|
|
151
|
+
{!!label && (
|
|
152
|
+
<Typography
|
|
153
|
+
fontWeight={600}
|
|
154
|
+
variant="caption"
|
|
155
|
+
sx={{ color: theme.palette.text.secondary, ...labelSx }}
|
|
156
|
+
>
|
|
157
|
+
{label.toUpperCase()}
|
|
158
|
+
</Typography>
|
|
159
|
+
)}
|
|
160
|
+
|
|
161
|
+
<DatePicker
|
|
162
|
+
{...props}
|
|
163
|
+
value={value}
|
|
164
|
+
onChange={onChange}
|
|
165
|
+
minDate={minDate}
|
|
166
|
+
maxDate={maxDate}
|
|
167
|
+
shouldDisableDate={shouldDisableDate}
|
|
168
|
+
readOnly={readOnly}
|
|
169
|
+
disabled={disabled}
|
|
170
|
+
format={format}
|
|
171
|
+
open={open}
|
|
172
|
+
onOpen={() => setOpen(true)}
|
|
173
|
+
onClose={() => setOpen(false)}
|
|
174
|
+
closeOnSelect={true}
|
|
175
|
+
slots={{ textField: CustomPickerTextField }}
|
|
176
|
+
slotProps={{
|
|
177
|
+
popper: {
|
|
178
|
+
...popoverProps,
|
|
179
|
+
},
|
|
180
|
+
}}
|
|
181
|
+
/>
|
|
182
|
+
|
|
183
|
+
{!!bottomNoteText && <BottomNote>{bottomNoteText}</BottomNote>}
|
|
184
|
+
</StyledDatePickerWrapper>
|
|
185
|
+
</LocalizationProvider>
|
|
186
|
+
);
|
|
187
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './BMDatePicker';
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import React, { FC } from "react";
|
|
2
|
+
import { Menu, MenuProps, PopoverOrigin, styled } from "@mui/material";
|
|
3
|
+
|
|
4
|
+
import { BMTooltip } from "../BMTooltip/BMTooltip";
|
|
5
|
+
|
|
6
|
+
export interface DropdownProps extends Omit<MenuProps, "open"> {
|
|
7
|
+
origin: React.ReactElement | ((dropdownOpen: boolean) => React.ReactElement);
|
|
8
|
+
position?: "bottom" | "bottomCenter" | "right";
|
|
9
|
+
growDirection?: "up" | "down" | "left" | "right";
|
|
10
|
+
keepOpenOnSelect?: boolean;
|
|
11
|
+
className?: string;
|
|
12
|
+
dataTestId: string;
|
|
13
|
+
tooltip?: string;
|
|
14
|
+
disabled?: boolean;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const OriginWrapper = styled("div")({
|
|
18
|
+
width: "fit-content",
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
export const BMDropdown: FC<DropdownProps> = ({
|
|
22
|
+
children,
|
|
23
|
+
position = "bottom",
|
|
24
|
+
growDirection,
|
|
25
|
+
origin,
|
|
26
|
+
keepOpenOnSelect,
|
|
27
|
+
className,
|
|
28
|
+
dataTestId,
|
|
29
|
+
tooltip,
|
|
30
|
+
disabled,
|
|
31
|
+
...menuProps
|
|
32
|
+
}) => {
|
|
33
|
+
const [anchorEl, setAnchorEl] = React.useState<HTMLElement | null>(null);
|
|
34
|
+
|
|
35
|
+
const handleClick = (event: React.MouseEvent<HTMLDivElement>) => {
|
|
36
|
+
if (!disabled) {
|
|
37
|
+
setAnchorEl(event.currentTarget);
|
|
38
|
+
}
|
|
39
|
+
event.stopPropagation();
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
const handleClose = (event: React.MouseEvent | Event) => {
|
|
43
|
+
setAnchorEl(null);
|
|
44
|
+
event.stopPropagation?.();
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
const handleMenuClick = (event: React.MouseEvent) => {
|
|
48
|
+
if (!keepOpenOnSelect) {
|
|
49
|
+
handleClose(event);
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
const open = Boolean(anchorEl);
|
|
54
|
+
|
|
55
|
+
let anchorOrigin: PopoverOrigin = { vertical: "bottom", horizontal: "right" };
|
|
56
|
+
let transformOrigin: PopoverOrigin = { vertical: "top", horizontal: "right" };
|
|
57
|
+
|
|
58
|
+
if (position === "bottom") {
|
|
59
|
+
anchorOrigin = {
|
|
60
|
+
vertical: "bottom",
|
|
61
|
+
horizontal: growDirection === "right" ? "left" : "right",
|
|
62
|
+
};
|
|
63
|
+
transformOrigin = {
|
|
64
|
+
vertical: "top",
|
|
65
|
+
horizontal: growDirection === "right" ? "left" : "right",
|
|
66
|
+
};
|
|
67
|
+
} else if (position === "bottomCenter") {
|
|
68
|
+
anchorOrigin = { vertical: "bottom", horizontal: "center" };
|
|
69
|
+
transformOrigin = { vertical: "top", horizontal: "center" };
|
|
70
|
+
} else if (position === "right") {
|
|
71
|
+
anchorOrigin = {
|
|
72
|
+
vertical: growDirection === "up" ? "bottom" : "top",
|
|
73
|
+
horizontal: "right",
|
|
74
|
+
};
|
|
75
|
+
transformOrigin = {
|
|
76
|
+
vertical: growDirection === "up" ? "bottom" : "top",
|
|
77
|
+
horizontal: "left",
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return (
|
|
82
|
+
<>
|
|
83
|
+
<BMTooltip title={tooltip ?? ""} placement="top">
|
|
84
|
+
<OriginWrapper
|
|
85
|
+
onClick={handleClick}
|
|
86
|
+
className={className}
|
|
87
|
+
data-testid={dataTestId}
|
|
88
|
+
>
|
|
89
|
+
{typeof origin === "function" ? origin(open) : origin}
|
|
90
|
+
</OriginWrapper>
|
|
91
|
+
</BMTooltip>
|
|
92
|
+
|
|
93
|
+
<Menu
|
|
94
|
+
open={open}
|
|
95
|
+
anchorEl={anchorEl}
|
|
96
|
+
disableAutoFocusItem
|
|
97
|
+
onClose={handleClose}
|
|
98
|
+
onClick={handleMenuClick}
|
|
99
|
+
anchorOrigin={anchorOrigin}
|
|
100
|
+
transformOrigin={transformOrigin}
|
|
101
|
+
{...menuProps}
|
|
102
|
+
>
|
|
103
|
+
{children}
|
|
104
|
+
</Menu>
|
|
105
|
+
</>
|
|
106
|
+
);
|
|
107
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./BMDropdown";
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import {
|
|
2
|
+
FormControlLabel,
|
|
3
|
+
type FormControlLabelProps,
|
|
4
|
+
styled,
|
|
5
|
+
} from "@mui/material";
|
|
6
|
+
|
|
7
|
+
const StyledFormControlLabel = styled(FormControlLabel)(({ theme }) => ({
|
|
8
|
+
marginLeft: 0,
|
|
9
|
+
marginRight: 0,
|
|
10
|
+
"& .bm-MuiFormControlLabel-label": {
|
|
11
|
+
...theme.typography.body2,
|
|
12
|
+
marginLeft: theme.spacing(0.5),
|
|
13
|
+
fontWeight: 400,
|
|
14
|
+
},
|
|
15
|
+
"&.Mui-disabled": {
|
|
16
|
+
color: theme.palette.grey[600],
|
|
17
|
+
cursor: "not-allowed",
|
|
18
|
+
},
|
|
19
|
+
}));
|
|
20
|
+
|
|
21
|
+
export const BMFormControlLabel = (props: FormControlLabelProps) => (
|
|
22
|
+
<StyledFormControlLabel {...props} />
|
|
23
|
+
);
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import {
|
|
2
|
+
InputLabel,
|
|
3
|
+
inputLabelClasses,
|
|
4
|
+
InputLabelProps,
|
|
5
|
+
styled,
|
|
6
|
+
} from "@mui/material";
|
|
7
|
+
|
|
8
|
+
const StyledLabel = styled(InputLabel)(({ theme }) => ({
|
|
9
|
+
marginLeft: 0,
|
|
10
|
+
marginRight: 0,
|
|
11
|
+
[`& .${inputLabelClasses.root}`]: {
|
|
12
|
+
...theme.typography.body2,
|
|
13
|
+
marginLeft: theme.spacing(0.5),
|
|
14
|
+
fontWeight: 400,
|
|
15
|
+
},
|
|
16
|
+
"&.Mui-disabled": {
|
|
17
|
+
color: theme.palette.grey[600],
|
|
18
|
+
cursor: "not-allowed",
|
|
19
|
+
},
|
|
20
|
+
}));
|
|
21
|
+
|
|
22
|
+
export const BMLabel = (props: InputLabelProps) => (
|
|
23
|
+
<StyledLabel {...props} />
|
|
24
|
+
);
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import React, { FC } from 'react';
|
|
2
|
+
import { Box, Link, styled, Typography } from '@mui/material';
|
|
3
|
+
|
|
4
|
+
import CloseIcon from '../../assets/icons/close-basic.svg';
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
const Panel = styled('div')(({ theme }) => ({
|
|
8
|
+
color: theme.palette.grey[700],
|
|
9
|
+
marginTop: theme.spacing(2),
|
|
10
|
+
backgroundColor: theme.palette.common.white,
|
|
11
|
+
padding: theme.spacing(2.7, 2.5),
|
|
12
|
+
border: `1px solid ${theme.palette.grey[200]}`,
|
|
13
|
+
boxShadow: '0px 8px 16px rgba(11, 17, 23, 0.08)',
|
|
14
|
+
borderRadius: theme.shape.borderRadius
|
|
15
|
+
}));
|
|
16
|
+
|
|
17
|
+
const StartTitle = styled(Typography)(({ theme }) => ({
|
|
18
|
+
color: theme.palette.common.indigo
|
|
19
|
+
}));
|
|
20
|
+
|
|
21
|
+
type BMHelloBanner = {
|
|
22
|
+
title?: string;
|
|
23
|
+
subTitle?: string | React.ReactElement;
|
|
24
|
+
showBanner: boolean;
|
|
25
|
+
setShowBanner?: (show: boolean) => void;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export const BMHelloBanner: FC<BMHelloBanner> = ({ title, subTitle, showBanner = true, setShowBanner }) => {
|
|
29
|
+
|
|
30
|
+
return showBanner ? (
|
|
31
|
+
<Panel>
|
|
32
|
+
<Box display="flex" justifyContent="space-between" alignItems="self-start" position="relative">
|
|
33
|
+
<Box display="flex" alignItems="self-start">
|
|
34
|
+
<Box mr={3} fontSize={32}>
|
|
35
|
+
{'👋'}
|
|
36
|
+
</Box>
|
|
37
|
+
<div>
|
|
38
|
+
{title && (
|
|
39
|
+
<StartTitle variant="h5">
|
|
40
|
+
{title}
|
|
41
|
+
</StartTitle>
|
|
42
|
+
)}
|
|
43
|
+
|
|
44
|
+
{subTitle && (
|
|
45
|
+
<Box mt={0.75} display="flex" color="grey.700">
|
|
46
|
+
<Box display="flex" alignItems="center" sx={{ fontWeight: 400 }}>
|
|
47
|
+
{subTitle}
|
|
48
|
+
</Box>
|
|
49
|
+
</Box>
|
|
50
|
+
)}
|
|
51
|
+
</div>
|
|
52
|
+
</Box>
|
|
53
|
+
<Box position="absolute" right={0}>
|
|
54
|
+
{setShowBanner && (
|
|
55
|
+
<Link component={'a'} onClick={() => setShowBanner(false)} sx={{ textDecoration: 'none' }}>
|
|
56
|
+
<Box display="flex" alignItems="center" color="primary.600">
|
|
57
|
+
<Box mr={0.5} display="flex" alignItems="center">
|
|
58
|
+
<CloseIcon />
|
|
59
|
+
</Box>
|
|
60
|
+
<Typography variant="subtitle1">Dismiss</Typography>
|
|
61
|
+
</Box>
|
|
62
|
+
</Link>
|
|
63
|
+
)}
|
|
64
|
+
</Box>
|
|
65
|
+
</Box>
|
|
66
|
+
</Panel>
|
|
67
|
+
) : null;
|
|
68
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './BMHelloBanner';
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { type StandardTextFieldProps, TextField } from "@mui/material";
|
|
2
|
+
import type { FC, ReactNode } from "react";
|
|
3
|
+
import { BMTooltip } from "../BMTooltip";
|
|
4
|
+
|
|
5
|
+
export type BMInputProps = {
|
|
6
|
+
tooltip?: ReactNode;
|
|
7
|
+
size?: "small" | "large" | "medium";
|
|
8
|
+
dataTestId: string;
|
|
9
|
+
} & Omit<
|
|
10
|
+
StandardTextFieldProps,
|
|
11
|
+
| "variant"
|
|
12
|
+
| "color"
|
|
13
|
+
| "classes"
|
|
14
|
+
| "select"
|
|
15
|
+
| "FormHelperTextProps"
|
|
16
|
+
| "SelectProps"
|
|
17
|
+
>;
|
|
18
|
+
|
|
19
|
+
export const BMInput: FC<BMInputProps> = ({ label, tooltip, dataTestId, ...props }) => (
|
|
20
|
+
<TextField
|
|
21
|
+
{...props}
|
|
22
|
+
label={
|
|
23
|
+
<>
|
|
24
|
+
{label} {tooltip && <BMTooltip title={tooltip} />}
|
|
25
|
+
|
|
26
|
+
</>
|
|
27
|
+
}
|
|
28
|
+
variant="standard"
|
|
29
|
+
data-testid={dataTestId}
|
|
30
|
+
/>
|
|
31
|
+
);
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { FC, ReactElement, useRef, useState } from "react";
|
|
2
|
+
import { Box, IconButton, styled } from "@mui/material";
|
|
3
|
+
|
|
4
|
+
import { BMInput, BMInputProps } from "../BMInput/BMInput";
|
|
5
|
+
import { BMTooltip } from "../BMTooltip/BMTooltip";
|
|
6
|
+
|
|
7
|
+
import CheckIcon from "../../assets/icons/check.svg";
|
|
8
|
+
import EditIcon from "../../assets/icons/pencil.svg";
|
|
9
|
+
import CloseIcon from "../../assets/icons/close_collapse.svg";
|
|
10
|
+
|
|
11
|
+
export interface BMInputEditableCodeProps
|
|
12
|
+
extends Omit<BMInputProps, "defaultValue" | "inputRef" | "tooltip"> {
|
|
13
|
+
content: string;
|
|
14
|
+
onSave: (savedString: string) => void;
|
|
15
|
+
tooltip?: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const Content = styled(Box)(({ theme }) => ({
|
|
19
|
+
borderStyle: "dashed",
|
|
20
|
+
borderWidth: "0 0 1px 0",
|
|
21
|
+
color: theme.palette.primary.main,
|
|
22
|
+
display: "inline",
|
|
23
|
+
fontStyle: "normal",
|
|
24
|
+
fontFamily: "Menlo",
|
|
25
|
+
"&:hover": {
|
|
26
|
+
cursor: "pointer",
|
|
27
|
+
},
|
|
28
|
+
}));
|
|
29
|
+
|
|
30
|
+
const IconButtonStyled = styled(IconButton)(({ theme }) => ({
|
|
31
|
+
height: 24,
|
|
32
|
+
width: 24,
|
|
33
|
+
borderRadius: theme.shape.borderRadius,
|
|
34
|
+
border: `1px solid ${theme.palette.grey[300]}`,
|
|
35
|
+
background: theme.palette.background.paper,
|
|
36
|
+
color: theme.palette.primary[600],
|
|
37
|
+
marginTop: theme.spacing(0.25),
|
|
38
|
+
marginRight: theme.spacing(0.375),
|
|
39
|
+
"&:hover": {
|
|
40
|
+
background: theme.palette.background.paper,
|
|
41
|
+
},
|
|
42
|
+
}));
|
|
43
|
+
|
|
44
|
+
const EditIconStyled = styled(EditIcon)(() => ({
|
|
45
|
+
position: "relative",
|
|
46
|
+
left: -4,
|
|
47
|
+
top: 7,
|
|
48
|
+
}));
|
|
49
|
+
|
|
50
|
+
export const BMInputEditableCode: FC<BMInputEditableCodeProps> = ({
|
|
51
|
+
content,
|
|
52
|
+
onSave,
|
|
53
|
+
tooltip,
|
|
54
|
+
...bmInputProps
|
|
55
|
+
}): ReactElement => {
|
|
56
|
+
const [isEditing, setIsEditing] = useState(false);
|
|
57
|
+
const fieldRef = useRef<HTMLInputElement>(null);
|
|
58
|
+
const placeholder = bmInputProps.placeholder ?? "";
|
|
59
|
+
|
|
60
|
+
return (
|
|
61
|
+
<>
|
|
62
|
+
{isEditing ? (
|
|
63
|
+
<Box display="inline-table" position="relative">
|
|
64
|
+
<Box
|
|
65
|
+
sx={{
|
|
66
|
+
"& .MuiFormLabel-root": {
|
|
67
|
+
display: "none",
|
|
68
|
+
},
|
|
69
|
+
}}
|
|
70
|
+
>
|
|
71
|
+
<BMInput
|
|
72
|
+
inputRef={fieldRef}
|
|
73
|
+
defaultValue={content}
|
|
74
|
+
{...bmInputProps}
|
|
75
|
+
/>
|
|
76
|
+
</Box>
|
|
77
|
+
<Box textAlign="right" position="absolute" right={0}>
|
|
78
|
+
<IconButtonStyled
|
|
79
|
+
onClick={() => {
|
|
80
|
+
if (fieldRef.current) {
|
|
81
|
+
if (fieldRef.current.value === "") {
|
|
82
|
+
setIsEditing(false);
|
|
83
|
+
} else {
|
|
84
|
+
fieldRef.current.value = "";
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}}
|
|
88
|
+
size="small"
|
|
89
|
+
>
|
|
90
|
+
<CloseIcon viewBox="-1 -1 17 17" />
|
|
91
|
+
</IconButtonStyled>
|
|
92
|
+
|
|
93
|
+
<IconButtonStyled
|
|
94
|
+
onClick={() => {
|
|
95
|
+
setIsEditing(false);
|
|
96
|
+
onSave(fieldRef?.current?.value ?? "");
|
|
97
|
+
}}
|
|
98
|
+
size="small"
|
|
99
|
+
>
|
|
100
|
+
<CheckIcon />
|
|
101
|
+
</IconButtonStyled>
|
|
102
|
+
</Box>
|
|
103
|
+
</Box>
|
|
104
|
+
) : (
|
|
105
|
+
<BMTooltip title={tooltip ?? placeholder}>
|
|
106
|
+
<Content
|
|
107
|
+
onClick={() => {
|
|
108
|
+
setIsEditing(true);
|
|
109
|
+
}}
|
|
110
|
+
>
|
|
111
|
+
<span>{content.length ? content : placeholder}</span>
|
|
112
|
+
<span>
|
|
113
|
+
<EditIconStyled />
|
|
114
|
+
</span>
|
|
115
|
+
</Content>
|
|
116
|
+
</BMTooltip>
|
|
117
|
+
)}
|
|
118
|
+
</>
|
|
119
|
+
);
|
|
120
|
+
};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { ReactElement } from "react";
|
|
2
|
+
import {
|
|
3
|
+
type FieldValues,
|
|
4
|
+
type UseControllerProps,
|
|
5
|
+
useController,
|
|
6
|
+
} from "react-hook-form";
|
|
7
|
+
import { BMInput, type BMInputProps } from "./BMInput";
|
|
8
|
+
|
|
9
|
+
export type BMInputFieldProps<T extends FieldValues> = UseControllerProps<T> &
|
|
10
|
+
BMInputProps;
|
|
11
|
+
|
|
12
|
+
export const BMInputField = <T extends FieldValues>(
|
|
13
|
+
props: BMInputFieldProps<T>,
|
|
14
|
+
): ReactElement => {
|
|
15
|
+
const {
|
|
16
|
+
name,
|
|
17
|
+
rules,
|
|
18
|
+
defaultValue,
|
|
19
|
+
control,
|
|
20
|
+
shouldUnregister,
|
|
21
|
+
...bmInputProps
|
|
22
|
+
} = props;
|
|
23
|
+
const {
|
|
24
|
+
field: { ref, ...fieldProps },
|
|
25
|
+
fieldState,
|
|
26
|
+
} = useController({ name, rules, defaultValue, control, shouldUnregister });
|
|
27
|
+
|
|
28
|
+
return (
|
|
29
|
+
<BMInput
|
|
30
|
+
{...fieldProps}
|
|
31
|
+
{...bmInputProps}
|
|
32
|
+
inputRef={ref}
|
|
33
|
+
error={!!fieldState.error}
|
|
34
|
+
helperText={fieldState.error?.message ?? bmInputProps.helperText}
|
|
35
|
+
/>
|
|
36
|
+
);
|
|
37
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { FC } from "react";
|
|
2
|
+
import { BMInput, BMInputProps } from "./BMInput";
|
|
3
|
+
import Search from '../../assets/icons/search.svg';
|
|
4
|
+
import { inputBaseClasses, styled } from "@mui/material";
|
|
5
|
+
|
|
6
|
+
const StyledSearch = styled(BMInput)(({ theme }) => ({
|
|
7
|
+
[`& .${inputBaseClasses.adornedStart}`]: {
|
|
8
|
+
padding: '4px 8px',
|
|
9
|
+
'& >svg': {
|
|
10
|
+
width: '26px'
|
|
11
|
+
},
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
}));
|
|
15
|
+
export const BMSearch: FC<BMInputProps> = (props) => {
|
|
16
|
+
return <StyledSearch InputProps={{ startAdornment: <Search />, disableUnderline: true }} type="search" {...props} />
|
|
17
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import React, { forwardRef, Ref } from "react";
|
|
2
|
+
import type { InputBaseComponentProps } from "@mui/material/InputBase";
|
|
3
|
+
|
|
4
|
+
interface BMStripeInputProps extends InputBaseComponentProps {
|
|
5
|
+
handleOnChange?: React.ChangeEventHandler<HTMLInputElement | HTMLTextAreaElement>;
|
|
6
|
+
handleOnBlur?: React.FocusEventHandler<HTMLInputElement | HTMLTextAreaElement>;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export const BMStripeInput = forwardRef<unknown, BMStripeInputProps>(
|
|
10
|
+
(props, ref: Ref<unknown>) => {
|
|
11
|
+
const { component: Component = "input", handleOnChange, handleOnBlur, ...rest } = props;
|
|
12
|
+
|
|
13
|
+
return (
|
|
14
|
+
<Component
|
|
15
|
+
{...rest}
|
|
16
|
+
ref={ref}
|
|
17
|
+
onChange={handleOnChange}
|
|
18
|
+
onBlur={handleOnBlur}
|
|
19
|
+
/>
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
BMStripeInput.displayName = "BMStripeInput";
|