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

Research/improve dx integration #28

Merged
merged 16 commits into from
Feb 20, 2022
Merged

Conversation

pgarciaegido
Copy link
Collaborator

@pgarciaegido pgarciaegido commented Feb 19, 2022

Here I make significant changes to the way our SDK is integrated. Here are the main improvements, and the nitty gritty on how they work.

Provider is no longer needed on the root of the customers application

How?

I have moved the state from the providers all the way down to the button. State is handled in two different hooks:

  • packages/ui/react-ui/src/hooks/useCrossMintStatus.ts: Here we handle the status of the client, from the client-id provided.
  • packages/ui/react-ui/src/hooks/useCrossMintModal.ts : Here we handle the state of the popup window.

We used to have a React component that created an overlay on the page, and its state was handled by a context at the provider level. Now, we manually create and append the div to the body when the user clicks on the crossmint button, and remove it when popup is closed. And actually, this is now optional (true by default). See more at the bottom.

Styles are no longer required to be attached manually

How?

Using a CSS in JS library (styled-components) that would bind the styles to the bundled output files. This actually simplifies a lot the customization of the button in the user side. We can leverage css specification and simply use button.<custom-class> in order to remove the need to use !importants. (See packages/starter/nextjs-starter/styles/globals.css)

New options to the button

Now the button is taking also the clientId prop, but also the development and some others (check packages/ui/react-ui/package/src/CrossMintButton.tsx interface).

I have added 3 more (optionals):

  • showOverlay True by default. Will show an overlay when the popup window is open and will remove it when its closed (like it works now). If false, button text will continue to change but overlay wont be shown.
  • crossmintOpened This expects a callback function that will be called everytime the popup window opens. This is handy for the devs to want to show a custom level or just to be able to track the state of the window.
  • crossmintClosed This expects a callback function that will be called everytime the popup window closes.

Downsides of this approach

  • I would say a downside is using and external library for the css in js. Now our g-ziped bundle size is around ~13kb which is not crazy, but certainly could be much lower. I might need to do a little research on finding another ligther css in js lib.
  • Not having a provider (crossmint global state available) and having to use callbacks to control the state of the button might be annoying to some more experienced devs that want to be able to check on the crossmint button anywhere on their app. There is a trade off here.

BTW guys, you see that I have created a pack script and linked the package manually on the next.js starter... I dont know if there is any other way you guys do that (maybe we could use Storybook for this?), but that will be removed if this goes forward.

⚠️ This needs to be tested more in detail before merging!

