-
Notifications
You must be signed in to change notification settings - Fork 1.8k
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
refactor(icons-react): add TypeScript types to icons-react package #14714
refactor(icons-react): add TypeScript types to icons-react package #14714
Conversation
✅ Deploy Preview for v11-carbon-react ready!Built without sensitive environment variables
To edit notification comments on pull requests, go to your Netlify site configuration. |
✅ Deploy Preview for carbon-elements ready!
To edit notification comments on pull requests, go to your Netlify site configuration. |
@jdharvey-ibm @metonym @joshblack @tay1orjones you may be interested in this PR given your involvement in #11317 and #12034. Since it's a major change, I'd like to have as many eyes as possible looking at this. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
0e97640
to
e769119
Compare
@tay1orjones thanks for spotting! Looks like I was mistaken that the |
With one more change, the icons now show up in the carbon-elements preview. |
function formatGlobals(string) { | ||
const mappings = string.split(',').map((mapping) => { | ||
return mapping.split('='); | ||
}); | ||
return mappings.reduce( | ||
(acc, [pkg, global]) => ({ | ||
...acc, | ||
[pkg]: global, | ||
}), | ||
{} | ||
); | ||
} | ||
|
||
function formatDependenciesIntoGlobals(dependencies) { | ||
return Object.keys(dependencies).reduce((acc, key) => { | ||
const parts = key.split('/').map((identifier, i) => { | ||
if (i === 0) { | ||
return identifier.replace(/@/, ''); | ||
} | ||
return identifier; | ||
}); | ||
|
||
return { | ||
...acc, | ||
[key]: pascalCase(parts.join(' ')), | ||
}; | ||
}, {}); | ||
} | ||
|
||
async function findPackageFolder(entrypoint) { | ||
let packageFolder = entrypoint; | ||
|
||
while (packageFolder !== '/' && path.dirname(packageFolder) !== '/') { | ||
packageFolder = path.dirname(packageFolder); | ||
const packageJsonPath = path.join(packageFolder, 'package.json'); | ||
|
||
if (await fs.pathExists(packageJsonPath)) { | ||
break; | ||
} | ||
} | ||
|
||
return packageFolder; | ||
} | ||
|
||
module.exports = bundle; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For these bottom three functions, what are your thoughts about exporting them from javascript.js
and importing them here instead of duplicating them in this file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jdharvey-ibm sounds like a good idea, I can do this.
packages/icon-helpers/tsconfig.json
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any thoughts on if this would be a good time to create a top-level tsconfig.base.json
and extend from that for here and in @carbon/react
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jdharvey-ibm I was basing on top of this comment for distinct tsconfig.json files: #12034 (comment). But I like the idea of using a top-level base config. I can certainly introduce it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah! Not gonna lie I forgot about that comment, but I do still agree with it 😂 . The major one was definitely @carbon/react
so with that in a good place, this might be a good time to treat as much of that config as makes sense as the top-level stuff, and have thinner configs for both carbon-react and now icons-react.
It's totally up to you if you want to handle that in this PR or if you'd prefer we do that in a separate one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's a good idea to handle it here, after all I did introduce these duplicating lines and agree it doesn't look pretty. I'll do this in coming days.
packages/react/tasks/build.js
Outdated
typescript({ | ||
noEmitOnError: true, | ||
noForceEmit: true, | ||
outputToFilesystem: false, | ||
compilerOptions: { | ||
emitDeclarationOnly: true, | ||
rootDir, | ||
outDir, | ||
}, | ||
}), | ||
babel(babelConfig), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some of these typescript config values seems to exist across a few different files (perhaps in slightly different forms). Is it possible to cue off of tsconfig files for these instead? Or is this maybe a limitation of the rollup tooling that we can't easily do that type of thing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jdharvey-ibm yeah, this is problematic... We have (at least) 2 different kinds of TS configs:
- The
tsconfig.json
files are mainly used in development environment, e.g.: by IDE, eslint, etc. - The inline rollup configs, which emit to build directories.
In this PR, I didn't quite think about the difference between group 1 and group 2 - I just based on whatever was there for each group. I guess unifying into one base config and then extending with options that absolutely must be different (e.g. rootDir/outDir) is the right way to go. I'll look at this together with addressing your other comment (#14714 (comment)).
@jdharvey-ibm I think I addressed your comments where you asked for extracting common TypeScript configuration. For better or worse - cause now there's a separate subproject that holds that config + some utils. Let me know if that's an acceptable solution. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think these changes look pretty awesome! I like the introduction of the typescript-config-carbon
package and how it gets used by the other packages.
One question: Can we safely remove the typescript dependency from all of the other packages now? My thinking being that we could use this new typescript-config-carbon
as the definitive source of a typescript version across the entire monorepo.
@tay1orjones Putting this on your radar to look over the new package, since you're way more familiar with the impacts of adding this on the repo as a whole.
@jdharvey-ibm I think we can, given I've forgotten to add it into |
0997f85
to
12c9248
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome work!
Does the package.json
for @carbon/icons-react
need to be updated to include the entry point for types?
I.e.,
"main": "lib/index.js",
"module": "es/index.js",
+ "types": "lib/index.d.ts",
@metonym thanks for reviewing!
That's a great question, that I don't know the answer for... So far everything works without it:
Also, the I'm willing to have additional discussions on this, if you have more information. For now, I'd rather keep this as is, since it works, and |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey thanks for this! I think this looks fine overall. Extracting the typescript config into it's own package is a great enhancement 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, small merge conflict to resolve then we should be good to go. Thanks for making this enhancement!
12c9248
to
d231524
Compare
d231524
to
b7cc8ce
Compare
51d41fa
These changes are published in @carbon/[email protected]. I'm testing the types, and they work great. ✅ import { WatsonHealth3DCursor } from "@carbon/icons-react";
✅ import { Accessibility } from "@carbon/icons-react/es"; However, I'm getting a type error when attempting to import using the full path. For example: ❌ import Icon from "@carbon/icons-react/es/4K"; The type def looks like this: // node_modules/@carbon/icons-react/es/4K.d.ts
import type { CarbonIconType } from './CarbonIcon';
export const _4K: CarbonIconType; While the generated JS code (abridged) has a default export: // node_modules/@carbon/icons-react/es/4K.js
// ...
export { _4K as default }; Should the typedef for an individual file instead have a default export? - export const _4K: CarbonIconType;
+ declare const _4K: CarbonIconType;
+ export default _4K; Can someone else confirm that they are able to repro? I hesitate to open a bug unless confirmed. |
@metonym thanks for finding this, I'll try to reproduce and address. |
As of version 11.29.0, I've also archived the source code used to generate the |
Closes #11317
Adds TypeScript types generation to the
@carbon/icons-react
package and to@carbon/react/icons
submodule.Changelog
New
@carbon/cli
@carbon/icons-react
Changed
Icon
component migrated to TypeScriptreact
andreactNext
builders in@carbon/icon-build-helpers
switched to compiling TypeScript codeicon-helpers
package converted to TypeScriptTesting / Reviewing
Icons rendering in Storybook (e.g. in Accordion or FileUploader components) should work without any visual and behavioral changes. In a TypeScript environment, you should be able to import and reference icons using
@carbon/react/icons
module, with props auto-completion working.