diff --git a/src/collapse-item/index.js b/src/collapse-item/index.tsx similarity index 81% rename from src/collapse-item/index.js rename to src/collapse-item/index.tsx index 3f7ce995d..7181ab08b 100644 --- a/src/collapse-item/index.js +++ b/src/collapse-item/index.tsx @@ -10,7 +10,7 @@ import { useLazyRender } from '../composables/use-lazy-render'; // Components import Cell, { cellProps } from '../cell'; -import { COLLAPSE_KEY } from '../collapse'; +import { COLLAPSE_KEY, CollapseProvide } from '../collapse'; const [createComponent, bem] = createNamespace('collapse-item'); @@ -26,18 +26,21 @@ export default createComponent({ }, setup(props, { slots }) { - const wrapperRef = ref(); - const contentRef = ref(); - const { parent, index } = useParent(COLLAPSE_KEY); + const wrapperRef = ref(); + const contentRef = ref(); + const { parent, index } = useParent(COLLAPSE_KEY); + + if (!parent) { + if (process.env.NODE_ENV !== 'production') { + console.error( + '[Vant] CollapseItem must be a child component of Collapse.' + ); + } + return; + } const currentName = computed(() => props.name ?? index.value); - - const expanded = computed(() => { - if (parent) { - return parent.isExpanded(currentName.value); - } - return null; - }); + const expanded = computed(() => parent.isExpanded(currentName.value)); const show = ref(expanded.value); const lazyRender = useLazyRender(show); @@ -46,7 +49,7 @@ export default createComponent({ if (!expanded.value) { show.value = false; } else { - wrapperRef.value.style.height = ''; + wrapperRef.value!.style.height = ''; } }; @@ -71,11 +74,11 @@ export default createComponent({ const { offsetHeight } = contentRef.value; if (offsetHeight) { const contentHeight = `${offsetHeight}px`; - wrapperRef.value.style.height = value ? 0 : contentHeight; + wrapperRef.value.style.height = value ? '0' : contentHeight; // use double raf to ensure animation can start doubleRaf(() => { - wrapperRef.value.style.height = value ? contentHeight : 0; + wrapperRef.value!.style.height = value ? contentHeight : '0'; }); } else { onTransitionEnd(); diff --git a/src/collapse/index.js b/src/collapse/index.tsx similarity index 60% rename from src/collapse/index.js rename to src/collapse/index.tsx index 00b23b879..2bf967406 100644 --- a/src/collapse/index.js +++ b/src/collapse/index.tsx @@ -1,3 +1,4 @@ +import { PropType } from 'vue'; import { createNamespace } from '../utils'; import { BORDER_TOP_BOTTOM } from '../utils/constant'; import { useChildren } from '@vant/use'; @@ -6,10 +7,20 @@ const [createComponent, bem] = createNamespace('collapse'); export const COLLAPSE_KEY = 'vanCollapse'; +export type CollapseProvide = { + toggle: (name: number | string, expanded: boolean) => void; + isExpanded: (name: number | string) => boolean; +}; + export default createComponent({ props: { accordion: Boolean, - modelValue: [String, Number, Array], + modelValue: { + type: [String, Number, Array] as PropType< + string | number | Array + >, + required: true, + }, border: { type: Boolean, default: true, @@ -21,24 +32,28 @@ export default createComponent({ setup(props, { emit, slots }) { const { linkChildren } = useChildren(COLLAPSE_KEY); - const toggle = (name, expanded) => { - const { accordion, modelValue } = props; - - if (accordion) { - if (name === modelValue) { - name = ''; - } - } else if (expanded) { - name = modelValue.concat(name); - } else { - name = modelValue.filter((activeName) => activeName !== name); - } - + const updateName = (name: number | string | Array) => { emit('change', name); emit('update:modelValue', name); }; - const isExpanded = (name) => { + const toggle = (name: number | string, expanded: boolean) => { + const { accordion, modelValue } = props; + + if (accordion) { + updateName(name === modelValue ? '' : name); + } else if (expanded) { + updateName((modelValue as Array).concat(name)); + } else { + updateName( + (modelValue as Array).filter( + (activeName) => activeName !== name + ) + ); + } + }; + + const isExpanded = (name: number | string) => { const { accordion, modelValue } = props; if (process.env.NODE_ENV !== 'production') { @@ -56,7 +71,9 @@ export default createComponent({ } } - return accordion ? modelValue === name : modelValue.indexOf(name) !== -1; + return accordion + ? modelValue === name + : (modelValue as Array).indexOf(name) !== -1; }; linkChildren({ toggle, isExpanded });