Thanks a lot!

],
"publishConfig": {
"access": "public"
},
"scripts": {
"clean": "shx rm -rf lib/*",
"build": "yarn clean && tsc -p tsconfig.json && tsc -p tsconfig-cjs.json",
"postbuild": "shx echo '{ \"type\": \"commonjs\" }' > lib/cjs/package.json && shx echo '{ \"type\": \"module\" }' > lib/esm/package.json"
"postbuild": "shx echo '{ \"type\": \"commonjs\" }' > lib/cjs/package.json && shx echo '{ \"type\": \"module\" }' > lib/esm/package.json",
"pack": "yarn build && yarn pack --filename package.tgz && tar -xf package.tgz"
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Here Im bulding the package locally in order to test in the nextjs starter.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Lets not do this lol. You just need to run yarn i believe, and the packages are linked automatically

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

yep yep, will delete 😄

},
"dependencies": {
"@crossmint/client-sdk-react-ui": "^0.0.5",
"@crossmint/client-sdk-react-ui": "file:/Users/pgarciaegido/Desktop/code/paella/crossmint-client-sdk/packages/ui/react-ui/package",
Copy link
Collaborator

Choose a reason for hiding this comment

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

this is not necessary, its done by lerna automatically using npm-link

@@ -15,6 +15,8 @@ export default function Index() {
collectionTitle="<TITLE_FOR_YOUR_COLLECTION>"
collectionDescription="<DESCRIPTION_OF_YOUR_COLLECTION>"
collectionPhoto="<OPT_URL_TO_PHOTO_COVER>"
clientId="12345"
Copy link
Collaborator

Choose a reason for hiding this comment

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

this is causing a shit ton of emails to be sent to us during your testing FYI lol

Copy link
Contributor

Choose a reason for hiding this comment

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

We should do #14 to fix this for good

Copy link
Contributor

Choose a reason for hiding this comment

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

And modify this to say "<YOUR_CLIENT_ID>"

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Sorry 😅

@@ -15,6 +15,8 @@ export default function Index() {
collectionTitle="<TITLE_FOR_YOUR_COLLECTION>"
collectionDescription="<DESCRIPTION_OF_YOUR_COLLECTION>"
collectionPhoto="<OPT_URL_TO_PHOTO_COVER>"
clientId="12345"
className="my-crossmint-button"
Copy link
Collaborator

Choose a reason for hiding this comment

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

Most people aren't going to understand that they need to remove this, they already don't even edit the props above...

Copy link
Contributor

Choose a reason for hiding this comment

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

+1. Maybe we can have a non customized button, and then a separate customized one? And add a comment in the cusotmized one explaining how it works

Copy link
Contributor

Choose a reason for hiding this comment

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

Also I would rename the classname to "my-custom-style-crossmint-button" or something like that, super obvious

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I would not give it up tbh. It makes the most sense to me at least. How about we just remove it from the examples and snippets, and maybe add a little comment to it in the very bottom of the docs?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Most good devs will just look here, or look at the ts type and see they can use this

But seems like a lot of the people we r dealing with are not good devs

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yeah... I mean to keep the prop as className.

Obviously, it needs to be gone from the example haha

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah the prop seems fine, my comment (and I think Maxwell's) was about keeping it in the main example

],
"publishConfig": {
"access": "public"
},
"scripts": {
"clean": "shx rm -rf lib/*",
"build": "yarn clean && tsc -p tsconfig.json && tsc -p tsconfig-cjs.json",
"postbuild": "shx echo '{ \"type\": \"commonjs\" }' > lib/cjs/package.json && shx echo '{ \"type\": \"module\" }' > lib/esm/package.json"
"postbuild": "shx echo '{ \"type\": \"commonjs\" }' > lib/cjs/package.json && shx echo '{ \"type\": \"module\" }' > lib/esm/package.json",
"pack": "yarn build && yarn pack --filename package.tgz && tar -xf package.tgz"
Copy link
Collaborator

Choose a reason for hiding this comment

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

Lets not do this lol. You just need to run yarn i believe, and the packages are linked automatically

const { hideMintOnInactiveClient, status } = useCrossMintStatus();

const { connecting, connect } = useCrossMintPopup();

const handleClick: MouseEventHandler<HTMLButtonElement> = useCallback(
(event) => {
if (onClick) onClick(event);
Copy link
Collaborator

Choose a reason for hiding this comment

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

If we are using crossmintOpened lets remove onClick

hideMintOnInactiveClient?: boolean;
clientId: string;
development?: boolean;
crossmintOpened?: () => any;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Nit, but i think onCrossmintOpened and onCrossmintClosed is more standard practice for a function handler

Copy link
Contributor

Choose a reason for hiding this comment

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

If these are new parameters that didn't exist before, can we take them out of this PR and send a different PR for them? OR file an issue to track

I'd want more time to define the API surface properly, but didn't want to block this PR from going out in the meantime

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Ok @alfonso-paella lets do that 😄

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Created #34

const PROD_URL = "https://www.crossmint.io";
const DEV_URL = "http://localhost:3001";

const executeIfExists = (fn?: () => any | undefined):void => {
Copy link
Contributor

Choose a reason for hiding this comment

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

This file doesn't seem to have been run through prettier

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

We dont have prettier set up in this repo I believe

Copy link
Contributor

Choose a reason for hiding this comment

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

Oops, we should add it then. Mind running it manually for now?

executeIfExists(crossmintOpened);
} else {
setConnecting(false);
console.log("Failed to open popup window");
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we make this a console.error and have it be more actionable for the developer? Can they do anything to fix this

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

sure! @mPaella anything comes to mind?

Copy link
Contributor

Choose a reason for hiding this comment

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

If it's not obvious let's leave a TODO and do in another task

@pgarciaegido
Copy link
Collaborator Author

pgarciaegido commented Feb 19, 2022

onOpen and onClose props already deleted 👍

@alfonso-paella
Copy link
Contributor

Mind adding back the onclick ? Until we figure out what to do with the onopen and onclose

Copy link
Contributor

@alfonso-paella alfonso-paella left a comment

Choose a reason for hiding this comment

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

I'm good pending the couple unresolved comments. Once you address those feel free to merge if you feel comfortable

@@ -0,0 +1,5 @@
// eslint-disable-next-line @typescript-eslint/no-var-requires
const withBundleAnalyzer = require('@next/bundle-analyzer')({
enabled: process.env.ANALYZE === 'true',
Copy link
Contributor

Choose a reason for hiding this comment

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

Run prettier in this file

@pgarciaegido pgarciaegido merged commit ad4c934 into main Feb 20, 2022
@pgarciaegido pgarciaegido deleted the research/improve-dx-integration branch February 20, 2022 07:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants