Skip to content

Commit 5db4058

Browse files
Fix disabled prop and add autofocus on searchbox (GH-89)
2 parents 0d465ed + 10ad856 commit 5db4058

File tree

12 files changed

+419
-72
lines changed

12 files changed

+419
-72
lines changed

.github/workflows/playground.yml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
name: playground
2+
3+
on:
4+
push:
5+
branches: [ master ]
6+
7+
jobs:
8+
deploy:
9+
environment:
10+
name: Playground
11+
url: https://playground.typesnippet.org/antd-phone-input-5.x
12+
runs-on: ubuntu-latest
13+
steps:
14+
- name: Run deployment script on server
15+
uses: appleboy/ssh-action@master
16+
with:
17+
host: ${{ secrets.HOST }}
18+
username: ${{ secrets.USERNAME }}
19+
key: ${{ secrets.KEY_ED25519 }}
20+
port: ${{ secrets.PORT }}
21+
script: bash ~/antd-phone-input/examples/deploy.sh

README.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,19 @@
11
# Antd Phone Input <img src="https://github.com/typesnippet.png" align="right" height="64" />
22

33
[![npm](https://img.shields.io/npm/v/antd-phone-input)](https://www.npmjs.com/package/antd-phone-input)
4+
[![Playground](https://img.shields.io/badge/playground-blue.svg?logo=data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/PjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+PHN2ZyB0PSIxNzEzNTE0OTc5MTUzIiBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHAtaWQ9IjE2MjciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iMjAwIiBoZWlnaHQ9IjIwMCI+PHBhdGggZD0iTTc2OCA1MDYuMDI2NjY3djExLjk0NjY2NmEzMi40MjY2NjcgMzIuNDI2NjY3IDAgMCAxLTE1Ljc4NjY2NyAyNy43MzMzMzRMMzcwLjM0NjY2NyA3NjhjLTIzLjA0IDEzLjY1MzMzMy0zNC45ODY2NjcgMTMuNjUzMzMzLTQ1LjIyNjY2NyA3LjY4bC0xMC42NjY2NjctNS45NzMzMzNhMzIuNDI2NjY3IDMyLjQyNjY2NyAwIDAgMS0xNS43ODY2NjYtMjYuODhWMjgxLjE3MzMzM2EzMi40MjY2NjcgMzIuNDI2NjY3IDAgMCAxIDE1Ljc4NjY2Ni0yNy43MzMzMzNsMTAuNjY2NjY3LTUuOTczMzMzYzEwLjI0LTUuOTczMzMzIDIyLjE4NjY2Ny01Ljk3MzMzMyA1Mi4wNTMzMzMgMTEuNTJsMzc1LjA0IDIxOS4zMDY2NjZhMzIuNDI2NjY3IDMyLjQyNjY2NyAwIDAgMSAxNS43ODY2NjcgMjcuNzMzMzM0eiIgcC1pZD0iMTYyOCIgZGF0YS1zcG0tYW5jaG9yLWlkPSJhMzEzeC5zZWFyY2hfaW5kZXguMC5pMS40NzE5M2E4MVdiYjYyWiIgY2xhc3M9IiIgZmlsbD0iI2ZmZmZmZiI+PC9wYXRoPjwvc3ZnPg==)](https://playground.typesnippet.org/antd-phone-input-5.x)
45
[![antd](https://img.shields.io/badge/antd-4.x%20%7C%205.x-blue)](https://github.com/ant-design/ant-design)
56
[![types](https://img.shields.io/npm/types/antd-phone-input)](https://www.npmjs.com/package/antd-phone-input)
67
[![License](https://img.shields.io/npm/l/antd-phone-input)](https://github.com/typesnippet/antd-phone-input/blob/master/LICENSE)
78
[![Tests](https://github.com/typesnippet/antd-phone-input/actions/workflows/tests.yml/badge.svg)](https://github.com/typesnippet/antd-phone-input/actions/workflows/tests.yml)
89

9-
Advanced phone input component for Material UI that leverages the [react-phone-hooks](https://www.npmjs.com/package/react-phone-hooks) supporting all countries. The package is compatible with [antd](https://github.com/ant-design/ant-design) 4 and 5 versions. It provides built-in support for area codes and strict validation.
10+
<p>Advanced phone input component for Material UI that leverages the <a href="https://github.com/typesnippet/react-phone-hooks">react-phone-hooks</a> supporting all countries. The package is compatible with <a href="https://github.com/ant-design/ant-design">antd</a> 4 and 5 versions. It provides built-in support for area codes and strict validation.</p>
11+
12+
<p align="center">
13+
<a href="https://playground.typesnippet.org/antd-phone-input-5.x">
14+
<img src="https://github.com/typesnippet/antd-phone-input/assets/44609997/37386477-3ab5-4afb-9c85-88be676e8afe" alt="Antd Phone Input"/>
15+
</a>
16+
</p>
1017

1118
## Value
1219

examples/antd4.x/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33
"version": "0.1.0",
44
"private": true,
55
"dependencies": {
6+
"@craco/craco": "^7.0.0",
67
"@types/react": "^18.2.0",
78
"@types/react-dom": "^18.2.0",
8-
"@craco/craco": "^7.0.0",
99
"antd": "^4.24.8",
1010
"antd-phone-input": "^0.3.5",
1111
"craco-less": "^2.0.0",

examples/antd4.x/public/index.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33
<head>
44
<meta charset="utf-8"/>
55
<meta name="viewport" content="width=device-width, initial-scale=1"/>
6-
<title>Antd 4.x</title>
6+
<title>Playground 4.x</title>
77
</head>
88
<body>
9-
<div id="root"></div>
9+
<div id="root" style="height: 100%"></div>
1010
</body>
1111
</html>

examples/antd4.x/src/Demo.tsx

Lines changed: 186 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,207 @@
1-
import {useState} from "react";
1+
import {useCallback, useMemo, useState} from "react";
2+
import copy from "copy-to-clipboard";
23
import Form from "antd/es/form";
4+
import Alert from "antd/es/alert";
35
import Button from "antd/es/button";
4-
import FormItem from "antd/es/form/FormItem";
6+
import Switch from "antd/es/switch";
7+
import Card from "antd/es/card/Card";
8+
import Divider from "antd/es/divider";
9+
import {useForm} from "antd/es/form/Form";
510
import PhoneInput from "antd-phone-input";
11+
import FormItem from "antd/es/form/FormItem";
12+
import Title from "antd/es/typography/Title";
13+
import Paragraph from "antd/es/typography/Paragraph";
14+
import SunOutlined from "@ant-design/icons/SunOutlined";
15+
import MoonOutlined from "@ant-design/icons/MoonOutlined";
16+
import CopyOutlined from "@ant-design/icons/CopyOutlined";
17+
import CheckOutlined from "@ant-design/icons/CheckOutlined";
18+
19+
import "antd/dist/reset.css";
620

721
const Demo = () => {
22+
const [form] = useForm();
823
const [value, setValue] = useState(null);
24+
const [strict, setStrict] = useState(false);
25+
const [search, setSearch] = useState(false);
26+
const [copied, setCopied] = useState(false);
27+
const [dropdown, setDropdown] = useState(true);
28+
const [disabled, setDisabled] = useState(false);
929

10-
const validator = (_: any, {valid}: any) => {
11-
if (valid()) {
12-
return Promise.resolve();
13-
}
30+
const validator = useCallback((_: any, {valid}: any) => {
31+
if (valid(strict)) return Promise.resolve();
1432
return Promise.reject("Invalid phone number");
15-
}
33+
}, [strict])
34+
35+
const code = useMemo(() => {
36+
let code = "<PhoneInput\n";
37+
if (disabled) code += " disabled\n";
38+
if (search && dropdown) code += " enableSearch\n";
39+
if (!dropdown) code += " disableDropdown\n";
40+
if (code === "<PhoneInput\n") code = "<PhoneInput />";
41+
else code += "/>";
42+
return code;
43+
}, [disabled, search, dropdown])
1644

1745
const changeTheme = () => {
18-
if (window.location.pathname === "/dark") {
19-
window.location.replace("/");
46+
const pathname = window.location.pathname.replace(/\/$/, '');
47+
if (pathname.endsWith("/dark")) {
48+
window.location.replace(pathname.replace('/dark', ''));
2049
} else {
21-
window.location.replace("/dark");
50+
window.location.replace(pathname + "/dark");
2251
}
2352
}
2453

2554
const handleFinish = ({phone}: any) => setValue(phone);
2655

2756
return (
28-
<div style={{margin: 20, maxWidth: 400}}>
29-
{value && (
30-
<pre style={{
31-
background: window.location.pathname === "/dark" ? "#1f1f1f" : "#efefef",
32-
color: window.location.pathname === "/dark" ? "#efefef" : "#1f1f1f",
33-
padding: 10, marginBottom: 24,
34-
}}>
35-
{JSON.stringify(value, null, 2)}
36-
</pre>
37-
)}
38-
<Form onFinish={handleFinish}>
39-
<FormItem name="phone" rules={[{validator}]}>
40-
<PhoneInput enableSearch/>
41-
</FormItem>
42-
<div style={{display: "flex", gap: 24}}>
43-
<Button htmlType="submit">Preview Value</Button>
44-
<Button htmlType="reset">Reset Value</Button>
45-
<Button onClick={changeTheme}>Change Theme</Button>
57+
<Card style={{height: "100%", borderRadius: 0, border: "none"}}
58+
bodyStyle={{
59+
padding: 0,
60+
height: "100%",
61+
display: "flex",
62+
justifyContent: "center",
63+
}}>
64+
<div style={{
65+
minWidth: 415,
66+
maxWidth: 415,
67+
display: "flex",
68+
margin: "10px 20px",
69+
flexDirection: "column",
70+
}}>
71+
<Title level={2}>
72+
Ant Phone Input Playground
73+
</Title>
74+
<Paragraph>
75+
This is a playground for the Ant Phone Input component. You can change the settings and see how
76+
the component behaves. Also, see the code for the component and the value it returns.
77+
</Paragraph>
78+
<Divider orientation="left" plain>Settings</Divider>
79+
<div style={{gap: 24, display: "flex", alignItems: "center"}}>
80+
<Form.Item label="Theme">
81+
<Switch
82+
onChange={changeTheme}
83+
checkedChildren={<MoonOutlined/>}
84+
unCheckedChildren={<SunOutlined/>}
85+
defaultChecked={window.location.pathname.endsWith("/dark")}
86+
/>
87+
</Form.Item>
88+
<Form.Item label="Validation">
89+
<Switch
90+
checkedChildren="strict"
91+
unCheckedChildren="default"
92+
onChange={() => setStrict(!strict)}
93+
/>
94+
</Form.Item>
95+
<Form.Item label="Disabled">
96+
<Switch onChange={() => setDisabled(!disabled)}/>
97+
</Form.Item>
98+
</div>
99+
<div style={{gap: 24, display: "flex", alignItems: "center"}}>
100+
<Form.Item label="Search" style={{margin: 0}}>
101+
<Switch
102+
disabled={!dropdown}
103+
checkedChildren="enabled"
104+
unCheckedChildren="disabled"
105+
onChange={() => setSearch(!search)}
106+
/>
107+
</Form.Item>
108+
<Form.Item label="Dropdown" style={{margin: 0}}>
109+
<Switch
110+
defaultChecked
111+
checkedChildren="enabled"
112+
unCheckedChildren="disabled"
113+
onChange={() => setDropdown(!dropdown)}
114+
/>
115+
</Form.Item>
116+
</div>
117+
<Divider orientation="left" plain>Code</Divider>
118+
<div style={{position: "relative"}}>
119+
<Button
120+
type="text"
121+
size="small"
122+
onClick={() => {
123+
copy(code);
124+
setCopied(true);
125+
setTimeout(() => setCopied(false), 2000);
126+
}}
127+
style={{position: "absolute", top: 10, right: 10}}
128+
icon={copied ? <CheckOutlined style={{color: "green"}}/> : <CopyOutlined/>}
129+
/>
130+
<pre style={{
131+
background: window.location.pathname.endsWith("/dark") ? "#1f1f1f" : "#efefef",
132+
color: window.location.pathname.endsWith("/dark") ? "#efefef" : "#1f1f1f",
133+
padding: 10,
134+
}}>
135+
{code}
136+
</pre>
137+
</div>
138+
<Divider orientation="left" plain>Component</Divider>
139+
<Form form={form} onFinish={handleFinish}>
140+
<FormItem name="phone" rules={[{validator}]}>
141+
<PhoneInput
142+
disabled={disabled}
143+
enableSearch={search}
144+
disableDropdown={!dropdown}
145+
/>
146+
</FormItem>
147+
{value && (
148+
<pre style={{
149+
background: window.location.pathname.endsWith("/dark") ? "#1f1f1f" : "#efefef",
150+
color: window.location.pathname.endsWith("/dark") ? "#efefef" : "#1f1f1f",
151+
padding: 10, marginBottom: 24,
152+
}}>
153+
{JSON.stringify(value, null, 2)}
154+
</pre>
155+
)}
156+
<div style={{display: "flex", gap: 24, justifyContent: "flex-start"}}>
157+
<Button htmlType="submit" type="primary">Preview Value</Button>
158+
<Button htmlType="reset">Reset Value</Button>
159+
</div>
160+
</Form>
161+
<Alert
162+
type="info"
163+
style={{marginTop: 24}}
164+
message={<>
165+
If your application uses <b>5.x</b> version of <b>Ant Design</b>, you should use this&nbsp;
166+
<a target="_blank" rel="noreferrer"
167+
href="//playground.typesnippet.org/antd-phone-input-5.x">playground</a>&nbsp;
168+
server to test the component.
169+
</>}
170+
/>
171+
<div style={{marginTop: "auto"}}>
172+
<Divider style={{margin: "10px 0"}}/>
173+
<div style={{
174+
display: "flex",
175+
alignItems: "center",
176+
justifyContent: "space-between",
177+
}}>
178+
<div>
179+
&copy; Made with ❤️ by&nbsp;
180+
<a href="//github.com/typesnippet" target="_blank" rel="noreferrer author">
181+
TypeSnippet
182+
</a>
183+
</div>
184+
<div style={{display: "flex", gap: 10}}>
185+
<a target="_blank" rel="noreferrer"
186+
href="//github.com/typesnippet/antd-phone-input/blob/master/LICENSE">
187+
<img src="//img.shields.io/npm/l/antd-phone-input" alt="MIT License"/>
188+
</a>
189+
<a href="//www.npmjs.com/package/antd-phone-input" target="_blank" rel="noreferrer">
190+
<img src="//img.shields.io/npm/v/antd-phone-input" alt="NPM Package"/>
191+
</a>
192+
</div>
193+
</div>
194+
<Paragraph style={{margin: "5px 0 0 0"}}>
195+
Find the&nbsp;
196+
<a href="//github.com/typesnippet/antd-phone-input/tree/master/examples/antd4.x"
197+
target="_blank" rel="noreferrer">
198+
source code
199+
</a>
200+
&nbsp;of this playground server on our GitHub repo.
201+
</Paragraph>
46202
</div>
47-
</Form>
48-
</div>
203+
</div>
204+
</Card>
49205
)
50206
}
51207

examples/antd4.x/src/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ const Light = lazy(() => import("./themes/Light"));
55
const Dark = lazy(() => import("./themes/Dark"));
66

77
const App = () => {
8-
return window.location.pathname === "/dark" ? <Dark/> : <Light/>;
8+
return window.location.pathname.endsWith("/dark") ? <Dark/> : <Light/>;
99
}
1010

1111
const elem = document.getElementById("root");

examples/antd5.x/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
"@types/react-dom": "^18.2.0",
88
"antd": "^5.8.3",
99
"antd-phone-input": "^0.3.5",
10+
"copy-to-clipboard": "^3.3.3",
1011
"react": "^18.2.0",
1112
"react-dom": "^18.2.0",
1213
"react-scripts": "^5.0.1",

examples/antd5.x/public/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<head>
44
<meta charset="utf-8"/>
55
<meta name="viewport" content="width=device-width, initial-scale=1"/>
6-
<title>Antd 5.x</title>
6+
<title>Playground 5.x</title>
77
</head>
88
<body>
99
<div id="root" style="height: 100%;"></div>

0 commit comments

Comments
 (0)