Giter Site home page Giter Site logo

mdsvexamples's Introduction

mdsvexamples

Render your Svelte code blocks in MDSveX

# Button

An example of how to use our Button component

```svelte example
<script>
    import Button from '$lib/Button.svelte'
</script>

<Button>Button</Button>
```

preview

Getting Started

npm install mdsvexamples

Setup

There are two plugins that you need to add: a remark plugin and a vite plugin.

There are plugins provided for esbuild and rollup as well, as it uses unplugin, but I have not tested these so YMMV

MDSveX

Add the remark plugin to your MDSveX config

// mdsvex.config.js
import { defineMDSveXConfig as defineConfig } from 'mdsvex'
import examples from 'mdsvexamples'

const config = defineConfig({
  extensions: ['.svelte.md', '.md', '.svx'],

  smartypants: {
    dashes: 'oldschool'
  },

  remarkPlugins: [examples],
  rehypePlugins: []
})

export default config

Vite

Add the vite plugin to your vite config

// vite.config.js
import { defineConfig } from 'vite'
import examples from 'mdsvexamples/vite'

export default defineConfig({
  plugins: [examples]
})

export default config

Usage

Add example to your Svelte code block and it will be rendered

```svelte example
<button>Button</button>
```

Imports also work!

```svelte example
<script>
	import Button from '../lib/Button.svelte'
</script>

<Button>Button</Button>
```

Customization

Examples can take various configurations. The defaults for all can be set in the remark plugin, but you can also provide them per-example as "meta" tags in the code block.

{
  remarkPlugins: [
    [
      examples,
      {
        defaults: {
          foo: true,
          bar: 'baz'
        }
      }
    ]
  ]
}
```svelte example foo bar="baz"

...

```

Wrapper

Example code blocks are rendered with a Svelte component. You can provide your own if you wish to customize its look or behaviour.

{
  remarkPlugins: [
    [
      examples,
      {
        defaults: {
          Wrapper: '/src/lib/Example.svelte',

          // or if the component is a named export
          Wrapper: ['some-package', 'CustomExample'] // -> import { CustomExample } from 'some-package'
        }
      }
    ]
  ]
}

When provided as code block meta, it can be relative to the file

```svelte example Wrapper="./Example.svelte"

...

```
<!-- src/lib/Example.svelte -->
<script>
  // the source of the example, if you want it
  export let src

  // all meta tags of the code block
  export let meta
</script>

<div class="example">
  <slot name="example" />
</div>
<div class="code">
  <pre class="language-svelte"><slot name="code" /></pre>
</div>

csr

Forces the example to only be imported & rendered client-side. This is useful for examples that consume libraries that may have issues server-side.

```svelte example csr
<script>
  import BrowserOnlyComponent from '../lib/BrowserOnlyComponent.svelte'
</script>

<BrowserOnlyComponent />
```

hideScript

Hides <script> tags from being shown in the displayed code. This will also remove it from the src prop if you have a custom Example component.

```svelte example hideScript
<script>
  console.log("Hello World!")
</script>

<button>Button</button>
```

hideStyle

Hides <style> tags from being shown in the displayed code. This will also remove it from the src prop if you have a custom Example component.

```svelte example hideStyle
<button>Button</button>

<style>
  button {
    background: green;
  }
</style>
```

mdsvexamples's People

Contributors

jjagielka avatar mattjennings avatar tropix126 avatar venashial avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

Forkers

tropix126 gi4no

mdsvexamples's Issues

How to display the "contents" of an imported component?

I'm writing components and trying to display the code for the contents of these components. It's possible to for example write a component , then copy the code to a new component which is wrapped in svelte example , and then using that component. Or, just copy paste the code of the component into a svelte example

I'm looking for a way to not have to duplicate the code and just get an example from the contents of my component.
Aka, I'm wondering if there's a way to display the contents of an imported component instead of the importing and usage of the component.

So for example instead of

Button

An example of how to use our Button component

<script>
    import Button from '$lib/Button.svelte'
</script>

<Button>Button</Button>

displaying

<script> import Button from '$lib/Button.svelte' </script>

Button

I would like it to act as if I copy pasted the code from $lib/Button.svelte into the
svelte example.

Is this possible somehow?

Option to hide script and style tags

It'd be useful to have an option to hide script and style tags from the displayed code block.

Ideas:

  • meta on code block to hide scripts
```svelte example hide-scripts
<script>
   import Button from '$lib/Button'
</script>

<Button class="button" />

<style>
   .button {}
</style>
```
  • use the hidden attribute on the tags themselves. i don't think they do anything on script/style? as long as it's safe to repurpose those, that'd be cool.
```svelte example
<script hidden>
   import Button from '$lib/Button'
</script>

<Button class="button" />

<style hidden>
   .button {}
</style>
``` 

Support passing Wrapper as SvelteComponent

Wrapper is currently set through an import path to a Svelte component. Would it be possible to allow passing in the component itself?

Reasoning: I'm using a CodeExample.svelte component from an NPM package across multiple projects. That component is not in the package's export map, meaning it's accessible as a named export but not a deep import:

import { CodeExample } from "svelte-zoo" // works
import CodeExample from "svelte-zoo/CodeExample.svelte" // doesn't work

and so this also doesn't work

Wrapper: `svelte-zoo/CodeExample.svelte`

Svelte 5 compat

Just a heads up that mdsvexamples might require changes to support Svelte 5. The alpha just dropped. Trying to build or spin up dev server raises

/slots/+page.svx___mdsvexample___1.svelte:21:17 Invalid assignment to const variable ($derived values, let: directives, :then/:catch variables and @const declarations count as const)

Just to clarify, I don't expect alpha support so no reaction needed. Just putting this on the radar.

How to make it width 100%

I added width 100% but the code and example blocks are about 500px.
How can I make it 100%?

You can see the size difference in the following image.

image

HMR for examples

Currently we trigger a full page reload when the example is edited

handleHotUpdate() {
// reload page when example is updated - would be nice to trigger HMR on owner svelte component instead
Object.keys(examples).forEach((key) => {
viteServer.moduleGraph.invalidateModule(viteServer.moduleGraph.getModuleById(key))
viteServer.ws.send({
type: 'full-reload'
})
})

it would be nice to HMR these changes instead, but I'm not sure how that works with virtual files.

feat: filename in meta

Would it be possible to add to meta the currently processed file name? I would be able, for example, to add links to GitHub directing straight to the file.

{
  "Wrapper": "/src/routes/utils/ExampleWrapper.svelte",
  "example": true,
  "file": "/src/pages/my_component_doc.md"
}

Svelte 5: File not found

Running sveltekit 2.5 @ svelte5.0.0-next.45 throws error for each route:

Plugin: mdsvexamples-plugin SvelteKitError: Not found: /___mdsvexample___2.svelte and so on.

Document relative component imports not supported

Very excited about this project! Thanks for putting it together. πŸ‘

Just tried it out on svelte-multiselect and get import errors when using relative imports:

10:20:47 AM [vite] Internal server error: Failed to resolve import "../lib/MultiSelect.svelte" from "src/routes/disabled.svx/___mdsvexample___0.svelte". Does the file exist?

Using import "$lib/MultiSelect.svelte" as shown in the readme works. I think the requirement to use alias imports should be stated more clearly (or relative imports supported).

Update dependency to vite 4.0.0

When I update vite to 4.0.0, I get an warning:

 WARN  Issues with peer dependencies found
.
└─┬ mdsvexamples 0.3.2
  └─┬ unplugin 0.7.2
    └── βœ• unmet peer vite@"^2.3.0 || ^3.0.0-0": found 4.0.0

Can you update to vite 4.0.0?

Vite plugin

According to the README file, I need to add the vite plugin to your vite config.
Normal SvelteKit installation doesn't have it.
Since it provide svelte.config.js, can I add vite config to the svelte.config.js?

imports from $lib

All works perfectly with:

<script>
import Component from "$lib/Component.svelte";
import { Component2 } from "$lib"; // if you created 'index.js' in src/lib
</script>

However, if you're building a svelte package and want to supply nice documentation for it, using $lib is not the best option.
Examples should show that you import from your just being built package. Is there a trick then to replace $lib with the package_name in the rendered examples?

<script>
import Component from "my-package-name/Component.svelte";
import { Component2 } from "my-package-name"; // if you created 'index.js' in src/lib
</script>

Custom Example.svelte needs an extra line at the top

I created src/lib/Example.svelte as you suggested in the README.

<script>
	// the source of the example is provided as a prop if you want it
	export let src;
</script>

<div
	class="container flex flex-wrap justify-center rounded-xl py-8 mx-auto bg-gradient-to-r bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-700 p-2 sm:p-6"
>
	<slot name="example" />
</div>

<div class="code">
	<pre class="language-svelte">
		<slot name="code" />
	</pre>
</div>

However if I don't add an extra empty line, it messes up the code as you see in the following image.

image

image

If I add an extra line there is too much space.

image

image

Typo code

At the end of the README file:

<!-- src/lib/Example.svelte -->
<script>
	// the source of the example is provided as a prop if you want it
	export let src
</script>

<div class="example">
	<slot name="example" />
</div>
<div class="code">
	<pre class="language-svelte">
		<slot name="code" />
	</pre>
</code>

The last line should be </div> instead of </code>.

Setting custom Wrapper component through config has no effect

Following the readme, I tried setting a custom component to render examples as follows to no effect.

import adapter from '@sveltejs/adapter-static'
import { mdsvex } from 'mdsvex'
import examples from 'mdsvexamples'
import preprocess from 'svelte-preprocess'

/** @type {import('@sveltejs/kit').Config} */
export default {
  extensions: [`.svelte`, `.svx`, `.md`],

  preprocess: [
    preprocess(),
    mdsvex({
      remarkPlugins: [
        examples,
        { defaults: { Wrapper: `/src/components/Example.svelte` } },
      ],
      extensions: [`.svx`, `.md`],
    }),
  ],

  kit: {
    adapter: adapter(),
  },
}

Setting it as code block meta works though:

```svelte example Wrapper="../../components/Example.svelte"
...
```

Here's a StackBlitz repro.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.