antoniandre / wave-ui

A UI framework for Vue.js 3 (and 2) with only the bright side. ā˜€ļø
https://antoniandre.github.io/wave-ui
MIT License
547 stars 40 forks source link

Any plans for Typescript support? #26

Closed MarkMcTernan closed 7 months ago

MarkMcTernan commented 3 years ago

Nice library, really clean. I checked it out because it was an early adopter of Vue 3, but Typescript is a requirement for me. Are there any plans to support a typelibrary for TS?

antoniandre commented 3 years ago

Hi @MarkMcTernan, thanks for the feedback! I would love to have support for typescript, really keen to add this, but lacking of time at the moment. I'll keep that in the pipe, if ever you would like to contribute on that you are most welcome! Cheers.

scottpageindysoft commented 3 years ago

As a workaround, for now, make your shims-vue-d.ts look like this following code block (could also put this in its own plugin file). I only spent about 15 minutes with this, so I'm not 100% on the WaveUI constructor options. I'll take a look again later tomorrow, when I get a chance.

Keep in mind that this is for Vue 2. I'm in the process of upgrading my huge project to Vue 3, so when I get to this I'll make it work and share the results.

declare module '*.vue' {
  import Vue from 'vue';
  export default Vue;
}

declare module 'wave-ui' {
  import Vue, { PluginFunction } from 'vue';

  interface Colors {
    primary?: string;
    secondary?: string;
  }

  interface Breakpoints {
    xs?: number;
    sm?: number;
    md?: number;
    lg?: number;
  }

  interface Presets {
    sm?: boolean;
    outlined?: boolean;
    round?: boolean;
  }

  interface ConstructorOptions {
    colors?: Colors;
    breakpoints?: Breakpoints;
    presets?: Presets;
  }

  export declare class WaveUI extends Vue {

    constructor(options?: ConstructorOptions);
    static install: PluginFunction<unknown>;
    static version: string;
  }

  declare module 'vue/types/options' {
    import Vue, { ComponentOptions } from 'vue';
    export interface ComponentOptions<
      V extends Vue,
      Data = DefaultData<V>,
      Methods = DefaultMethods<V>,
      Computed = DefaultComputed,
      PropsDef = PropsDefinition<DefaultProps>,
      Props = DefaultProps> {
        waveui?: WaveUI
    }
  }

  export default WaveUI;
}
scottpageindysoft commented 3 years ago

Maybe later I'll add an updated (corrected) version to DefinitelyTyped.

antoniandre commented 3 years ago

Thanks so much for your input @scottpageindysoft! Iā€™d be glad to integrate some TS support in the codebase if we come up with sufficient defs. It looks like quite some work though to cover all the components.

scottpageindysoft commented 3 years ago

Anytime! It could take some time to go through each component and the utilities, but what's nice about TypeScript is you can adopt it as you find the time. It's not necessary to move to full TypeScript once you start the process. So, you could do it one component at a time, without breaking anything. The downside to doing that would be that only the components you have migrated to TS will have any TS definitions after being built.

Quite often I find myself only converting small portions of apps, as needed, until it's finally fully converted eventually.

talrejrc1 commented 3 years ago

Hey @scottpageindysoft, Thank you. Any update on this ? Does that mean we can't use waveui with typescript till we get an updated d.ts file ? thanks again.

MedLabs commented 2 years ago

We still can't use wave-ui on typescript based projects :(

johnson86tw commented 2 years ago

This works for me with Vue CLI + Vue 3 + TypeScript:

// shims-vue.d.ts
declare module 'wave-ui' {
  export default WaveUI
}
Anwinity commented 1 year ago

