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

add default (= null) for classNames prop so it's optional for WizardTaskItem and CollapsibleBody #9157

Merged
merged 12 commits into from
Oct 2, 2024

Conversation

haszari
Copy link
Contributor

@haszari haszari commented Jul 24, 2024

Fixes #9142

Changes proposed in this Pull Request

  • Migrates the WizardTaskItem and CollapsibleBody components to typescript, explicitly defining the className as optional
  • Remove redundant className=null prop in tax modal code – no longer needed.

Clients currently have to pass classNames = { null } to appease TypeScript. The prop is actually optional, only used if client wants to customise the class of generated markup.

See https://github.com/Automattic/woocommerce-payments/blob/develop/client/vat/form/tasks/vat-number-task.tsx for an example.

The goal of this PR is to streamline code like VatNumberTask so it doesn't need to pass meaningless className={ null }.

Testing instructions

  • Hack any code using WizardTaskItem and CollapsibleBody and add a custom className, to confirm that the rendered component still supports arbitrary custom classes as before.
  • Confirm that linters, TypeScript, code checks are all green ✅ and happy.
  • Hack on any code that uses WizardTaskItem and CollapsibleBody
    • Remove the classNames={ null }, ensure no errors/linter/typescript warnings and UI works as expected.
    • Add custom classes via classNames and ensure they are rendered correctly in generated markup.

  • Run npm run changelog to add a changelog file, choose patch to leave it empty if the change is not significant. You can add multiple changelog files in one PR by running this command a few times.
  • Covered with tests (or have a good reason not to test in description ☝️)
  • Tested on mobile (or does not apply)

Post merge

- for WizardTaskItem and CollapsibleBody
@botwoo
Copy link
Collaborator

botwoo commented Jul 24, 2024

Test the build

Option 1. Jetpack Beta

  • Install and activate Jetpack Beta.
  • Use this build by searching for PR number 9157 or branch name fix/9142-classname-optional-default-null in your-test.site/wp-admin/admin.php?page=jetpack-beta&plugin=woocommerce-payments

Option 2. Jurassic Ninja - available for logged-in A12s

🚀 Launch a JN site with this branch 🚀

ℹ️ Install this Tampermonkey script to get more options.


Build info:

  • Latest commit: faf777f
  • Build time: 2024-10-02 04:50:33 UTC

Note: the build is updated when a new commit is pushed to this PR.

Copy link
Contributor

github-actions bot commented Jul 24, 2024

Size Change: -2 B (0%)

Total Size: 1.33 MB

Filename Size Change
release/woocommerce-payments/dist/index.js 302 kB -2 B (0%)
ℹ️ View Unchanged
Filename Size
release/woocommerce-payments/assets/css/admin.css 1.08 kB
release/woocommerce-payments/assets/css/admin.rtl.css 1.08 kB
release/woocommerce-payments/assets/css/success.css 173 B
release/woocommerce-payments/assets/css/success.rtl.css 173 B
release/woocommerce-payments/dist/blocks-checkout-rtl.css 2.64 kB
release/woocommerce-payments/dist/blocks-checkout.css 2.64 kB
release/woocommerce-payments/dist/blocks-checkout.js 67 kB
release/woocommerce-payments/dist/cart-block.js 16.6 kB
release/woocommerce-payments/dist/cart.js 5.73 kB
release/woocommerce-payments/dist/checkout-rtl.css 927 B
release/woocommerce-payments/dist/checkout.css 927 B
release/woocommerce-payments/dist/checkout.js 32.8 kB
release/woocommerce-payments/dist/express-checkout-rtl.css 230 B
release/woocommerce-payments/dist/express-checkout.css 230 B
release/woocommerce-payments/dist/express-checkout.js 14.6 kB
release/woocommerce-payments/dist/frontend-tracks.js 858 B
release/woocommerce-payments/dist/index-rtl.css 39.3 kB
release/woocommerce-payments/dist/index.css 39.2 kB
release/woocommerce-payments/dist/multi-currency-analytics.js 1.08 kB
release/woocommerce-payments/dist/multi-currency-rtl.css 3.41 kB
release/woocommerce-payments/dist/multi-currency-switcher-block.js 60.6 kB
release/woocommerce-payments/dist/multi-currency.css 3.41 kB
release/woocommerce-payments/dist/multi-currency.js 55.6 kB
release/woocommerce-payments/dist/order-rtl.css 730 B
release/woocommerce-payments/dist/order.css 730 B
release/woocommerce-payments/dist/order.js 42.7 kB
release/woocommerce-payments/dist/payment-gateways-rtl.css 1.35 kB
release/woocommerce-payments/dist/payment-gateways.css 1.35 kB
release/woocommerce-payments/dist/payment-gateways.js 39.3 kB
release/woocommerce-payments/dist/payment-request-rtl.css 230 B
release/woocommerce-payments/dist/payment-request.css 230 B
release/woocommerce-payments/dist/payment-request.js 14 kB
release/woocommerce-payments/dist/plugins-page-rtl.css 386 B
release/woocommerce-payments/dist/plugins-page.css 386 B
release/woocommerce-payments/dist/plugins-page.js 20.1 kB
release/woocommerce-payments/dist/product-details-rtl.css 433 B
release/woocommerce-payments/dist/product-details.css 436 B
release/woocommerce-payments/dist/product-details.js 11.8 kB
release/woocommerce-payments/dist/settings-rtl.css 11.6 kB
release/woocommerce-payments/dist/settings.css 11.5 kB
release/woocommerce-payments/dist/settings.js 225 kB
release/woocommerce-payments/dist/subscription-edit-page.js 703 B
release/woocommerce-payments/dist/subscription-product-onboarding-modal-rtl.css 524 B
release/woocommerce-payments/dist/subscription-product-onboarding-modal.css 524 B
release/woocommerce-payments/dist/subscription-product-onboarding-modal.js 20.2 kB
release/woocommerce-payments/dist/subscription-product-onboarding-toast.js 730 B
release/woocommerce-payments/dist/subscriptions-empty-state-rtl.css 120 B
release/woocommerce-payments/dist/subscriptions-empty-state.css 120 B
release/woocommerce-payments/dist/subscriptions-empty-state.js 19.3 kB
release/woocommerce-payments/dist/tokenized-payment-request-rtl.css 230 B
release/woocommerce-payments/dist/tokenized-payment-request.css 230 B
release/woocommerce-payments/dist/tokenized-payment-request.js 14.8 kB
release/woocommerce-payments/dist/tos-rtl.css 235 B
release/woocommerce-payments/dist/tos.css 235 B
release/woocommerce-payments/dist/tos.js 21.8 kB
release/woocommerce-payments/dist/woopay-direct-checkout.js 6.14 kB
release/woocommerce-payments/dist/woopay-express-button.js 24.4 kB
release/woocommerce-payments/dist/woopay-rtl.css 4.52 kB
release/woocommerce-payments/dist/woopay.css 4.49 kB
release/woocommerce-payments/dist/woopay.js 71.6 kB
release/woocommerce-payments/includes/subscriptions/assets/css/plugin-page.css 625 B
release/woocommerce-payments/includes/subscriptions/assets/js/plugin-page.js 814 B
release/woocommerce-payments/vendor/automattic/jetpack-assets/build/i18n-loader.js 2.46 kB
release/woocommerce-payments/vendor/automattic/jetpack-assets/build/jetpack-script-data.js 735 B
release/woocommerce-payments/vendor/automattic/jetpack-assets/build/react-jsx-runtime.js 553 B
release/woocommerce-payments/vendor/automattic/jetpack-assets/src/js/i18n-loader.js 1.02 kB
release/woocommerce-payments/vendor/automattic/jetpack-assets/src/js/script-data.js 69 B
release/woocommerce-payments/vendor/automattic/jetpack-connection/babel.config.js 163 B
release/woocommerce-payments/vendor/automattic/jetpack-connection/dist/identity-crisis.css 2.45 kB
release/woocommerce-payments/vendor/automattic/jetpack-connection/dist/identity-crisis.js 14.2 kB
release/woocommerce-payments/vendor/automattic/jetpack-connection/dist/identity-crisis.rtl.css 2.45 kB
release/woocommerce-payments/vendor/automattic/jetpack-connection/dist/jetpack-sso-admin-create-user.css 198 B
release/woocommerce-payments/vendor/automattic/jetpack-connection/dist/jetpack-sso-admin-create-user.js 280 B
release/woocommerce-payments/vendor/automattic/jetpack-connection/dist/jetpack-sso-admin-create-user.rtl.css 198 B
release/woocommerce-payments/vendor/automattic/jetpack-connection/dist/jetpack-sso-login.css 625 B
release/woocommerce-payments/vendor/automattic/jetpack-connection/dist/jetpack-sso-login.js 333 B
release/woocommerce-payments/vendor/automattic/jetpack-connection/dist/jetpack-sso-login.rtl.css 626 B
release/woocommerce-payments/vendor/automattic/jetpack-connection/dist/jetpack-sso-users.js 417 B
release/woocommerce-payments/vendor/automattic/jetpack-connection/dist/tracks-ajax.js 521 B
release/woocommerce-payments/vendor/automattic/jetpack-connection/dist/tracks-callables.js 584 B
release/woocommerce-payments/vendor/automattic/jetpack-connection/src/sso/jetpack-sso-admin-create-user.css 215 B
release/woocommerce-payments/vendor/automattic/jetpack-connection/src/sso/jetpack-sso-admin-create-user.js 521 B
release/woocommerce-payments/vendor/automattic/jetpack-connection/src/sso/jetpack-sso-login.css 721 B
release/woocommerce-payments/vendor/automattic/jetpack-connection/src/sso/jetpack-sso-login.js 412 B
release/woocommerce-payments/vendor/automattic/jetpack-connection/src/sso/jetpack-sso-users.js 621 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/css/about.css 1.04 kB
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/css/admin-empty-state.css 294 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/css/admin-order-statuses.css 408 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/css/admin.css 3.59 kB
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/css/checkout.css 301 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/css/modal.css 746 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/css/view-subscription.css 574 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/css/wcs-upgrade.css 414 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/admin/admin-pointers.js 543 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/admin/admin.js 9.4 kB
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/admin/jstz.js 6.78 kB
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/admin/jstz.min.js 3.84 kB
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/admin/meta-boxes-coupon.js 545 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/admin/meta-boxes-subscription.js 2.52 kB
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/admin/moment.js 22.2 kB
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/admin/moment.min.js 11.7 kB
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/admin/payment-method-restrictions.js 1.29 kB
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/admin/wcs-meta-boxes-order.js 507 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/frontend/payment-methods.js 358 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/frontend/single-product.js 428 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/frontend/view-subscription.js 1.38 kB
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/frontend/wcs-cart.js 782 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/modal.js 1.09 kB
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/wcs-upgrade.js 1.26 kB
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/build/index.css 391 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/build/index.js 3.04 kB

