storybook icon indicating copy to clipboard operation
storybook copied to clipboard

Vue: Improve generated code snippets

Open larsrickert opened this issue 9 months ago • 4 comments

relates to #26691

What I did

I created a new improved Vue source code generator that has several improvements compared to the current one:

  • use shorthand for truthy booleans: my-prop instead of :my-prop="true"
  • Support double quoted strings like my-prop='"I am double quoted"', useful if e.g. passing SVG icon content as props
  • use correct source code for arrays (:my-props="['a', 'b']"), currently they are generated as object (:my-prop="{0:'a',1: 'b'}") which is incorrect
  • do not render "undefined / null" values
  • support for BigInt in props and slots
  • support for Symbol in props
  • do not add unnecessary <template #default> for default slot without bindings
  • improved source code generate when using slots with bindings
  • support for <script lang="ts" setup> (automatically move arrays and objects there)
  • support for v-models
  • support for slots that use VNodes / custom Vue components

Here is an example which compares the most important features of this PR:

Old:

<template>
  <SourceCode
    foo="Example string"
    :bar="42"
    :array="{0:'A',1:'B',2:'C'}"
    :object="{a:'Test A',b:42}"
    model-value="Model value"
  >
    <template #default>Default slot content</template>
    <template #namedSlots="{foo}">
      {{["Plain text", h("div", {
      style: "color:red"
    }, ["Div child", h("span", foo)])]}}
    </template>
  </SourceCode>
</template>

New:

<script lang="ts" setup>
import { ref } from "vue";

const array = ["A","B","C"];

const modelValue = ref("Model value");

const object = {"a":"Test A","b":42};
</script>

<template>
  <SourceCode
    :array="array"
    :bar="42"
    foo="Example string"
    v-model="modelValue"
    :object="object"
  >
    Default slot content

    <template #namedSlots="{ foo }">
      Plain text
      <div style="color:red">
        Div child
        <span>{{ foo }}</span>
      </div>
    </template>
  </SourceCode>
</template>

As reference, here is the Story source for the above example:

export const Default = {
  args: {
    foo: 'Example string',
    bar: 42,
    array: ['A', 'B', 'C'],
    object: {
      a: 'Test A',
      b: 42,
    },
    modelValue: 'Model value',
    default: 'Default slot content',
    namedSlots: ({ foo }) => [
      'Plain text',
      h('div', { style: 'color:red' }, ['Div child', h('span', foo)]),
    ],
  },
} satisfies Story;

Checklist for Contributors

Testing

The changes in this PR are covered in the following automated tests:

  • [x] stories
  • [x] unit tests
  • [ ] integration tests
  • [ ] end-to-end tests

Manual testing

  1. Run a sandbox for template, e.g. yarn task --task sandbox --start-from auto --template vue3-vite/default-ts
  2. Open Storybook in your browser
  3. Access http://localhost:6006/?path=/docs/stories-renderers-vue3-vue3-vite-default-ts-sourcecode--docs
  4. Click on "Show code" to see the generated source code

Documentation

  • [ ] Add or update documentation reflecting your changes
  • [ ] If you are deprecating/removing a feature, make sure to update MIGRATION.MD

Checklist for Maintainers

  • [x] When this PR is ready for testing, make sure to add ci:normal, ci:merged or ci:daily GH label to it to run a specific set of sandboxes. The particular set of sandboxes can be found in code/lib/cli/src/sandbox-templates.ts

  • [x] Make sure this PR contains one of the labels below:

    Available labels
    • bug: Internal changes that fixes incorrect behavior.
    • maintenance: User-facing maintenance tasks.
    • dependencies: Upgrading (sometimes downgrading) dependencies.
    • build: Internal-facing build tooling & test updates. Will not show up in release changelog.
    • cleanup: Minor cleanup style change. Will not show up in release changelog.
    • documentation: Documentation only changes. Will not show up in release changelog.
    • feature request: Introducing a new feature.
    • BREAKING CHANGE: Changes that break compatibility in some way with current major version.
    • other: Changes that don't fit in the above categories.

🦋 Canary release

This PR does not have a canary release associated. You can request a canary release of this pull request by mentioning the @storybookjs/core team here.

core team members can create a canary release here or locally with gh workflow run --repo storybookjs/storybook canary-release-pr.yml --field pr=<PR_NUMBER>

larsrickert avatar May 18 '24 11:05 larsrickert