Giter Club home page Giter Club logo

histoire's Introduction

Histoire logo


Histoire

Fast and beautiful interactive component playgrounds

Test status Test status Test status Test status

Read the Documentation | Discord server | Discussions board

⚡️ Lightning fast development and instant HMR thanks to Vite 👓 Build and visually test your components in isolation 📚 Document your components with stories and variants 📝 Generate source code examples automatically 🎨 Beautiful and customizable interface

screenshot

Contributing

See Contributing Guide to learn more about the repository and how you can contribute.

Sponsors

Become a sponsor!

We are very grateful to all our sponsors for their support:

License

MIT

histoire's People

Contributors

50rayn avatar akryum avatar alvarosabu avatar arpansaha13 avatar atuttle avatar benmccann avatar bluwy avatar cogor avatar d-ivashchuk avatar danielroe avatar ediaz2 avatar epr3 avatar fermellone avatar filiphazardous avatar gerrywilko avatar guilhermesdev avatar hellobojack avatar holi0317 avatar hugoattal avatar medfreeman avatar michaelthomas0721 avatar mobyrr avatar nozomuikuta avatar peterbud avatar pikax avatar reslear avatar sapphi-red avatar serkodev avatar sor4chi avatar yustarandomname 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  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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

histoire's Issues

Media queries handling for responsive design