compressed-size-action

@haszari haszari self-assigned this Sep 25, 2024
@haszari
Copy link
Contributor Author

haszari commented Sep 25, 2024

Hack any code using WizardTaskItem and CollapsibleBody and add a custom className, to confirm that the rendered component still supports arbitrary custom classes as before.

Dang - we now get a TypeScript error if passing a className! Which is not cool.

// Type 'string' is not assignable to type 'null | undefined'.
<WizardTaskItem
	className="gandalf"

So I need to find a way to tell TypeScript that this thing can be null or string.

@reykjalin @Jinksi if you know how to elegantly fix this let me know! I am trying to avoid a rabbit hole of strongly typing everything (these components are JS, i.e. inferred types - which I think is a good thing).

@reykjalin
Copy link
Contributor

Doing this on mobile, sorry for the lack of links and examples. You should be able to use JSDoc to provide type information that TS will use.

@Jinksi
Copy link
Member

Jinksi commented Sep 26, 2024

So I need to find a way to tell TypeScript that this thing can be null or string.

I would consider migrating the WizardTaskItem component to TSX. The only change will be adding an interface for the props, which is a common pattern in this codebase we're used to seeing and working with.

image

@haszari
Copy link
Contributor Author

haszari commented Sep 26, 2024

The only change will be adding an interface for the props, which is a common pattern in this codebase we're used to seeing and working with.

Sounds good, as long as we get some benefits from strongly typing this! It feels like the tooling is forcing us to strongly type everything – once we start, we can't stop.

To me, strictly typing everything seems like a heavy cost to pay – there should be a way to nudge TypeScript to correctly infer that className is an optional string parameter.

@Jinksi
Copy link
Member

Jinksi commented Sep 26, 2024

