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

Addon-docs: Props component should accept a sort function. #9917

Closed
patricklafrance opened this issue Feb 20, 2020 · 15 comments
Closed

Addon-docs: Props component should accept a sort function. #9917

patricklafrance opened this issue Feb 20, 2020 · 15 comments

Comments

@patricklafrance
Copy link
Member

patricklafrance commented Feb 20, 2020

Is your feature request related to a problem? Please describe.
IMO for a user, this is easier to find a specific property in the props table if the props are sort. I believe this is still best to keep the declaration order by default but the component should allow a way to provide sorting.

Describe the solution you'd like
The <Props /> component could accept a sort function, something similar to sort function for the nav.

Otherwise, maybe it could be a string prop accepting 2 values asc and desc.

Material UI props are sort ascending (https://material-ui.com/api/form-control/):

image

Same thing with Semantic UI (https://react.semantic-ui.com/elements/button/):

image

┆Issue is synchronized with this Asana task by Unito

@stale
Copy link

stale bot commented Mar 12, 2020

Hi everyone! Seems like there hasn't been much going on in this issue lately. If there are still questions, comments, or bugs, please feel free to continue the discussion. Unfortunately, we don't have time to get to every issue. We are always open to contributions so please send us a pull request if you would like to help. Inactive issues will be closed after 30 days. Thanks!

@stale stale bot added the inactive label Mar 12, 2020
@stale stale bot removed the inactive label Mar 12, 2020
@meyerds
Copy link

meyerds commented Apr 7, 2020

I'd like to see this option too. This bug is affecting me, but I'm in a Typescript codebase, so the bugfix on that issue didn't have any effect. A sort prop on the Props component seems like the best way to make everybody happy.

@mattcorner
Copy link

Would also like a sort function. Currently the input args to my first story seem to be overriding the order of the props, such that if props "C" and "D" are input to the first story, the props table order is "C", "D", "A", "B" even if they were defined alphabetically.

@Vadorequest
Copy link

Could the default be changed until this is done?

Basically, split all props in 2, those enabled and those disabled, and sort alphabetically each group, so that disabled props always appear at the bottom and not at the top (they currently appear at the top when we disable them on a component/story level).

@chadlavi-casebook
Copy link

Any updates on this or anyone know a sneaky workaround for TypeScript users?

It's maddening that the props are in a seemingly random order. For components that have dozens of props this ends up making it quite difficult to find the one you want.

@shilman
Copy link
Member

shilman commented Feb 25, 2021

There's an open PR for this and I'll try to get it merged before 6.2 is released #13125

@shilman
Copy link
Member

shilman commented Mar 15, 2021

ZOMG!! I just released https://github.com/storybookjs/storybook/releases/tag/v6.2.0-beta.15 containing PR #13125 that references this issue. Upgrade today to the @next NPM tag to try it out!

npx sb upgrade --prerelease

Closing this issue. Please re-open if you think there's still more to do.

@shilman shilman closed this as completed Mar 15, 2021
@pybuche
Copy link

pybuche commented Apr 1, 2021

@shilman Thanks for this awesome feature! I'm just wondering: it doesn't seem to work on the ArgsTable, only on the controls panels, am I right? Is there a way to make it work in the docs blocks?

@shaneajeffery
Copy link

shaneajeffery commented Sep 2, 2021

Just in case someone reaches this PR and is confused on how to implement the solution that @shilman implemented, look at: https://storybook.js.org/docs/react/essentials/controls#sorting-controls

It is just an update to the story parameters for each story or you an add it as a global parameter like I did in the preview.js:

export const parameters = {
  ...
  controls: { sort: 'requiredFirst' },
}

Documentation for global parameters: https://storybook.js.org/docs/react/writing-stories/parameters#global-parameters

This solution should work for both your Canvas controls and for your Args Table. It works for both of mine with this change.

@nicollecastrog
Copy link

First of all, thanks for your solution @shilman! 😍 requiredFirst is already SO much better than the seemingly random order the props were displaying in before.

However, I was wondering if you (or anyone else) knows of a way to set an actual sort function for the props? I know you can do this for the order of the Stories themselves (parameters.options.storySort) and was hoping for a similar param for the order of the props as I have an unusual use-case.

For context: my component is a superset of a MUI component, so it has LOADS of props, but I want to highlight certain important props at the top of my Docs ArgsTable, some of which are required, some of which are optional but that are nonetheless more important to know about than the other slew of 40+ props. So I want to implement a custom prop sorting function to achieve this.

Any help is appreciated 🙏

@IndProgo
Copy link

This change would help

-  const sortFn = sortFns[sort];
+  const sortFn = typeof sort === "function" ? sort : sortFns[sort];

Then in preview.js I can make my custom sort function, in addition to requiredFirst

const SORT_PROPTYPES_FUNC = (a, b) => Number(!!b.type?.required) - Number(!!a.type?.required)
    || Number(a.description.includes('custom')) - Number(b.description.includes('custom'))
    || a.name.localeCompare(b.name)

const parameters = {
    controls: {
        sort: SORT_PROPTYPES_FUNC,
    },
    docs: {
        controls: {
            sort: SORT_PROPTYPES_FUNC,
        },
    }
}

To temporarely modify source file, I put pre- script in packages.json which would update node_modules file before building storybook

For example:

{
  "scripts: {
    "predev-storybook": "node _utils/node-replacer.js",
  }
}

node-replacer.js

const fs = require('fs')
const { resolve } = require('path')
const nodemodulesfile = resolve(__dirname, '../node_modules/@storybook/blocks/dist/index.mjs')

fs.readFile(nodemodulesfile, 'utf8', function (err, data) {
    if (err) {
        return console.error(err);
    }

    // Allow custom sort function for ArgTables canvas and docs
    const result = data
        .replace('let sortFn=sortFns[sort],', 'let sortFn=typeof sort==="function"?sort:sortFns[sort],')

    if (result !== data) {
        fs.writeFile(nodemodulesfile, result, 'utf8', function (err) {
            if (err) return console.error(err);
        });
    }
});

@wesleymostien
Copy link

sorting controls in every component by setting it globally in preview file is not working for me:

const preview = {
  parameters: {
    controls: {
      sort: 'alpha',
    },
...

export default preview;

@PVUL
Copy link

PVUL commented Feb 7, 2024

@wesleymostien try:

const preview = {
  parameters: {
    docs: {
      controls: {
        sort: 'alpha',
      },
...

export default preview;

@wesleymostien
Copy link

@wesleymostien try:

const preview = {
  parameters: {
    docs: {
      controls: {
        sort: 'alpha',
      },
...

export default preview;

that works like a charm, thanks for the tip @PVUL

@Shinigami92
Copy link

This change would help

-  const sortFn = sortFns[sort];
+  const sortFn = typeof sort === "function" ? sort : sortFns[sort];

Then in preview.js I can make my custom sort function, in addition to requiredFirst

const SORT_PROPTYPES_FUNC = (a, b) => Number(!!b.type?.required) - Number(!!a.type?.required)
    || Number(a.description.includes('custom')) - Number(b.description.includes('custom'))
    || a.name.localeCompare(b.name)

const parameters = {
    controls: {
        sort: SORT_PROPTYPES_FUNC,
    },
    docs: {
        controls: {
            sort: SORT_PROPTYPES_FUNC,
        },
    }
}

To temporarely modify source file, I put pre- script in packages.json which would update node_modules file before building storybook

For example:

{
  "scripts: {
    "predev-storybook": "node _utils/node-replacer.js",
  }
}

node-replacer.js

const fs = require('fs')
const { resolve } = require('path')
const nodemodulesfile = resolve(__dirname, '../node_modules/@storybook/blocks/dist/index.mjs')

fs.readFile(nodemodulesfile, 'utf8', function (err, data) {
    if (err) {
        return console.error(err);
    }

    // Allow custom sort function for ArgTables canvas and docs
    const result = data
        .replace('let sortFn=sortFns[sort],', 'let sortFn=typeof sort==="function"?sort:sortFns[sort],')

    if (result !== data) {
        fs.writeFile(nodemodulesfile, result, 'utf8', function (err) {
            if (err) return console.error(err);
        });
    }
});

The new location seems to be here:

Could someone provide a PR?

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

No branches or pull requests