It's been a while since this was originally posted, are there any plans to add official typing? I'd like to try this library, but I need ts support to do so... :(

KazimirPodolski commented 1 year ago

Lack of proper Typescript support is a show stopper for us, and many others. You might also miss the productivity it gives yourself.

antoniandre commented 1 year ago

I'm open to add support, but I need help to get started. Anyone wanting to move forward with this feature, please suggest a PR with a couple of files where they are best placed and I will continue. (branch out from Main please)

PaulCEllsworth commented 1 year ago

I will fork and work on an amount of TypeScripting. I have been loathing the transition away from ES/JS but a "smaller than my monster" project (it has four large apps inside it) may be the way to drag myself kicking and screaming into this particular coding decade. [8/31: Miaybe a show stopper on a fork: I haven't used PUG and am loathe to do so. May make any form a not-worth it task because the merge back would be nearly impossible, Thoughts?]

antoniandre commented 1 year ago

Hi @PaulCEllsworth, thanks for suggesting help and looking into the codebase. For typescript definitions, I don't think you even need to write/read/bother with Pug, do you? If I'm not mistaken the typescript definitions will be provided for the Javascript part, the methods, arguments, etc. If you are thinking to rewrite all the components in ts, then I think we can already start with baby steps like ts definitions and see how it goes. let me know your thoughts. Cheers.

luc122c commented 1 year ago

It is possible to generate declaration files (.d.ts) from the existing JS files by annotating the functions. That might be an easier first step? https://www.typescriptlang.org/docs/handbook/declaration-files/dts-from-js.html @antoniandre Perhaps you could create a ts branch that we could contribute these to?

antoniandre commented 1 year ago

I think it's the best approach yes. Ok I'll create the branch right away šŸš€

antoniandre commented 1 year ago

You have it!

DerrikMilligan commented 1 year ago

@antoniandre There's also the @types repo which could serve as some middleground and perhaps a setup up from the JSDoc extraction. Because I'm not sure if we can actually get real Vue types that define the props, slots, events, and methods correctly. I've been working on a script that will build out all the initial typescript definition files by parsing the Vue components and the API documentation components.

I'll have to fill in a bunch of gaps by reading through the code. But I was planning on making a pull request there once I got that finished.

Once done one could run npm install --save-dev @types/wave-ui and then have access to all those typescript types.

PaulCEllsworth commented 1 year ago

Quoting from antoniandre: "if I'm not mistaken the typescript definitions will be provided for the Javascript part, the methods, arguments, etc.".... we can already start with baby steps like ts definitions and see how it goes. let me know your thoughts."...

Excellent points, so I will try that on a couple of them and see if I can do so successfully. Also with the TS branch we might be able to somewhat "crowd source" the coding which is why open source flourished to begin with. Then again I'm old enough to remember when Linux was approaching "v.2x" so perhaps I am a bit naive... deliberately. I do like some of the suggested approaches to speed the process BTW.

DerrikMilligan commented 1 year ago

Changing the components to using Vue 3 with script setup isn't too bad if that's the route everyone decides to take I'll gladly help. It still be pretty straightforward besides the mixins, they'd have to be re-worked since the composition API doesn't support them.

But if we can get just types for everything without having to refactor it then that's a fine start. I can show some of what I have going on the next week or so. Just been doing it in my spare time at work.

luc122c commented 1 year ago

There's also the @types repo which could serve as some middleground and perhaps a setup up from the JSDoc extraction.

Once done one could run npm install --save-dev @types/wave-ui and then have access to all those typescript types.

This is usually more of a workaround when it's not possible to include the types with the package itself. In this case, the author is active and willing to include the types directly in the package.

I agree with you both, incrementally adding JSDocs and definition files is the easiest/simplest path. A re-write to the composition API might be better long-term but that would be a major change.

antoniandre commented 1 year ago

@luc122c I will rewrite everything in composition API when supporting Vue 2 is obsolete. For now, it's not a problem at all to not use it, and very helpful for backward compatibility. Having almost the same codebase for both tags allows me to release features for both without too much work/troubles.

antoniandre commented 1 year ago

including the types definitions in the project is what we choose. Thanks for the PR @luc122c, it's a good start. Can someone add one ts definition file in the started ts branch for one of the Wave UI components, or just start the skeleton, or point me in the right direction to do it please. Then also I need help to know how to test the result, how can I view it in action? Do I only need to have the ts files in the dist build so users will benefit from the intellisense in VS Code when using Wave UI? And do we need JS Doc for every single function of the codebase in the /src/wave-ui folder? Cheers! šŸ˜Ž

DerrikMilligan commented 1 year ago

Here is my pull request for the ts branch with all the component definitions, initial typescript build files, and some other helpful types.

I know that this is a little different than trying to use the jsdoc to generate the types or converting the project to using Vue 3, however I think we get some advantages this way:

The downside of the approach is that we will have to maintain two separate components. When making changes to the .vue component you'll need to update the .ts type file of it as well. But I think this could be a good starting point for us.

antoniandre commented 1 year ago

Hey everybody šŸ‘‹ Thanks to your help guys, and in particular @DerrikMilligan, we have a solid good start in the ts branch! And I don't think there's a long road before we merge it into main since it's already usable. šŸš€ However I would really encourage any TS aficionados to have a look at the /src/wave-ui/types/ folder as well as the definitions files to verify if we all think the configuration is correct, and in order to improve the definitions for some left over anys.

The chosen approach is to have type definitions in separate files (may be they should rather be at the same level of each Vue component?) and not complete rewrite into TS of the project - which I don't want, at least not now.

Despites the advantages listed by @DerrikMilligan, it is really a big constraint to have to maintain this types definitions separately. Maybe a script like the one you build @DerrikMilligan could be run each time I build-bundle and generate the types files from the JS Doc if it was a lot more complete? Food for thoughts for longer term improvements, but for now and for a start, we can definitely ship like that with what we have.

If someone can guide me how to test the types (view the autocompletions in VS Code) while developing them. that would speed up the dev and release.

Cheers!

DerrikMilligan commented 1 year ago

@antoniandre I know you don't want to swap to the composition API right now, which makes sense, but would doing something like this be an option for you?

https://vuejs.org/guide/typescript/options-api.html

We could try something like that maybe? And maybe move the JSDocs I generated into the Vue files themselves?

If you don't want to go down that route I'll work on a good way to test it more as is. The only was I'd been testing it was registering the components globally doing this:

import type {
  WSelect,
  WList,
  // ...
} from 'wave-ui';

declare module '@vue/runtime-core' {
  export interface GlobalComponents {
      WSelect: WSelect,
      WList: WList,
      // ...
  }
}

Which would then let me test the components in my other Vue files in my project.

antoniandre commented 1 year ago

Hey @DerrikMilligan, thanks for the suggestion. On one hand I think this would be another step toward Typescript, which is great for supporting TS. But on the other hand it seems that this is the one huge step that I can't afford now that we still have Vue 2. Let me explain, and maybe we can find an in-between step:

Following the documentation @ https://vuejs.org/guide/typescript/options-api.html#typing-component-props:

So I am up for introducing more typing in the codebase, as long as it doesn't explode and create too much work, because it would be wasted now. In a few months, I will stop supporting the legacy branch and we can rewrite everything in composition API in the main branch.

I'm open to suggestions :)

antoniandre commented 1 year ago

btw, if you want to have an overview of the work to be done to move to TS at least by adding lang="ts", I suggest you start from this commit and continue the transformation until it does not complain on that file. then times the amount of components! lol šŸ”«

DerrikMilligan commented 1 year ago

I assume by blowing up you mean that linting rules and missing types right? I think that could be the only path to go maybe. Adding all the types so long as it still works for the Vue 2 components. We still have to fill out a whole lot of those with the interfaces I've made as well.

I've been trying to move the interfaces next to the actual component files but what I don't quite know how to do is make it so when you import the component you get the actual component that you can register with Vue AND the typed component that you can use.

The issues I'm currently running into trying to follow this method are outlined on a typescript issue here

Here is a commit with what I've been trying to do with this. To have a tests file where you can test things and trying to fix how to import things side by side.

From that commit this technically does work in the tests file.

import wSelect from '@/types/components/w-select'

// ...

const select = ref<InstanceType<typeof wSelect>>()

And you could test things on the select.value for some of the auto-completion things. But it's not in a .vue component. So I've been really trying to figure out how to work around the vue-shim.d.ts file that all Vue typescript projects have, and having the declared modules that import correctly.

When I build the project and in my external project try importing the Vue component the shim takes precedence over the declared module. image

So I'm really not sure the best way to handle this going forward. For either testing or for people to use the types. Because not everyone wants to register the components globally I'm sure. Even though that was working for me with the typings.

antoniandre commented 12 months ago

hey! Feel like I should revive this. I can't help on the best approach for TS since I'm not using Typescript, but if everybody thinks the current work is good to go, from this point discussed above:

Hey everybody šŸ‘‹ Thanks to your help guys, and in particular @DerrikMilligan, we have a solid good start in the ts branch! And I don't think there's a long road before we merge it into main since it's already usable. šŸš€ However I would really encourage any TS aficionados to have a look at the /src/wave-ui/types/ folder as well as the definitions files to verify if we all think the configuration is correct, and in order to improve the definitions for some left over anys.

The chosen approach is to have type definitions in separate files (may be they should rather be at the same level of each Vue component?) and not complete rewrite into TS of the project - which I don't want, at least not now.

Despites the advantages listed by @DerrikMilligan, it is really a big constraint to have to maintain this types definitions separately. Maybe a script like the one you build @DerrikMilligan could be run each time I build-bundle and generate the types files from the JS Doc if it was a lot more complete? Food for thoughts for longer term improvements, but for now and for a start, we can definitely ship like that with what we have.

If someone can guide me how to test the types (view the autocompletions in VS Code) while developing them. that would speed up the dev and release.

Cheers!

Then, I will merge the current work (/src/wave-ui/types/) in the main branch. It looks to me like this was a good start, and that the next suggested step was not easily doable now. So let me know @DerrikMilligan, and everybody what you vote for! let's get this out first and improve over time.

DerrikMilligan commented 11 months ago

I think getting live what we have would be a massive improvement and at the very least, help me and my team with using Wave-UI. It's not a perfect solution, but I don't know that there is one in this situation until we use typescript more in wave-ui itself. I'd love for what we have to go live!

antoniandre commented 9 months ago

Hi everybody, @DerrikMilligan Happy new year! A new pre-release containing TS definitions is ready at npm i wave-ui@3.10.0-ts.0. Please install and give feedback!

DerrikMilligan commented 9 months ago

My initial look at the typescript branch, it's working well for me!

I have a components.d.ts file in my root src/ directory and now am getting the typing and auto-completion!

/* eslint-disable @typescript-eslint/naming-convention */
import type {
    WAccordion,
    WAlert,
    // ... cut for brevity
    WTooltip,
    WTree,
} from 'wave-ui';

declare module '@vue/runtime-core' {
    export interface GlobalComponents {
        WAccordion          : WAccordion;
        WAlert              : WAlert;
        // ... cut for brevity
        WTooltip            : WTooltip;
        WTree               : WTree;
    }
}
antoniandre commented 7 months ago

Seeing the last results and no other complaints, the TS branch has been merged into main and released in version 3.11.0. @DerrikMilligan - and all - you are welcome to contribute with PRs to refine the definitions. :)

We can close this issue now. If you face any problem, please open a new one.