If you wanted to keep this as JS and lean more into type inference, without explicitly declaring the prop types (nor in JSDoc), I think className = '' would work here.

const WizardTaskItem = ( {
	children,
	title,
	index,
	className = '',
} ) => {

To me, strictly typing everything seems like a heavy cost to pay

I agree, we should prefer inference wherever possible. However, writing an interface for a React component is straightforward when TS inference isn't sufficient or accurate. In this case, all the props are inferred as any which means the code reader has to look for this information elsewhere. E.g. is index meant to be passed as a string, an int, or maybe either is fine?

Rua Haszard added 2 commits October 1, 2024 11:40
…:Automattic/woocommerce-payments into fix/9142-classname-optional-default-null
@haszari
Copy link
Contributor Author

haszari commented Sep 30, 2024

If you wanted to keep this as JS and lean more into type inference, without explicitly declaring the prop types (nor in JSDoc), I think className = '' would work here.

Great idea! I have updated the PR with this approach, it works great, with minimal code impact.

I'm open to trying full-TypeScript approach, but decided against trying that myself today since I'd need to rename various files – more code impact. @Jinksi if you want to try that approach before merging, feel free to commandeer this PR 🤾🏻

@haszari
Copy link
Contributor Author

haszari commented Sep 30, 2024

Re-requested reviews, this should be good to go.

I'm happy to for anyone to take this over and merge/wrap up, equally happy to handle myself when I get to it.

Copy link
Member

@Jinksi Jinksi left a comment

Choose a reason for hiding this comment

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

This looks good @haszari – a nice enhancement to our code quality.

I've tested this with the VAT download task list following the instructions from #8974 and confirm that the wizard renders correctly:

image
image

Also note that snapshot tests are still passing, meaning the correct classNames are being applied.

expect( container ).toMatchSnapshot(
'snapshot-multi-currency-onboarding'
);

I'm open to trying full-TypeScript approach, but decided against trying that myself today since I'd need to rename various files – more code impact. @Jinksi if you want to try that approach before merging, feel free to commandeer this PR 🤾🏻

Note I've tried the TS approach in #9510 that could be merged into this PR – let me know what you think @haszari (I slightly prefer the TS approach and will merge unless you think otherwise 😎).

Test instructions followed

Note you'll need to test this with a store with account country that supports tax docs. Ideally, test with different accounts to see UI for different countries. Tip: if you set wcpay_accounts[].deleted to a date in the past, you can onboard a new account. Or switch between accounts by setting wcpay_accounts[].deleted=NULL` on the account you want to use.

  1. Set up tax docs so you have a document to view at Payments > Documents. Fake one up with this CLI command:
    • wp wcpay add_document_for_account [account_id] vat_invoice --mode=test --period_from="2024-04-01 00:00:00" --period_to="2024-04-30 23:59:59"
    • Or can use wp wcpay backfill_merchant_vat_invoices
  2. If you've added VAT id / tax information previously, clear it out so you can see the modal:
  3. Go to Payments > Documents.
  4. Click Download for a tax doc row.
  5. See modal.
  6. Test adding valid and invalid tax info.
  7. Test downloading the generated tax doc – confirm the merchant details are correct.

@Jinksi
Copy link
Member

Jinksi commented Oct 2, 2024

I've merged #9510 into this branch (after discussion and approval from @haszari) and mentioned in this PR description that we're migrating the WizardTaskItem and CollapsibleBody components to typescript, explicitly defining the className as optional.

@Jinksi Jinksi added this pull request to the merge queue Oct 2, 2024
Merged via the queue into develop with commit 5faa312 Oct 2, 2024
25 checks passed
@Jinksi Jinksi deleted the fix/9142-classname-optional-default-null branch October 2, 2024 05:09
@haszari
Copy link
Contributor Author

haszari commented Oct 2, 2024

Thanks @Jinksi !

Let's keep our eyes open for examples that might be less amenable to strong typing.
Some parts of our codebase that are still .js might be a hint.

I like this idea. Maybe we can add a comment to these files as we see them, i.e. intentionally not migrated, with rationale/explanation. That way the code base can be a living record of our decisions ⇒ experience of the trickier aspects of JS ⇒ TS.

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.

TypeScript: WizardTaskItem and CollapsibleBody require a className prop (should be optional)
4 participants