Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions src/calendar/calendar.en-US.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ firstDayOfWeek | Number | 0 | \- | N
format | Function | - | Typescript:`CalendarFormatType ` `type CalendarFormatType = (day: TDate) => TDate` `type TDateType = 'selected' \| 'disabled' \| 'start' \| 'centre' \| 'end' \| ''` `interface TDate { date: Date; day: number; type: TDateType; className?: string; prefix?: string; suffix?: string;}`。[see more ts definition](https://github.com/Tencent/tdesign-mobile-vue/tree/develop/src/calendar/type.ts) | N
maxDate | Number / Date | - | Typescript:` number \| Date` | N
minDate | Number / Date | - | Typescript:` number \| Date` | N
readonly | Boolean | - | `1.9.3` | N
readonly | Boolean | undefined | `1.9.3` | N
switchMode | String | none | `1.8.1`。options: none/month/year-month | N
title | String / Slot / Function | - | Typescript:`string \| TNode`。[see more ts definition](https://github.com/Tencent/tdesign-mobile-vue/blob/develop/src/common.ts) | N
type | String | 'single' | options: single/multiple/range | N
Expand All @@ -23,7 +23,7 @@ onChange | Function | | Typescript:`(value: Date) => void`<br/> | N
onClose | Function | | Typescript:`(trigger: CalendarTrigger) => void`<br/>[see more ts definition](https://github.com/Tencent/tdesign-mobile-vue/tree/develop/src/calendar/type.ts)。<br/>`type CalendarTrigger = 'close-btn' \| 'confirm-btn' \| 'overlay'`<br/> | N
onConfirm | Function | | Typescript:`(value: Date) => void`<br/> | N
onPanelChange | Function | | Typescript:`(context: { year: number, month: number }) => void`<br/>`1.8.1` | N
onScroll | Function | | Typescript:`(context: {e: Event}) => void`<br/>triggered when scrolling | N
onScroll | Function | | Typescript:`(context: {e: Event}) => void`<br/>`1.8.1`。triggered when scrolling | N
onSelect | Function | | Typescript:`(value: Date) => void`<br/> | N

### Calendar Events
Expand All @@ -34,7 +34,7 @@ change | `(value: Date)` | \-
close | `(trigger: CalendarTrigger)` | [see more ts definition](https://github.com/Tencent/tdesign-mobile-vue/tree/develop/src/calendar/type.ts)。<br/>`type CalendarTrigger = 'close-btn' \| 'confirm-btn' \| 'overlay'`<br/>
confirm | `(value: Date)` | \-
panel-change | `(context: { year: number, month: number })` | `1.8.1`
scroll | `(context: {e: Event})` | triggered when scrolling
scroll | `(context: {e: Event})` | `1.8.1`。triggered when scrolling
select | `(value: Date)` | \-

### CSS Variables
Expand All @@ -54,4 +54,4 @@ Name | Default Value | Description
--td-calendar-switch-mode-icon-color | @text-color-secondary | -
--td-calendar-switch-mode-icon-disabled-color | @text-color-disabled | -
--td-calendar-title-color | @text-color-primary | -
--td-calendar-title-font-size | 18px | -
--td-calendar-title-font-size | 18px | -
8 changes: 4 additions & 4 deletions src/calendar/calendar.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ firstDayOfWeek | Number | 0 | 第一天从星期几开始,默认 0 = 周日 |
format | Function | - | 用于格式化日期的函数。TS 类型:`CalendarFormatType ` `type CalendarFormatType = (day: TDate) => TDate` `type TDateType = 'selected' \| 'disabled' \| 'start' \| 'centre' \| 'end' \| ''` `interface TDate { date: Date; day: number; type: TDateType; className?: string; prefix?: string; suffix?: string;}`。[详细类型定义](https://github.com/Tencent/tdesign-mobile-vue/tree/develop/src/calendar/type.ts) | N
maxDate | Number / Date | - | 最大可选的日期,不传则默认半年后。TS 类型:` number \| Date` | N
minDate | Number / Date | - | 最小可选的日期,不传则默认今天。TS 类型:` number \| Date` | N
readonly | Boolean | - | `1.9.3`。是否只读,只读状态下不能选择日期 | N
readonly | Boolean | undefined | `1.9.3`。是否只读,只读状态下不能选择日期 | N
switchMode | String | none | `1.8.1`。切换模式。 `none` 表示平铺展示所有月份; `month` 表示支持按月切换, `year-month` 表示既按年切换,也支持按月切换。可选项:none/month/year-month | N
title | String / Slot / Function | - | 标题,不传默认为“请选择日期”。TS 类型:`string \| TNode`。[通用类型定义](https://github.com/Tencent/tdesign-mobile-vue/blob/develop/src/common.ts) | N
type | String | 'single' | 日历的选择类型,single = 单选;multiple = 多选; range = 区间选择。可选项:single/multiple/range | N
Expand All @@ -23,7 +23,7 @@ onChange | Function | | TS 类型:`(value: Date) => void`<br/>不显示 confi
onClose | Function | | TS 类型:`(trigger: CalendarTrigger) => void`<br/>关闭按钮时触发。[详细类型定义](https://github.com/Tencent/tdesign-mobile-vue/tree/develop/src/calendar/type.ts)。<br/>`type CalendarTrigger = 'close-btn' \| 'confirm-btn' \| 'overlay'`<br/> | N
onConfirm | Function | | TS 类型:`(value: Date) => void`<br/>点击确认按钮时触发 | N
onPanelChange | Function | | TS 类型:`(context: { year: number, month: number }) => void`<br/>`1.8.1`。切换月或年时触发(switch-mode 不为 none 时有效) | N
onScroll | Function | | TS 类型:`(context: {e: Event}) => void`<br/>滚动时触发 | N
onScroll | Function | | TS 类型:`(context: {e: Event}) => void`<br/>`1.8.1`。滚动时触发 | N
onSelect | Function | | TS 类型:`(value: Date) => void`<br/>点击日期时触发 | N

### Calendar Events
Expand All @@ -34,7 +34,7 @@ change | `(value: Date)` | 不显示 confirm-btn 时,完成选择时触发(
close | `(trigger: CalendarTrigger)` | 关闭按钮时触发。[详细类型定义](https://github.com/Tencent/tdesign-mobile-vue/tree/develop/src/calendar/type.ts)。<br/>`type CalendarTrigger = 'close-btn' \| 'confirm-btn' \| 'overlay'`<br/>
confirm | `(value: Date)` | 点击确认按钮时触发
panel-change | `(context: { year: number, month: number })` | `1.8.1`。切换月或年时触发(switch-mode 不为 none 时有效)
scroll | `(context: {e: Event})` | 滚动时触发
scroll | `(context: {e: Event})` | `1.8.1`。滚动时触发
select | `(value: Date)` | 点击日期时触发

### CSS Variables
Expand All @@ -54,4 +54,4 @@ select | `(value: Date)` | 点击日期时触发
--td-calendar-switch-mode-icon-color | @text-color-secondary | -
--td-calendar-switch-mode-icon-disabled-color | @text-color-disabled | -
--td-calendar-title-color | @text-color-primary | -
--td-calendar-title-font-size | 18px | -
--td-calendar-title-font-size | 18px | -
4 changes: 3 additions & 1 deletion src/calendar/calendar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import props from './props';
import { useTNodeJSX } from '../hooks/tnode';
import TCalendarTemplate from './template';
import { usePrefixClass } from '../hooks/useClass';
import { useFormReadonly } from '../form/hooks';

const { prefix } = config;

Expand All @@ -17,8 +18,9 @@ export default defineComponent({

const calendarTemplateRef = ref();
const renderTNodeJSX = useTNodeJSX();
const isReadonly = useFormReadonly();

provide('templateProps', reactive(props));
provide('templateProps', { ...reactive(props), readonly: isReadonly.value });
const selectedValueIntoView = () => {
const type = props.type === 'range' ? 'start' : 'selected';
const { templateRef } = calendarTemplateRef.value;
Expand Down
5 changes: 4 additions & 1 deletion src/calendar/props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,10 @@ export default {
type: [Number, Date] as PropType<TdCalendarProps['minDate']>,
},
/** 是否只读,只读状态下不能选择日期 */
readonly: Boolean,
readonly: {
type: Boolean,
default: undefined,
},
/** 切换模式。 `none` 表示平铺展示所有月份; `month` 表示支持按月切换, `year-month` 表示既按年切换,也支持按月切换 */
switchMode: {
type: String as PropType<TdCalendarProps['switchMode']>,
Expand Down
8 changes: 4 additions & 4 deletions src/checkbox/checkbox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { TNode } from '../shared';
import useVModel from '../hooks/useVModel';
import { TdCheckboxProps } from '../checkbox/type';
import { useTNodeJSX, useContent } from '../hooks/tnode';
import { useFormDisabled } from '../form/hooks';
import { useFormDisabled, useFormReadonly } from '../form/hooks';
import { usePrefixClass } from '../hooks/useClass';

const { prefix } = config;
Expand All @@ -40,6 +40,8 @@ export default defineComponent({

const checkboxGroup: any = inject('checkboxGroup', undefined);
const disabled = useFormDisabled(checkboxGroup?.disabled);
const isReadonly = useFormReadonly(checkboxGroup?.readonly);

const indeterminate = computed<boolean>(() => {
if (props.checkAll && checkboxGroup != null) return checkboxGroup.checkAllStatus.value === 'indeterminate';
return props.indeterminate;
Expand Down Expand Up @@ -83,10 +85,8 @@ export default defineComponent({
return disabled.value;
});

const finalReadonly = computed(() => Boolean(props.readonly || checkboxGroup?.readonly.value));

const handleChange = (e: Event, source?: string) => {
if (isDisabled.value || finalReadonly.value) return;
if (isDisabled.value || isReadonly.value) return;
if (source === 'text' && props.contentDisabled) return;

const value = !isChecked.value;
Expand Down
1 change: 1 addition & 0 deletions src/form/form.en-US.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ errorMessage | Object | - | Typescript:`FormErrorMessage` | N
labelAlign | String | right | options: left/right/top | N
labelWidth | String / Number | '81px' | \- | N
preventSubmitDefault | Boolean | true | \- | N
readonly | Boolean | undefined | \- | N
requiredMark | Boolean | undefined | \- | N
requiredMarkPosition | String | left | Display position of required symbols。options: left/right | N
resetType | String | empty | options: empty/initial | N
Expand Down
1 change: 1 addition & 0 deletions src/form/form.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ errorMessage | Object | - | 表单错误信息配置,示例:`{ idcard: '请
labelAlign | String | right | 表单字段标签对齐方式:左对齐、右对齐、顶部对齐。可选项:left/right/top | N
labelWidth | String / Number | '81px' | 可以整体设置label标签宽度,默认为81px | N
preventSubmitDefault | Boolean | true | 是否阻止表单提交默认事件(表单提交默认事件会刷新页面),设置为 `true` 可以避免刷新 | N
readonly | Boolean | undefined | 是否整个表单只读 | N
requiredMark | Boolean | undefined | 是否显示必填符号(*),默认显示 | N
requiredMarkPosition | String | left | 表单必填符号(*)显示位置。可选项:left/right | N
resetType | String | empty | 重置表单的方式,值为 empty 表示重置表单为空,值为 initial 表示重置表单数据为初始值。可选项:empty/initial | N
Expand Down
6 changes: 5 additions & 1 deletion src/form/form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
} from './type';
import props from './props';
import { FormInjectionKey, FormItemContext } from './const';
import { FormDisabledProvider } from './hooks';
import { FormDisabledProvider, FormReadonlyProvider } from './hooks';
import config from '../config';
import { renderContent } from '../shared';
import { preventDefault } from '../shared/dom';
Expand Down Expand Up @@ -45,6 +45,7 @@ export default defineComponent({
const renderTNodeJSX = useTNodeJSX();
const {
disabled,
readonly,
showErrorMessage,
labelWidth,
labelAlign,
Expand All @@ -64,6 +65,9 @@ export default defineComponent({
provide<FormDisabledProvider>('formDisabled', {
disabled,
});
provide<FormReadonlyProvider>('formReadonly', {
readonly,
});

provide(
FormInjectionKey,
Expand Down
30 changes: 30 additions & 0 deletions src/form/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,33 @@ export function useFormDisabled(extend?: Ref<boolean>) {
return false;
});
}

export interface FormReadonlyProvider {
readonly: Ref<TdFormProps['readonly']>;
}

/**
* 用于实现 form 的全局只读状态hook
* 只读优先级: 组件 > 组件组 > 表单(propsReadonly.value > extend?.value > readonly?.value)
* @returns
*/
export function useFormReadonly(extend?: Ref<boolean>) {
const ctx = getCurrentInstance();
const propsReadonly = computed(() => ctx?.props.readonly as boolean);
const { readonly } = inject<FormReadonlyProvider>('formReadonly', Object.create(null));
return computed(() => {
// 组件
if (isBoolean(propsReadonly.value)) {
return propsReadonly.value;
}
// 组件组
if (isBoolean(extend?.value)) {
return extend.value;
}
// 表单
if (isBoolean(readonly?.value)) {
return readonly.value;
}
return false;
});
}
5 changes: 5 additions & 0 deletions src/form/props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ export default {
type: Boolean,
default: true,
},
/** 是否整个表单只读 */
readonly: {
type: Boolean,
default: undefined,
},
/** 是否显示必填符号(*),默认显示 */
requiredMark: {
type: Boolean,
Expand Down
4 changes: 4 additions & 0 deletions src/form/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ export interface TdFormProps<FormData extends Data = Data> {
* @default true
*/
preventSubmitDefault?: boolean;
/**
* 是否整个表单只读
*/
readonly?: boolean;
/**
* 是否显示必填符号(*),默认显示
*/
Expand Down
7 changes: 4 additions & 3 deletions src/input/input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import InputProps from './props';
import { InputValue, TdInputProps } from './type';
import { extendAPI } from '../shared';
import { FormItemInjectionKey } from '../form/const';
import { useFormDisabled } from '../form/hooks';
import { useFormDisabled, useFormReadonly } from '../form/hooks';
import useVModel from '../hooks/useVModel';
import { usePrefixClass } from '../hooks/useClass';
import { useTNodeJSX } from '../hooks/tnode';
Expand Down Expand Up @@ -41,6 +41,7 @@ export default defineComponent({
const renderTNodeJSX = useTNodeJSX();
const inputClass = usePrefixClass('input');
const isDisabled = useFormDisabled();
const isReadonly = useFormReadonly();

const inputRef = ref();

Expand Down Expand Up @@ -70,7 +71,7 @@ export default defineComponent({
},
]);
const showClear = computed(() => {
if (isDisabled.value || props.readonly === true) return false;
if (isDisabled.value || isReadonly.value) return false;

if (props.clearable && innerValue.value && String(innerValue.value).length > 0) {
return props.clearTrigger === 'always' || (props.clearTrigger === 'focus' && focused.value);
Expand Down Expand Up @@ -257,7 +258,7 @@ export default defineComponent({
disabled: isDisabled.value,
autocomplete: props.autocomplete ? 'On' : 'Off',
placeholder: props.placeholder,
readonly: props.readonly,
readonly: isReadonly.value,
// maxlength: props.maxlength,
pattern: props.pattern,
inputmode: props.inputmode,
Expand Down
13 changes: 7 additions & 6 deletions src/radio/radio.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import config from '../config';
import props from './props';
import { TdRadioGroupProps, TdRadioProps } from './type';
import useVModel from '../hooks/useVModel';
import { useFormDisabled } from '../form/hooks';
import { useFormDisabled, useFormReadonly } from '../form/hooks';
import { usePrefixClass } from '../hooks/useClass';
import { useContent, useTNodeJSX } from '../hooks/tnode';

Expand All @@ -14,7 +14,7 @@ export default defineComponent({
name: `${prefix}-radio`,
props,
emits: ['update:checked', 'update:modelValue', 'change'],
setup(props, context) {
setup(props) {
const renderTNodeContent = useContent();
const renderTNodeJSX = useTNodeJSX();
const radioClass = usePrefixClass('radio');
Expand All @@ -35,6 +35,9 @@ export default defineComponent({
const groupDisabled = computed(() => rootGroupProps?.disabled);
const isDisabled = useFormDisabled(groupDisabled);

const groupReadonly = computed(() => rootGroupProps?.readonly);
const isReadonly = useFormReadonly(groupReadonly);

const radioChecked = computed(() =>
rootGroupValue?.value !== undefined ? props.value === rootGroupValue?.value : innerChecked.value,
);
Expand All @@ -50,14 +53,12 @@ export default defineComponent({

const finalAllowUncheck = computed(() => Boolean(props.allowUncheck || rootGroupProps?.allowUncheck));

const finalReadonly = computed(() => Boolean(props.readonly || rootGroupProps?.readonly));

// input props attribute
const inputProps = computed(() => ({
name: rootGroupProps.name || props.name,
checked: radioChecked.value,
disabled: isDisabled.value,
readonly: finalReadonly.value,
readonly: isReadonly.value,
value: props.value,
}));

Expand Down Expand Up @@ -102,7 +103,7 @@ export default defineComponent({
};

const radioOrgChange = (e: Event) => {
if (isDisabled.value || finalReadonly.value) {
if (isDisabled.value || isReadonly.value) {
return;
}
if (rootGroupChange) {
Expand Down
7 changes: 5 additions & 2 deletions src/search/search.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import useLengthLimit from '../hooks/useLengthLimit';
import { TdSearchProps } from './type';
import { ENTER_REG } from '../_common/js/common';
import TCell from '../cell/cell';
import { useFormReadonly, useFormDisabled } from '../form/hooks';

const { prefix } = config;

Expand All @@ -21,6 +22,8 @@ export default defineComponent({
const renderTNodeJSX = useTNodeJSX();
const classPrefix = usePrefixClass();
const searchClass = usePrefixClass('search');
const isDisabled = useFormDisabled();
const isReadonly = useFormReadonly();

const isShowResultList = ref(false);
const inputRef = ref<HTMLInputElement>();
Expand Down Expand Up @@ -191,8 +194,8 @@ export default defineComponent({
class={inputClasses.value}
autofocus={props.focus}
placeholder={props.placeholder}
readonly={props.readonly}
disabled={props.disabled}
readonly={isReadonly.value}
disabled={isDisabled.value}
onKeypress={handleSearch}
onFocus={handleFocus}
onBlur={handleBlur}
Expand Down
4 changes: 3 additions & 1 deletion src/steps/steps.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { TdStepsProps } from './type';
import useVModel from '../hooks/useVModel';
import { useTNodeJSX } from '../hooks/tnode';
import { usePrefixClass } from '../hooks/useClass';
import { useFormReadonly } from '../form/hooks';

const { prefix } = config;

Expand All @@ -14,11 +15,12 @@ export default defineComponent({
emits: ['update:current', 'update:modelValue', 'change'],
setup(props, context) {
const stepsClass = usePrefixClass('steps');
const isReadonly = useFormReadonly();
const baseClass = computed(() => [
stepsClass.value,
`${stepsClass.value}--${props.layout}`,
`${stepsClass.value}--${props.sequence}`,
{ [`${stepsClass.value}--readonly`]: props.readonly },
{ [`${stepsClass.value}--readonly`]: isReadonly.value },
]);
const renderTNodeJSX = useTNodeJSX();

Expand Down
Loading