vant/src/submit-bar/SubmitBar.tsx
neverland bd609e1df0
perf: add truthProp util (#8522)
* perf: add TruthyProp util

* chore: rename

* chore: upd
2021-04-14 10:26:21 +08:00

119 lines
2.8 KiB
TypeScript

import { PropType, CSSProperties, defineComponent } from 'vue';
import { truthProp, createNamespace } from '../utils';
// Components
import { Icon } from '../icon';
import { Button, ButtonType } from '../button';
const [name, bem, t] = createNamespace('submit-bar');
export default defineComponent({
name,
props: {
tip: String,
label: String,
price: Number,
tipIcon: String,
loading: Boolean,
disabled: Boolean,
textAlign: String as PropType<CSSProperties['textAlign']>,
buttonText: String,
buttonColor: String,
suffixLabel: String,
safeAreaInsetBottom: truthProp,
decimalLength: {
type: [Number, String],
default: 2,
},
currency: {
type: String,
default: '¥',
},
buttonType: {
type: String as PropType<ButtonType>,
default: 'danger',
},
},
emits: ['submit'],
setup(props, { emit, slots }) {
const renderText = () => {
const {
price,
label,
currency,
textAlign,
suffixLabel,
decimalLength,
} = props;
if (typeof price === 'number') {
const pricePair = (price / 100).toFixed(+decimalLength).split('.');
const decimal = decimalLength ? `.${pricePair[1]}` : '';
return (
<div class={bem('text')} style={{ textAlign }}>
<span>{label || t('label')}</span>
<span class={bem('price')}>
{currency}
<span class={bem('price-integer')}>{pricePair[0]}</span>
{decimal}
</span>
{suffixLabel && (
<span class={bem('suffix-label')}>{suffixLabel}</span>
)}
</div>
);
}
};
const renderTip = () => {
const { tip, tipIcon } = props;
if (slots.tip || tip) {
return (
<div class={bem('tip')}>
{tipIcon && <Icon class={bem('tip-icon')} name={tipIcon} />}
{tip && <span class={bem('tip-text')}>{tip}</span>}
{slots.tip?.()}
</div>
);
}
};
const onClickButton = () => emit('submit');
const renderButton = () => {
if (slots.button) {
return slots.button();
}
return (
<Button
round
type={props.buttonType}
text={props.buttonText}
class={bem('button', props.buttonType)}
color={props.buttonColor}
loading={props.loading}
disabled={props.disabled}
onClick={onClickButton}
/>
);
};
return () => (
<div class={bem({ unfit: !props.safeAreaInsetBottom })}>
{slots.top?.()}
{renderTip()}
<div class={bem('bar')}>
{slots.default?.()}
{renderText()}
{renderButton()}
</div>
</div>
);
},
});