I know this is a long shot, and we certainly won't focus on this in the short term.
But we discussed displaying different resolutions of stories to test responsive design, and there will probably be some problem with the media queries (as we won't use iframe).

I just wanted to mention a couple of links that might help to tackle this problem in the future:

It's just a proposal for now, but the fact that a polyfill exists may be a good starting point to make media queries based on a specific div (just to see how Google did this specifically). Also, we may have to create a plugin that change the way CSS is compiled for Histoire?

Config hot reload

It would be nice to handle config changes and hot reload the project

  • Histoire config file
  • Vite config file (histoire field)

Introduce a configuration file

  • Load config file (using cosmiconfig?)
  • Load histoire field from vite.config.js|ts
  • Provide default config values

The config typing is already in node/config.ts

Add config for the histoire vite server

I believe we should add a server option to histoire config, that would be use by the histoire vite server, mainly for specifying a custom port (but maybe there could be other use for it).

Story/variant trees

It would be nice to have a tree-like UX for stories and variants.

  • Use slashes in the title prop
  • Option to use filesystem folders

Add opengraph images

I think it would be better for the public release to have some opengraph images on the documentation website to have nice preview on social networks.

Can't use pinia with defineSetupVue3

It seems that we can't use pinia with this:

export const setupVue3 = defineSetupVue3(({ app }) => {
  const pinia = createPinia()
  app.use(pinia)
})

image

Add a test framework

We should add a test framework, there are a lot of things that should be tested 😅

Suggestion: Peeky or Vitest

Builtin control components

  • Text input
  • Textarea
  • Number input
  • Checkbox
  • Select
  • Button group
  • Radio list
  • Checkbox list
  • Slider
  • Date/hour
  • Color picker
  • JSON code editor

Default styling for histoire menu/control tabs being overridden

I'm willing to submit a PR if this is something that the team thinks should be addressed.

In my project, we have a CSS file that is brought in that has same shared styles across components. Currently, when that CSS is brought into histoire, it is overriding the histoire link styles on the sidebar and controls tabs. Is there a way to control the link styles for the sidebar and control tabs? This could be beneficial for future users looking to customize histoire.

In my histoire.setup
import '@path/to/our/library/css.min.css';

This CSS contains a rule
a { color: blue }

Which leads to some unwanted styling side effects within histoire

image
image

Some approaches could be:

  1. Add a tailwind class to try to ensure the links are a certain color
  2. Add a class to the containers for controls/story menus to allow targeting of the links within a custom histoire.css

Investigate first launch stability

It's not the first time that I get weird errors on the first launch of Histoire (like, but not limited to, getActivePinia was called with no active Pinia).

A simple refresh fixes it, but it could be a good idea to investigate why these bugs occurs in the first place.

State presets

I think we should provide a way to have some presets to states.
It would also be cool to be able to quickly save presets on the local storage.

Wdyt?

Responsive size no more reactive

The responsive size seems not to be reactive anymore:

When you resize, it doesn't update on the preset panel, and when you set something in the preset panel, it doesn't update the view (though, both are saved to the local storage).

Responsive design

Make sure the generated app is responsive and is great on mobile devices.

Optional variant

In the case of a single variant, I think the variant tag should be optional (to have one indent) and create a variant with name "default".

I suggest variant should inherit story params. Basically, these 3 snippets should do the same thing:

<template>
  <Story
    title="State"
  >
    <Variant
      title="default"
      :init-state="initState"
    >
      <!-- Things  -->
   </Variant>
  </Story>
</template>
<template>
  <Story
    title="State"
    :init-state="initState"
  >
    <Variant
      title="default"
    >
      <!-- Things  -->
   </Variant>
  </Story>
</template>
<template>
  <Story
    title="State"
    :init-state="initState"
  >
    <!-- Things -->
  </Story>
</template>

Shared controls for story with different variants

I think we should add a <template #controls="{ state }"> to <Story> components.

This would display the controls on all the variants. If variants have also controls, the story controls should be placed on top of the variant controls.

The typical use-case would be the grid layout with a lot of components and you want a centralized state (for example, what do the buttons look like when they're all disabled?)

Add a dark mode

This may not be very the most needed feature, but I think it's a quick win with a relatively easy implementation.

Also, it'll introduce a top bar that will contain other options in the future.
For now, it'll only contain a switch for the dark mode.

We'll need a dark colors scheme for tailwind.

Vite config base property override

I'm not sure some of the vite config overrides are working properly when building histoire.

export default defineConfig({
    storyIgnored: ["build/**/*"],
    vite: {
        base: "/testing-base-property/",
    },
});

I run histoire build

And the generated index.html file looks like:

<!DOCTYPE html>
<html>
<head>
  <title>Histoire</title>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width,initial-scale=1">
  <meta name="description" content="">
  <link rel="stylesheet" href="/assets/style.cd50dc45.css">
  
  <link rel="preload" href="assets/vendor.1140a396.js" as="script" crossOrigin="anonymous"><link rel="prefetch" href="assets/global-components.051985e6.js" as="script" crossOrigin="anonymous"><link rel="prefetch" href="assets/reactivity.f8b69e5d.js" as="script" crossOrigin="anonymous"><link rel="prefetch" href="assets/StoryView.81328ff5.js" as="script" crossOrigin="anonymous">
</head>
<body>
  <div id="app"></div>
  <script type="module" src="/assets/index.83a07c35.js"></script>
</body>
</html>

For reference, if I try the same config change on my vite app

export default defineConfig({
    plugins: [vue()],
    base: "/testing-base-property/",
    resolve: {
        alias: {
            "@": fileURLToPath(new URL("./src", import.meta.url)),
        },
    },
});

It looks like this

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <link
            rel="icon"
            href="/testing-base-property/favicon.ico"
        />
        <meta
            name="viewport"
            content="width=device-width, initial-scale=1.0"
        />
        <title>Vite App</title>
      <script type="module" crossorigin src="/testing-base-property/assets/index.e6e26712.js"></script>
    </head>
    <body>
        <div id="app"></div>
        
    </body>
</html>

Can't use CSS var with theme colors

Maybe we should be able to add CSS vars support for theming?

example:

theme: {
  colors: {
    gray: {
      100: "var(--color-background-0)",
      200: "hsl(200, 35%, 25%)",
      /* ... */
    }
  }
}

For now, we get this:

14:23:15 [vite] Internal server error: Cannot read properties of null (reading 'color')
      at Context.load (file:///D:/Library/Projects/LunaPark/node_modules/.pnpm/[email protected]_rwdbogf7wrm2jtre4wogxlia4e/node_modules/histoire/dist/node/vite.js:136:117)
      at Object.load (D:\Library\Projects\LunaPark\node_modules\.pnpm\[email protected][email protected]\node_modules\vite\dist\node\chunks\dep-3397b401.js:38793:50)
      at processTicksAndRejections (node:internal/process/task_queues:96:5)
      at async doTransform (D:\Library\Projects\LunaPark\node_modules\.pnpm\[email protected][email protected]\node_modules\vite\dist\node\chunks\dep-3397b401.js:55688:24)

Probably linked to the parseColor function call.

And the HSL color simply does not work since the frontend still use a rgb function on hsl percentages.

Code error on readme quick start

Missing close tag for template tag

<script setup>
import MyComponent from './MyComponent.vue'

function initState () {
  return {
    disabled: false,
  }
}
</script>

<template>
  <Story
    title="MyComponent"
    :layout="/* {
      type: 'grid',
      width: 200,
    } */"
  >
    <Variant
      title="playground"
      :init-state="initState"
    >
      <template #default="{ state }">
        <MyComponent
          :disabled="state.disabled"
        >
          Hello world
        </MyComponent>
      </template>

      <template #controls="{ state }">
        <HstCheckbox v-model="state.disabled">
          Disabled
        </HstCheckbox>
+     </template>
    </Variant>

    <Variant
      title="green"
      icon="carbon:star-filled"
      icon-color="#10B981"
    >
      <MyComponent
        color="green"
      >
        Hello world
      </MyComponent>
    </Variant>
  </Story>
</template>

Add global CSS and JS

Some platforms use global CSS to set a default background or to declare global CSS vars.

We should include it inside iframe preview:

image

Maybe with a global.css file? If so, it should also support scss, sass, etc...
Also, I didn't checked yet, but it's probably breaking with global JS too, like when using a pinia store.

Internal server error when launching on Windows

How to reproduce

Just run pnpm run story:dev under the example folder (after building the package).
Then navigate to the launched server (localhost:3000).

Result

image

16:35:45 [vite] Internal server error: Failed to resolve import "/componentsBaseButton.story.vue" from "..\..\..\..\..\$histoire-stories-resolved". Does the file exist?
  Plugin: vite:import-analysis
  File: /$histoire-stories-resolved
  1  |  import Comp0 from '/components\BaseButton.story.vue'
     |                     ^
  2  |  import Comp1 from '/components\Meow.story.vue'
  3  |  export let files = [{ id: 'components-basebutton-story-vue', file: '/components\BaseButton.story.vue', component: Comp0 },
      at formatError (D:\Library\Projects\histoire\node_modules\.pnpm\[email protected]\node_modules\vite\dist\node\chunks\dep-f5552faa.js:36769:46)
      at TransformContext.error (D:\Library\Projects\histoire\node_modules\.pnpm\[email protected]\node_modules\vite\dist\node\chunks\dep-f5552faa.js:36765:19)
      at normalizeUrl (D:\Library\Projects\histoire\node_modules\.pnpm\[email protected]\node_modules\vite\dist\node\chunks\dep-f5552faa.js:73703:26)
      at processTicksAndRejections (node:internal/process/task_queues:96:5)
      at async TransformContext.transform (D:\Library\Projects\histoire\node_modules\.pnpm\[email protected]\node_modules\vite\dist\node\chunks\dep-f5552faa.js:73843:57)
      at async Object.transform (D:\Library\Projects\histoire\node_modules\.pnpm\[email protected]\node_modules\vite\dist\node\chunks\dep-f5552faa.js:36985:30)
      at async doTransform (D:\Library\Projects\histoire\node_modules\.pnpm\[email protected]\node_modules\vite\dist\node\chunks\dep-f5552faa.js:52060:29)

Vite build error with pnpm

Steps to reproduce:

  • Create a vite app with pnpm
  • Install histoire
  • run histoire dev

Error:

Error: Failed to resolve force included dependency: @vue/runtime-core
    at optimizeDeps (/home/akryum/Projects/demos/histoire-stackblitz/node_modules/.pnpm/[email protected]/node_modules/vite/dist/node/chunks/dep-9c153816.js:55784:27)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at async runOptimize (/home/akryum/Projects/demos/histoire-stackblitz/node_modules/.pnpm/[email protected]/node_modules/vite/dist/node/chunks/dep-9c153816.js:56647:44)
    at async Server.httpServer.listen (/home/akryum/Projects/demos/histoire-stackblitz/node_modules/.pnpm/[email protected]/node_modules/vite/dist/node/chunks/dep-9c153816.js:56662:21)

Workaround:

pnpm i --force --shamefully-hoist

Add dark mode to the website

Not a top priority, but I feel like the website should also support dark mode (especially when it'll have documentation) 🙂

Handle story title conflict

Currently, having two stories with the same title silently overwrite all but one stories with the same title. Ideally we would like to either display an error or deduplicate the titles (for example My Story, My Story (1), My Story (2)...).

Plugins/Addons

I think it would be a cool idea to provide APIs to create addons.

Example of APIs :

  • Provide App, Story and Variant access (Already covered with defineVue3StorySetup)
  • Inject script to app
  • Inject script to stories
  • Add icon to story top bar
  • Add icon to explorer top bar
  • Add tab to Controls/Doc panel
  • Add panels

Then have a process of installing some addons.
Probably something like this in the setup script

import myCoolAddon from 'myCoolAddon'
import { installAddon } from 'histoire/client'

installAddon(myCoolAddon, { myConfigParam: true })

or directly in the config file

export default defineConfig({ 
  addons: [
    { package: 'myCoolAddon', config: { myConfigParam: true } }
  ]
})

Snap preview resizers

I think it would be a good idea to be able to snap the resizers to the border of the available space

image

Once snapped, the resize value would be an empty string so that we can see the "Auto" placeholder in the resize tooltip

image

Story type for colors, shades and fonts

Most brand guidelines platform have a page to preview their colors, shades and fonts.

I think we should create a special type to handle these. Maybe something like that:

<script setup lang="ts">
const colors = [
    {name: "Histoire green", color: "#abcdef"},
    {name: "Magistral blue", color: "#abcdef"},
];

const primaryShades = ["#abcdef", "#abcdef", "#abcdef", "#abcdef"];
</script>

<template>
<Story type="docs">
      <VariantColors :colors="colors" />
      <VariantShades title="Primary Shades" :shades="primaryShades" />
      <VariantText font="Franchise" />
</Story>
</template>

Investigate dark mode flickering

There's sometimes a disturbing flickering with white/dark mode...

Maybe it's linked to vueuse? (Pinia documentation had the same problem: vuejs/pinia#686)

Doing this "conveniently" make it work 😐 ...

// util/dark.ts
export const toggleDark_ = useToggle(isDark)

export const toggleDark = () => {
  toggleDark_()
  console.trace()
}

Add a drop-down to common responsive width

I think we should add a drop-down to select common responsive width.

image

Suggested width:

  • 2560px (4K)
  • 1920px (HD)
  • 1440px (Laptop L)
  • 1024px (Laptop)
  • 768px (Tablet)
  • 425px (Mobile L)
  • 375px (Mobile M)
  • 320px (Mobile S)

Config:

interface Config {
  responsivePresets: ({
    width: number
    label: string
  })[]
}

Some ideas for another issue maybe:

  • Scale down when provided width is superior to the element actual width
  • Provide default width in the story parameter

Events

Track and display events in the right sidepane

Search stories and variants

I would be very useful to add an input at the top of the story tree to filter out stories and quickly find the one you're looking for.

Maybe we could also add an exported "keywords" field if the story title isn't good enough.

Also, we should highlight the part of the title that matches the query.

Error reported using sass preprocessor

Hi, histoire team.

I used sass prepropressor in my component and got an error, do I need to configure anything?

log:

Error while collecting story /Users/ryanwang/Desktop/vue-project/src/components/HelloWorld.story.vue:
TypeError: render is not a function
    at result (/Users/ryanwang/Desktop/vue-project/node_modules/.pnpm/vite@2.8.6_sass@1.49.9/node_modules/vite/dist/node/chunks/dep-9c153816.js:19156:13)
    at new Promise (<anonymous>)
    at scss (/Users/ryanwang/Desktop/vue-project/node_modules/.pnpm/[email protected][email protected]/node_modules/vite/dist/node/chunks/dep-9c153816.js:19155:30)
    at async compileCSS (/Users/ryanwang/Desktop/vue-project/node_modules/.pnpm/[email protected][email protected]/node_modules/vite/dist/node/chunks/dep-9c153816.js:18853:34)
    at async TransformContext.transform (/Users/ryanwang/Desktop/vue-project/node_modules/.pnpm/[email protected][email protected]/node_modules/vite/dist/node/chunks/dep-9c153816.js:18488:50)
    at async Object.transform (/Users/ryanwang/Desktop/vue-project/node_modules/.pnpm/[email protected][email protected]/node_modules/vite/dist/node/chunks/dep-9c153816.js:38334:30)
    at async doTransform (/Users/ryanwang/Desktop/vue-project/node_modules/.pnpm/[email protected][email protected]/node_modules/vite/dist/node/chunks/dep-9c153816.js:53030:29)

Reproduction link: https://codesandbox.io/s/blissful-aryabhata-f2txri?file=/src/components/HelloWorld.story.vue

White label customization

Depends on #17

We should have some kind of customization regarding the design (colors and font), and maybe the name/logo of the app.

  • theme config (below options are nested inside)
    • title: name of the user project/company
    • favicon
    • logoSquare: square logo (favicon/home)
    • logoLight: free-form logo for light mode
    • logoDark: free-form logo for dark mode
    • primaryColors: object for the primary color palette
    • grayColors: object for the gray color palette
    • textFont
    • codeFont
  • Custom CSS (setupFile)
  • Auto generate CSS custom props in a standard file __theme.css and automatically include it in the app
  • Use those custom props in the histoire tailwind config for the histoire package (override)
  • Add 750, 850 and 950 shades to default gray colors (zinc already done) #35

(Colors customization should also work with projects not using tailwind 😛)

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.