Skip to content

Commit

Permalink
Implement disableParentheses option (GH-16)
Browse files Browse the repository at this point in the history
  • Loading branch information
ArtyomVancyan authored Jun 15, 2024
2 parents 63a586c + 68c5561 commit bf0245b
Show file tree
Hide file tree
Showing 15 changed files with 133 additions and 87 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ Apart from the phone-specific properties described below, all [Input](https://mu
| searchNotFound | The value is shown if `enableSearch` is `true` and the query does not match any country. Default value is `No country found`. | string |
| searchPlaceholder | The value is shown if `enableSearch` is `true`. Default value is `Search country`. | string |
| disableDropdown | Disables the manual country selection through the dropdown menu. | boolean |
| disableParentheses | Disables parentheses from the input masks. Default enabled. | boolean |
| onlyCountries | Country codes to be included in the list. E.g. `onlyCountries={['us', 'ca', 'uk']}`. | string[] |
| excludeCountries | Country codes to be excluded from the list of countries. E.g. `excludeCountries={['us', 'ca', 'uk']}`. | string[] |
| preferredCountries | Country codes to be at the top of the list. E.g. `preferredCountries={['us', 'ca', 'uk']}`. | string[] |
Expand Down
2 changes: 1 addition & 1 deletion examples/base/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"@mui/material": "^5.15.1",
"@types/react": "^18.2.0",
"@types/react-dom": "^18.2.0",
"mui-phone-input": "^0.1.0",
"mui-phone-input": "^0.1.2",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-scripts": "^5.0.1",
Expand Down
2 changes: 1 addition & 1 deletion examples/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"@material-ui/core": "^4.12.4",
"@types/react": "^17.0.0",
"@types/react-dom": "^17.0.0",
"mui-phone-input": "^0.1.0",
"mui-phone-input": "^0.1.2",
"react": "^17.0.0",
"react-dom": "^17.0.0",
"react-scripts": "^5.0.1",
Expand Down
2 changes: 1 addition & 1 deletion examples/joy/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"@mui/joy": "^5.0.0-beta.15",
"@types/react": "^18.2.0",
"@types/react-dom": "^18.2.0",
"mui-phone-input": "^0.1.0",
"mui-phone-input": "^0.1.2",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-scripts": "^5.0.1",
Expand Down
2 changes: 1 addition & 1 deletion examples/material/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"@types/react": "^18.2.0",
"@types/react-dom": "^18.2.0",
"copy-to-clipboard": "^3.3.3",
"mui-phone-input": "^0.1.0",
"mui-phone-input": "^0.1.2",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-hook-form": "^7.51.4",
Expand Down
12 changes: 12 additions & 0 deletions examples/material/src/Demo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ const Demo = () => {
const [preview, setPreview] = useState<boolean>(false);
const [dropdown, setDropdown] = useState<boolean>(true);
const [disabled, setDisabled] = useState<boolean>(false);
const [parentheses, setParentheses] = useState(true);

const phoneProps = register("phone", {
validate: (value: any) => checkValidity(parsePhoneNumber(value)),
Expand Down Expand Up @@ -129,6 +130,16 @@ const Demo = () => {
style={{margin: 0}}
label="Dropdown"
/>
<FormControlLabel
control={<Switch
defaultChecked
color="primary"
onChange={() => setParentheses(!parentheses)}
/>}
labelPlacement="start"
style={{margin: 0}}
label="Parentheses"
/>
</div>
<Divider textAlign="left" style={{margin: "16px 0"}}>Code</Divider>
<div style={{position: "relative"}}>
Expand Down Expand Up @@ -163,6 +174,7 @@ const Demo = () => {
enableSearch={search}
style={{width: "100%"}}
disableDropdown={!dropdown}
disableParentheses={!parentheses}
/>
)}
{(preview && value && !error) && (
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"version": "0.1.1",
"version": "0.1.2",
"name": "mui-phone-input",
"description": "Advanced, highly customizable phone input component for Material UI.",
"keywords": [
Expand Down Expand Up @@ -47,7 +47,7 @@
"react": "^16.8.6 || ^17.0.0 || ^18.0.0"
},
"dependencies": {
"react-phone-hooks": "^0.1.4"
"react-phone-hooks": "^0.1.5"
},
"devDependencies": {
"@emotion/styled": "^11.11.0",
Expand Down
15 changes: 13 additions & 2 deletions src/base/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,17 @@ import {PhoneInputProps, PhoneNumber} from "./types";
injectMergedStyles();

const Input = forwardRef<HTMLInputElement, InputProps>(({slotProps, ...props}, ref) => {
const defaultInputProps = (slotProps?.input as any)?.className ? {} : {outline: "none", border: "none", paddingLeft: 5, width: "calc(100% - 30px)"};
const defaultRootProps = (slotProps?.root as any)?.className ? {} : {background: "white", color: "black", paddingLeft: 5};
const defaultInputProps = (slotProps?.input as any)?.className ? {} : {
outline: "none",
border: "none",
paddingLeft: 5,
width: "calc(100% - 30px)"
};
const defaultRootProps = (slotProps?.root as any)?.className ? {} : {
background: "white",
color: "black",
paddingLeft: 5
};
return (
<BaseInput
ref={ref}
Expand Down Expand Up @@ -51,6 +60,7 @@ const Input = forwardRef<HTMLInputElement, InputProps>(({slotProps, ...props}, r
const PhoneInput = forwardRef(({
value: initialValue = "",
country = getDefaultISO2Code(),
disableParentheses = false,
onlyCountries = [],
excludeCountries = [],
preferredCountries = [],
Expand All @@ -76,6 +86,7 @@ const PhoneInput = forwardRef(({
onlyCountries,
excludeCountries,
preferredCountries,
disableParentheses,
});

const {
Expand Down
2 changes: 2 additions & 0 deletions src/base/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ export interface PhoneInputProps extends Omit<InputProps, "onChange"> {

country?: string;

disableParentheses?: boolean;

onlyCountries?: string[];

excludeCountries?: string[];
Expand Down
58 changes: 31 additions & 27 deletions src/core/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ const PhoneInput = forwardRef(({
disabled = false,
enableSearch = false,
disableDropdown = false,
disableParentheses = false,
onlyCountries = [],
excludeCountries = [],
preferredCountries = [],
Expand Down Expand Up @@ -150,33 +151,36 @@ const PhoneInput = forwardRef(({
/>
)}
<div className="mui-phone-input-search-list">
{countriesList.length ? countriesList.map(([iso, name, dial, mask]) => (
<MenuItem
disableRipple
key={iso + mask}
value={iso + dial}
style={{maxWidth}}
selected={selectValue === iso + dial}
onClick={() => {
const formattedNumber = getFormattedNumber(mask, mask);
const input = inputRef.current.querySelector("input");
input.value = formattedNumber;
setValue(formattedNumber);
setCountryCode(iso);
setQuery("");
const nativeInputValueSetter = (Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, "value") as any).set;
nativeInputValueSetter.call(input, formattedNumber);
input.dispatchEvent(new Event("change", {bubbles: true}));
setTimeout(() => input.focus(), 100);
}}
children={<div className="mui-phone-input-select-item">
<div className={`flag ${iso}`}/>
<div className="label">
{name}&nbsp;{displayFormat(mask)}
</div>
</div>}
/>
)) : <MenuItem disabled>{searchNotFound}</MenuItem>}
{countriesList.length ? countriesList.map(([iso, name, dial, pattern]) => {
const mask = disableParentheses ? pattern.replace(/[()]/g, "") : pattern;
return (
<MenuItem
disableRipple
key={iso + mask}
value={iso + dial}
style={{maxWidth}}
selected={selectValue === iso + dial}
onClick={() => {
const formattedNumber = getFormattedNumber(mask, mask);
const input = inputRef.current.querySelector("input");
input.value = formattedNumber;
setValue(formattedNumber);
setCountryCode(iso);
setQuery("");
const nativeInputValueSetter = (Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, "value") as any).set;
nativeInputValueSetter.call(input, formattedNumber);
input.dispatchEvent(new Event("change", {bubbles: true}));
setTimeout(() => input.focus(), 100);
}}
children={<div className="mui-phone-input-select-item">
<div className={`flag ${iso}`}/>
<div className="label">
{name}&nbsp;{displayFormat(mask)}
</div>
</div>}
/>
)
}) : <MenuItem disabled>{searchNotFound}</MenuItem>}
</div>
</div>
</Select>
Expand Down
2 changes: 2 additions & 0 deletions src/core/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ export interface PhoneInputProps extends Omit<TextFieldProps, "onChange"> {

disableDropdown?: boolean;

disableParentheses?: boolean;

onlyCountries?: string[];

excludeCountries?: string[];
Expand Down
59 changes: 32 additions & 27 deletions src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ const PhoneInput = forwardRef(({
disabled = false,
enableSearch = false,
disableDropdown = false,
disableParentheses = false,
onlyCountries = [],
excludeCountries = [],
preferredCountries = [],
Expand Down Expand Up @@ -63,6 +64,7 @@ const PhoneInput = forwardRef(({
onlyCountries,
excludeCountries,
preferredCountries,
disableParentheses,
});

const {
Expand Down Expand Up @@ -145,33 +147,36 @@ const PhoneInput = forwardRef(({
/>
)}
<div className="mui-phone-input-search-list">
{countriesList.length ? countriesList.map(([iso, name, dial, mask]) => (
<MenuItem
disableRipple
key={iso + mask}
value={iso + dial}
style={{maxWidth}}
selected={selectValue === iso + dial}
onClick={() => {
const formattedNumber = getFormattedNumber(mask, mask);
const input = inputRef.current.querySelector("input");
input.value = formattedNumber;
setValue(formattedNumber);
setCountryCode(iso);
setQuery("");
const nativeInputValueSetter = (Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, "value") as any).set;
nativeInputValueSetter.call(input, formattedNumber);
input.dispatchEvent(new Event("change", {bubbles: true}));
setTimeout(() => input.focus(), 100);
}}
children={<div className="mui-phone-input-select-item">
<div className={`flag ${iso}`}/>
<div className="label">
{name}&nbsp;{displayFormat(mask)}
</div>
</div>}
/>
)) : <MenuItem disabled>{searchNotFound}</MenuItem>}
{countriesList.length ? countriesList.map(([iso, name, dial, pattern]) => {
const mask = disableParentheses ? pattern.replace(/[()]/g, "") : pattern;
return (
<MenuItem
disableRipple
key={iso + mask}
value={iso + dial}
style={{maxWidth}}
selected={selectValue === iso + dial}
onClick={() => {
const formattedNumber = getFormattedNumber(mask, mask);
const input = inputRef.current.querySelector("input");
input.value = formattedNumber;
setValue(formattedNumber);
setCountryCode(iso);
setQuery("");
const nativeInputValueSetter = (Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, "value") as any).set;
nativeInputValueSetter.call(input, formattedNumber);
input.dispatchEvent(new Event("change", {bubbles: true}));
setTimeout(() => input.focus(), 100);
}}
children={<div className="mui-phone-input-select-item">
<div className={`flag ${iso}`}/>
<div className="label">
{name}&nbsp;{displayFormat(mask)}
</div>
</div>}
/>
)
}) : <MenuItem disabled>{searchNotFound}</MenuItem>}
</div>
</div>
</Select>
Expand Down
Loading

0 comments on commit bf0245b

Please sign in to comment.