Skip to content

Commit 02524ae

Browse files
committed
release: 7.1.0
1 parent ee3d7c5 commit 02524ae

30 files changed

+885
-807
lines changed

README.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
MDB 5 React
22

3-
Version: FREE 7.0.0
3+
Version: FREE 7.1.0
44

55
Documentation:
66
https://mdbootstrap.com/docs/b5/react/

app/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "mdb-react-ui-kit-demo",
3-
"version": "7.0.0",
3+
"version": "7.1.0",
44
"main": "index.js",
55
"repository": {
66
"type": "git",

app/src/free/components/Dropdown/Dropdown.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ import { DropdownProvider } from './contexts/DropdownContext';
55
import { DropdownBody } from './DropdownBody/DropdownBody';
66
import type { DropdownProps } from './types';
77

8-
const MDBDropdown = ({ animation, onClose, onOpen, ...props }: DropdownProps) => {
8+
const MDBDropdown = ({ animation, onClose, onOpen, wrapper = true, ...props }: DropdownProps) => {
99
return (
1010
<DropdownProvider animation={animation} onClose={onClose} onOpen={onOpen} {...props}>
11-
<DropdownBody {...props} />
11+
<DropdownBody wrapper={wrapper} {...props} />
1212
</DropdownProvider>
1313
);
1414
};

app/src/free/components/Dropdown/DropdownBody/DropdownBody.tsx

+4-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export const DropdownBody = ({
1313
dropup,
1414
dropright,
1515
dropleft,
16+
wrapper,
1617
...props
1718
}: DropdownProps) => {
1819
useClickOutside();
@@ -25,9 +26,11 @@ export const DropdownBody = ({
2526
className
2627
);
2728

28-
return (
29+
return wrapper ? (
2930
<Tag className={classes} {...props}>
3031
{children}
3132
</Tag>
33+
) : (
34+
<>{children}</>
3235
);
3336
};

app/src/free/components/Dropdown/DropdownMenu/DropdownMenu.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ const MDBDropdownMenu = ({
8585
>
8686
{Children.map(children, (child, idx) =>
8787
cloneElement(child, {
88-
tabIndex: 1,
88+
tabIndex: 0,
8989
'data-active': activeIndex === idx && true,
9090
className: clsx(activeIndex === idx ? 'active' : '', child.props.className),
9191
})

app/src/free/components/Dropdown/contexts/types.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export interface Dropdown {
1919
}
2020

2121
export interface DropdownProviderProps {
22-
children: ReactNode;
22+
children?: ReactNode;
2323
isOpen?: boolean;
2424
options?: Record<string, unknown>;
2525
animation?: boolean;

app/src/free/components/Dropdown/types.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,5 @@ export interface DropdownProps extends BaseComponent {
1313
tag?: ComponentProps<any>;
1414
onClose?: (e: MouseEvent | SyntheticEvent | KeyboardEvent) => any;
1515
onOpen?: (e: MouseEvent | SyntheticEvent | KeyboardEvent) => any;
16+
wrapper?: boolean;
1617
}

app/src/free/forms/File/File.tsx

+21-15
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,27 @@
11
import clsx from 'clsx';
2-
import React from 'react';
2+
import React, { useRef, forwardRef, useImperativeHandle } from 'react';
33
import type { FileProps } from './types';
44

5-
const MDBFile: React.FC<FileProps> = ({ className, labelClass, labelStyle, inputRef, size, label, id, ...props }) => {
6-
const inputClasses = clsx('form-control', `form-control-${size}`, className);
7-
const labelClasses = clsx('form-label', labelClass);
5+
const MDBFile: React.FC<FileProps> = forwardRef<HTMLInputElement, FileProps>(
6+
({ className, labelClass, labelStyle, inputRef: inputRefProp, size, label, id, ...props }, ref) => {
7+
const inputClasses = clsx('form-control', `form-control-${size}`, className);
8+
const labelClasses = clsx('form-label', labelClass);
9+
const inputRef = useRef<HTMLInputElement>(null);
810

9-
return (
10-
<>
11-
{label && (
12-
<label className={labelClasses} style={labelStyle} htmlFor={id}>
13-
{label}
14-
</label>
15-
)}
16-
<input className={inputClasses} type='file' id={id} ref={inputRef} {...props} />
17-
</>
18-
);
19-
};
11+
useImperativeHandle(ref, () => inputRef.current || inputRefProp?.current);
2012

13+
return (
14+
<>
15+
{label && (
16+
<label className={labelClasses} style={labelStyle} htmlFor={id}>
17+
{label}
18+
</label>
19+
)}
20+
<input className={inputClasses} type='file' id={id} ref={inputRef} {...props} />
21+
</>
22+
);
23+
}
24+
);
25+
26+
MDBFile.displayName = 'MDBFile';
2127
export default MDBFile;

app/src/free/forms/Input/Input.tsx

+36-39
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,16 @@
11
'use client';
22

33
import clsx from 'clsx';
4-
import React, { useState, useEffect, useRef, FocusEvent, ChangeEvent, useCallback, useImperativeHandle } from 'react';
4+
import React, {
5+
useState,
6+
useEffect,
7+
useRef,
8+
FocusEvent,
9+
ChangeEvent,
10+
useCallback,
11+
useImperativeHandle,
12+
useMemo,
13+
} from 'react';
514
import type { InputProps } from './types';
615
import { useOnScreen } from '../../../utils/hooks';
716

@@ -11,7 +20,7 @@ const MDBInput: React.FC<InputProps> = React.forwardRef<HTMLInputElement, InputP
1120
className,
1221
size,
1322
contrast,
14-
value,
23+
value: valueProp,
1524
defaultValue,
1625
id,
1726
labelClass,
@@ -31,20 +40,24 @@ const MDBInput: React.FC<InputProps> = React.forwardRef<HTMLInputElement, InputP
3140
},
3241
ref
3342
) => {
34-
const [newValue, setNewValue] = useState(value || defaultValue);
43+
const [valueState, setValueState] = useState(defaultValue);
44+
const value = useMemo(() => {
45+
if (valueProp !== undefined) {
46+
return valueProp;
47+
}
48+
return valueState;
49+
}, [valueProp, valueState]);
50+
3551
const [labelWidth, setLabelWidth] = useState(0);
3652
const [active, setActive] = useState(false);
3753
const [counter, setCounter] = useState(0);
38-
3954
const innerRef = useRef<HTMLInputElement>(null);
4055
const isVisible = useOnScreen(innerRef);
41-
42-
useImperativeHandle(ref, () => innerRef.current as HTMLInputElement);
43-
4456
const labelEl = useRef<HTMLLabelElement>(null);
45-
4657
const labelReference = labelRef ? labelRef : labelEl;
4758

59+
useImperativeHandle(ref, () => innerRef.current as HTMLInputElement);
60+
4861
const wrapperClasses = clsx('form-outline', contrast && 'form-white', wrapperClass);
4962
const inputClasses = clsx(
5063
'form-control',
@@ -55,58 +68,42 @@ const MDBInput: React.FC<InputProps> = React.forwardRef<HTMLInputElement, InputP
5568
);
5669
const labelClasses = clsx('form-label', labelClass);
5770

58-
useEffect(() => {
59-
if (!innerRef.current) return;
60-
61-
const { value } = innerRef.current;
62-
63-
value != '' ? setActive(true) : setActive(false);
64-
}, [innerRef.current?.value]);
65-
66-
useEffect(() => {
67-
if (value === undefined) return;
68-
value != '' ? setActive(true) : setActive(false);
69-
}, [value]);
70-
71-
useEffect(() => {
72-
if (defaultValue === undefined) return;
73-
defaultValue != '' ? setActive(true) : setActive(false);
74-
}, [defaultValue]);
75-
7671
const setWidth = useCallback(() => {
7772
if (labelReference.current?.clientWidth) {
7873
setLabelWidth(labelReference.current.clientWidth * 0.8 + 8);
7974
}
8075
}, [labelReference]);
8176

82-
useEffect(() => {
83-
setWidth();
84-
}, [labelReference.current?.clientWidth, setWidth, isVisible]);
85-
8677
const handleChange = (e: ChangeEvent<HTMLInputElement>) => {
87-
setNewValue(e.target.value);
78+
setValueState(e.target.value);
8879
showCounter && setCounter(e.target.value.length);
8980
onChange?.(e);
9081
};
9182

9283
const handleBlur = useCallback(
9384
(e: FocusEvent<HTMLInputElement, Element>) => {
9485
if (!innerRef.current) return;
95-
96-
if (
97-
(newValue !== undefined && newValue != '') ||
98-
(value !== undefined && value != '') ||
99-
innerRef.current.value != ''
100-
) {
86+
if (value) {
10187
setActive(true);
10288
} else {
10389
setActive(false);
10490
}
10591
onBlur && onBlur(e);
10692
},
107-
[newValue, value, onBlur]
93+
[value, onBlur]
10894
);
10995

96+
useEffect(() => {
97+
setWidth();
98+
}, [labelReference.current?.clientWidth, setWidth, isVisible]);
99+
100+
useEffect(() => {
101+
if (value) {
102+
return setActive(true);
103+
}
104+
setActive(false);
105+
}, [value]);
106+
110107
return (
111108
<WrapperTag className={wrapperClasses} style={wrapperStyle}>
112109
<input
@@ -116,7 +113,7 @@ const MDBInput: React.FC<InputProps> = React.forwardRef<HTMLInputElement, InputP
116113
onBlur={handleBlur}
117114
onChange={handleChange}
118115
onFocus={setWidth}
119-
value={value}
116+
value={valueProp}
120117
defaultValue={defaultValue}
121118
id={id}
122119
ref={innerRef}
Original file line numberDiff line numberDiff line change
@@ -1,68 +1,74 @@
11
import clsx from 'clsx';
2-
import React from 'react';
2+
import React, { forwardRef } from 'react';
33
import type { InputTemplateProps } from './types';
44

5-
const InputTemplate: React.FC<InputTemplateProps> = ({
6-
className,
7-
inputRef,
8-
labelClass,
9-
wrapperClass,
10-
labelStyle,
11-
wrapperTag: WrapperTag = 'div',
12-
wrapperStyle,
13-
label,
14-
inline,
15-
btn,
16-
id,
17-
btnColor,
18-
disableWrapper,
19-
toggleSwitch,
20-
...props
21-
}) => {
22-
let inputStyle = 'form-check-input';
23-
let labelClassName = 'form-check-label';
5+
const InputTemplate: React.FC<InputTemplateProps> = forwardRef(
6+
(
7+
{
8+
className,
9+
inputRef,
10+
labelClass,
11+
wrapperClass,
12+
labelStyle,
13+
wrapperTag: WrapperTag = 'div',
14+
wrapperStyle,
15+
label,
16+
inline,
17+
btn,
18+
id,
19+
btnColor,
20+
disableWrapper,
21+
toggleSwitch,
22+
...props
23+
},
24+
ref
25+
) => {
26+
let inputStyle = 'form-check-input';
27+
let labelClassName = 'form-check-label';
2428

25-
if (btn) {
26-
inputStyle = 'btn-check';
29+
if (btn) {
30+
inputStyle = 'btn-check';
2731

28-
if (btnColor) {
29-
labelClassName = `btn btn-${btnColor}`;
30-
} else {
31-
labelClassName = 'btn btn-primary';
32+
if (btnColor) {
33+
labelClassName = `btn btn-${btnColor}`;
34+
} else {
35+
labelClassName = 'btn btn-primary';
36+
}
3237
}
33-
}
3438

35-
const wrapperClasses = clsx(
36-
label && !btn && 'form-check',
37-
inline && !btn && 'form-check-inline',
38-
toggleSwitch && 'form-switch',
39-
wrapperClass
40-
);
41-
const inputClasses = clsx(inputStyle, className);
42-
const labelClasses = clsx(labelClassName, labelClass);
39+
const wrapperClasses = clsx(
40+
label && !btn && 'form-check',
41+
inline && !btn && 'form-check-inline',
42+
toggleSwitch && 'form-switch',
43+
wrapperClass
44+
);
45+
const inputClasses = clsx(inputStyle, className);
46+
const labelClasses = clsx(labelClassName, labelClass);
4347

44-
const inputBody = (
45-
<>
46-
<input className={inputClasses} id={id} ref={inputRef} {...props} />
47-
{label && (
48-
<label className={labelClasses} style={labelStyle} htmlFor={id}>
49-
{label}
50-
</label>
51-
)}
52-
</>
53-
);
48+
const inputBody = (
49+
<>
50+
<input className={inputClasses} id={id} ref={inputRef} {...props} />
51+
{label && (
52+
<label className={labelClasses} style={labelStyle} htmlFor={id}>
53+
{label}
54+
</label>
55+
)}
56+
</>
57+
);
5458

55-
return (
56-
<>
57-
{disableWrapper ? (
58-
inputBody
59-
) : (
60-
<WrapperTag style={wrapperStyle} className={wrapperClasses}>
61-
{inputBody}
62-
</WrapperTag>
63-
)}
64-
</>
65-
);
66-
};
59+
return (
60+
<>
61+
{disableWrapper ? (
62+
inputBody
63+
) : (
64+
<WrapperTag style={wrapperStyle} className={wrapperClasses} ref={ref}>
65+
{inputBody}
66+
</WrapperTag>
67+
)}
68+
</>
69+
);
70+
}
71+
);
6772

73+
InputTemplate.displayName = 'InputTemplate';
6874
export default InputTemplate;

0 commit comments

Comments
 (0)