Code Monkey home page Code Monkey logo

swingset's Introduction

swingset

Welcome to Swingset. Swingset is a drop-in component documentation system built for Next.js's App Router and React Server Components.

Note Swingset is currently under active development. We're actively iterating on the core features and APIs, and some things may change.

Installation

Install swingset with your package manager of choice:

npm install swingset

Import the plugin in your next.config.mjs file:

// next.config.mjs
import withSwingset from 'swingset'

export default withSwingset({
  componentRoot: './components',
  theme: 'swingset-theme-custom',
})()

Features

App Router native

Swingset is built for the new App Router and React Server Components. Running the bootstrap command will generate a route group for swingset:

$ swingset bootstrap

Generating swingset route group...

Success! Route group created:

(swingset)
  ├ /layout.tsx
  └ /swingset
    ├ /page.tsx
    └ /[...path]
      └ /page.tsx

Component documentation

Document your components with MDX by placing a docs.mdx file next to your component source:

components/
  button/
    docs.mdx
    index.tsx

Component prop extraction

Swingset automatically exposes prop metadata for components imported into your documentation.

<PropsTable component={Button} />

Custom documentation

Swingset also supports standalone documentation pages. By default, .mdx files in /app/(swingset)/swingset/docs/ are rendered.

Custom themes

By default, Swingset only exposes the data necessary to fully render your documentation content. Swingset can be configured with a custom theme to control rendering.

// next.config.mjs
import withSwingset from 'swingset'

export default withSwingset({
  componentRoot: './components',
  theme: 'swingset-theme-custom',
})()

Custom remark and rehype plugins

Want to add support for GitHub Flavored Markdown? Swingset accepts remark and rehype plugins.

  • Add remarkGfm
  • Restart your server
  • Render task lists!
// next.config.mjs
import withSwingset from 'swingset'
import remarkGfm from 'remark-gfm'

export default withSwingset({
  componentRoot: './components',
  remarkPlugins: [remarkGfm],
})()

Integrates with @next/mdx

Swingset integrates with @next/mdx by supporting the same mdx-components.ts file at the root of your application. Swingset will make the custom components declared there available.

Use with Storybook

Documentation pages within Swingset are treated as modules. This means that you can import other modules into your .mdx files as you would any other JavaScript file. This works great if you leverage Storybook for component development, as stories are directly consumable from your documentation:

import * as stories from './Button.stories'

# This is the Primary story

<stories.Primary />

Contributing

See CONTRIBUTING.md.

swingset's People

Contributors

alexcarpenter avatar ashleemboyer avatar dependabot[bot] avatar dstaley avatar github-actions[bot] avatar hashibot-web avatar hashicorp-copywrite[bot] avatar hashicorp-tsccr[bot] avatar jescalan avatar jmfury avatar nandereck avatar prestonbourne avatar thiskevinwang avatar wkentdag avatar zchsh avatar ztanner 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  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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

swingset's Issues

Update type definitions for placeholder modules intercepted by loader

We use a few modules as placeholders that are ultimately intercepted by our loader. Currently, we manually maintain definition files for these placeholders so that type information is accurate when these modules are imported in custom themes and during usage.

Placeholder modules:

  • swingset/meta
  • swingset/theme

Each module should have a a .d.ts file in packages/swingset/src

Add `swingset bootstrap` command

Swingset should expose a small CLI with a bootstrap command to add the necessary boilerplate.

Mock output:

$ swingset bootstrap

Generating swingset route group...

Success! Route group created:

(swingset)
  ├ /layout.tsx
  └ /swingset
    ├ /page.tsx 
    └ /[...path]
      └ /page.tsx

feat: parse path frontmatter property in component docs

When parsing a component's documentation file, we should read the path frontmatter property and parse out a few values.

---
path: '[category]/[folder]/[page]'
---
  • [category] - optional top-level sidebar category, no URL implications
  • [folder] - optional nested folder, represented in URL
  • [page] - Page’s title

To start, we want to parse these values out of the path frontmatter property if it exists. Heuristic: The [page] will always be pulled from the last segment. The root [category] will always be the first segment (if > 1). [folder] is optional and will be treated as the 2nd segment if 3 are provided.

Input:

---
path: 'Components/Forms/Input'
---

output:

{
  category: 'Components',
  folder: 'Forms',
  page: 'Input'
}

Input:

---
path: 'Components/Button'
---

output:

{
  category: 'Components',
  page: 'Button'
}

Input:

---
path: 'Button'
---

output:

{
  page: 'Button'
}

Finalize custom theme module contract

Currently, themes are expected to expose a default export and a named Page export. The default export is the Layout, and the named export is used as the page component for the dynamic swingset route. It might make more sense to have both of these be named exports for clarity.

// layout.ts
import { layout } from 'swingset/theme'

export default layout
// page.ts
import { page } from 'swingset/theme'

export default page

Swingset fails to load components on Windows

👋 It looks like since globby doesn't support Windows paths (sindresorhus/globby#130 & sindresorhus/globby#127), the globbing and path operations across swingset silently fail on Windows machines.

To be clear, the package still compiles and no errors are thrown, yet when running on Windows, components-loader.js won't find any components to build into Next.js pages.

I've got a branch working that addresses these issues, but it's tricky since globby, path, and webpack need a variety of path styles. I have successfully run the peerComponents example with [some ugly] changes made locally 🎉

