carbon-design-system / carbon-components-vue

Vue implementation of the Carbon Design System
http://vue.carbondesignsystem.com
Apache License 2.0
597 stars 176 forks source link

Carbon v11 #1587

Open benceszenassy opened 2 months ago

benceszenassy commented 2 months ago

Is your feature request related to a problem? Please describe. We should keep up, with the design kit, react and angular components.

Describe the solution you'd like On a separate branch, we should update the components incrementally, based on the react components.

Additional context There are lot of basic features missing from v10 like readonly form fields, toasts that remove them selves after x ms, etc.

@davidnixon I'm gladly participating in this update, if we can do it.

davidnixon commented 2 months ago

1596

LMK what you think of wrapping web components. The HUGE advantage is that we have a large pool of maintainers on the web components team.

@jeffchew I wrapped cds-button and cds-text-input. Those work pretty well. I would still like to try and generate wrappers automatically so I'll keep exploring that.

davidnixon commented 2 months ago

https://github.com/carbon-design-system/carbon-components-vue/tree/carbon11?tab=readme-ov-file#carbonvue-3

benceszenassy commented 2 months ago

I didn't play too much with web components, the first thing that pops in my mind, is scoped slots, but i think we can workaround it with provide / inject.

There are also some areas where we find custom elements to be limiting: Eager slot evaluation hinders component composition. Vue's scoped slots are a powerful mechanism for component composition, which can't be supported by custom elements due to native slots' eager nature. Eager slots also mean the receiving component cannot control when or whether to render a piece of slot content.
Shipping custom elements with shadow DOM scoped CSS today requires embedding the CSS inside JavaScript so that they can be injected into shadow roots at runtime. They also result in duplicated styles in markup in SSR scenarios. There are platform features being worked on in this area - but as of now they are not yet universally supported, and there are still production performance / SSR concerns to be addressed. In the meanwhile, Vue SFCs provide CSS scoping mechanisms that support extracting the styles into plain CSS files.

vuejs.org

Other than that i think its a good direction.

I ran through your commits, i like the idea of using vite. It now seems like a full rewrite so i would introduce typescript too, i dont think it will be too much of a burden.

For wrapper generation, lit labs have something like that, but i didn't tried it yet - gen-wrapper-vue

benceszenassy commented 1 month ago

Hey @davidnixon, i played a little with this lib, its not near an automated wrapper generator, but it can definitely can generate types for props and such.

I checked out the carbon repository, and wired-in the lib.

package.json

...
  "scripts": {
    "generate-vue-types": "custom-elements-manifest analyze && node generate-vue-types.js",
...
  "devDependencies": {
    "@custom-elements-manifest/analyzer": "^0.10.2",
    "custom-element-vuejs-integration": "^1.2.0",
...

generate-vue-types.js

import { generateVuejsTypes } from 'custom-element-vuejs-integration';
import manifest from './custom-elements.json' assert { type: 'json' };

const options = {
  outdir: './',
  fileName: 'vue-types.d.ts',
  componentTypePath: (name, tag) => `./src/components/${tag}/index.ts`,
};

generateVuejsTypes(manifest, options);

Generated custom-elements.json: custom-elements.json

Generated vue-types.d.ts (d.ts upload not supported): vue-types.txt

Its not exporting its types, but i think for a starter its better than nothing. There are libs for VSCode and JetBrains custom html and css json generations too.

And there is a lib for react component generation, maybe it can help to create a vue component generator? custom-element-react-wrappers

github-actions[bot] commented 2 weeks ago

This issue has been marked as stale because it has required additional info or a response from the author for over 14 days. When you get the chance, please comment with the additional info requested. Otherwise, this issue will be closed in 14 days.

davidnixon commented 2 weeks ago

@benceszenassy I have also been looking at tools and I found https://github.com/open-wc/custom-elements-manifest which I think is the same tool you referece above but a different git repo? And this one https://www.npmjs.com/package/custom-element-jet-brains-integration (I use WebStorm).

So I was able to generate this json carbon-web-components-web-types.json

And from that I generated a VERY simple component for the copy button:

<template>
  <cds-copy-button v-bind="props">
    <slot> Copy to Clipboard </slot>
  </cds-copy-button>
</template>
<script setup>
import '@carbon/web-components/es/components/copy-button/index.js';
import { useSlots } from 'vue';
const props = defineProps({
  /** Specify an optional className to be added to your Button */
  buttonClassName: { type: String },
  /** `true` if the button should be disabled. */
  disabled: { type: Boolean },
  /** Specify the string that is displayed when the button is clicked and the content is copi */
  feedback: { type: String, default: 'Copied!' },
  /** The number in milliseconds to determine how long the tooltip should remain. */
  feedbackTimeout: { type: Number, default: 2000 },
  /** Focuses on the first focusable element in the shadow DOM. */
  focus: { type: String },
});
</script>

The generateReactWrappers is VERY interesting. I failed for some of the dot com components but it worked enough to look promising. I'll look at it this week.

I also looked at this one which did not really work at all https://www.npmjs.com/package/@lit-labs/gen-wrapper-vue

davidnixon commented 2 weeks ago

I think the comment above will remove the stale label when the action rus again.

benceszenassy commented 2 weeks ago

@davidnixon i thinkered with it too, here is a gist with the generator (its not complete, but it can generate the basics) and with one example of a generated component.

https://gist.github.com/benceszenassy/7c06de0043e2dfe937008477489d24eb

With emits i dont know what would be the best practice, they didnt get any type for payload... we should create x amount of v-on handler with any as payload type, and simply emit with each? There are custom types in some of the props, those cant be generated, the custom-elements.json cant pick up it well.