mirror of
https://github.com/ant-design/ant-design.git
synced 2025-06-07 17:44:35 +08:00
chore: Add demo tsx check (#28389)
* chore: Add demo tsx check * chore: Prettier * chore: Fix lint * fix: Upload ts definition * chore: Demo onlt * docs: Fix demo * chore: Add CI action * chore: Use real name * chore: fix ts define * chore: fix more ts * chore: fix more ts * chore: More ts * chore: More ts * chore: More ts * chore: More ts * chore: More ts * chore: More ts * chore: More ts * chore: Update all rest TS demo * fix test case
This commit is contained in:
parent
0a6167b995
commit
55e0d13234
@ -3,6 +3,7 @@ components/**/*.jsx
|
||||
!components/*/__tests__/**/*.js
|
||||
!components/*/demo/*
|
||||
!.*.js
|
||||
~*
|
||||
# Docs templates
|
||||
site/theme/template/Color/ColorPicker.jsx
|
||||
site/theme/template/IconDisplay/*.js
|
||||
@ -27,4 +28,4 @@ coverage
|
||||
**/*.d.ts
|
||||
# Scripts
|
||||
scripts/previewEditor/**/*
|
||||
jest-stare
|
||||
jest-stare
|
22
.github/workflows/test.yml
vendored
22
.github/workflows/test.yml
vendored
@ -95,6 +95,28 @@ jobs:
|
||||
run: npm run lint
|
||||
needs: setup
|
||||
|
||||
tsx-demo:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: checkout
|
||||
uses: actions/checkout@master
|
||||
|
||||
- name: restore cache from package-lock.json
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: package-temp-dir
|
||||
key: lock-${{ github.sha }}
|
||||
|
||||
- name: restore cache from node_modules
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: node_modules
|
||||
key: node_modules-${{ hashFiles('**/package-temp-dir/package-lock.json') }}
|
||||
|
||||
- name: tsx-demo
|
||||
run: npm run check-ts-demo
|
||||
needs: setup
|
||||
|
||||
check_metadata:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
|
@ -18,7 +18,7 @@ import React, { useState } from 'react';
|
||||
import { Affix, Button } from 'antd';
|
||||
|
||||
const Demo: React.FC = () => {
|
||||
const [container, setContainer] = useState(null);
|
||||
const [container, setContainer] = useState<HTMLDivElement | null>(null);
|
||||
return (
|
||||
<div className="scrollable-container" ref={setContainer}>
|
||||
<div className="background">
|
||||
|
@ -996,7 +996,7 @@ Array [
|
||||
|
||||
exports[`renders ./components/alert/demo/error-boundary.md correctly 1`] = `
|
||||
<button
|
||||
class="ant-btn ant-btn-danger"
|
||||
class="ant-btn ant-btn-dangerous"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
|
@ -28,7 +28,7 @@ const ThrowError: React.FC = () => {
|
||||
throw error;
|
||||
}
|
||||
return (
|
||||
<Button type="danger" onClick={onClick}>
|
||||
<Button danger onClick={onClick}>
|
||||
Click me to throw a error
|
||||
</Button>
|
||||
);
|
||||
|
@ -28,7 +28,7 @@ const Complete: React.FC = () => (
|
||||
options={options}
|
||||
placeholder="try to type `b`"
|
||||
filterOption={(inputValue, option) =>
|
||||
option.value.toUpperCase().indexOf(inputValue.toUpperCase()) !== -1
|
||||
option!.value.toUpperCase().indexOf(inputValue.toUpperCase()) !== -1
|
||||
}
|
||||
/>
|
||||
);
|
||||
|
@ -26,7 +26,7 @@ const searchResult = (query: string) => {
|
||||
return new Array(getRandomInt(5))
|
||||
.join('.')
|
||||
.split('.')
|
||||
.map((item, idx) => {
|
||||
.map((_, idx) => {
|
||||
const category = `${query}${idx}`;
|
||||
return {
|
||||
value: category,
|
||||
|
@ -19,7 +19,7 @@ import React, { useState, useRef } from 'react';
|
||||
import { Drawer, ConfigProvider, Button } from 'antd';
|
||||
|
||||
const App: React.FC = () => {
|
||||
const domRef = useRef();
|
||||
const domRef = useRef<HTMLDivElement>(null);
|
||||
const [visible, setVisible] = useState(false);
|
||||
const showDrawer = () => {
|
||||
setVisible(true);
|
||||
@ -30,7 +30,7 @@ const App: React.FC = () => {
|
||||
return (
|
||||
<ConfigProvider
|
||||
getPopupContainer={() => {
|
||||
return domRef.current;
|
||||
return domRef.current!;
|
||||
}}
|
||||
>
|
||||
<div ref={domRef} className="site-drawer-render-in-current-wrapper">
|
||||
|
@ -52,7 +52,7 @@ const AdvancedSearchForm = () => {
|
||||
return children;
|
||||
};
|
||||
|
||||
const onFinish = values => {
|
||||
const onFinish = (values: any) => {
|
||||
console.log('Received values of form: ', values);
|
||||
};
|
||||
|
||||
|
@ -25,11 +25,11 @@ const tailLayout = {
|
||||
};
|
||||
|
||||
const Demo = () => {
|
||||
const onFinish = values => {
|
||||
const onFinish = (values: any) => {
|
||||
console.log('Success:', values);
|
||||
};
|
||||
|
||||
const onFinishFailed = errorInfo => {
|
||||
const onFinishFailed = (errorInfo: any) => {
|
||||
console.log('Failed:', errorInfo);
|
||||
};
|
||||
|
||||
|
@ -33,7 +33,7 @@ const tailLayout = {
|
||||
const Demo = () => {
|
||||
const [form] = Form.useForm();
|
||||
|
||||
const onGenderChange = value => {
|
||||
const onGenderChange = (value: string) => {
|
||||
switch (value) {
|
||||
case 'male':
|
||||
form.setFieldsValue({ note: 'Hi, man!' });
|
||||
@ -47,7 +47,7 @@ const Demo = () => {
|
||||
}
|
||||
};
|
||||
|
||||
const onFinish = values => {
|
||||
const onFinish = (values: any) => {
|
||||
console.log(values);
|
||||
};
|
||||
|
||||
|
@ -30,30 +30,30 @@ const tailLayout = {
|
||||
class Demo extends React.Component {
|
||||
formRef = React.createRef<FormInstance>();
|
||||
|
||||
onGenderChange = value => {
|
||||
onGenderChange = (value: string) => {
|
||||
switch (value) {
|
||||
case 'male':
|
||||
this.formRef.current.setFieldsValue({ note: 'Hi, man!' });
|
||||
this.formRef.current!.setFieldsValue({ note: 'Hi, man!' });
|
||||
return;
|
||||
case 'female':
|
||||
this.formRef.current.setFieldsValue({ note: 'Hi, lady!' });
|
||||
this.formRef.current!.setFieldsValue({ note: 'Hi, lady!' });
|
||||
return;
|
||||
case 'other':
|
||||
this.formRef.current.setFieldsValue({ note: 'Hi there!' });
|
||||
this.formRef.current!.setFieldsValue({ note: 'Hi there!' });
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
onFinish = values => {
|
||||
onFinish = (values: any) => {
|
||||
console.log(values);
|
||||
};
|
||||
|
||||
onReset = () => {
|
||||
this.formRef.current.resetFields();
|
||||
this.formRef.current!.resetFields();
|
||||
};
|
||||
|
||||
onFill = () => {
|
||||
this.formRef.current.setFieldsValue({
|
||||
this.formRef.current!.setFieldsValue({
|
||||
note: 'Hello world!',
|
||||
gender: 'male',
|
||||
});
|
||||
|
@ -25,9 +25,11 @@ import { Form, Input, Select, Button } from 'antd';
|
||||
|
||||
const { Option } = Select;
|
||||
|
||||
type Currency = 'rmb' | 'dollar';
|
||||
|
||||
interface PriceValue {
|
||||
number?: number;
|
||||
currency?: 'rmb' | 'dollar';
|
||||
currency?: Currency;
|
||||
}
|
||||
|
||||
interface PriceInputProps {
|
||||
@ -37,16 +39,16 @@ interface PriceInputProps {
|
||||
|
||||
const PriceInput: React.FC<PriceInputProps> = ({ value = {}, onChange }) => {
|
||||
const [number, setNumber] = useState(0);
|
||||
const [currency, setCurrency] = useState('rmb');
|
||||
const [currency, setCurrency] = useState<Currency>('rmb');
|
||||
|
||||
const triggerChange = changedValue => {
|
||||
const triggerChange = (changedValue: { number?: number; currency?: Currency }) => {
|
||||
if (onChange) {
|
||||
onChange({ number, currency, ...value, ...changedValue });
|
||||
}
|
||||
};
|
||||
|
||||
const onNumberChange = e => {
|
||||
const newNumber = parseInt(e.target.value || 0, 10);
|
||||
const onNumberChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const newNumber = parseInt(e.target.value || '0', 10);
|
||||
if (Number.isNaN(number)) {
|
||||
return;
|
||||
}
|
||||
@ -56,7 +58,7 @@ const PriceInput: React.FC<PriceInputProps> = ({ value = {}, onChange }) => {
|
||||
triggerChange({ number: newNumber });
|
||||
};
|
||||
|
||||
const onCurrencyChange = newCurrency => {
|
||||
const onCurrencyChange = (newCurrency: Currency) => {
|
||||
if (!('currency' in value)) {
|
||||
setCurrency(newCurrency);
|
||||
}
|
||||
@ -84,11 +86,11 @@ const PriceInput: React.FC<PriceInputProps> = ({ value = {}, onChange }) => {
|
||||
};
|
||||
|
||||
const Demo = () => {
|
||||
const onFinish = values => {
|
||||
const onFinish = (values: any) => {
|
||||
console.log('Received values from form: ', values);
|
||||
};
|
||||
|
||||
const checkPrice = (rule, value) => {
|
||||
const checkPrice = (_: any, value: { number: number }) => {
|
||||
if (value.number > 0) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ const DynamicRule = () => {
|
||||
form.validateFields(['nickname']);
|
||||
}, [checkNick]);
|
||||
|
||||
const onCheckboxChange = e => {
|
||||
const onCheckboxChange = (e: { target: { checked: boolean } }) => {
|
||||
setCheckNick(e.target.checked);
|
||||
};
|
||||
|
||||
|
@ -17,6 +17,7 @@ Use `Form.Provider` to process data between forms. In this case, submit button i
|
||||
import React, { useState, useEffect, useRef } from 'react';
|
||||
import { Form, Input, InputNumber, Modal, Button, Avatar, Typography } from 'antd';
|
||||
import { SmileOutlined, UserOutlined } from '@ant-design/icons';
|
||||
import { FormInstance } from 'antd/lib/form';
|
||||
|
||||
const layout = {
|
||||
labelCol: { span: 8 },
|
||||
@ -26,14 +27,19 @@ const tailLayout = {
|
||||
wrapperCol: { offset: 8, span: 16 },
|
||||
};
|
||||
|
||||
interface UserType {
|
||||
name: string;
|
||||
age: string;
|
||||
}
|
||||
|
||||
interface ModalFormProps {
|
||||
visible: boolean;
|
||||
onCancel: () => void;
|
||||
}
|
||||
|
||||
// reset form fields when modal is form, closed
|
||||
const useResetFormOnCloseModal = ({ form, visible }) => {
|
||||
const prevVisibleRef = useRef();
|
||||
const useResetFormOnCloseModal = ({ form, visible }: { form: FormInstance; visible: boolean }) => {
|
||||
const prevVisibleRef = useRef<boolean>();
|
||||
useEffect(() => {
|
||||
prevVisibleRef.current = visible;
|
||||
}, [visible]);
|
||||
@ -83,7 +89,7 @@ const Demo = () => {
|
||||
setVisible(false);
|
||||
};
|
||||
|
||||
const onFinish = values => {
|
||||
const onFinish = (values: any) => {
|
||||
console.log('Finish:', values);
|
||||
};
|
||||
|
||||
@ -108,7 +114,7 @@ const Demo = () => {
|
||||
shouldUpdate={(prevValues, curValues) => prevValues.users !== curValues.users}
|
||||
>
|
||||
{({ getFieldValue }) => {
|
||||
const users = getFieldValue('users') || [];
|
||||
const users: UserType[] = getFieldValue('users') || [];
|
||||
return users.length ? (
|
||||
<ul>
|
||||
{users.map((user, index) => (
|
||||
|
@ -86,7 +86,7 @@ const CollectionCreateForm: React.FC<CollectionCreateFormProps> = ({
|
||||
const CollectionsPage = () => {
|
||||
const [visible, setVisible] = useState(false);
|
||||
|
||||
const onCreate = values => {
|
||||
const onCreate = (values: any) => {
|
||||
console.log('Received values of form: ', values);
|
||||
setVisible(false);
|
||||
};
|
||||
|
@ -22,11 +22,11 @@ import React, { useState } from 'react';
|
||||
import { Form, Input } from 'antd';
|
||||
|
||||
interface FieldData {
|
||||
name: string[];
|
||||
value: any;
|
||||
touched: boolean;
|
||||
validating: boolean;
|
||||
errors: string[];
|
||||
name: string | number | (string | number)[];
|
||||
value?: any;
|
||||
touched?: boolean;
|
||||
validating?: boolean;
|
||||
errors?: string[];
|
||||
}
|
||||
|
||||
interface CustomizedFormProps {
|
||||
@ -40,7 +40,7 @@ const CustomizedForm: React.FC<CustomizedFormProps> = ({ onChange, fields }) =>
|
||||
name="global_state"
|
||||
layout="inline"
|
||||
fields={fields}
|
||||
onFieldsChange={(changedFields, allFields) => {
|
||||
onFieldsChange={(_, allFields) => {
|
||||
onChange(allFields);
|
||||
}}
|
||||
>
|
||||
@ -56,7 +56,7 @@ const CustomizedForm: React.FC<CustomizedFormProps> = ({ onChange, fields }) =>
|
||||
};
|
||||
|
||||
const Demo = () => {
|
||||
const [fields, setFields] = useState([{ name: ['username'], value: 'Ant Design' }]);
|
||||
const [fields, setFields] = useState<FieldData[]>([{ name: ['username'], value: 'Ant Design' }]);
|
||||
|
||||
return (
|
||||
<>
|
||||
|
@ -20,14 +20,14 @@ import { UserOutlined, LockOutlined } from '@ant-design/icons';
|
||||
|
||||
const HorizontalLoginForm = () => {
|
||||
const [form] = Form.useForm();
|
||||
const [, forceUpdate] = useState();
|
||||
const [, forceUpdate] = useState({});
|
||||
|
||||
// To disable submit button at the beginning.
|
||||
useEffect(() => {
|
||||
forceUpdate({});
|
||||
}, []);
|
||||
|
||||
const onFinish = values => {
|
||||
const onFinish = (values: any) => {
|
||||
console.log('Finish:', values);
|
||||
};
|
||||
|
||||
@ -56,7 +56,7 @@ const HorizontalLoginForm = () => {
|
||||
htmlType="submit"
|
||||
disabled={
|
||||
!form.isFieldsTouched(true) ||
|
||||
form.getFieldsError().filter(({ errors }) => errors.length).length
|
||||
!!form.getFieldsError().filter(({ errors }) => errors.length).length
|
||||
}
|
||||
>
|
||||
Log in
|
||||
|
@ -17,11 +17,13 @@ There are three layout for form: `horizontal`, `vertical`, `inline`.
|
||||
import React, { useState } from 'react';
|
||||
import { Form, Input, Button, Radio } from 'antd';
|
||||
|
||||
type LayoutType = Parameters<typeof Form>[0]['layout'];
|
||||
|
||||
const FormLayoutDemo = () => {
|
||||
const [form] = Form.useForm();
|
||||
const [formLayout, setFormLayout] = useState('horizontal');
|
||||
const [formLayout, setFormLayout] = useState<LayoutType>('horizontal');
|
||||
|
||||
const onFormLayoutChange = ({ layout }) => {
|
||||
const onFormLayoutChange = ({ layout }: { layout: LayoutType }) => {
|
||||
setFormLayout(layout);
|
||||
};
|
||||
|
||||
|
@ -33,7 +33,7 @@ const validateMessages = {
|
||||
};
|
||||
|
||||
const Demo = () => {
|
||||
const onFinish = values => {
|
||||
const onFinish = (values: any) => {
|
||||
console.log(values);
|
||||
};
|
||||
|
||||
|
@ -20,7 +20,7 @@ import { Form, Input, Button, Checkbox } from 'antd';
|
||||
import { UserOutlined, LockOutlined } from '@ant-design/icons';
|
||||
|
||||
const NormalLoginForm = () => {
|
||||
const onFinish = values => {
|
||||
const onFinish = (values: any) => {
|
||||
console.log('Received values of form: ', values);
|
||||
};
|
||||
|
||||
|
@ -30,7 +30,6 @@ import {
|
||||
import { QuestionCircleOutlined } from '@ant-design/icons';
|
||||
|
||||
const { Option } = Select;
|
||||
const AutoCompleteOption = AutoComplete.Option;
|
||||
|
||||
const residences = [
|
||||
{
|
||||
@ -93,7 +92,7 @@ const tailFormItemLayout = {
|
||||
const RegistrationForm = () => {
|
||||
const [form] = Form.useForm();
|
||||
|
||||
const onFinish = values => {
|
||||
const onFinish = (values: any) => {
|
||||
console.log('Received values of form: ', values);
|
||||
};
|
||||
|
||||
@ -106,9 +105,9 @@ const RegistrationForm = () => {
|
||||
</Form.Item>
|
||||
);
|
||||
|
||||
const [autoCompleteResult, setAutoCompleteResult] = useState([]);
|
||||
const [autoCompleteResult, setAutoCompleteResult] = useState<string[]>([]);
|
||||
|
||||
const onWebsiteChange = value => {
|
||||
const onWebsiteChange = (value: string) => {
|
||||
if (!value) {
|
||||
setAutoCompleteResult([]);
|
||||
} else {
|
||||
@ -175,7 +174,7 @@ const RegistrationForm = () => {
|
||||
message: 'Please confirm your password!',
|
||||
},
|
||||
({ getFieldValue }) => ({
|
||||
validator(rule, value) {
|
||||
validator(_, value) {
|
||||
if (!value || getFieldValue('password') === value) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
@ -18,11 +18,13 @@ import React, { useState } from 'react';
|
||||
import { Form, Input, Button, Radio } from 'antd';
|
||||
import { InfoCircleOutlined } from '@ant-design/icons';
|
||||
|
||||
type RequiredMark = boolean | 'optional';
|
||||
|
||||
const FormLayoutDemo = () => {
|
||||
const [form] = Form.useForm();
|
||||
const [requiredMark, setRequiredMarkType] = useState<boolean | 'optional'>('optional');
|
||||
const [requiredMark, setRequiredMarkType] = useState<RequiredMark>('optional');
|
||||
|
||||
const onRequiredTypeChange = ({ requiredMark }) => {
|
||||
const onRequiredTypeChange = ({ requiredMark }: { requiredMark: RequiredMark }) => {
|
||||
setRequiredMarkType(requiredMark);
|
||||
};
|
||||
|
||||
|
@ -27,9 +27,12 @@ import {
|
||||
TreeSelect,
|
||||
Switch,
|
||||
} from 'antd';
|
||||
|
||||
type SizeType = Parameters<typeof Form>[0]['size'];
|
||||
|
||||
const FormSizeDemo = () => {
|
||||
const [componentSize, setComponentSize] = useState('default');
|
||||
const onFormLayoutChange = ({ size }) => {
|
||||
const [componentSize, setComponentSize] = useState<SizeType | 'default'>('default');
|
||||
const onFormLayoutChange = ({ size }: { size: SizeType }) => {
|
||||
setComponentSize(size);
|
||||
};
|
||||
return (
|
||||
@ -40,7 +43,7 @@ const FormSizeDemo = () => {
|
||||
layout="horizontal"
|
||||
initialValues={{ size: componentSize }}
|
||||
onValuesChange={onFormLayoutChange}
|
||||
size={componentSize}
|
||||
size={componentSize as SizeType}
|
||||
>
|
||||
<Form.Item label="Form Size" name="size">
|
||||
<Radio.Group>
|
||||
@ -96,5 +99,6 @@ const FormSizeDemo = () => {
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
ReactDOM.render(<FormSizeDemo />, mountNode);
|
||||
```
|
||||
|
@ -29,14 +29,14 @@ const formItemLayout = {
|
||||
},
|
||||
};
|
||||
const config = {
|
||||
rules: [{ type: 'object', required: true, message: 'Please select time!' }],
|
||||
rules: [{ type: 'object' as const, required: true, message: 'Please select time!' }],
|
||||
};
|
||||
const rangeConfig = {
|
||||
rules: [{ type: 'array', required: true, message: 'Please select time!' }],
|
||||
rules: [{ type: 'array' as const, required: true, message: 'Please select time!' }],
|
||||
};
|
||||
|
||||
const TimeRelatedForm = () => {
|
||||
const onFinish = fieldsValue => {
|
||||
const onFinish = (fieldsValue: any) => {
|
||||
// Should format date value before submit.
|
||||
const rangeValue = fieldsValue['range-picker'];
|
||||
const rangeTimeValue = fieldsValue['range-time-picker'];
|
||||
|
@ -37,7 +37,7 @@ const formItemLayout = {
|
||||
wrapperCol: { span: 14 },
|
||||
};
|
||||
|
||||
const normFile = e => {
|
||||
const normFile = (e: any) => {
|
||||
console.log('Upload event:', e);
|
||||
if (Array.isArray(e)) {
|
||||
return e;
|
||||
@ -46,7 +46,7 @@ const normFile = e => {
|
||||
};
|
||||
|
||||
const Demo = () => {
|
||||
const onFinish = values => {
|
||||
const onFinish = (values: any) => {
|
||||
console.log('Received values of form: ', values);
|
||||
};
|
||||
|
||||
|
@ -17,7 +17,11 @@ title:
|
||||
import React, { useState } from 'react';
|
||||
import { Form, InputNumber } from 'antd';
|
||||
|
||||
function validatePrimeNumber(number) {
|
||||
type ValidateStatus = Parameters<typeof Form.Item>[0]['validateStatus'];
|
||||
|
||||
function validatePrimeNumber(
|
||||
number: number,
|
||||
): { validateStatus: ValidateStatus; errorMsg: string | null } {
|
||||
if (number === 11) {
|
||||
return {
|
||||
validateStatus: 'success',
|
||||
@ -36,14 +40,18 @@ const formItemLayout = {
|
||||
};
|
||||
|
||||
const RawForm = () => {
|
||||
const [number, setNumber] = useState({
|
||||
const [number, setNumber] = useState<{
|
||||
value: number;
|
||||
validateStatus?: ValidateStatus;
|
||||
errorMsg?: string | null;
|
||||
}>({
|
||||
value: 11,
|
||||
});
|
||||
|
||||
const tips =
|
||||
'A prime is a natural number greater than 1 that has no positive divisors other than 1 and itself.';
|
||||
|
||||
const onNumberChange = value => {
|
||||
const onNumberChange = (value: number) => {
|
||||
setNumber({
|
||||
...validatePrimeNumber(value),
|
||||
value,
|
||||
|
@ -34,7 +34,7 @@ const App = () => {
|
||||
}
|
||||
};
|
||||
|
||||
const checkMention = async (rule, value, callback) => {
|
||||
const checkMention = async (_: any, value: string) => {
|
||||
const mentions = getMentions(value);
|
||||
|
||||
if (mentions.length < 2) {
|
||||
@ -51,7 +51,7 @@ const App = () => {
|
||||
wrapperCol={{ span: 16 }}
|
||||
rules={[{ validator: checkMention }]}
|
||||
>
|
||||
<Mentions rows="1">
|
||||
<Mentions rows={1}>
|
||||
<Option value="afc163">afc163</Option>
|
||||
<Option value="zombieJ">zombieJ</Option>
|
||||
<Option value="yesmeck">yesmeck</Option>
|
||||
@ -64,7 +64,7 @@ const App = () => {
|
||||
wrapperCol={{ span: 16 }}
|
||||
rules={[{ required: true }]}
|
||||
>
|
||||
<Mentions rows="3" placeholder="You can use @ to ref user here">
|
||||
<Mentions rows={3} placeholder="You can use @ to ref user here">
|
||||
<Option value="afc163">afc163</Option>
|
||||
<Option value="zombieJ">zombieJ</Option>
|
||||
<Option value="yesmeck">yesmeck</Option>
|
||||
|
@ -4166,7 +4166,9 @@ exports[`renders ./components/table/demo/edit-row.md correctly 1`] = `
|
||||
<td
|
||||
class="ant-table-cell"
|
||||
>
|
||||
<a>
|
||||
<a
|
||||
class="ant-typography"
|
||||
>
|
||||
Edit
|
||||
</a>
|
||||
</td>
|
||||
@ -4193,7 +4195,9 @@ exports[`renders ./components/table/demo/edit-row.md correctly 1`] = `
|
||||
<td
|
||||
class="ant-table-cell"
|
||||
>
|
||||
<a>
|
||||
<a
|
||||
class="ant-typography"
|
||||
>
|
||||
Edit
|
||||
</a>
|
||||
</td>
|
||||
@ -4220,7 +4224,9 @@ exports[`renders ./components/table/demo/edit-row.md correctly 1`] = `
|
||||
<td
|
||||
class="ant-table-cell"
|
||||
>
|
||||
<a>
|
||||
<a
|
||||
class="ant-typography"
|
||||
>
|
||||
Edit
|
||||
</a>
|
||||
</td>
|
||||
@ -4247,7 +4253,9 @@ exports[`renders ./components/table/demo/edit-row.md correctly 1`] = `
|
||||
<td
|
||||
class="ant-table-cell"
|
||||
>
|
||||
<a>
|
||||
<a
|
||||
class="ant-typography"
|
||||
>
|
||||
Edit
|
||||
</a>
|
||||
</td>
|
||||
@ -4274,7 +4282,9 @@ exports[`renders ./components/table/demo/edit-row.md correctly 1`] = `
|
||||
<td
|
||||
class="ant-table-cell"
|
||||
>
|
||||
<a>
|
||||
<a
|
||||
class="ant-typography"
|
||||
>
|
||||
Edit
|
||||
</a>
|
||||
</td>
|
||||
@ -4301,7 +4311,9 @@ exports[`renders ./components/table/demo/edit-row.md correctly 1`] = `
|
||||
<td
|
||||
class="ant-table-cell"
|
||||
>
|
||||
<a>
|
||||
<a
|
||||
class="ant-typography"
|
||||
>
|
||||
Edit
|
||||
</a>
|
||||
</td>
|
||||
@ -4328,7 +4340,9 @@ exports[`renders ./components/table/demo/edit-row.md correctly 1`] = `
|
||||
<td
|
||||
class="ant-table-cell"
|
||||
>
|
||||
<a>
|
||||
<a
|
||||
class="ant-typography"
|
||||
>
|
||||
Edit
|
||||
</a>
|
||||
</td>
|
||||
@ -4355,7 +4369,9 @@ exports[`renders ./components/table/demo/edit-row.md correctly 1`] = `
|
||||
<td
|
||||
class="ant-table-cell"
|
||||
>
|
||||
<a>
|
||||
<a
|
||||
class="ant-typography"
|
||||
>
|
||||
Edit
|
||||
</a>
|
||||
</td>
|
||||
@ -4382,7 +4398,9 @@ exports[`renders ./components/table/demo/edit-row.md correctly 1`] = `
|
||||
<td
|
||||
class="ant-table-cell"
|
||||
>
|
||||
<a>
|
||||
<a
|
||||
class="ant-typography"
|
||||
>
|
||||
Edit
|
||||
</a>
|
||||
</td>
|
||||
@ -4409,7 +4427,9 @@ exports[`renders ./components/table/demo/edit-row.md correctly 1`] = `
|
||||
<td
|
||||
class="ant-table-cell"
|
||||
>
|
||||
<a>
|
||||
<a
|
||||
class="ant-typography"
|
||||
>
|
||||
Edit
|
||||
</a>
|
||||
</td>
|
||||
|
@ -16,8 +16,9 @@ Table with editable cells.
|
||||
```tsx
|
||||
import React, { useContext, useState, useEffect, useRef } from 'react';
|
||||
import { Table, Input, Button, Popconfirm, Form } from 'antd';
|
||||
import { FormInstance } from 'antd/lib/form';
|
||||
|
||||
const EditableContext = React.createContext<any>();
|
||||
const EditableContext = React.createContext<FormInstance<any> | null>(null);
|
||||
|
||||
interface Item {
|
||||
key: string;
|
||||
@ -45,7 +46,7 @@ interface EditableCellProps {
|
||||
title: React.ReactNode;
|
||||
editable: boolean;
|
||||
children: React.ReactNode;
|
||||
dataIndex: string;
|
||||
dataIndex: keyof Item;
|
||||
record: Item;
|
||||
handleSave: (record: Item) => void;
|
||||
}
|
||||
@ -60,12 +61,12 @@ const EditableCell: React.FC<EditableCellProps> = ({
|
||||
...restProps
|
||||
}) => {
|
||||
const [editing, setEditing] = useState(false);
|
||||
const inputRef = useRef();
|
||||
const form = useContext(EditableContext);
|
||||
const inputRef = useRef<Input>(null);
|
||||
const form = useContext(EditableContext)!;
|
||||
|
||||
useEffect(() => {
|
||||
if (editing) {
|
||||
inputRef.current.focus();
|
||||
inputRef.current!.focus();
|
||||
}
|
||||
}, [editing]);
|
||||
|
||||
@ -74,7 +75,7 @@ const EditableCell: React.FC<EditableCellProps> = ({
|
||||
form.setFieldsValue({ [dataIndex]: record[dataIndex] });
|
||||
};
|
||||
|
||||
const save = async e => {
|
||||
const save = async () => {
|
||||
try {
|
||||
const values = await form.validateFields();
|
||||
|
||||
@ -111,9 +112,28 @@ const EditableCell: React.FC<EditableCellProps> = ({
|
||||
return <td {...restProps}>{childNode}</td>;
|
||||
};
|
||||
|
||||
class EditableTable extends React.Component {
|
||||
constructor(props) {
|
||||
type EditableTableProps = Parameters<typeof Table>[0];
|
||||
|
||||
interface DataType {
|
||||
key: React.Key;
|
||||
name: string;
|
||||
age: string;
|
||||
address: string;
|
||||
}
|
||||
|
||||
interface EditableTableState {
|
||||
dataSource: DataType[];
|
||||
count: number;
|
||||
}
|
||||
|
||||
type ColumnTypes = Exclude<EditableTableProps['columns'], undefined>;
|
||||
|
||||
class EditableTable extends React.Component<EditableTableProps, EditableTableState> {
|
||||
columns: (ColumnTypes[number] & { editable?: boolean; dataIndex: string })[];
|
||||
|
||||
constructor(props: EditableTableProps) {
|
||||
super(props);
|
||||
|
||||
this.columns = [
|
||||
{
|
||||
title: 'name',
|
||||
@ -132,7 +152,7 @@ class EditableTable extends React.Component {
|
||||
{
|
||||
title: 'operation',
|
||||
dataIndex: 'operation',
|
||||
render: (text, record) =>
|
||||
render: (_, record: { key: React.Key }) =>
|
||||
this.state.dataSource.length >= 1 ? (
|
||||
<Popconfirm title="Sure to delete?" onConfirm={() => this.handleDelete(record.key)}>
|
||||
<a>Delete</a>
|
||||
@ -160,17 +180,17 @@ class EditableTable extends React.Component {
|
||||
};
|
||||
}
|
||||
|
||||
handleDelete = key => {
|
||||
handleDelete = (key: React.Key) => {
|
||||
const dataSource = [...this.state.dataSource];
|
||||
this.setState({ dataSource: dataSource.filter(item => item.key !== key) });
|
||||
};
|
||||
|
||||
handleAdd = () => {
|
||||
const { count, dataSource } = this.state;
|
||||
const newData = {
|
||||
const newData: DataType = {
|
||||
key: count,
|
||||
name: `Edward King ${count}`,
|
||||
age: 32,
|
||||
age: '32',
|
||||
address: `London, Park Lane no. ${count}`,
|
||||
};
|
||||
this.setState({
|
||||
@ -179,7 +199,7 @@ class EditableTable extends React.Component {
|
||||
});
|
||||
};
|
||||
|
||||
handleSave = row => {
|
||||
handleSave = (row: DataType) => {
|
||||
const newData = [...this.state.dataSource];
|
||||
const index = newData.findIndex(item => row.key === item.key);
|
||||
const item = newData[index];
|
||||
@ -204,7 +224,7 @@ class EditableTable extends React.Component {
|
||||
}
|
||||
return {
|
||||
...col,
|
||||
onCell: record => ({
|
||||
onCell: (record: DataType) => ({
|
||||
record,
|
||||
editable: col.editable,
|
||||
dataIndex: col.dataIndex,
|
||||
@ -223,7 +243,7 @@ class EditableTable extends React.Component {
|
||||
rowClassName={() => 'editable-row'}
|
||||
bordered
|
||||
dataSource={dataSource}
|
||||
columns={columns}
|
||||
columns={columns as ColumnTypes}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
@ -17,7 +17,7 @@ Table with editable rows.
|
||||
|
||||
```tsx
|
||||
import React, { useState } from 'react';
|
||||
import { Table, Input, InputNumber, Popconfirm, Form } from 'antd';
|
||||
import { Table, Input, InputNumber, Popconfirm, Form, Typography } from 'antd';
|
||||
|
||||
interface Item {
|
||||
key: string;
|
||||
@ -86,7 +86,7 @@ const EditableTable = () => {
|
||||
|
||||
const isEditing = (record: Item) => record.key === editingKey;
|
||||
|
||||
const edit = (record: Item) => {
|
||||
const edit = (record: Partial<Item> & { key: React.Key }) => {
|
||||
form.setFieldsValue({ name: '', age: '', address: '', ...record });
|
||||
setEditingKey(record.key);
|
||||
};
|
||||
@ -153,9 +153,9 @@ const EditableTable = () => {
|
||||
</Popconfirm>
|
||||
</span>
|
||||
) : (
|
||||
<a disabled={editingKey !== ''} onClick={() => edit(record)}>
|
||||
<Typography.Link disabled={editingKey !== ''} onClick={() => edit(record)}>
|
||||
Edit
|
||||
</a>
|
||||
</Typography.Link>
|
||||
);
|
||||
},
|
||||
},
|
||||
|
@ -25,7 +25,7 @@ const columns = [
|
||||
{
|
||||
title: 'Name',
|
||||
dataIndex: 'name',
|
||||
render: text => <a>{text}</a>,
|
||||
render: (text: string) => <a>{text}</a>,
|
||||
},
|
||||
{
|
||||
title: 'Age',
|
||||
@ -36,7 +36,15 @@ const columns = [
|
||||
dataIndex: 'address',
|
||||
},
|
||||
];
|
||||
const data = [
|
||||
|
||||
interface DataType {
|
||||
key: React.Key;
|
||||
name: string;
|
||||
age: number;
|
||||
address: string;
|
||||
}
|
||||
|
||||
const data: DataType[] = [
|
||||
{
|
||||
key: '1',
|
||||
name: 'John Brown',
|
||||
@ -65,17 +73,17 @@ const data = [
|
||||
|
||||
// rowSelection object indicates the need for row selection
|
||||
const rowSelection = {
|
||||
onChange: (selectedRowKeys, selectedRows) => {
|
||||
onChange: (selectedRowKeys: React.Key[], selectedRows: DataType[]) => {
|
||||
console.log(`selectedRowKeys: ${selectedRowKeys}`, 'selectedRows: ', selectedRows);
|
||||
},
|
||||
getCheckboxProps: record => ({
|
||||
getCheckboxProps: (record: DataType) => ({
|
||||
disabled: record.name === 'Disabled User', // Column configuration not to be checked
|
||||
name: record.name,
|
||||
}),
|
||||
};
|
||||
|
||||
const Demo = () => {
|
||||
const [selectionType, setSelectionType] = useState('checkbox');
|
||||
const [selectionType, setSelectionType] = useState<'checkbox' | 'radio'>('checkbox');
|
||||
|
||||
return (
|
||||
<div>
|
||||
|
@ -20,12 +20,12 @@ import ResizeObserver from 'rc-resize-observer';
|
||||
import classNames from 'classnames';
|
||||
import { Table } from 'antd';
|
||||
|
||||
function VirtualTable(props) {
|
||||
function VirtualTable(props: Parameters<typeof Table>[0]) {
|
||||
const { columns, scroll } = props;
|
||||
const [tableWidth, setTableWidth] = useState(0);
|
||||
|
||||
const widthColumnCount = columns.filter(({ width }) => !width).length;
|
||||
const mergedColumns = columns.map(column => {
|
||||
const widthColumnCount = columns!.filter(({ width }) => !width).length;
|
||||
const mergedColumns = columns!.map(column => {
|
||||
if (column.width) {
|
||||
return column;
|
||||
}
|
||||
@ -69,28 +69,36 @@ function VirtualTable(props) {
|
||||
ref={gridRef}
|
||||
className="virtual-grid"
|
||||
columnCount={mergedColumns.length}
|
||||
columnWidth={index => {
|
||||
columnWidth={(index: number) => {
|
||||
const { width } = mergedColumns[index];
|
||||
return totalHeight > scroll.y && index === mergedColumns.length - 1
|
||||
? width - scrollbarSize - 1
|
||||
: width;
|
||||
return totalHeight > scroll!.y! && index === mergedColumns.length - 1
|
||||
? (width as number) - scrollbarSize - 1
|
||||
: (width as number);
|
||||
}}
|
||||
height={scroll.y}
|
||||
height={scroll!.y as number}
|
||||
rowCount={rawData.length}
|
||||
rowHeight={() => 54}
|
||||
width={tableWidth}
|
||||
onScroll={({ scrollLeft }) => {
|
||||
onScroll={({ scrollLeft }: { scrollLeft: number }) => {
|
||||
onScroll({ scrollLeft });
|
||||
}}
|
||||
>
|
||||
{({ columnIndex, rowIndex, style }) => (
|
||||
{({
|
||||
columnIndex,
|
||||
rowIndex,
|
||||
style,
|
||||
}: {
|
||||
columnIndex: number;
|
||||
rowIndex: number;
|
||||
style: React.CSSProperties;
|
||||
}) => (
|
||||
<div
|
||||
className={classNames('virtual-table-cell', {
|
||||
'virtual-table-cell-last': columnIndex === mergedColumns.length - 1,
|
||||
})}
|
||||
style={style}
|
||||
>
|
||||
{rawData[rowIndex][mergedColumns[columnIndex].dataIndex]}
|
||||
{(rawData[rowIndex] as any)[(mergedColumns as any)[columnIndex].dataIndex]}
|
||||
</div>
|
||||
)}
|
||||
</Grid>
|
||||
|
@ -62,12 +62,12 @@ const treeData = [
|
||||
];
|
||||
|
||||
const Demo = () => {
|
||||
const [expandedKeys, setExpandedKeys] = useState<string[]>(['0-0-0', '0-0-1']);
|
||||
const [checkedKeys, setCheckedKeys] = useState<string[]>(['0-0-0']);
|
||||
const [selectedKeys, setSelectedKeys] = useState<string[]>([]);
|
||||
const [expandedKeys, setExpandedKeys] = useState<React.Key[]>(['0-0-0', '0-0-1']);
|
||||
const [checkedKeys, setCheckedKeys] = useState<React.Key[]>(['0-0-0']);
|
||||
const [selectedKeys, setSelectedKeys] = useState<React.Key[]>([]);
|
||||
const [autoExpandParent, setAutoExpandParent] = useState<boolean>(true);
|
||||
|
||||
const onExpand = expandedKeys => {
|
||||
const onExpand = (expandedKeys: React.Key[]) => {
|
||||
console.log('onExpand', expandedKeys);
|
||||
// if not set autoExpandParent to false, if children expanded, parent can not collapse.
|
||||
// or, you can remove all expanded children keys.
|
||||
@ -75,12 +75,12 @@ const Demo = () => {
|
||||
setAutoExpandParent(false);
|
||||
};
|
||||
|
||||
const onCheck = checkedKeys => {
|
||||
const onCheck = (checkedKeys: React.Key[]) => {
|
||||
console.log('onCheck', checkedKeys);
|
||||
setCheckedKeys(checkedKeys);
|
||||
};
|
||||
|
||||
const onSelect = (selectedKeys, info) => {
|
||||
const onSelect = (selectedKeys: React.Key[], info: any) => {
|
||||
console.log('onSelect', info);
|
||||
setSelectedKeys(selectedKeys);
|
||||
};
|
||||
|
@ -47,11 +47,11 @@ const treeData = [
|
||||
];
|
||||
|
||||
const Demo = () => {
|
||||
const onSelect = (selectedKeys, info) => {
|
||||
const onSelect = (selectedKeys: React.Key[], info: any) => {
|
||||
console.log('selected', selectedKeys, info);
|
||||
};
|
||||
|
||||
const onCheck = (checkedKeys, info) => {
|
||||
const onCheck = (checkedKeys: React.Key[], info: any) => {
|
||||
console.log('onCheck', checkedKeys, info);
|
||||
};
|
||||
|
||||
|
@ -38,8 +38,8 @@ const treeData = [
|
||||
];
|
||||
|
||||
const Demo: React.FC<{}> = () => {
|
||||
const onSelect = (keys, event) => {
|
||||
console.log('Trigger Select', keys, event);
|
||||
const onSelect = (keys: React.Key[], info: any) => {
|
||||
console.log('Trigger Select', keys, info);
|
||||
};
|
||||
|
||||
const onExpand = () => {
|
||||
|
@ -51,8 +51,8 @@ function updateTreeData(list: DataNode[], key: React.Key, children: DataNode[]):
|
||||
const Demo: React.FC<{}> = () => {
|
||||
const [treeData, setTreeData] = useState(initTreeDate);
|
||||
|
||||
function onLoadData({ key, children }) {
|
||||
return new Promise(resolve => {
|
||||
function onLoadData({ key, children }: any) {
|
||||
return new Promise<void>(resolve => {
|
||||
if (children) {
|
||||
resolve();
|
||||
return;
|
||||
|
@ -84,20 +84,20 @@ const treeData = [
|
||||
];
|
||||
|
||||
const Demo: React.FC<{}> = () => {
|
||||
const [showLine, setShowLine] = useState(true);
|
||||
const [showIcon, setShowIcon] = useState(false);
|
||||
const [showLeafIcon, setShowLeafIcon] = useState(true);
|
||||
const [showLine, setShowLine] = useState<boolean | { showLeafIcon: boolean }>(true);
|
||||
const [showIcon, setShowIcon] = useState<boolean>(false);
|
||||
const [showLeafIcon, setShowLeafIcon] = useState<boolean>(true);
|
||||
|
||||
const onSelect = (selectedKeys, info) => {
|
||||
const onSelect = (selectedKeys: React.Key[], info: any) => {
|
||||
console.log('selected', selectedKeys, info);
|
||||
};
|
||||
|
||||
const onSetLeafIcon = checked => {
|
||||
const onSetLeafIcon = (checked: boolean) => {
|
||||
setShowLeafIcon(checked);
|
||||
setShowLine({ showLeafIcon: checked });
|
||||
};
|
||||
|
||||
const onSetShowLine = checked => {
|
||||
const onSetShowLine = (checked: boolean) => {
|
||||
if (checked) {
|
||||
showLeafIcon ? setShowLine(checked) : setShowLine({ showLeafIcon });
|
||||
} else {
|
||||
@ -108,7 +108,7 @@ const Demo: React.FC<{}> = () => {
|
||||
return (
|
||||
<div>
|
||||
<div style={{ marginBottom: 16 }}>
|
||||
showLine: <Switch checked={showLine} onChange={onSetShowLine} />
|
||||
showLine: <Switch checked={!!showLine} onChange={onSetShowLine} />
|
||||
<br />
|
||||
<br />
|
||||
showIcon: <Switch checked={showIcon} onChange={setShowIcon} />
|
||||
|
@ -231,6 +231,7 @@ const InternalUpload: React.ForwardRefRenderFunction<unknown, UploadProps> = (pr
|
||||
...props,
|
||||
prefixCls,
|
||||
beforeUpload,
|
||||
onChange: undefined,
|
||||
};
|
||||
|
||||
delete rcUploadProps.className;
|
||||
|
@ -1,4 +1,5 @@
|
||||
import * as React from 'react';
|
||||
import { UploadRequestOption as RcCustomRequestOptions } from 'rc-upload/lib/interface';
|
||||
import { ProgressProps } from '../progress';
|
||||
|
||||
export type UploadFileStatus = 'error' | 'success' | 'done' | 'uploading' | 'removed';
|
||||
@ -13,18 +14,6 @@ export interface RcFile extends File {
|
||||
readonly webkitRelativePath: string;
|
||||
}
|
||||
|
||||
export interface RcCustomRequestOptions {
|
||||
onProgress: (event: { percent: number }, file: RcFile) => void;
|
||||
onError: (error: Error, response?: any, file?: RcFile) => void;
|
||||
onSuccess: (response: object, file: RcFile) => void;
|
||||
data: object;
|
||||
filename: string;
|
||||
file: RcFile;
|
||||
withCredentials: boolean;
|
||||
action: string;
|
||||
headers: object;
|
||||
}
|
||||
|
||||
export interface UploadFile<T = any> {
|
||||
uid: string;
|
||||
size: number;
|
||||
@ -96,7 +85,7 @@ export interface UploadProps<T = any> {
|
||||
showUploadList?: boolean | ShowUploadListInterface;
|
||||
multiple?: boolean;
|
||||
accept?: string;
|
||||
beforeUpload?: (file: RcFile, FileList: RcFile[]) => boolean | PromiseLike<void | Blob | File>;
|
||||
beforeUpload?: (file: RcFile, FileList: RcFile[]) => boolean | Promise<void | Blob | File>;
|
||||
onChange?: (info: UploadChangeParam) => void;
|
||||
listType?: UploadListType;
|
||||
className?: string;
|
||||
|
@ -51,6 +51,7 @@
|
||||
"build": "npm run compile && NODE_OPTIONS='--max-old-space-size=4096' npm run dist",
|
||||
"bundlesize": "bundlesize",
|
||||
"check-commit": "node ./scripts/check-commit",
|
||||
"check-ts-demo": "node ./scripts/check-ts-demo",
|
||||
"prestart": "npm run version",
|
||||
"precompile": "npm run version",
|
||||
"pretest": "npm run version",
|
||||
@ -122,7 +123,7 @@
|
||||
"rc-dialog": "~8.4.0",
|
||||
"rc-drawer": "~4.1.0",
|
||||
"rc-dropdown": "~3.2.0",
|
||||
"rc-field-form": "~1.17.0",
|
||||
"rc-field-form": "~1.17.3",
|
||||
"rc-image": "~4.2.0",
|
||||
"rc-input-number": "~6.1.0",
|
||||
"rc-mentions": "~1.5.0",
|
||||
@ -144,7 +145,7 @@
|
||||
"rc-tooltip": "~5.0.0",
|
||||
"rc-tree": "~4.0.0",
|
||||
"rc-tree-select": "~4.2.0",
|
||||
"rc-upload": "~3.3.1",
|
||||
"rc-upload": "~3.3.4",
|
||||
"rc-util": "^5.1.0",
|
||||
"scroll-into-view-if-needed": "^2.2.25",
|
||||
"warning": "^4.0.3"
|
||||
@ -167,6 +168,7 @@
|
||||
"@types/react-color": "^3.0.1",
|
||||
"@types/react-copy-to-clipboard": "^5.0.0",
|
||||
"@types/react-dom": "^17.0.0",
|
||||
"@types/react-window": "^1.8.2",
|
||||
"@types/warning": "^3.0.0",
|
||||
"@typescript-eslint/eslint-plugin": "^4.1.1",
|
||||
"@typescript-eslint/parser": "^4.1.1",
|
||||
|
88
scripts/check-ts-demo.js
Normal file
88
scripts/check-ts-demo.js
Normal file
@ -0,0 +1,88 @@
|
||||
/* eslint-disable no-await-in-loop, no-console */
|
||||
|
||||
const path = require('path');
|
||||
const glob = require('glob');
|
||||
const fs = require('fs-extra');
|
||||
const chalk = require('chalk');
|
||||
const { spawn } = require('child_process');
|
||||
|
||||
(async () => {
|
||||
console.time('Execution...');
|
||||
|
||||
const demoFiles = glob.sync(path.join(process.cwd(), 'components/**/demo/*.md'));
|
||||
|
||||
const tmpFolder = path.resolve('components', '~tmp');
|
||||
await fs.remove(tmpFolder);
|
||||
await fs.ensureDir(tmpFolder);
|
||||
|
||||
function getTypescriptDemo(content, demoPath) {
|
||||
const lines = content.split(/[\n\r]/);
|
||||
|
||||
const tsxStartLine = lines.findIndex(line =>
|
||||
line.replace(/\s/g).toLowerCase().includes('```tsx'),
|
||||
);
|
||||
|
||||
if (tsxStartLine < 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const tsxEndLine = lines.findIndex(
|
||||
(line, index) => index > tsxStartLine && line.trim() === '```',
|
||||
);
|
||||
|
||||
let script = lines.slice(tsxStartLine + 1, tsxEndLine).join('\n');
|
||||
|
||||
// insert React & ReactDOM
|
||||
if (!script.includes('import React') && !script.includes('import * as React')) {
|
||||
script = `import React from 'react';\n${script}`;
|
||||
}
|
||||
script = `import ReactDOM from 'react-dom';\n${script}`;
|
||||
|
||||
// Replace mountNode
|
||||
script = script.replace('mountNode', `document.getElementById('#root')`);
|
||||
|
||||
// Replace antd
|
||||
script = script.replace(`from 'antd'`, `from '..'`);
|
||||
|
||||
// Add path
|
||||
script = `/* eslint-disabled */\n// ${demoPath}\n${script}`;
|
||||
|
||||
return script;
|
||||
}
|
||||
|
||||
for (let i = 0; i < demoFiles.length; i += 1) {
|
||||
const demoPath = demoFiles[i];
|
||||
|
||||
const content = await fs.readFile(demoPath, 'utf8');
|
||||
const script = getTypescriptDemo(content, demoPath);
|
||||
|
||||
const dirs = path.dirname(demoPath).split(path.sep);
|
||||
|
||||
// Parse TSX
|
||||
if (script) {
|
||||
const tmpFile = path.join(
|
||||
tmpFolder,
|
||||
`${dirs[dirs.length - 2]}-${path.basename(demoPath).replace(/\..*/, '')}.tsx`,
|
||||
);
|
||||
await fs.writeFile(tmpFile, script, 'utf8');
|
||||
}
|
||||
}
|
||||
|
||||
const child = spawn('npm', ['run', 'tsc']);
|
||||
|
||||
child.stdout.pipe(process.stdout);
|
||||
child.stderr.pipe(process.stderr);
|
||||
|
||||
child.on('exit', async code => {
|
||||
console.timeEnd('Execution...');
|
||||
|
||||
if (code) {
|
||||
console.log(chalk.red('💥 OPS! Seems some tsx demo not pass tsc...'));
|
||||
} else {
|
||||
await fs.remove(tmpFolder);
|
||||
console.log(chalk.green('🤪 All tsx demo passed. Congratulations!'));
|
||||
}
|
||||
|
||||
process.exit(code);
|
||||
});
|
||||
})();
|
2
typings/custom-typings.d.ts
vendored
2
typings/custom-typings.d.ts
vendored
@ -50,8 +50,6 @@ declare module 'rc-steps';
|
||||
|
||||
declare module 'rc-switch';
|
||||
|
||||
declare module 'rc-upload';
|
||||
|
||||
declare module '*.json' {
|
||||
const value: any;
|
||||
export const version: string;
|
||||
|
Loading…
Reference in New Issue
Block a user