feat(Signature): expose resize method (#12405)

This commit is contained in:
inottn 2023-10-29 16:52:07 +08:00 committed by GitHub
parent 3b88ed6ded
commit 873f49908c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 60 additions and 3 deletions

View File

@ -3,18 +3,30 @@ import {
ref, ref,
onMounted, onMounted,
defineComponent, defineComponent,
watch,
type ExtractPropTypes, type ExtractPropTypes,
} from 'vue'; } from 'vue';
// Utils
import { import {
inBrowser, inBrowser,
makeNumberProp, makeNumberProp,
makeStringProp, makeStringProp,
createNamespace, createNamespace,
preventDefault, preventDefault,
windowWidth,
} from '../utils'; } from '../utils';
// Composables
import { useRect } from '@vant/use'; import { useRect } from '@vant/use';
import { useExpose } from '../composables/use-expose';
// Components
import { Button } from '../button'; import { Button } from '../button';
// Types
import type { SignatureExpose } from './types';
const [name, bem, t] = createNamespace('signature'); const [name, bem, t] = createNamespace('signature');
export const signatureProps = { export const signatureProps = {
@ -143,7 +155,7 @@ export default defineComponent({
emit('clear'); emit('clear');
}; };
onMounted(() => { const initialize = () => {
if (isRenderCanvas && canvasRef.value) { if (isRenderCanvas && canvasRef.value) {
const canvas = canvasRef.value; const canvas = canvasRef.value;
const dpr = inBrowser ? window.devicePixelRatio : 1; const dpr = inBrowser ? window.devicePixelRatio : 1;
@ -153,6 +165,22 @@ export default defineComponent({
ctx.value?.scale(dpr, dpr); ctx.value?.scale(dpr, dpr);
setCanvasBgColor(ctx.value); setCanvasBgColor(ctx.value);
} }
};
const resize = () => {
if (ctx.value) {
const data = ctx.value.getImageData(0, 0, canvasWidth, canvasHeight);
initialize();
ctx.value.putImageData(data, 0, 0);
}
};
watch(windowWidth, resize);
onMounted(initialize);
useExpose<SignatureExpose>({
resize,
}); });
return () => ( return () => (

View File

@ -4,7 +4,7 @@ import _Signature from './Signature';
export const Signature = withInstall(_Signature); export const Signature = withInstall(_Signature);
export default Signature; export default Signature;
export type { SignatureProps } from './Signature'; export type { SignatureProps } from './Signature';
export type { SignatureThemeVars } from './types'; export type { SignatureInstance, SignatureThemeVars } from './types';
declare module 'vue' { declare module 'vue' {
export interface GlobalComponents { export interface GlobalComponents {

View File

@ -1,6 +1,6 @@
import 'vitest-canvas-mock'; import 'vitest-canvas-mock';
import { Signature } from '..'; import { Signature } from '..';
import { mount } from '../../../test'; import { mount, trigger } from '../../../test';
test('renders a canvas element when canvas is supported', async () => { test('renders a canvas element when canvas is supported', async () => {
const wrapper = mount(Signature); const wrapper = mount(Signature);
@ -91,3 +91,20 @@ test('should allow to custom button text', async () => {
expect(wrapper.find('.van-signature__footer').html()).toMatchSnapshot(); expect(wrapper.find('.van-signature__footer').html()).toMatchSnapshot();
}); });
test('expose resize method', async () => {
const wrapper = mount(Signature);
expect(wrapper.vm.resize).toBeTypeOf('function');
expect(wrapper.vm.resize()).toBeUndefined();
});
test('should call resize when window width changes', async () => {
const wrapper = mount(Signature);
const canvas = wrapper.find('canvas');
const ctx = canvas.element.getContext('2d')!;
const spy = vi.spyOn(ctx, 'getImageData');
Object.defineProperty(window, 'innerWidth', { value: 400 });
await trigger(window, 'resize');
expect(spy).toBeCalled();
});

View File

@ -1,3 +1,15 @@
import type { ComponentPublicInstance } from 'vue';
import type { SignatureProps } from './Signature';
export type SignatureExpose = {
resize: () => void;
};
export type SignatureInstance = ComponentPublicInstance<
SignatureProps,
SignatureExpose
>;
export type SignatureThemeVars = { export type SignatureThemeVars = {
signaturePadding?: string; signaturePadding?: string;
signatureContentHeight?: string; signatureContentHeight?: string;