vue-signature-pad
vue-signature-pad copied to clipboard
Still no typescript support?
I am having trouble using the component in my vue.js app without typescript support. Can't find a working example online. I see an old issue that was closed but the example isn't working for me.
PR is welcome!
I copied over and enhanced issue #61 typings (sharing code as image is pretty evil...)
Can definitely be improved further.
declare module 'vue-signature-pad' {
import { default as _Vue } from 'vue';
export interface VueSignaturePad extends _Vue {
width: string;
height: string;
saveType: string;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
options: Record<string, any>;
images: [];
customStyle: CSSStyleDeclaration;
saveSignature():
| { isEmpty: true; data: undefined }
| { isEmpty: false; data: string };
undoSignature(): void;
clearSignature(): void;
// eslint-disable-next-line @typescript-eslint/ban-types
mergeImagesAndSignature(signature: object | string): void;
addImages(images: []): void;
lockSignaturePad(): void;
openSignaturePad(): void;
getPropImagesAndCacheImages(): void;
clearCacheImages(): void;
fromDataURL(data: string): void;
isEmpty(): boolean;
toData(): string;
}
export function VueSignaturePad(Vue: typeof _Vue): void;
export default VueSignaturePad;
}
Suggested usage (with Composition API) to leverage TS discriminated unions on the signature object:
const signatureStepPadRef = ref() as Ref<VueSignaturePad>;
const methodCalledToReadSignature = () => {
const signature = signatureStepPadRef.value.saveSignature();
if (!signature.isEmpty) {
console.log(signature.data);
}
}
Thanks a lot for this update !
I tried to import the module including the ".d.ts" file, but I got the following error :
143:5 Argument of type '{ components: { TopToolbar: typeof TopToolbar; VueSignaturePad: (Vue: VueConstructor<Vue>) => void; }; }' is not assignable to parameter of type 'VueClass<Vue>'.
Object literal may only specify known properties, but 'components' does not exist in type 'VueClass<Vue>'. Did you mean to write 'component'?
141 |
142 | @Component({
> 143 | components: {
| ^
144 | TopToolbar,
145 | VueSignaturePad,
146 | }
Any idea where it could come from ?
I don't use Class API, sorry
I copied over and enhanced issue #61 typings (sharing code as image is pretty evil...)
Can definitely be improved further.
declare module 'vue-signature-pad' { import { default as _Vue } from 'vue'; export interface VueSignaturePad extends _Vue { width: string; height: string; saveType: string; // eslint-disable-next-line @typescript-eslint/no-explicit-any options: Record<string, any>; images: []; customStyle: CSSStyleDeclaration; saveSignature(): | { isEmpty: true; data: undefined } | { isEmpty: false; data: string }; undoSignature(): void; clearSignature(): void; // eslint-disable-next-line @typescript-eslint/ban-types mergeImagesAndSignature(signature: object | string): void; addImages(images: []): void; lockSignaturePad(): void; openSignaturePad(): void; getPropImagesAndCacheImages(): void; clearCacheImages(): void; fromDataURL(data: string): void; isEmpty(): boolean; toData(): string; } export function VueSignaturePad(Vue: typeof _Vue): void; export default VueSignaturePad; }
Suggested usage (with Composition API) to leverage TS discriminated unions on the signature object:
const signatureStepPadRef = ref() as Ref<VueSignaturePad>; const methodCalledToReadSignature = () => { const signature = signatureStepPadRef.value.saveSignature(); if (!signature.isEmpty) { console.log(signature.data); } }
It doesn't work with Nuxt unfortunately. Got error Invalid module name in augmentation. Module 'vue-signature-pad' resolves to an untyped module at 'D:/myproject/nuxt-ts/node_modules/vue-signature-pad/dist/vue-signature-pad.ssr.js', which cannot be augmented.ts(2665)
in index.d.ts
I don't think Nuxt has something to do with it, it's a problem in TS realm. No idea why you get that tho.
It may happen if you are doing something else in that file apart declaring this module typings
I don't think Nuxt has something to do with it, it's a problem in TS realm. No idea why you get that tho.
It may happen if you are doing something else in that file apart declaring this module typings
@IlCallo This is inside in my index.d.ts
file. Idk much about TS anymore.
import { accessorType } from '~/store'
import { default as _Vue } from 'vue'
declare module 'vue/types/vue' {
interface Vue {
$accessor: typeof accessorType
}
}
declare module '@nuxt/types' {
interface NuxtAppOptions {
$accessor: typeof accessorType
}
}
declare module 'vue-signature-pad' {
export interface VueSignaturePad extends _Vue {
width: string;
height: string;
saveType: string;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
options: Record<string, any>;
images: [];
customStyle: CSSStyleDeclaration;
saveSignature():
| { isEmpty: true; data: undefined }
| { isEmpty: false; data: string };
undoSignature(): void;
clearSignature(): void;
// eslint-disable-next-line @typescript-eslint/ban-types
mergeImagesAndSignature(signature: object | string): void;
addImages(images: []): void;
lockSignaturePad(): void;
openSignaturePad(): void;
getPropImagesAndCacheImages(): void;
clearCacheImages(): void;
fromDataURL(data: string): void;
isEmpty(): boolean;
toData(): string;
}
export function VueSignaturePad(Vue: typeof _Vue): void;
export default VueSignaturePad;
}
Is there something wrong with it?
Well, the temporary solution for now is to make it as any. Like this
const { isEmpty, data } = (this.$refs.signaturePad as any).saveSignature()
This is the way I could think of so far.
You should move your imports INTO the declare module
stuff, or the ambient declaration just won't have effect, as even a single top level import
or export
makes that file an ES module to TS and treated as such
You should move your imports INTO the
declare module
stuff, or the ambient declaration just won't have effect, as even a single top levelimport
orexport
makes that file an ES module to TS and treated as such
Well, tried that but got this error
If I import vue/types/vue
, it would throw an error like this
I tried to make a two file, first is index.d.ts
then vue-shim.d.ts
then types.d.ts
and so on. No luck so far. That's why I put that on top I thought it would make a difference, but none also. Probably I would make a new project, see if my project is broken or something.
Remember to restart VSCode between each rename of the files, as sometimes it get out of sync
Remember to restart VSCode between each rename of the files, as sometimes it get out of sync
I even restart my pc because the past overwhelm-headache-kindof issue I have with vscode, so when someone told me to restart IDE, I restart my pc instead hehe
By the way, in Nuxt, I should put it in index.d.ts
on the root project, right? not in plugins folder, isn't?
Honestly dunno, never used Nuxt :sweat_smile:
Updated version compatible with Vue3 and Volar
/* eslint-disable @typescript-eslint/no-explicit-any */
declare module 'vue-signature-pad' {
import {
ComponentPublicInstance,
ComponentOptions,
ComputedOptions,
Plugin,
MethodOptions,
} from 'vue';
type ComponentConstructor<
Component extends ComponentPublicInstance<
Props,
RawBindings,
D,
C,
M
> = ComponentPublicInstance<any>,
Props = any,
RawBindings = any,
D = any,
C extends ComputedOptions = ComputedOptions,
M extends MethodOptions = MethodOptions
> = { new (): Component } & ComponentOptions<Props, RawBindings, D, C, M>;
export interface VueSignaturePadProps {
width?: string;
height?: string;
saveType?: string;
options?: Record<string, any>;
images?: [];
customStyle?: CSSStyleDeclaration;
}
export interface VueSignaturePad
extends ComponentPublicInstance<VueSignaturePadProps> {
saveSignature():
| { isEmpty: true; data: undefined }
| { isEmpty: false; data: string };
undoSignature(): void;
clearSignature(): void;
// eslint-disable-next-line @typescript-eslint/ban-types
mergeImagesAndSignature(signature: object | string): void;
addImages(images: []): void;
lockSignaturePad(): void;
openSignaturePad(): void;
getPropImagesAndCacheImages(): void;
clearCacheImages(): void;
fromDataURL(data: string): void;
isEmpty(): boolean;
toData(): string;
}
export const VueSignaturePad: ComponentConstructor<VueSignaturePad>;
const plugin: Plugin;
export default plugin;
}
By the way, in Nuxt, I should put it in
index.d.ts
on the root project, right? not in plugins folder, isn't?
A little late but it cost me the past half hour to figure this out, so hopefully this helps someone with "nuxt": "^2.15.3"
:
- Create plugin
vue-signature-pad
in plugins folder with this content:
import Vue from 'vue'
import VueSignaturePad from 'vue-signature-pad'
Vue.use(VueSignaturePad)
- add module declaration to
decs.d.ts
in root folder using the code created by @fahmiegerton - add plugin to nuxt.config.js
plugins: ['~/plugins/vue-signature-pad'],
If you are using Nuxt 3, the plugin step is replaced with:
import VueSignaturePad from 'vue-signature-pad'
export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.vueApp.use(VueSignaturePad);
})
By the way, in Nuxt, I should put it in
index.d.ts
on the root project, right? not in plugins folder, isn't?A little late but it cost me the past half hour to figure this out, so hopefully this helps someone with
"nuxt": "^2.15.3"
:
- Create plugin
vue-signature-pad
in plugins folder with this content:import Vue from 'vue' import VueSignaturePad from 'vue-signature-pad' Vue.use(VueSignaturePad)
- add module declaration to
decs.d.ts
in root folder using the code created by @fahmiegerton- add plugin to nuxt.config.js
plugins: ['~/plugins/vue-signature-pad'],