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

Angular: Correctly set the 'required' argType #28718

Open
wants to merge 18 commits into
base: next
Choose a base branch
from

Conversation

ryan-bendel
Copy link

@ryan-bendel ryan-bendel commented Jul 26, 2024

Closes #28706

What I did

Updated the @storybook/angular package, where we are setting properties in compodoc.ts. Correctly set the argType type: { required: true} to be required: true if it is represented in the compodoc output for the component property in components.inputsClass property. This was not working when using compodoc and the property was there.

Checklist for Contributors

Testing

The changes in this PR are covered in the following automated tests:

  • stories
  • [ x] unit tests
  • integration tests
  • end-to-end tests

Manual testing

  1. Updated the example button.component.ts so that the button label was a required input
  2. Run a sandbox for template, e.g. yarn task --task sandbox --start-from auto --template angular-cli/default-ts
  3. Open Storybook in your browser
  4. Access Button story
  5. No fields are marked as required
  6. Made my changes, re-ran the project
  7. Verified that the required flag was correctly showing for the label field for the label control only

Documentation

Did not add any specific documentation, as it is already implied by the docs that controls are inferred from the components themselves (via compodoc in this case) - this just fixes something that I already expected to work from the docs

Checklist for Maintainers

  • When this PR is ready for testing, make sure to add ci:normal, ci:merged or ci:daily GH label to it to run a specific set of sandboxes. The particular set of sandboxes can be found in code/lib/cli/src/sandbox-templates.ts

  • Make sure this PR contains one of the labels below:

    Available labels
    • bug: Internal changes that fixes incorrect behavior.
    • maintenance: User-facing maintenance tasks.
    • dependencies: Upgrading (sometimes downgrading) dependencies.
    • build: Internal-facing build tooling & test updates. Will not show up in release changelog.
    • cleanup: Minor cleanup style change. Will not show up in release changelog.
    • documentation: Documentation only changes. Will not show up in release changelog.
    • feature request: Introducing a new feature.
    • BREAKING CHANGE: Changes that break compatibility in some way with current major version.
    • other: Changes that don't fit in the above categories.

🦋 Canary release

This PR does not have a canary release associated. You can request a canary release of this pull request by mentioning the @storybookjs/core team here.

core team members can create a canary release here or locally with gh workflow run --repo storybookjs/storybook canary-release-pr.yml --field pr=<PR_NUMBER>

name before after diff z %
createSize 0 B 0 B 0 B - -
generateSize 78 MB 78 MB 0 B 1 0%
initSize 143 MB 143 MB 724 B 1.03 0%
diffSize 65.1 MB 65.1 MB 724 B 1.73 0%
buildSize 6.87 MB 6.87 MB -40 B 2.95 0%
buildSbAddonsSize 1.51 MB 1.51 MB 244 B 12.41 0%
buildSbCommonSize 195 kB 195 kB 0 B - 0%
buildSbManagerSize 1.9 MB 1.9 MB -444 B 0.2 0%
buildSbPreviewSize 271 kB 271 kB 0 B - 0%
buildStaticSize 0 B 0 B 0 B - -
buildPrebuildSize 3.88 MB 3.88 MB -200 B 1.89 0%
buildPreviewSize 3 MB 3 MB 160 B 30.34 0%
testBuildSize 0 B 0 B 0 B - -
testBuildSbAddonsSize 0 B 0 B 0 B - -
testBuildSbCommonSize 0 B 0 B 0 B - -
testBuildSbManagerSize 0 B 0 B 0 B - -
testBuildSbPreviewSize 0 B 0 B 0 B - -
testBuildStaticSize 0 B 0 B 0 B - -
testBuildPrebuildSize 0 B 0 B 0 B - -
testBuildPreviewSize 0 B 0 B 0 B - -
name before after diff z %
createTime 7.6s 6.9s -746ms -1.04 -10.8%
generateTime 22s 19.6s -2s -413ms -1.09 -12.3%
initTime 16.3s 15.6s -732ms -0.36 -4.7%
buildTime 7.7s 7.7s 39ms -1.08 0.5%
testBuildTime 0ms 0ms 0ms - -
devPreviewResponsive 4.8s 5.3s 509ms -0.86 9.5%
devManagerResponsive 3s 3.5s 456ms -0.71 12.9%
devManagerHeaderVisible 487ms 757ms 270ms 1.18 35.7%
devManagerIndexVisible 556ms 850ms 294ms 1.41 🔺34.6%
devStoryVisibleUncached 854ms 1.3s 449ms 0.6 34.5%
devStoryVisible 556ms 849ms 293ms 1.53 🔺34.5%
devAutodocsVisible 439ms 540ms 101ms -0.27 18.7%
devMDXVisible 438ms 813ms 375ms 2.91 🔺46.1%
buildManagerHeaderVisible 472ms 584ms 112ms -0.2 19.2%
buildManagerIndexVisible 481ms 600ms 119ms -0.19 19.8%
buildStoryVisible 473ms 583ms 110ms -0.2 18.9%
buildAutodocsVisible 413ms 463ms 50ms -0.49 10.8%
buildMDXVisible 390ms 485ms 95ms -0.13 19.6%

Greptile Summary

This pull request corrects the required argType for Angular components when using compodoc output.

  • Updated code/frameworks/angular/src/client/docs/compodoc.ts to correctly set required attribute in argType.
  • Enhanced tests in code/frameworks/angular/src/client/docs/compodoc.test.ts to cover required and non-required properties.
  • Added required property to Property interface in code/frameworks/angular/src/client/docs/types.ts.
  • Modified code/frameworks/angular/template/cli/button.component.ts and code/frameworks/angular/template/components/button.component.ts to mark label input as required.

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

5 file(s) reviewed, no comment(s)
Edit PR Review Bot Settings

Copy link

nx-cloud bot commented Jul 26, 2024

☁️ Nx Cloud Report

CI is running/has finished running commands for commit 20a4456. As they complete they will appear below. Click to see the status, the terminal output, and the build insights.

📂 See all runs for this CI Pipeline Execution


✅ Successfully ran 1 target

Sent with 💌 from NxCloud.

Comment on lines 23 to 25
export const isRequired = (prop: Property): object =>
prop.hasOwnProperty('required') && prop.required ? { required: true } : {};

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems a little misleading, with how it is named. Typically a is* represents a boolean. would it be better to change this to returning a boolean and changing the places this is used to required: isRequired(property). It doesn't change the end result, but I wonder if it would make the code more clear and the method more reusable. I don't have a strong opinion either way, it just stuck out as odd when I was reading the code and initially thought it was applying the spread operator to a boolean.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah good shout, I'll rework it a bit 👍

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One thing I want to be careful of though, re: returning a boolean, was most of the time it will return false (most @Inputs() don't have the required: true prop. Which is why i used the spread operator checking if the prop exists AND if it was set to true, and if not, return an empty object essentially not adding anything onto the argType.

It felt a bit redundant enhancing the argTypes with lots of required: false so prob want to avoid that if possible

Copy link
Member

@Marklb Marklb Aug 8, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That makes sense. When I want to only add a property, I normally do something like ...(isRequired(property) ? { required: true } : {}). It is fairly easy to read, but I know it doesn't look great. If we want to use the method, like you had, a rename or additional method may work. This isn't a major piece of code that would be used outside of this file, so it doesn't matter much. An isRequired method that returns a boolean may not be needed, unless we need it for that other required property.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've updated that now, subtle difference but a bit clearer 😄

@Marklb
Copy link
Member

Marklb commented Aug 7, 2024

On the following line, should we consider the required property, as well as the optional? I don't remember where that property is used.

required: isMethod(item) ? false : !item.optional,

Also, is optional even something that should be considered required? Wouldn't that be incorrect for an optional that has a default assignment, because optional just means that it can be undefined?

@ryan-bendel
Copy link
Author

On the following line, should we consider the required property, as well as the optional? I don't remember where that property is used.

required: isMethod(item) ? false : !item.optional,

Also, is optional even something that should be considered required? Wouldn't that be incorrect for an optional that has a default assignment, because optional just means that it can be undefined?

Yeah I have no idea about optional either 🤣 - happy to take a look though

@ryan-bendel
Copy link
Author

@Marklb - any idea when this would be ok to merge? Thanks

@@ -256,7 +263,7 @@ export const extractArgTypesFromData = (componentData: Class | Directive | Injec
category: section,
type: {
summary: isMethod(item) ? displaySignature(item) : item.type,
required: isMethod(item) ? false : !item.optional,
required: isMethod(item) ? false : item.required,
Copy link
Member

@Marklb Marklb Sep 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was going to ask if this should be required: isMethod(item) ? false : isRequired(item), to avoid undefined, but I don't know if anything even uses this. I thought it used to do something, but I can't find where any of the other frameworks arg type extract functions seem to set it. Maybe if I dug some more I could find why it is here, but if the other frameworks aren't setting it then maybe it doesn't even need to be here.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Marklb You're right, i'm not sure it is even used. If i set that prop manually in a story, i.e:

argTypes: {
  title: {
     table: {
          type: { required: true },
      },
  }
}

It does absolutely nothing.

However manually setting it this way:

argTypes: {
  title: {
     type: { name: 'string', required: true },
  }
}

renders the correct asterix in red to say it's required (which was the intention of the PR)

That gets fixed by this change in the PR:

return { name: compodocType, ...setRequiredProperty(property) }; (line 153)

So i'm happy to either refactor to as you mentioned above, or remove entirely as part of the PR if we're confident it's no longer used - happy to take your steer on that :)

@Marklb
Copy link
Member

Marklb commented Sep 5, 2024

@valentinpalkovic Have you got a chance to look at this? I think it looks good. The only part I am undecided on is the table.required property.

@valentinpalkovic
Copy link
Contributor

Not yet. I am trying to plan it in for the next business days

@valentinpalkovic valentinpalkovic changed the title fix: Correctly set the 'required' argType for Angular Angular: Correctly set the 'required' argType Sep 10, 2024
@@ -79,7 +79,7 @@ export const Object: Story = {
name: 'DEPRECATED: Object',
args: {
value: objectOptions.B,
argType: { options: objectOptions },
argType: { options: objectOptions as any },
Copy link
Contributor

@valentinpalkovic valentinpalkovic Nov 1, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is technically an effect of a breaking change. We have to ensure that passing options the deprecated way is still supported and shouldn't trigger type issues for our users. We can definitely make the above type changes in Storybook 9, but not now. Can you adjust the PR to not throw away the custom types in code/lib/blocks/src/components/ArgsTable/types.ts, but leave a note instead to remove them in Storybook 9?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@valentinpalkovic - i think you made this change to that file did you not? 🤔 9f440259ec06dc5c1faf336bb67b431ca10a041e

Copy link
Contributor

@valentinpalkovic valentinpalkovic Nov 1, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hehe. I knew the changes were kind of familiar to me xD. I'll take another look then.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hehe. I knew the changes were kind of familiar to me xD. I'll take another look then.

Heh no worries, I have weeks/months like that. Looked at so many code/projects I can't remember what I've done 😆

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

Successfully merging this pull request may close these issues.

[Bug]: Storybook Angular not setting required Inputs() correctly
3 participants