I'll have a PR up for this once I do a bit of clean up on my fork 😄

cc: @BRKalow

defaultValue is not the default prop value

When using a props.json5 file, its defaultValue property is used to control the default control value in a <KnobsComponent>. This is confusing, as the props.json5 file refers to "props" in its name, suggesting defaultValue would be the default value in the shape of the data, like defaultProps in React, or a default parameter in JS.

It might make more sense to move context-specific props into their own object.

{
  inline: {
    description: 'Determines whether to display the alert inline and only with a tagline',
    type: 'boolean',
    knob: {
      type: 'checkbox',
      defaultValue: false
    }
  }
}

Improve development setup

Each workspace has a dev command that works, but they need to be triggered manually in order to get the example to run. We should come up with a way to encapsulate this. Current:

In three separate shells:

  1. npx turbo run dev --filter 'swingset'
  2. npx turbo run dev --filter 'swingset-theme-hashicorp'
  3. npx turbo run dev --filter 'example-basic'

"No loaders configured to process this file"

Hello, we were trying to integrate Swingset in our application to have a less heavy platform to display our components on.

Despite reading in your README that it is not recommended for use, we hoped to give it a shot. Unfortunately I can't seem to get it working properly.

I get the following error message:

./node_modules/swingset/page.jsx 33:6
Module parse failed: Unexpected token (33:6)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
| 
|     return (
>       <div className={s.root}>
|         <Head>
|           <title key="title">Component Library</title>

I've tried installing next-transpile-modules to hope to fix this issue but that resulted in another error message:

Server Error
TypeError: Cannot read property 'src' of undefined

../../pages/_document.tsx (86:33) @ Function.getInitialProps

    |     }
    | 
 >  |     const { html, head } = await ctx.renderPage({ enhanceApp })
    |                                 ^
    |     const styles = [...flush()]
    |     return { html, head, styles }
    |   }

We're using the latest version of next ( 10.0.7 ) and are using TSX for all our components.

I totally understand if you'd close this issue. 😄

Super exciting project!

Not an issue, but discussions aren't enabled, so I'm leaving this here.

I'm currently looking for a Storybook replacement that allows for more flexibility. Am looking at building a component library site with Nextra (and a forked docs theme). Swingset looks like it might integrate well with that. I'm looking forward to seeing how/if this project progresses.

README.mdx

Octavo could switch from doc.mdx to README.mdx.

GitHub supports README.mdx files and gives them the same treatment as README.md files when viewing a directory. NPM also supports README.mdx files.

In both cases, they are displayed static, meaning the react components themselves are not hydrated. Self-closing elements, like the knobs component, would not be rendered at all in the static view, which may actually be ideal.

Using README.mdx seems like a better fallback pattern, and it would result in less repetition than having both docs.mdx and README.mdx files.

Remove `clsx`

The Docs for the class-variance-authority package, point out that that clsx is already included under the export cx

For the sake of consistency let's ensure we're only using cx instead of having the same package twice under different names

`ComponentEntity` should be `ComponentNode` in `categories`

Entities contain unnecessary that we don't need exposed to the theme.

The unneeded properties are being removed however the types don't reflect this.

See packages/swingset/src/types.ts and packages/swingset/src/get-nav-tree.ts to resolve

Write Tests for `getNavigationTree`

The getNavigationTree is large and needs should have some tests to prevent regression down the line, especially for when standalone docs become more involved.

Error: path.replace is not a function

I have started seeing the following error.

error - ./node_modules/@hashicorp/octavo/__octavo_components.js
TypeError: path.replace is not a function

I have removed node_modules and started the project over. I have also inspected that file, which is nearly empty with the following contents:

// this import is always intercepted by a loader
module.exports = {}

Expose utility from `swingset/meta` to get document list based on type and category

Internally, swingset distinguishes between component documentation and standalone documentation. This is evident on the generated metadata objects for each detected document:

  "text": {
    "__type": "component", // 👈 __type property represented here
    "frontmatter": {},
    "category": "default",
    "filepath": "...",
    "relativePath": "components/text/docs.mdx",
    "normalizedPath": "text",
    "componentPath": "components/text",
    "slug": "text"
  },

We should expose a method to get metadata based on the document type and category. This will allow themes to build a navigation element that has access to all available paths.

Sort Navigation Tree

The exported categories currently is currently indexed by insertion order.

To ensure the top level array and the children, render alphabetically, the getNavigationTree function should also contain sorting logic.

GitHub Actions - deprecated warnings found - action required!

Workflow Name: Release
Branch: main
Run URL: https://github.com/hashicorp/swingset/actions/runs/4886563487

save-state deprecation warnings: 0
set-output deprecation warnings: 1
node12 deprecation warnings: 1

Please review these deprecation warnings as soon as possible and merge in the necessary updates.

GitHub will be removing support for these commands and plan to fully disable them on 31st May 2023. At this time, any workflow that still utilizes these commands will fail. See https://github.blog/changelog/2022-10-11-github-actions-deprecating-save-state-and-set-output-commands/.

GitHub have not finalized a date for deprecating node12 yet but have indicated that this will be summer 2023. So it is advised to switch to node16 asap. See https://github.blog/changelog/2022-09-22-github-actions-all-actions-will-begin-running-on-node16-instead-of-node12/.

If you need any help, please reach out to us in #team-rel-eng.

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.