storybookjs / storybook

Storybook is the industry standard workshop for building, documenting, and testing UI components in isolation
https://storybook.js.org
MIT License
84.21k stars 9.26k forks source link

Controls with control: text unexpectedly translate ISO 8601 formatted datetime #13713

Open scscgit opened 3 years ago

scscgit commented 3 years ago

Imagine any text input element as a story Template described by:

<Meta
  title="TextInput"
  argTypes={{
    value: {
      control: 'text',
    },
  }}
  args={{
    value: '',
  }}
/>
<Story
    name="Datetime in ISO format"
    args={{
      value: '2021-01-21T20:02:26Z',
    }}
>
  {Template.bind({})}
</Story>

Instead of displaying a provided value of 2021-01-21T20:02:26Z, the controls suddenly jump to conclusions and decide to do some black-box magic, translating this to Thu Jan 21 2021 21:02:26 GMT+0100 (Central European Standard Time).

image

I'm sure this should be an opt-in feature rather than taking away our ability to visually test & document any time-related inputs. I couldn't find any workaround, considering that the string input doesn't provide any other alternative to the 'text'.

yannbf commented 3 years ago

Hey @scscgit thanks for opening this issue!

While we'll take a look at that, I'm wondering if a date picker could help your use case?

<Meta
  title="TextInput"
  argTypes={{
    value: {
      control: 'date',
    },
  }}
  args={{
      value: '2021-01-21T20:02:26Z',
  }}
/>
scscgit commented 3 years ago

Hi @yannbf, thanks, but my specific use-case is actually about working with the ISO value as a text, so the date control would just make it even more ambiguous about which value is really being passed (making it more difficult to manually test correct inputs).

jmaicher commented 3 years ago

I'm facing the same problem. I explicitly want to use plain ISO date strings as text input, a date control is not a replacement.

Is there any workaround? :thinking:

scscgit commented 3 years ago

Note that this behavior occurs only when using Z as a timezone, i.e. 2021-01-21T21:02:00+01:00 works as expected but 2021-01-21T21:02:00Z doesn't.

aygee commented 3 years ago

The workaround is to convert to another timezone. Would be great if it can be fixed so that we can use UTC timezone as it is.

MrGrigri commented 3 years ago
control: 'date',

Holy Shit!!!!! Why isn't this control documented anywhere?!!! Do you realize how long I tried to look for this control!!!

ghost commented 3 years ago

@MrGrigri i think this is the documentation you are looking for. May also bei present in the Docs of your selected Framework https://storybook.js.org/docs/svelte/essentials/controls

adityasrini commented 2 years ago

I too need a text for that field and this time when I put in an ISO string of 2021-01-22T15:37:26.021Z, this is what I get

Screen Shot 2021-11-18 at 11 36 49 AM

While the date control (and even object) is a workaround, the component and the data in the backend is for an ISO string. And changing the date causes a millisecond timestamp to be sent rather than an ISO string so conversions need to be made prior to the component being called. Would be a lot more straightforward for our cases if a text was just rendered as a text like how object's are currently handled.

kresli commented 2 years ago

explicit argType should override any implicit behaviour. If I specify the text argument then please render the text argument. My component accepts string as ISOString but currently is impossible to use text control

nathanredblur commented 2 years ago

even if I define it as a text, this control convert it to a weird Date... why?

I have this problem where I define the initial value like this "2020-11-06T00:22:29Z" on run storybook, the control for startTime is empty and in red, and when I try to manually input this text 2020-11-06T00:22:29Z my component receive Thu Nov 05 2020 19:22:29 GMT-0500 (Colombia Standard Time)

I already try to set argType as text

export default {
  title: "Components/CalendarTime",
  component: CalendarTime,
  argTypes: {
    startTime: {
      control: "text",
    },
  },
} as ComponentMeta<typeof CalendarTime>;

but is not working... any workaround?

CleanShot 2022-07-27 at 22 38 41

nathanredblur commented 2 years ago

:( also happen with objects... why? CleanShot 2022-07-28 at 15 54 37

BikashSah999 commented 1 year ago

Hi @shilman @ndelangen @JReinhold , the root cause of this issue is telejson.parse parsing ISO string to Date object. For the solution, we think we can merge CHANNEL_OPTIONS with default option like { allowDate: false }. WDYT about this solution?

ndelangen commented 1 year ago

@BikashSah999 you can indeed override the channelOptions in main.js:

https://github.com/storybookjs/storybook/blob/4f511dfd33ccd463dd69b3cc76206b4c52ac2c56/code/lib/builder-webpack5/src/preview/iframe-webpack.config.ts#L236

module.exports = {
  // .. rest of your config
  core: {
    channelOptions: { allowDate: false },
  },
  // .. rest of your config
}
BikashSah999 commented 1 year ago

@ndelangen it means users should use channelOptions in their main.js as a workaround solution, and we are not going to fix this issue in codebase right?

ndelangen commented 1 year ago

@BikashSah999 a fix in our codebase would break for users who DO want those dates to be converted to date Classes.

Yeah, this seems like a good candidate for why you'd want to change the channelOptions in your main.js. I get it's not optimal for you, but I don't really see another way. There are no true date values in JSON, it must be a string. So SOME sort of string is going to be converted back into a Date class instance... I'm open to novel ideas, of course!