diff --git a/__tests__/renderers/Form/__snapshots__/datetime.test.tsx.snap b/__tests__/renderers/Form/__snapshots__/datetime.test.tsx.snap
index 46239e57d..4575d1916 100644
--- a/__tests__/renderers/Form/__snapshots__/datetime.test.tsx.snap
+++ b/__tests__/renderers/Form/__snapshots__/datetime.test.tsx.snap
@@ -56,11 +56,12 @@ exports[`Renderer:date 1`] = `
class="cxd-DatePicker"
tabindex="0"
>
-
- 2019-06-06 21:11:00
-
+
diff --git a/__tests__/renderers/Form/__snapshots__/inputDate.test.tsx.snap b/__tests__/renderers/Form/__snapshots__/inputDate.test.tsx.snap
index 723b7f43f..e29b39f60 100644
--- a/__tests__/renderers/Form/__snapshots__/inputDate.test.tsx.snap
+++ b/__tests__/renderers/Form/__snapshots__/inputDate.test.tsx.snap
@@ -56,11 +56,12 @@ exports[`Renderer:inputDate 1`] = `
class="cxd-DatePicker"
tabindex="0"
>
-
- 2019-06-07
-
+
diff --git a/__tests__/renderers/Form/datetime.test.tsx b/__tests__/renderers/Form/datetime.test.tsx
index f03a30c9a..496a555d5 100644
--- a/__tests__/renderers/Form/datetime.test.tsx
+++ b/__tests__/renderers/Form/datetime.test.tsx
@@ -31,8 +31,11 @@ test('Renderer:date', async () => {
)
);
- const input = container.querySelector('.cxd-DatePicker-value');
- expect(input?.innerHTML).toEqual(
+ const input = container.querySelector(
+ '.cxd-DatePicker input'
+ )! as HTMLInputElement;
+
+ expect(input.value).toEqual(
moment(1559826660, 'X').format('YYYY-MM-DD HH:mm:ss')
);
diff --git a/__tests__/renderers/Form/inputDate.test.tsx b/__tests__/renderers/Form/inputDate.test.tsx
index 0d983da39..4582af62b 100644
--- a/__tests__/renderers/Form/inputDate.test.tsx
+++ b/__tests__/renderers/Form/inputDate.test.tsx
@@ -31,10 +31,10 @@ test('Renderer:inputDate', async () => {
)
);
- const input = container.querySelector('.cxd-DatePicker-value');
- expect(input?.innerHTML).toEqual(
- moment(1559836800, 'X').format('YYYY-MM-DD')
- );
+ const input = container.querySelector(
+ '.cxd-DatePicker input'
+ )! as HTMLInputElement;
+ expect(input.value).toEqual(moment(1559836800, 'X').format('YYYY-MM-DD'));
expect(container).toMatchSnapshot();
});
diff --git a/__tests__/renderers/Form/inputMonth.test.tsx b/__tests__/renderers/Form/inputMonth.test.tsx
index ccbbf48d5..09de307bc 100644
--- a/__tests__/renderers/Form/inputMonth.test.tsx
+++ b/__tests__/renderers/Form/inputMonth.test.tsx
@@ -8,27 +8,28 @@ import {makeEnv} from '../../helper';
import moment from 'moment';
test('Renderer:inputMonth click', async () => {
- const {container, findByText} = render(
- amisRender(
- {
- type: 'form',
- api: '/api/xxx',
- body: [
- {
- type: 'input-month',
- name: 'month',
- label: '时间'
- }
- ],
- title: 'The form',
- actions: []
- },
- {},
- makeEnv({})
- )
- );
+ const {container, findByText, findByPlaceholderText, findByDisplayValue} =
+ render(
+ amisRender(
+ {
+ type: 'form',
+ api: '/api/xxx',
+ body: [
+ {
+ type: 'input-month',
+ name: 'month',
+ label: '时间'
+ }
+ ],
+ title: 'The form',
+ actions: []
+ },
+ {},
+ makeEnv({})
+ )
+ );
- const inputDate = await findByText('请选择月份');
+ const inputDate = await findByPlaceholderText('请选择月份');
fireEvent.click(inputDate);
@@ -43,11 +44,11 @@ test('Renderer:inputMonth click', async () => {
const lastYearMonth = moment().subtract(1, 'year').format('YYYY') + '-01';
- await findByText(lastYearMonth);
+ await findByDisplayValue(lastYearMonth);
const value = document.querySelector(
- '.cxd-DatePicker-value'
- ) as HTMLSpanElement;
+ '.cxd-DatePicker input'
+ ) as HTMLInputElement;
- expect(value.innerHTML).toEqual(lastYearMonth);
+ expect(value.value).toEqual(lastYearMonth);
});
diff --git a/__tests__/renderers/Form/inputYear.test.tsx b/__tests__/renderers/Form/inputYear.test.tsx
index 8da3f5e8e..9e617a54b 100644
--- a/__tests__/renderers/Form/inputYear.test.tsx
+++ b/__tests__/renderers/Form/inputYear.test.tsx
@@ -8,7 +8,7 @@ import {makeEnv} from '../../helper';
import moment from 'moment';
test('Renderer:inputYear click', async () => {
- const {container, findByText} = render(
+ const {container, findByPlaceholderText, findByText} = render(
amisRender(
{
type: 'form',
@@ -28,7 +28,7 @@ test('Renderer:inputYear click', async () => {
)
);
- const inputDate = await findByText('请选择年');
+ const inputDate = await findByPlaceholderText('请选择年');
fireEvent.click(inputDate);
@@ -39,8 +39,8 @@ test('Renderer:inputYear click', async () => {
fireEvent.click(thisYear);
const value = document.querySelector(
- '.cxd-DatePicker-value'
- ) as HTMLSpanElement;
+ '.cxd-DatePicker input'
+ ) as HTMLInputElement;
- expect(value.innerHTML).toEqual(thisYearText);
+ expect(value.value).toEqual(thisYearText);
});
diff --git a/__tests__/renderers/Form/mobileInputDate.test.tsx b/__tests__/renderers/Form/mobileInputDate.test.tsx
index c3103bcbc..e10298f70 100644
--- a/__tests__/renderers/Form/mobileInputDate.test.tsx
+++ b/__tests__/renderers/Form/mobileInputDate.test.tsx
@@ -17,7 +17,7 @@ afterAll(() => {
});
test('Renderer:mobile Input Date', async () => {
- const {container, findByText, getByText} = render(
+ const {container, findByPlaceholderText, getByText} = render(
amisRender(
{
type: 'form',
@@ -35,7 +35,7 @@ test('Renderer:mobile Input Date', async () => {
)
);
- const inputDate = await findByText('请选择日期');
+ const inputDate = await findByPlaceholderText('请选择日期');
fireEvent.click(inputDate);
const confirmButton = document.querySelector(
@@ -44,9 +44,9 @@ test('Renderer:mobile Input Date', async () => {
fireEvent.click(confirmButton);
- const value = document.querySelector(
- '.cxd-DatePicker-value'
- ) as HTMLSpanElement;
+ // const value = document.querySelector(
+ // '.cxd-DatePicker-value'
+ // ) as HTMLSpanElement;
// TODO: 这里原组件的日错了,等修复
// expect(value.innerHTML).toEqual(moment().format('YYYY-MM-DD'));
diff --git a/docs/zh-CN/components/form/switch.md b/docs/zh-CN/components/form/switch.md
index 2d78cf9dd..5e84634a5 100755
--- a/docs/zh-CN/components/form/switch.md
+++ b/docs/zh-CN/components/form/switch.md
@@ -84,20 +84,39 @@ order: 51
}
```
+## 默认值
+
+和其它表单项一样,如果要设置默认值,可以使用 value 属性
+
+```schema: scope="body"
+{
+ "type": "form",
+ "debug": true,
+ "body": [
+ {
+ "name": "switch",
+ "type": "switch",
+ "label": "开关",
+ "value": false
+ }
+ ]
+}
+```
+
## 属性表
除了支持 [普通表单项属性表](./formitem#%E5%B1%9E%E6%80%A7%E8%A1%A8) 中的配置以外,还支持下面一些配置
-| 属性名 | 类型 | 默认值 | 说明 |
-| ---------- | -------- | --------- | ------------ |
-| option | `string` | | 选项说明 |
-| onText | `string / IconSchema` | | 开启时开关显示的内容 |
-| offText | `string / IconSchema` | | 关闭时开关显示的内容 |
-| trueValue | `boolean / string / number` | `true` | 标识真值 |
-| falseValue | `boolean / string / number` | `false` | 标识假值 |
+| 属性名 | 类型 | 默认值 | 说明 |
+| ---------- | --------------------------- | ------- | -------------------- |
+| option | `string` | | 选项说明 |
+| onText | `string / IconSchema` | | 开启时开关显示的内容 |
+| offText | `string / IconSchema` | | 关闭时开关显示的内容 |
+| trueValue | `boolean / string / number` | `true` | 标识真值 |
+| falseValue | `boolean / string / number` | `false` | 标识假值 |
IconSchema 配置
-| 属性名 | 类型 | 默认值 | 说明 |
+| 属性名 | 类型 | 默认值 | 说明 |
| ---------- | -------- | --------- | ------------ |
-| type | `string` | | `icon` |
-| icon | `string` | | icon的类型 |
+| type | `string` | | `icon` |
+| icon | `string` | | icon 的类型 |
diff --git a/scss/components/form/_date.scss b/scss/components/form/_date.scss
index 4e5e2c809..b8f3948e6 100644
--- a/scss/components/form/_date.scss
+++ b/scss/components/form/_date.scss
@@ -12,6 +12,19 @@
background: var(--DatePicker-bg);
border-radius: var(--DatePicker-borderRadius);
+ input {
+ display: inline-block;
+ width: 100%;
+ background: none;
+ padding: 0;
+ border: 0;
+ &:focus {
+ border: none;
+ outline: none;
+ box-sizing: none;
+ }
+ }
+
@include input-border();
&:not(.is-disabled) {
diff --git a/src/components/DatePicker.tsx b/src/components/DatePicker.tsx
index 168c0f904..56217d417 100644
--- a/src/components/DatePicker.tsx
+++ b/src/components/DatePicker.tsx
@@ -17,6 +17,7 @@ import Calendar from './calendar/Calendar';
import {localeable, LocaleProps, TranslateFn} from '../locale';
import {isMobile, ucFirst} from '../utils/helper';
import CalendarMobile from './CalendarMobile';
+import Input from './Input';
const availableShortcuts: {[propName: string]: any} = {
now: {
@@ -302,6 +303,7 @@ export interface DatePickerState {
isOpened: boolean;
isFocused: boolean;
value: moment.Moment | undefined;
+ inputValue: string | undefined; // 手动输入的值
}
function normalizeValue(value: any, format?: string) {
@@ -329,11 +331,15 @@ export class DatePicker extends React.Component {
state: DatePickerState = {
isOpened: false,
isFocused: false,
- value: normalizeValue(this.props.value, this.props.format)
+ value: normalizeValue(this.props.value, this.props.format),
+ inputValue:
+ normalizeValue(this.props.value, this.props.format)?.format(
+ this.props.inputFormat
+ ) || ''
};
constructor(props: DateProps) {
super(props);
-
+ this.inputRef = React.createRef();
this.handleChange = this.handleChange.bind(this);
this.selectRannge = this.selectRannge.bind(this);
this.checkIsValidDate = this.checkIsValidDate.bind(this);
@@ -348,10 +354,13 @@ export class DatePicker extends React.Component {
this.getTarget = this.getTarget.bind(this);
this.handlePopOverClick = this.handlePopOverClick.bind(this);
this.renderShortCuts = this.renderShortCuts.bind(this);
+ this.inputChange = this.inputChange.bind(this);
}
dom: HTMLDivElement;
+ inputRef: React.RefObject;
+
componentDidUpdate(prevProps: DateProps) {
const props = this.props;
@@ -403,13 +412,17 @@ export class DatePicker extends React.Component {
}
open(fn?: () => void) {
- this.props.disabled ||
- this.setState(
- {
- isOpened: true
- },
- fn
- );
+ if (this.props.disabled) {
+ return;
+ }
+ this.setState(
+ {
+ isOpened: true
+ },
+ fn
+ );
+ const input = this.inputRef.current;
+ input && input.focus();
}
close() {
@@ -423,6 +436,7 @@ export class DatePicker extends React.Component {
e.stopPropagation();
const onChange = this.props.onChange;
onChange('');
+ this.setState({inputValue: ''});
}
handleChange(value: moment.Moment) {
@@ -432,6 +446,7 @@ export class DatePicker extends React.Component {
minDate,
maxDate,
dateFormat,
+ inputFormat,
timeFormat,
closeOnSelect,
utc,
@@ -453,6 +468,31 @@ export class DatePicker extends React.Component {
if (closeOnSelect && dateFormat && !timeFormat) {
this.close();
}
+
+ this.setState({
+ inputValue: utc
+ ? moment.utc(value).format(inputFormat)
+ : value.format(inputFormat)
+ });
+ }
+
+ // 手动输入日期
+ inputChange(e: React.ChangeEvent) {
+ const {onChange, inputFormat, format, utc} = this.props;
+ const value = e.currentTarget.value;
+ this.setState({inputValue: value});
+ if (value === '') {
+ onChange('');
+ } else {
+ const newDate = moment(value, inputFormat);
+ const dateValue = utc
+ ? moment.utc(newDate).format(format)
+ : newDate.format(format);
+ // 小于 0 的日期丢弃
+ if (!dateValue.startsWith('-')) {
+ onChange(dateValue);
+ }
+ }
}
selectRannge(item: any) {
@@ -693,15 +733,13 @@ export class DatePicker extends React.Component {
ref={this.domRef}
onClick={this.handleClick}
>
- {date ? (
-
- {date.format(inputFormat)}
-
- ) : (
-
- {__(placeholder)}
-
- )}
+
{clearable && !disabled && normalizeValue(value, format) ? (
diff --git a/src/components/calendar/Calendar.tsx b/src/components/calendar/Calendar.tsx
index b9e5d7cb5..734a57643 100644
--- a/src/components/calendar/Calendar.tsx
+++ b/src/components/calendar/Calendar.tsx
@@ -161,18 +161,19 @@ class BaseDatePicker extends React.Component<
updatedState = this.getStateFromProps(props);
}
- if (updatedState.open === undefined) {
- if (typeof props.open !== 'undefined') {
- updatedState.open = props.open;
- } else if (
- prevProps.closeOnSelect &&
- this.state.currentView !== viewModes.TIME
- ) {
- updatedState.open = false;
- } else {
- updatedState.open = this.state.open;
- }
- }
+ // open 是外部控制了
+ // if (updatedState.open === undefined) {
+ // if (typeof props.open !== 'undefined') {
+ // updatedState.open = props.open;
+ // } else if (
+ // prevProps.closeOnSelect &&
+ // this.state.currentView !== viewModes.TIME
+ // ) {
+ // updatedState.open = false;
+ // } else {
+ // updatedState.open = this.state.open;
+ // }
+ // }
if (props.viewMode !== prevProps.viewMode) {
updatedState.currentView = props.viewMode;
@@ -236,6 +237,10 @@ class BaseDatePicker extends React.Component<
updatedState.viewDate = moment(props.viewDate);
}
+ if (Object.keys(updatedState).length) {
+ this.setState(updatedState);
+ }
+
this.checkTZ(props);
}