Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: devtools #2196

Open
wants to merge 63 commits into
base: v3
Choose a base branch
from
Open

feat: devtools #2196

wants to merge 63 commits into from

Conversation

romhml
Copy link
Collaborator

@romhml romhml commented Sep 13, 2024

This PR introduces devtools for Nuxt UI. It allows users to browse Nuxt UI components and interact with their props.

image

How it works

There's two big parts to this implementation:

  • DevtoolsRenderer

    • Renders Nuxt UI components using the user's settings
    • it is mounted directly into the end user's app through the main Nuxt module.
  • Devtools App

    • A separate standalone app mounted on the Vite server.
    • It displays the ComponentRenderer inside an iframe and communicates with it using custom events.
    • It uses nuxt-component-meta to parse component props and render interactive inputs.

@benjamincanac benjamincanac added the v3 #1289 label Sep 16, 2024
@atinux
Copy link
Member

atinux commented Sep 16, 2024

Awesome 😍

Next step would be the Copy Code button I guess (like for assets):
CleanShot 2024-09-16 at 15 38 03@2x

Copy link

cloudflare-workers-and-pages bot commented Oct 5, 2024

Deploying ui3 with  Cloudflare Pages  Cloudflare Pages

Latest commit: 87cc977
Status: ✅  Deploy successful!
Preview URL: https://b613cfd1.ui-6q2.pages.dev
Branch Preview URL: https://wip-devtools.ui-6q2.pages.dev

View logs

Copy link

pkg-pr-new bot commented Oct 14, 2024

pnpm add https://pkg.pr.new/@nuxt/ui@2196

commit: 87cc977

@romhml
Copy link
Collaborator Author

romhml commented Oct 15, 2024

The PR is ready! I've put some efforts in generalizing the implementation because I think this can be made into a standalone module. I'll look into it soon 😄.

I have some ideas for improvements we can implement later on:

  • Adding a theme tab to edit and preview the ui props and the Nuxt UI configuration.
  • Implementing a specific input for icons with a preview.
  • Supporting multiple inputs / types for props.
  • Displaying multiple variants of a components in the preview (e.g. variant x size).

@romhml romhml marked this pull request as ready for review October 15, 2024 17:26
{ id: 'array', schema: arrayInputSchema, component: ArrayInput }
]

export function usePropSchema() {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This composable is used to infer which component to use for a property. It uses zod to match and transform schema since the matching logic can be a bit tricky and is most likely going to evolve.

@@ -0,0 +1,36 @@
/* eslint-disable no-undef */
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a duplicate from the prettier worker in the documentation with some improvements to await the imports instead of returning an error if they have not resolved yet.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could it be worth updating the docs one with those improvements?

}

// A Plugin to parse additional metadata for the Nuxt UI Devtools.
export function devtoolsMetaPlugin() {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This vite plugin is used to parse the content of the extendDevtoolsMeta macro and inject it into the component meta.

},

configureServer(server: ViteDevServer) {
server.middlewares.use('/__nuxt_ui__/devtools/api/component-meta', async (_req, res) => {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is used by the devtools to fetch component metas.

res.end(JSON.stringify(meta))
})

server.middlewares.use('/__nuxt_ui__/devtools/api/component-example', async (req, res) => {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is used by the devtools to fetch example code.

Comment on lines +191 to +194
// https://github.com/nuxt/nuxt/pull/29366
// meta: {
// isolate: true
// }
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Without this, the renderer will inherit from the user's app.vue code which could lead to unexpected behaviour on the devtools interface.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll figure out a workaround if needed! It'll be a bit more restrictive tho

devtools/app/composables/useMarkdownParser.ts Outdated Show resolved Hide resolved
if (value === false) return
if (!value) return
if (props.component?.defaultVariants?.[key] === value) return
if (props.component?.meta?.props.find(prop => prop.name === key && prop.default === value)) return
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's an issue here leading to some default (multi-words) props behind displayed in the preview most likely caused by diffs in casing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
v3 #1289
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants