From 16d09cdc01e13a0a4dc50784f00ef1d849331f63 Mon Sep 17 00:00:00 2001 From: Tanner Reits Date: Mon, 12 Dec 2022 21:13:09 -0500 Subject: [PATCH 01/18] docs(framework-integrations): line-break angular docs --- src/docs/framework-integration/angular.md | 53 +++++++++++++++-------- 1 file changed, 36 insertions(+), 17 deletions(-) diff --git a/src/docs/framework-integration/angular.md b/src/docs/framework-integration/angular.md index 9c692fd52..737768eed 100644 --- a/src/docs/framework-integration/angular.md +++ b/src/docs/framework-integration/angular.md @@ -10,13 +10,15 @@ contributors: - jeanbenitez - mburger81 - splitinfinities + - tanner-reits --- # Angular Integration **Supports: Angular 12+ • TypeScript 4.0+ • Stencil v2.9.0+** -Stencil can generate Angular component wrappers for your web components. This allows your Stencil components to be used within an Angular application. The benefits of using Stencil's component wrappers over the standard web components include: +Stencil can generate Angular component wrappers for your web components. This allows your Stencil components to be used within +an Angular application. The benefits of using Stencil's component wrappers over the standard web components include: - Angular component wrappers will be detached from change detection, preventing unnecessary repaints of your web component. - Web component events will be converted to RxJS observables to align with Angular's `@Output()` and will not emit across component boundaries. @@ -26,7 +28,8 @@ Stencil can generate Angular component wrappers for your web components. This al ### Project Structure -We recommend using a monorepo structure for your component library with component wrappers. Your project workspace should contain your Stencil component library and the library for the generated Angular component wrappers. +We recommend using a monorepo structure for your component library with component wrappers. Your project workspace should contain your +Stencil component library and the library for the generated Angular component wrappers. An example project set-up may look similar to: @@ -98,9 +101,11 @@ export const config: Config = { }; ``` -> The `directivesProxyFile` is the relative path to the file that will be generated with all of the Angular component wrappers. You will replace the file path to match your project's structure and respective names. You can generate any file name instead of `components.ts`. +> The `directivesProxyFile` is the relative path to the file that will be generated with all of the Angular component wrappers. +> You will replace the file path to match your project's structure and respective names. You can generate any file name instead of `components.ts`. -> The `directivesArrayFile` is the relative path to the file that will be generated with a constant of all the Angular component wrappers. This constant can be used to easily declare and export all the wrappers. +> The `directivesArrayFile` is the relative path to the file that will be generated with a constant of all the Angular component wrappers. +> This constant can be used to easily declare and export all the wrappers. You can now build your Stencil component library to generate the component wrappers. @@ -125,7 +130,8 @@ import { DIRECTIVES } from './stencil-generated'; export class ExampleLibraryModule {} ``` -Any components that are included in the `exports` array should additionally be exported in your main entry point (either `public-api.ts` or `index.ts`). Skipping this step will lead to Angular Ivy errors when building for production. +Any components that are included in the `exports` array should additionally be exported in your main entry point (either `public-api.ts` or +`index.ts`). Skipping this step will lead to Angular Ivy errors when building for production. ```ts export { DIRECTIVES } from './stencil-generated'; @@ -157,9 +163,11 @@ yarn link name-of-your-stencil-package The name of your Stencil package should match the `name` property from the Stencil component library's `package.json`. -Your component libraries are now linked together. You can make changes in the Stencil component library and run `npm run build` to propagate the changes to the Angular component library. +Your component libraries are now linked together. You can make changes in the Stencil component library and run `npm run build` to propagate the +changes to the Angular component library. -> **NOTE**: As an alternative to `npm link` , you can also run `npm install` with a relative path to your Stencil component library. This strategy, however, will modify your `package.json` so it is important to make sure you do not commit those changes. +> **NOTE**: As an alternative to `npm link` , you can also run `npm install` with a relative path to your Stencil component library. This strategy, +however, will modify your `package.json` so it is important to make sure you do not commit those changes. ## Consumer Usage @@ -198,15 +206,18 @@ Developers can now directly leverage your components in their template and take ### What is the best format to write event names? -Event names shouldn’t include special characters when initially written in Stencil, try to lean on using camelCased event names for interoperability between frameworks. +Event names shouldn’t include special characters when initially written in Stencil, try to lean on using camelCased event names for interoperability +between frameworks. ### How do I bind input events directly to a value accessor? -You can configure how your input events can map directly to a value accessor, allowing two-way data-binding to be a built in feature of any of your components. Take a look at [valueAccessorConfig's option below](). +You can configure how your input events can map directly to a value accessor, allowing two-way data-binding to be a built in feature of any of your +components. Take a look at [valueAccessorConfig's option below](). ### How do I add IE11 or Edge support? -If you want your custom elements to be able to work on older browsers, you should add the `applyPolyfills()` that surround the `defineCustomElements()` function. +If you want your custom elements to be able to work on older browsers, you should add the `applyPolyfills()` that surround the `defineCustomElements()` +function. ```ts import { applyPolyfills, defineCustomElements } from 'test-components/loader'; @@ -241,9 +252,12 @@ export class HomeComponent { ### Why aren't my custom interfaces exported from within the index.d.ts file? -Usually when beginning this process, you may bump into a situation where you find that some of the interfaces you've used in your Stencil component library aren't working in your Angular component library. You can resolve this issue by adding an `interfaces.d.ts` file located within the root of your Stencil component library's project folder, then manually exporting types from that file e.g. `export * from './components';` +Usually when beginning this process, you may bump into a situation where you find that some of the interfaces you've used in your Stencil component +library aren't working in your Angular component library. You can resolve this issue by adding an `interfaces.d.ts` file located within the root +of your Stencil component library's project folder, then manually exporting types from that file e.g. `export * from './components';` -When adding this file, it's also recommended to update your package.json's types property to be the distributed file, something like: `"types": "dist/types/interfaces.d.ts"` +When adding this file, it's also recommended to update your package.json's types property to be the distributed file, something like: +`"types": "dist/types/interfaces.d.ts"` ## API @@ -251,7 +265,8 @@ The angularOutputTarget method accepts 5 parameters: ### componentCorePackage -The title of the Stencil package where components are available for consumers. This is used during compilation to write the correct imports for components e.g. +The title of the Stencil package where components are available for consumers. This is used during compilation to write the correct imports +for components e.g. ```js import { IonApp } from '@ionic/core/components/ion-app.js'; @@ -259,7 +274,8 @@ import { IonApp } from '@ionic/core/components/ion-app.js'; ### directivesProxyFile -This parameter allows you to name the file that contains all the component wrapper definitions produced during the compilation process. This is the first file you should import in your Angular project. +This parameter allows you to name the file that contains all the component wrapper definitions produced during the compilation process. This is the +first file you should import in your Angular project. ### includeImportCustomElements @@ -267,7 +283,8 @@ If `true`, Angular components will import and define elements from the `dist-cus ### directivesArrayFile -Used to provide a list of type Proxies to the Angular Component Library. [See Ionic Framework for a sample](https://github.com/ionic-team/ionic-framework/blob/main/angular/src/directives/proxies-list.txt). +Used to provide a list of type Proxies to the Angular Component Library. +[See Ionic Framework for a sample](https://github.com/ionic-team/ionic-framework/blob/main/angular/src/directives/proxies-list.txt). ### directivesUtilsFile @@ -275,7 +292,8 @@ This is the file where helper functions for the component wrappers are defined. ### valueAccessorConfigs -This lets you define which components should be integrated with ngModel (I.e. form components). It lets you set what the target prop is (I.e. `value`), which event will cause the target prop to change, and more. +This lets you define which components should be integrated with ngModel (I.e. form components). It lets you set what the target prop is (I.e. `value`), +which event will cause the target prop to change, and more. ```tsx const angularValueAccessorBindings: ValueAccessorConfig[] = [ @@ -305,4 +323,5 @@ export const config: Config = { ### excludeComponents -This lets you exclude wrapping certain Web Components. This is useful if you need to write framework-specific versions of components. In Ionic Framework, this is used for routing components - like tabs - so that Ionic Framework can integrate better with Angular's Router. +This lets you exclude wrapping certain Web Components. This is useful if you need to write framework-specific versions of components. In Ionic +Framework, this is used for routing components - like tabs - so that Ionic Framework can integrate better with Angular's Router. From c880e2fd1d2003a623763d0816e4fbd4448879e1 Mon Sep 17 00:00:00 2001 From: Tanner Reits Date: Mon, 12 Dec 2022 21:17:50 -0500 Subject: [PATCH 02/18] docs(framework-integration): swap api & faq sections for angular --- src/docs/framework-integration/angular.md | 114 +++++++++++----------- 1 file changed, 57 insertions(+), 57 deletions(-) diff --git a/src/docs/framework-integration/angular.md b/src/docs/framework-integration/angular.md index 737768eed..100891d5d 100644 --- a/src/docs/framework-integration/angular.md +++ b/src/docs/framework-integration/angular.md @@ -202,63 +202,6 @@ Developers can now directly leverage your components in their template and take ``` -## FAQs - -### What is the best format to write event names? - -Event names shouldn’t include special characters when initially written in Stencil, try to lean on using camelCased event names for interoperability -between frameworks. - -### How do I bind input events directly to a value accessor? - -You can configure how your input events can map directly to a value accessor, allowing two-way data-binding to be a built in feature of any of your -components. Take a look at [valueAccessorConfig's option below](). - -### How do I add IE11 or Edge support? - -If you want your custom elements to be able to work on older browsers, you should add the `applyPolyfills()` that surround the `defineCustomElements()` -function. - -```ts -import { applyPolyfills, defineCustomElements } from 'test-components/loader'; -... -applyPolyfills().then(() => { - defineCustomElements(); -}); -``` - -### How do I access components with ViewChild or ViewChildren? - -Once included, components could be referenced in your code using `ViewChild` and `ViewChildren` as in the following example: - -```tsx -import { Component, ElementRef, ViewChild } from '@angular/core'; - -import { TestComponent } from 'test-components'; - -@Component({ - selector: 'app-home', - template: ``, - styleUrls: ['./home.component.scss'], -}) -export class HomeComponent { - @ViewChild(TestComponent) myTestComponent: ElementRef; - - async onAction() { - await this.myTestComponent.nativeElement.testComponentMethod(); - } -} -``` - -### Why aren't my custom interfaces exported from within the index.d.ts file? - -Usually when beginning this process, you may bump into a situation where you find that some of the interfaces you've used in your Stencil component -library aren't working in your Angular component library. You can resolve this issue by adding an `interfaces.d.ts` file located within the root -of your Stencil component library's project folder, then manually exporting types from that file e.g. `export * from './components';` - -When adding this file, it's also recommended to update your package.json's types property to be the distributed file, something like: -`"types": "dist/types/interfaces.d.ts"` - ## API The angularOutputTarget method accepts 5 parameters: @@ -325,3 +268,60 @@ export const config: Config = { This lets you exclude wrapping certain Web Components. This is useful if you need to write framework-specific versions of components. In Ionic Framework, this is used for routing components - like tabs - so that Ionic Framework can integrate better with Angular's Router. + +## FAQs + +### What is the best format to write event names? + +Event names shouldn’t include special characters when initially written in Stencil, try to lean on using camelCased event names for interoperability +between frameworks. + +### How do I bind input events directly to a value accessor? + +You can configure how your input events can map directly to a value accessor, allowing two-way data-binding to be a built in feature of any of your +components. Take a look at [valueAccessorConfig's option below](). + +### How do I add IE11 or Edge support? + +If you want your custom elements to be able to work on older browsers, you should add the `applyPolyfills()` that surround the `defineCustomElements()` +function. + +```ts +import { applyPolyfills, defineCustomElements } from 'test-components/loader'; +... +applyPolyfills().then(() => { + defineCustomElements(); +}); +``` + +### How do I access components with ViewChild or ViewChildren? + +Once included, components could be referenced in your code using `ViewChild` and `ViewChildren` as in the following example: + +```tsx +import { Component, ElementRef, ViewChild } from '@angular/core'; + +import { TestComponent } from 'test-components'; + +@Component({ + selector: 'app-home', + template: ``, + styleUrls: ['./home.component.scss'], +}) +export class HomeComponent { + @ViewChild(TestComponent) myTestComponent: ElementRef; + + async onAction() { + await this.myTestComponent.nativeElement.testComponentMethod(); + } +} +``` + +### Why aren't my custom interfaces exported from within the index.d.ts file? + +Usually when beginning this process, you may bump into a situation where you find that some of the interfaces you've used in your Stencil component +library aren't working in your Angular component library. You can resolve this issue by adding an `interfaces.d.ts` file located within the root +of your Stencil component library's project folder, then manually exporting types from that file e.g. `export * from './components';` + +When adding this file, it's also recommended to update your package.json's types property to be the distributed file, something like: +`"types": "dist/types/interfaces.d.ts"` From da9de97f5169de9dc30ba41977c9ec2709aff5da Mon Sep 17 00:00:00 2001 From: Tanner Reits Date: Tue, 13 Dec 2022 20:52:25 -0500 Subject: [PATCH 03/18] docs(framework-integrations): update Angular target API docs --- src/docs/framework-integration/angular.md | 131 +++++++++++++++++----- 1 file changed, 106 insertions(+), 25 deletions(-) diff --git a/src/docs/framework-integration/angular.md b/src/docs/framework-integration/angular.md index 100891d5d..f6b44f329 100644 --- a/src/docs/framework-integration/angular.md +++ b/src/docs/framework-integration/angular.md @@ -23,13 +23,14 @@ an Angular application. The benefits of using Stencil's component wrappers over - Angular component wrappers will be detached from change detection, preventing unnecessary repaints of your web component. - Web component events will be converted to RxJS observables to align with Angular's `@Output()` and will not emit across component boundaries. - Optionally, form control web components can be used as control value accessors with Angular's reactive forms or `[ngModel]`. +- It is not necessary to include the `CUSTOM_ELEMENTS_SCHEMA` in all modules consuming your Stencil components. ## Setup ### Project Structure -We recommend using a monorepo structure for your component library with component wrappers. Your project workspace should contain your -Stencil component library and the library for the generated Angular component wrappers. +We recommend using a [monorepo](https://www.toptal.com/front-end/guide-to-monorepos) structure for your component library with component +wrappers. Your project workspace should contain your Stencil component library and the library for the generated Angular component wrappers. An example project set-up may look similar to: @@ -92,6 +93,13 @@ import { angularOutputTarget } from '@stencil/angular-output-target'; export const config: Config = { namespace: 'stencil-library', outputTargets: [ + // By default, the generated proxy components will + // leverage the output from the `dist` target, so we + // need to explicitly define that output alongside the + // Angular target + { + type: 'dist', + }, angularOutputTarget({ componentCorePackage: 'your-stencil-library-package-name', directivesProxyFile: '../angular-workspace/projects/component-library/src/lib/stencil-generated/components.ts', @@ -101,11 +109,7 @@ export const config: Config = { }; ``` -> The `directivesProxyFile` is the relative path to the file that will be generated with all of the Angular component wrappers. -> You will replace the file path to match your project's structure and respective names. You can generate any file name instead of `components.ts`. - -> The `directivesArrayFile` is the relative path to the file that will be generated with a constant of all the Angular component wrappers. -> This constant can be used to easily declare and export all the wrappers. +See the [API section below](#api) for details on each of the output target's options. You can now build your Stencil component library to generate the component wrappers. @@ -137,9 +141,12 @@ Any components that are included in the `exports` array should additionally be e export { DIRECTIVES } from './stencil-generated'; ``` +> **NOTE:** The default behavior does not automatically define the Web Components needed by the proxy components. You can manually define the Web +> Components following the [documentation for the dist output target](docs/custom-elements#defining-exported-custom-elements). + ### Link your packages (optional) -> If you are using a monorepo tool (Lerna, Nx), skip this section. +> If you are using a monorepo tool (Lerna, Nx, etc.), skip this section. Before you can successfully build a local version of your Angular component library, you will need to link the Stencil package to the Angular package. @@ -167,7 +174,7 @@ Your component libraries are now linked together. You can make changes in the St changes to the Angular component library. > **NOTE**: As an alternative to `npm link` , you can also run `npm install` with a relative path to your Stencil component library. This strategy, -however, will modify your `package.json` so it is important to make sure you do not commit those changes. +> however, will modify your `package.json` so it is important to make sure you do not commit those changes. ## Consumer Usage @@ -204,38 +211,84 @@ Developers can now directly leverage your components in their template and take ## API -The angularOutputTarget method accepts 5 parameters: - ### componentCorePackage -The title of the Stencil package where components are available for consumers. This is used during compilation to write the correct imports -for components e.g. +**Required** + +**Type: `string`** + +The title of the Stencil package where components are available for consumers (i.e. the `name` property value in your Stencil project's `package.json`). +This is used during compilation to write the correct imports for components. + +For the Ionic Framework, a generated import would look like: ```js import { IonApp } from '@ionic/core/components/ion-app.js'; ``` -### directivesProxyFile +In the generated statement, `@ionic/core` is the value supplied for `componentCorePackage`. -This parameter allows you to name the file that contains all the component wrapper definitions produced during the compilation process. This is the -first file you should import in your Angular project. +### customElementsDir -### includeImportCustomElements +**Optional** + +**Default: 'dist/components'** -If `true`, Angular components will import and define elements from the `dist-custom-elements` build, rather than `dist`. +If [includeImportCustomElements](#includeimportcustomelements) is `true`, this option can be used to specify the directory where the generated +custom elements live. This value only needs to be set if the `dir` field on the `dist-custom-elements` output target was set to something other than +the default directory. + +### excludeComponents + +**Optional** + +**Default: `[]`** + +**Type: `string[]`** + +This lets you specify component tag names for which you don't want to generate Angular wrapper components. This is useful if you need to write framework-specific versions of components. For instance, in Ionic Framework, this is used for routing components - like tabs - so that +Ionic Framework can integrate better with Angular's Router. ### directivesArrayFile +**Optional** + +**Default: `null`** + +**Type: `string`** + Used to provide a list of type Proxies to the Angular Component Library. [See Ionic Framework for a sample](https://github.com/ionic-team/ionic-framework/blob/main/angular/src/directives/proxies-list.txt). -### directivesUtilsFile +### directivesProxyFile + +**Required** -This is the file where helper functions for the component wrappers are defined. +**Type: `string`** + +This parameter allows you to name the file that contains all the component wrapper definitions produced during the compilation process. This is the +first file you should import in your Angular project. + +### includeImportCustomElements + +**Optional** + +**Default: `false`** + +**Type: `boolean`** + +If `true`, Angular components will import and define elements from the `dist-custom-elements` build, rather than `dist`. For more information +on using the `dist-custom-elements` output for the Angular proxies, see the [FAQ answer below](#do-i-have-to-use-the-dist-output-target). ### valueAccessorConfigs -This lets you define which components should be integrated with ngModel (I.e. form components). It lets you set what the target prop is (I.e. `value`), +**Optional** + +**Default: `[]`** + +**Type: `ValueAccessorConfig[]`** + +This lets you define which components should be integrated with ngModel (I.e. form components). It lets you set what the target prop is (i.e. `value`), which event will cause the target prop to change, and more. ```tsx @@ -264,12 +317,40 @@ export const config: Config = { }; ``` -### excludeComponents +## FAQs -This lets you exclude wrapping certain Web Components. This is useful if you need to write framework-specific versions of components. In Ionic -Framework, this is used for routing components - like tabs - so that Ionic Framework can integrate better with Angular's Router. +### Do I have to use the `dist` output target? -## FAQs +No! By default, this output target will look to use the `dist` output, but the output from `dist-custom-elements` can be used alternatively. + +To do so, simply set the `includeImportCustomElements` option in the output target's config and ensure the +[custom elements output target](docs/custom-elements) is added to the Stencil config's output target array: + +```ts +// stencil.config.ts + +export const config: Config = { + ..., + outputTargets: [ + // Needs to be included + { + type: 'dist-custom-elements' + }, + angularOutputTarget({ + componentCorePackage: 'component-library', + directivesProxyFile: '{path to your proxy file}', + // This is what tells the target to use the custom elements output + includeImportCustomElements: true + }) + ] +} +``` + +Now, all generated imports will point to the default directory for the custom elements output. If you specified a different directory +using the `dir` property for `dist-custom-elements`, you need to also specify that directory for the Angular output target. See +[the API section](#customelementsdir) for more information. + +In addition, all the Web Component will be automatically defined as the generated component modules are bootstrapped. ### What is the best format to write event names? From f4a475426cfea508a8ceb51c5072ffb8e588dbf0 Mon Sep 17 00:00:00 2001 From: Tanner Reits Date: Mon, 19 Dec 2022 20:40:15 -0500 Subject: [PATCH 04/18] fix(): PR feedback --- src/docs/framework-integration/angular.md | 42 ++++++++++++++++++----- 1 file changed, 34 insertions(+), 8 deletions(-) diff --git a/src/docs/framework-integration/angular.md b/src/docs/framework-integration/angular.md index f6b44f329..1229c663c 100644 --- a/src/docs/framework-integration/angular.md +++ b/src/docs/framework-integration/angular.md @@ -23,7 +23,7 @@ an Angular application. The benefits of using Stencil's component wrappers over - Angular component wrappers will be detached from change detection, preventing unnecessary repaints of your web component. - Web component events will be converted to RxJS observables to align with Angular's `@Output()` and will not emit across component boundaries. - Optionally, form control web components can be used as control value accessors with Angular's reactive forms or `[ngModel]`. -- It is not necessary to include the `CUSTOM_ELEMENTS_SCHEMA` in all modules consuming your Stencil components. +- It is not necessary to include the [Angular `CUSTOM_ELEMENTS_SCHEMA`](https://angular.io/api/core/CUSTOM_ELEMENTS_SCHEMA) in all modules consuming your Stencil components. ## Setup @@ -109,6 +109,12 @@ export const config: Config = { }; ``` +> The `directivesProxyFile` is the relative path to the file that will be generated with all of the Angular component wrappers. You will replace the +> file path to match your project's structure and respective names. You can generate any file name instead of `components.ts`. + +> The `directivesArrayFile` is the relative path to the file that will be generated with a constant of all the Angular component wrappers. This +> constant can be used to easily declare and export all the wrappers. + See the [API section below](#api) for details on each of the output target's options. You can now build your Stencil component library to generate the component wrappers. @@ -142,7 +148,7 @@ export { DIRECTIVES } from './stencil-generated'; ``` > **NOTE:** The default behavior does not automatically define the Web Components needed by the proxy components. You can manually define the Web -> Components following the [documentation for the dist output target](docs/custom-elements#defining-exported-custom-elements). +> Components following the [documentation for the dist output target](/docs/custom-elements#defining-exported-custom-elements). ### Link your packages (optional) @@ -220,13 +226,33 @@ Developers can now directly leverage your components in their template and take The title of the Stencil package where components are available for consumers (i.e. the `name` property value in your Stencil project's `package.json`). This is used during compilation to write the correct imports for components. -For the Ionic Framework, a generated import would look like: +For a starter Stencil project generated by running: -```js -import { IonApp } from '@ionic/core/components/ion-app.js'; +```bash +npm init stencil component my-component-lib +``` + +The `componentCorePackage` would be set to: + +```ts +// stencil.config.ts + +export const config: Config = { + ..., + outputTargets: [ + angularOutputTarget({ + componentCorePackage: 'my-component-lib', + // ... additional config options + }) + ] +} ``` -In the generated statement, `@ionic/core` is the value supplied for `componentCorePackage`. +Which would result in an import path like: + +```js +import { MyComponent } from 'my-component-lib/components/my-component.js'; +``` ### customElementsDir @@ -288,7 +314,7 @@ on using the `dist-custom-elements` output for the Angular proxies, see the [FAQ **Type: `ValueAccessorConfig[]`** -This lets you define which components should be integrated with ngModel (I.e. form components). It lets you set what the target prop is (i.e. `value`), +This lets you define which components should be integrated with `ngModel` (i.e. form components). It lets you set what the target prop is (i.e. `value`), which event will cause the target prop to change, and more. ```tsx @@ -324,7 +350,7 @@ export const config: Config = { No! By default, this output target will look to use the `dist` output, but the output from `dist-custom-elements` can be used alternatively. To do so, simply set the `includeImportCustomElements` option in the output target's config and ensure the -[custom elements output target](docs/custom-elements) is added to the Stencil config's output target array: +[custom elements output target](/docs/custom-elements) is added to the Stencil config's output target array: ```ts // stencil.config.ts From 8cf947520a37228ea74f77723c2618f597d6fc01 Mon Sep 17 00:00:00 2001 From: Tanner Reits Date: Mon, 19 Dec 2022 20:42:58 -0500 Subject: [PATCH 05/18] fix(): add `--dev` flag for `yarn add` command --- src/docs/framework-integration/angular.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/docs/framework-integration/angular.md b/src/docs/framework-integration/angular.md index 1229c663c..1351a972b 100644 --- a/src/docs/framework-integration/angular.md +++ b/src/docs/framework-integration/angular.md @@ -82,7 +82,7 @@ Install the `@stencil/angular-output-target` dependency to your Stencil componen # Install dependency npm install @stencil/angular-output-target --save-dev # or if using yarn -yarn add @stencil/angular-output-target +yarn add @stencil/angular-output-target --dev ``` In your project's `stencil.config.ts`, add the `angularOutputTarget` configuration to the `outputTargets` array: From b05b5d28e0357d22b6792f46216a9849445ed0ea Mon Sep 17 00:00:00 2001 From: Tanner Reits Date: Tue, 3 Jan 2023 16:44:12 -0500 Subject: [PATCH 06/18] docs(react-wrapper): swap FAQ & API sections --- src/docs/framework-integration/react.md | 28 ++++++++++++------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/docs/framework-integration/react.md b/src/docs/framework-integration/react.md index c40dd5d00..81d3ebf2c 100644 --- a/src/docs/framework-integration/react.md +++ b/src/docs/framework-integration/react.md @@ -202,6 +202,20 @@ import { MyComponent } from 'component-library-react'; With that, your component is now available to be used like any other React component. +## API + +### proxiesFile + +This parameter allows you to name the file that contains all the component wrapper definitions produced during the compilation process. This is the first file you should import in your React project. + +### includeDefineCustomElements + +If `true`, React components will import and define elements from the [`dist-custom-elements` build](/docs/custom-elements), rather than [`dist`](/docs/distribution). + +### excludeComponents + +This lets you exclude wrapping certain Web Components. This is useful if you need to write framework-specific versions of components. In Ionic Framework, this is used for routing components, like tabs, so that Ionic Framework can integrate better with React's Router. + ## FAQ's ### What is the best format to write event names? @@ -219,17 +233,3 @@ applyPolyfills().then(() => { defineCustomElements(); }); ``` - -## API - -### proxiesFile - -This parameter allows you to name the file that contains all the component wrapper definitions produced during the compilation process. This is the first file you should import in your React project. - -### includeDefineCustomElements - -If `true`, React components will import and define elements from the [`dist-custom-elements` build](/docs/custom-elements), rather than [`dist`](/docs/distribution). - -### excludeComponents - -This lets you exclude wrapping certain Web Components. This is useful if you need to write framework-specific versions of components. In Ionic Framework, this is used for routing components, like tabs, so that Ionic Framework can integrate better with React's Router. From 3b0aea8f2dea713be9bb3845d1a220ddd7b48c19 Mon Sep 17 00:00:00 2001 From: Tanner Reits Date: Tue, 3 Jan 2023 18:43:31 -0500 Subject: [PATCH 07/18] docs(react-wrapper): Update to match Angular docs --- src/docs/framework-integration/react.md | 281 +++++++++++++++++------- 1 file changed, 207 insertions(+), 74 deletions(-) diff --git a/src/docs/framework-integration/react.md b/src/docs/framework-integration/react.md index 81d3ebf2c..fc7667406 100644 --- a/src/docs/framework-integration/react.md +++ b/src/docs/framework-integration/react.md @@ -1,6 +1,6 @@ --- title: React Integration with Stencil -description: React Integration with Stencil +description: Learn how to wrap your components so that people can use them natively in React url: /docs/react contributors: - jthoms1 @@ -11,6 +11,7 @@ contributors: - danawoodman - a-giuliano - rwaskiewicz + - tanner-reits --- # React Integration @@ -25,7 +26,10 @@ One benefit of the wrapper pattern includes improved maintainability since you c ### Project Structure -To organize the generated component libraries for different frameworks, we recommend using a monorepo structure. This monorepo will contain your Stencil component library as well as the component libraries for whatever frameworks you choose. The overall structure of a monorepo with Stencil and React component libraries might look something like this +We recommend using a [monorepo](https://www.toptal.com/front-end/guide-to-monorepos) structure for your component library with component +wrappers. Your project workspace should contain your Stencil component library and the library for the generated React component wrappers. + +An example project set-up may look similar to: ``` top-most-directory/ @@ -38,21 +42,13 @@ top-most-directory/ └── index.ts ``` -To do this, start by creating a monorepo - -```bash -mkdir {the name of your monorepo} -``` +### Creating a React Component Library -And then move your Stencil component library into your monorepo - -```bash -mv {the path to your Stencil component library} {the path to your monorepo} -``` +> If you already have a React component library, skip this section. -### Create a React Component Library +The first time you want to create the component wrappers, you will need to have a Rect library package to write to. -Next, we will need to create the React component library that will wrap your Stencil components. This library will be a sibling to your Stencil component library. Inside your monorepo, you can create your own React project, or you can use the [React component library template](https://github.com/ionic-team/stencil-ds-react-template) to bootstrap it. To do this, run the following command +You can create your own React project using a [recommended toolchain](https://reactjs.org/docs/create-a-new-react-app.html#recommended-toolchains), or by using the [React component library template](https://github.com/ionic-team/stencil-ds-react-template). To use the template, run the following: ```bash git clone https://github.com/ionic-team/stencil-ds-react-template component-library-react @@ -60,87 +56,86 @@ cd component-library-react npm i ``` -> **NOTE**: If you want to name your React component library something different, add the new name at the end of the clone command like so +> **NOTE**: If you want to name your React component library something different, add the new name at the end of the clone command like so: -```bash -git clone https://github.com/ionic-team/stencil-ds-react-template {the name of your React component library} -cd {the name of your React component library} -npm i -``` +> ```bash +> git clone https://github.com/ionic-team/stencil-ds-react-template {the name of your React component library} +> cd {the name of your React component library} +> npm i # or yarn install +> ``` -If you do rename your React component library, be sure to change the `name` in the `package.json` to match your new name. +> If you do rename your React component library, be sure to change the `name` in the `package.json` to match your new name. -### Install the React Output Target in your Stencil Component Library +#### Creating a Stencil Component Library -Now that the project structure is set up, we can install the React Output Target package in your Stencil component library. This package contains the React wrapper function that we will use to generate our React wrapped components inside a 'React component library'. To install the React Output Target package, run the following command in your **Stencil project directory** +> If you already have a Stencil component library, skip this section. ```bash -npm install @stencil/react-output-target --save-dev +npm init stencil components stencil-library +cd stencil-library +# Install dependencies +npm install +# or if using yarn +yarn install ``` -Or +### Adding the React Output Target + +Install the `@stencil/react-output-target` dependency to your Stencil component library package. ```bash +# Install dependency +npm install @stencil/react-output-target --save-dev +# or if using yarn yarn add @stencil/react-output-target --dev ``` ### Add the React Wrapper Function to your Stencil Component Library -With the React Output Target package installed, we can now configure our Stencil component library to build our React wrapped components (within our React component library). In the `stencil.config.ts` file of your Stencil component library, add the React wrapper function +In your project's `stencil.config.ts`, add the `reactOutputTarget` configuration to the `outputTargets` array: -```tsx -import { Config } from '@stencil/core'; -import { reactOutputTarget as react } from '@stencil/react-output-target'; +```ts +import { reactOutputTarget } from '@stencil/react-output-target'; export const config: Config = { - ... + namespace: 'stencil-library', outputTargets: [ - react({ - componentCorePackage: 'your-stencil-library-name', - proxiesFile: '../your-react-library-name/src/components/stencil-generated/index.ts', - includeDefineCustomElements: true, - }), + // By default, the generated proxy components will + // leverage the output from the `dist` target, so we + // need to explicitly define that output alongside the + // React target { type: 'dist', - esmLoaderPath: '../loader', }, - { - type: 'dist-custom-elements', - }, - ... + reactOutputTarget({ + componentCorePackage: 'your-stencil-library-package-name', + proxiesFile: '../react-library/src/components/stencil-generated/index.ts', + }), ], }; ``` -First, make sure to import the `reactOutputTarget` function from `@stencil/react-output-target` at the top of the file. With that imported, we can now use it in the `outputTargets` array and specify the relevant parameters. The `componentCorePackage` should be the name of your Stencil component library. The `proxiesFile` is the file that gets generated by the React wrapper function and contains the definitions of all the React wrapper components. Be sure to change the path names to reflect the names of your packages. +> The `proxiesFile` is the relative path to the file that will be generated with all of the React component wrappers. You will replace the +> file path to match your project's structure and respective names. You can generate any file name instead of `index.ts`. + +See the [API section below](#api) for details on each of the output target's options. For details on the `includeDefineCustomElements` option, and all other options, visit the API documentation section below. -With the `reactOutputTarget` configured, we can now generate our React wrapped components. In your **Stencil component library** run +You can now build your Stencil component library to generate the component wrappers. ```bash +# Build the library and wrappers npm run build +# or if using yarn +yarn run build ``` -You’ll see the new generated file in your React component library at the location specified by the `proxiesFile` . - -``` -top-most-directory/ -├── stencil-library/ -│ ├── stencil.config.js -│ └── src/components/ -└── react-library/ - └── src/ - └── components/ - │ └── stencil-generated/ - │ └── react-component-lib/ - │ └── index.ts <-- the newly generated file - └── index.ts -``` +If the build is successful, you’ll see the new generated file in your React component library at the location specified by the `proxiesFile` argument. ### Add the Components to your React Component Library's Entry File -> **Note:** If you are using our React template, this should already be prepared for you, and this step can be safely skipped. +> If you are using Ionic's React template, skip this section. In order to make the generated files available within your React component library and its consumers, you’ll need to export everything from within your entry file - commonly the `src/index.ts` file. To do this, you’ll write: @@ -150,31 +145,38 @@ export * from './components'; ### Link Your Packages (Optional) -If you want to build and test your components locally, you will need to link the packages together. This is a replacement for publishing packages to npm that allows you to develop and test locally. To do this, we’ll use the `npm link` command. This command creates a global symlink for a given package and thereby allows it to be consumed by other packages in your environment. - -First, build your Stencil component library. In your **Stencil component library**, run +> If you are using a monorepo tool (Lerna, Nx, etc.), skip this section. -```bash -npm run build -``` +Before you can successfully build a local version of your React component library, you will need to link the Stencil package to the React package. -Now you can create a symlink for your Stencil component library. From within your **Stencil component library**, run +From your Stencil project's directory, run the following command: ```bash +# Link the working directory npm link +# or if using yarn +yarn link ``` -With the symlink created, we next need to specify which packages will be consuming them. Your React component library will need to consume your Stencil component library. In the directory of your **React component library** run +From your React component library's directory, run the following command: ```bash -npm link {Stencil library name} +# Link the package name +npm link name-of-your-stencil-package +# or if using yarn +yarn link name-of-your-stencil-package ``` -And with that, your component libraries are linked together. Now, you can make changes in your Stencil component library and run `npm run build` to propagate them through to the React component library without having to relink. +The name of your Stencil package should match the `name` property from the Stencil component library's `package.json`. + +Your component libraries are now linked together. You can make changes in the Stencil component library and run `npm run build` to propagate the +changes to the React component library. > **NOTE:** As an alternative to `npm link` , you can also run `npm install` with a relative path to your Stencil component library. This strategy, however, will modify your `package.json` so it is important to make sure you do not commit those changes. -## Usage +## Consumer Usage + +This section covers how developers consuming your React component wrappers will use your package and component wrappers. If you are developing and testing your React component library locally, you'll have to use `npm link` again to make your React component library available in your React application. If your components are published to npm, you can skip this step. @@ -204,20 +206,151 @@ With that, your component is now available to be used like any other React compo ## API -### proxiesFile +### componentCorePackage -This parameter allows you to name the file that contains all the component wrapper definitions produced during the compilation process. This is the first file you should import in your React project. +**Optional** -### includeDefineCustomElements +**Default: The `components.d.ts` file in the Stencil project's `package.json` types field** + +**Type: `string`** -If `true`, React components will import and define elements from the [`dist-custom-elements` build](/docs/custom-elements), rather than [`dist`](/docs/distribution). +The title of the Stencil package where components are available for consumers (i.e. the `name` property value in your Stencil project's `package.json`). +This is used during compilation to write the correct imports for components. + +For a starter Stencil project generated by running: + +```bash +npm init stencil component my-component-lib +``` + +The `componentCorePackage` would be set to: + +```ts +// stencil.config.ts + +export const config: Config = { + ..., + outputTargets: [ + reactOutputTarget({ + componentCorePackage: 'my-component-lib', + // ... additional config options + }) + ] +} +``` + +Which would result in an import path like: + +```js +import { defineCustomElement as defineMyComponent } from 'my-component-lib/components/my-component.js'; +``` + +> **NOTE:** Although this field is optional, it is _highly_ recommended that it always be defined to avoid potential issues with paths not being generated correctly when combining other API arguments. + +### customElementsDir + +**Optional** + +**Default: 'dist/components'** + +If [includeImportCustomElements](#includeimportcustomelements) is `true`, this option can be used to specify the directory where the generated +custom elements live. This value only needs to be set if the `dir` field on the `dist-custom-elements` output target was set to something other than +the default directory. ### excludeComponents -This lets you exclude wrapping certain Web Components. This is useful if you need to write framework-specific versions of components. In Ionic Framework, this is used for routing components, like tabs, so that Ionic Framework can integrate better with React's Router. +**Optional** + +**Default: `[]`** + +**Type: `string[]`** + +This lets you specify component tag names for which you don't want to generate React wrapper components. This is useful if you need to write framework-specific versions of components. For instance, in Ionic Framework, this is used for routing components - like tabs - so that +Ionic Framework can integrate better with React's Router. + +### includeDefineCustomElements + +**Optional** + +**Default: `true`** + +**Type: `boolean`** + +If `true`, all Web Components will automatically be registered with the Custom Elements Registry. This can only be used when lazy loading Web Components and will not work when `includeImportCustomElements` is `true`. + +### includeImportCustomElements + +**Optional** + +**Default: `undefined`** + +**Type: `boolean`** + +If `true`, the output target will import the custom element instance and register it with the Custom Elements Registry when the component is imported inside of a user's app. This can only be used with the [Custom Elements Bundle](/docs/custom-elements) and will not work with lazy loaded components. + +### includePolyfills + +**Optional** + +**Default: `true`** + +**Type: `boolean`** + +If `true`, polyfills will automatically be imported and the `applyPolyfills` function will be called in your proxies file. This can only be used when lazy loading Web Components and will not work when `includeImportCustomElements` is enabled. + +### loaderDir + +**Optional** + +**Default: `/dist/loader`** + +**Type: `string`** + +The path to where the `defineCustomElements` helper method exists within the built project. This option is only used when `includeDefineCustomElements` is enabled. + +### proxiesFile + +**Required** + +**Type: `string`** + +This parameter allows you to name the file that contains all the component wrapper definitions produced during the compilation process. This is the first file you should import in your React project. ## FAQ's +### Do I have to use the `dist` output target? + +No! By default, this output target will look to use the `dist` output, but the output from `dist-custom-elements` can be used alternatively. + +To do so, simply set the `includeImportCustomElements` option in the output target's config and ensure the +[custom elements output target](/docs/custom-elements) is added to the Stencil config's output target array: + +```ts +// stencil.config.ts + +export const config: Config = { + ..., + outputTargets: [ + // Needs to be included + { + type: 'dist-custom-elements' + }, + reactOutputTarget({ + componentCorePackage: 'component-library', + proxiesFile: '{path to your proxy file}', + // This is what tells the target to use the custom elements output + includeImportCustomElements: true + }) + ] +} +``` + +Now, all generated imports will point to the default directory for the custom elements output. If you specified a different directory +using the `dir` property for `dist-custom-elements`, you need to also specify that directory for the React output target. See +[the API section](#customelementsdir) for more information. + +In addition, all the Web Component will be automatically defined as the generated component modules are bootstrapped. + ### What is the best format to write event names? Event names shouldn’t include special characters when initially written in Stencil. Try to lean on using camelCased event names for interoperability between frameworks. From eebe505fdf0fc35bd225d21bad867aae3bdcc7ec Mon Sep 17 00:00:00 2001 From: Tanner Reits Date: Tue, 3 Jan 2023 20:02:36 -0500 Subject: [PATCH 08/18] docs(react-wrapper): add section for creating monorepo & fix headings --- src/docs/framework-integration/react.md | 56 +++++++++++++++++-------- 1 file changed, 39 insertions(+), 17 deletions(-) diff --git a/src/docs/framework-integration/react.md b/src/docs/framework-integration/react.md index fc7667406..a226ec654 100644 --- a/src/docs/framework-integration/react.md +++ b/src/docs/framework-integration/react.md @@ -42,7 +42,44 @@ top-most-directory/ └── index.ts ``` -### Creating a React Component Library +This guide uses Lerna for the monorepo, but you can use other solutions such as Nx, TurboRepo, etc. + +To use Lerna with this walk through, globally install Lerna: + +```bash +npm install --global lerna +# or if you are using yarn +yarn global add lerna +``` + +#### Creating a Monorepo + +> If you already have a monorepo, skip this section. + +```bash +# From your top-most-directory/, initialize a workspace +lerna init + +# install typescript and node types +npm install typescript @types/node --save-dev +# or if you are using yarn +yarn add typescript @types/node --dev +``` + +#### Creating a Stencil Component Library + +> If you already have a Stencil component library, skip this section. + +```bash +npm init stencil components stencil-library +cd stencil-library +# Install dependencies +npm install +# or if using yarn +yarn install +``` + +#### Creating a React Component Library > If you already have a React component library, skip this section. @@ -66,20 +103,7 @@ npm i > If you do rename your React component library, be sure to change the `name` in the `package.json` to match your new name. -#### Creating a Stencil Component Library - -> If you already have a Stencil component library, skip this section. - -```bash -npm init stencil components stencil-library -cd stencil-library -# Install dependencies -npm install -# or if using yarn -yarn install -``` - -### Adding the React Output Target +#### Adding the React Output Target Install the `@stencil/react-output-target` dependency to your Stencil component library package. @@ -90,8 +114,6 @@ npm install @stencil/react-output-target --save-dev yarn add @stencil/react-output-target --dev ``` -### Add the React Wrapper Function to your Stencil Component Library - In your project's `stencil.config.ts`, add the `reactOutputTarget` configuration to the `outputTargets` array: ```ts From 1430e58140ebdecdd29dfa74cb7be42a7290d7ce Mon Sep 17 00:00:00 2001 From: Tanner Reits Date: Wed, 4 Jan 2023 09:06:41 -0500 Subject: [PATCH 09/18] docs(react-wrapper): remove redundant admonishment section --- src/docs/framework-integration/react.md | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/src/docs/framework-integration/react.md b/src/docs/framework-integration/react.md index a226ec654..f9dfbfd07 100644 --- a/src/docs/framework-integration/react.md +++ b/src/docs/framework-integration/react.md @@ -88,20 +88,12 @@ The first time you want to create the component wrappers, you will need to have You can create your own React project using a [recommended toolchain](https://reactjs.org/docs/create-a-new-react-app.html#recommended-toolchains), or by using the [React component library template](https://github.com/ionic-team/stencil-ds-react-template). To use the template, run the following: ```bash -git clone https://github.com/ionic-team/stencil-ds-react-template component-library-react -cd component-library-react -npm i +git clone https://github.com/ionic-team/stencil-ds-react-template {the name of your React component library} +cd {the name of your React component library} +npm i # or yarn install ``` -> **NOTE**: If you want to name your React component library something different, add the new name at the end of the clone command like so: - -> ```bash -> git clone https://github.com/ionic-team/stencil-ds-react-template {the name of your React component library} -> cd {the name of your React component library} -> npm i # or yarn install -> ``` - -> If you do rename your React component library, be sure to change the `name` in the `package.json` to match your new name. +> **NOTE:** Be sure the name in the React project's `package.json` matches the name you used for the project. #### Adding the React Output Target From 3c63979e6864401ca8a96552b7a55eb537868452 Mon Sep 17 00:00:00 2001 From: Tanner Reits Date: Mon, 9 Jan 2023 20:26:12 -0500 Subject: [PATCH 10/18] chore(): PR feedback & misc additions --- src/docs/framework-integration/react.md | 46 ++++++++++++------------- 1 file changed, 22 insertions(+), 24 deletions(-) diff --git a/src/docs/framework-integration/react.md b/src/docs/framework-integration/react.md index f9dfbfd07..f1ba1f673 100644 --- a/src/docs/framework-integration/react.md +++ b/src/docs/framework-integration/react.md @@ -18,9 +18,11 @@ contributors: **Supports: React v16.7+ • TypeScript 3.7+ • Stencil v2.9.0+** -Stencil provides a wrapper for your custom elements to be used as first-class React components. The goal of a wrapper is to easily integrate your Stencil components into a specific framework. Wrappers provide a function that you can use within Stencil’s Output Targets to automatically create components for the targeted framework that wrap the web components you create in a Stencil project. +Stencil can generate React component wrappers for your web components. This allows your Stencil components to be used within +a React application. The benefits of using Stencil's component wrappers over the standard web components include: -One benefit of the wrapper pattern includes improved maintainability since you can write code once, and reuse it across different frameworks. Today, there are some challenges associated with using HTML Custom Elements in a React app. Custom events are not handled properly, as well as properties/attributes that are not a string or number. By using Stencil's component wrappers, you can solve these issues and receive first-class React components. +- Custom events will be handled correctly and correctly propagate through the React render tree +- Properties and attributes that are not a string or number will be correctly bound to the component ## Setup @@ -33,13 +35,14 @@ An example project set-up may look similar to: ``` top-most-directory/ -├── stencil-library/ -│ ├── stencil.config.js -│ └── src/components/ -└── react-library/ - └── src/ - ├── components/ - └── index.ts +└── packages/ + ├── stencil-library/ + │ ├── stencil.config.js + │ └── src/components/ + └── react-library/ + └── src/ + ├── components/ + └── index.ts ``` This guide uses Lerna for the monorepo, but you can use other solutions such as Nx, TurboRepo, etc. @@ -70,8 +73,10 @@ yarn add typescript @types/node --dev > If you already have a Stencil component library, skip this section. +From the `packages` directory, run the following commands to create a Stencil component library: + ```bash -npm init stencil components stencil-library +npm init stencil component stencil-library cd stencil-library # Install dependencies npm install @@ -83,17 +88,12 @@ yarn install > If you already have a React component library, skip this section. -The first time you want to create the component wrappers, you will need to have a Rect library package to write to. - -You can create your own React project using a [recommended toolchain](https://reactjs.org/docs/create-a-new-react-app.html#recommended-toolchains), or by using the [React component library template](https://github.com/ionic-team/stencil-ds-react-template). To use the template, run the following: +The first time you want to create the component wrappers, you will need to have a React library package to write to. -```bash -git clone https://github.com/ionic-team/stencil-ds-react-template {the name of your React component library} -cd {the name of your React component library} -npm i # or yarn install -``` +You can create your own React component library in the `packages` directory using a [toolchain](https://reactjs.org/docs/create-a-new-react-app.html#recommended-toolchains) or from scratch ([this](https://dev.to/alexeagleson/how-to-create-and-publish-a-react-component-library-2oe) guide walks through the entire process). -> **NOTE:** Be sure the name in the React project's `package.json` matches the name you used for the project. +If you are using Lerna (or another monorepo tool), you may also need to update your React library's dependencies to reference the generated Stencil +library. See the Lerna documentation on [package dependency management](https://lerna.js.org/docs/getting-started#package-dependency-management) for more information. If you are not using a monorepo, you may want [link your packages](#link-your-packages-optional) for local development. #### Adding the React Output Target @@ -134,8 +134,6 @@ export const config: Config = { See the [API section below](#api) for details on each of the output target's options. -For details on the `includeDefineCustomElements` option, and all other options, visit the API documentation section below. - You can now build your Stencil component library to generate the component wrappers. ```bash @@ -149,8 +147,6 @@ If the build is successful, you’ll see the new generated file in your React co ### Add the Components to your React Component Library's Entry File -> If you are using Ionic's React template, skip this section. - In order to make the generated files available within your React component library and its consumers, you’ll need to export everything from within your entry file - commonly the `src/index.ts` file. To do this, you’ll write: ```tsx @@ -267,6 +263,8 @@ import { defineCustomElement as defineMyComponent } from 'my-component-lib/compo **Default: 'dist/components'** +**Type: `string`** + If [includeImportCustomElements](#includeimportcustomelements) is `true`, this option can be used to specify the directory where the generated custom elements live. This value only needs to be set if the `dir` field on the `dist-custom-elements` output target was set to something other than the default directory. @@ -300,7 +298,7 @@ If `true`, all Web Components will automatically be registered with the Custom E **Type: `boolean`** -If `true`, the output target will import the custom element instance and register it with the Custom Elements Registry when the component is imported inside of a user's app. This can only be used with the [Custom Elements Bundle](/docs/custom-elements) and will not work with lazy loaded components. +If `true`, the output target will import the custom element instance and register it with the Custom Elements Registry when the component is imported inside of a user's app. This can only be used with the [Custom Elements](/docs/custom-elements) output and will not work with lazy loaded components. ### includePolyfills From 988030da97831d61cb9b0650eebd28d00f6a6e5e Mon Sep 17 00:00:00 2001 From: Tanner Reits Date: Tue, 24 Jan 2023 17:39:13 -0500 Subject: [PATCH 11/18] docs(react-integration): clarify steps, add consumer app section --- src/docs/framework-integration/react.md | 167 ++++++++++++++++++++---- 1 file changed, 145 insertions(+), 22 deletions(-) diff --git a/src/docs/framework-integration/react.md b/src/docs/framework-integration/react.md index f1ba1f673..fce601eab 100644 --- a/src/docs/framework-integration/react.md +++ b/src/docs/framework-integration/react.md @@ -63,20 +63,25 @@ yarn global add lerna # From your top-most-directory/, initialize a workspace lerna init +# install dependencies +npm install +# or if you are using yarn +yarn install + # install typescript and node types npm install typescript @types/node --save-dev # or if you are using yarn -yarn add typescript @types/node --dev +yarn add typescript @types/node --dev -W ``` #### Creating a Stencil Component Library > If you already have a Stencil component library, skip this section. -From the `packages` directory, run the following commands to create a Stencil component library: +From the `packages/` directory, run the following commands to create a Stencil component library: ```bash -npm init stencil component stencil-library +npm init stencil components stencil-library cd stencil-library # Install dependencies npm install @@ -90,10 +95,90 @@ yarn install The first time you want to create the component wrappers, you will need to have a React library package to write to. -You can create your own React component library in the `packages` directory using a [toolchain](https://reactjs.org/docs/create-a-new-react-app.html#recommended-toolchains) or from scratch ([this](https://dev.to/alexeagleson/how-to-create-and-publish-a-react-component-library-2oe) guide walks through the entire process). +Run the following commands from the root directory of your monorepo to create a React component library: -If you are using Lerna (or another monorepo tool), you may also need to update your React library's dependencies to reference the generated Stencil -library. See the Lerna documentation on [package dependency management](https://lerna.js.org/docs/getting-started#package-dependency-management) for more information. If you are not using a monorepo, you may want [link your packages](#link-your-packages-optional) for local development. +```bash +# Create a project +lerna create react-library # fill out the prompts accordingly +cd packages/react-library + +# Install core dependencies +npm install react typescript @types/react --save-dev +# of if using yarn +yarn add react typescript @types/react --dev +``` + +Lerna does not ship with a TypeScript configuration. At the root of the workspace, create a `tsconfig.json`: + +```json +{ + "compilerOptions": { + "module": "commonjs", + "declaration": true, + "noImplicitAny": false, + "removeComments": true, + "noLib": false, + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "target": "es6", + "sourceMap": true, + "lib": ["es6"], + }, + "exclude": ["node_modules", "**/*.spec.ts", "**/__tests__/**"] +} +``` + +In your `react-library` project, create a project specific `tsconfig.json` that will extend the root config: + +```json +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "./dist", + "lib": ["dom", "es2015"], + "module": "es2015", + "moduleResolution": "node", + "target": "es2015", + "skipLibCheck": true, + "jsx": "react", + "allowSyntheticDefaultImports": true, + "declarationDir": "./dist/types" + }, + "include": ["lib"], + "exclude": ["node_modules"] +} +``` + +Update the generated `package.json` in your `react-library`, adding the following options to the existing config: + +```diff +{ +- "main": "lib/react-library.js", ++ "main": "dist/index.js", ++ "module": "dist/index.js", ++ "types": "dist/types/index.d.ts", + "scripts": { +- "test": "test": "node ./__tests__/react-library.test.js" ++ "test": "test": "node ./__tests__/react-library.test.js", ++ "build": "npm run tsc", ++ "tsc": "tsc -p ." +- } ++ }, + "files": [ +- "lib" ++ "dist" + ] ++ "publishConfig": { ++ "access": "public" ++ }, ++ "dependencies": { ++ "stencil-library": "*" ++ } +} +``` + +> **NOTE:** The `stencil-library` dependency is how Lerna knows to resolve the internal Stencil library dependency. See Lerna's documentation on +> [package dependency management](https://lerna.js.org/docs/getting-started#package-dependency-management) for more information. #### Adding the React Output Target @@ -122,8 +207,8 @@ export const config: Config = { type: 'dist', }, reactOutputTarget({ - componentCorePackage: 'your-stencil-library-package-name', - proxiesFile: '../react-library/src/components/stencil-generated/index.ts', + componentCorePackage: 'stencil-library', + proxiesFile: '../react-library/lib/components/stencil-generated/index.ts', }), ], }; @@ -131,6 +216,8 @@ export const config: Config = { > The `proxiesFile` is the relative path to the file that will be generated with all of the React component wrappers. You will replace the > file path to match your project's structure and respective names. You can generate any file name instead of `index.ts`. +> +> The `componentCorePackage` should match the `name` field in your Stencil project's `package.json`. See the [API section below](#api) for details on each of the output target's options. @@ -147,10 +234,22 @@ If the build is successful, you’ll see the new generated file in your React co ### Add the Components to your React Component Library's Entry File -In order to make the generated files available within your React component library and its consumers, you’ll need to export everything from within your entry file - commonly the `src/index.ts` file. To do this, you’ll write: +In order to make the generated files available within your React component library and its consumers, you’ll need to export everything from within your entry file. First, rename `react-library.js` to `index.ts`. Then, modify the contents to match the following: ```tsx -export * from './components'; +export * from './components/stencil-generated'; +``` + +### Registering Custom Elements + +To register your web components for the lazy-loaded (hydrated) bundle, you'll need to expose a method for registering the underlying Stencil +generated custom elements for the React proxy components to leverage. The easiest way to do this is to modify the React library's entry file +to re-export the Stencil loader's `defineCustomElements()` method. In your React library's entry file (`packages/react-library/lib/index.ts`), +add the follow: + +```diff +export * from "./components/stencil-generated"; ++ export { defineCustomElements } from "stencil-library/loader"; ``` ### Link Your Packages (Optional) @@ -186,33 +285,57 @@ changes to the React component library. ## Consumer Usage -This section covers how developers consuming your React component wrappers will use your package and component wrappers. +### Creating a Consumer React App -If you are developing and testing your React component library locally, you'll have to use `npm link` again to make your React component library available in your React application. If your components are published to npm, you can skip this step. +> If you already have a React app, skip this section. -To link your React component library, navigate to your **React component library** and run +From the `packages/` directory, run the following command to create a starter React app: ```bash -npm run build -npm link +# Create the React app +npx create-react-app my-app --template typescript --use-npm +# of if using yarn +npx create-react-app my-app --template typescript +``` + +You'll also need to link your React component library as a dependency. This step makes it so your React app will be able to correctly resolve imports from your React library. This +is easily done by modifying your React app's `project.json` to include the following: + +```json +"dependencies": { + "react-library": "*" +} ``` -To build your React component library and create a symlink to the project. +### Consuming the React Wrapper Components + +This section covers how developers consuming your React component wrappers will use your package and component wrappers. -Navigate to your **React application directory** and run +Before you can consume your React proxy components, you'll need to build your React component library. From `packages/react-library` run: ```bash -npm link {React component library} +yarn run build ``` To make use of your React component library in your React application, import your components from your React component library in the file where you want to use them. ```tsx -// if your React component library has another name, replace 'component-library-react' with that name -import { MyComponent } from 'component-library-react'; -``` +// App.tsx +import './App.css'; +import { MyComponent, defineCustomElements } from 'react-library'; + +defineCustomElements(); + +function App() { + return ( +
+ +
+ ); +} -With that, your component is now available to be used like any other React component. +export default App; +``` ## API From 86d139d0b8ba1de70dc7c16245444c699cf85d53 Mon Sep 17 00:00:00 2001 From: Tanner Reits Date: Thu, 26 Jan 2023 10:00:37 -0500 Subject: [PATCH 12/18] docs(react-integration): update to use docusaurus tools --- src/docs/framework-integration/react.md | 90 +++++++++++++------------ 1 file changed, 46 insertions(+), 44 deletions(-) diff --git a/src/docs/framework-integration/react.md b/src/docs/framework-integration/react.md index fce601eab..15c86e77c 100644 --- a/src/docs/framework-integration/react.md +++ b/src/docs/framework-integration/react.md @@ -49,63 +49,59 @@ This guide uses Lerna for the monorepo, but you can use other solutions such as To use Lerna with this walk through, globally install Lerna: -```bash +```bash npm2yarn npm install --global lerna -# or if you are using yarn -yarn global add lerna ``` #### Creating a Monorepo -> If you already have a monorepo, skip this section. +:::note +If you already have a monorepo, skip this section. +::: -```bash +```bash npm2yarn # From your top-most-directory/, initialize a workspace lerna init # install dependencies npm install -# or if you are using yarn -yarn install # install typescript and node types npm install typescript @types/node --save-dev -# or if you are using yarn -yarn add typescript @types/node --dev -W ``` #### Creating a Stencil Component Library -> If you already have a Stencil component library, skip this section. +:::note +If you already have a Stencil component library, skip this section. +::: From the `packages/` directory, run the following commands to create a Stencil component library: -```bash +```bash npm2yarn npm init stencil components stencil-library cd stencil-library # Install dependencies npm install -# or if using yarn -yarn install ``` #### Creating a React Component Library -> If you already have a React component library, skip this section. +:::note +If you already have a React component library, skip this section. +::: The first time you want to create the component wrappers, you will need to have a React library package to write to. Run the following commands from the root directory of your monorepo to create a React component library: -```bash +```bash npm2yarn # Create a project lerna create react-library # fill out the prompts accordingly cd packages/react-library # Install core dependencies npm install react typescript @types/react --save-dev -# of if using yarn -yarn add react typescript @types/react --dev ``` Lerna does not ship with a TypeScript configuration. At the root of the workspace, create a `tsconfig.json`: @@ -122,7 +118,7 @@ Lerna does not ship with a TypeScript configuration. At the root of the workspac "experimentalDecorators": true, "target": "es6", "sourceMap": true, - "lib": ["es6"], + "lib": ["es6"] }, "exclude": ["node_modules", "**/*.spec.ts", "**/__tests__/**"] } @@ -172,23 +168,23 @@ Update the generated `package.json` in your `react-library`, adding the followin + "access": "public" + }, + "dependencies": { -+ "stencil-library": "*" ++ "stencil-library": "*" + } } ``` -> **NOTE:** The `stencil-library` dependency is how Lerna knows to resolve the internal Stencil library dependency. See Lerna's documentation on -> [package dependency management](https://lerna.js.org/docs/getting-started#package-dependency-management) for more information. +:::note +The `stencil-library` dependency is how Lerna knows to resolve the internal Stencil library dependency. See Lerna's documentation on +[package dependency management](https://lerna.js.org/docs/getting-started#package-dependency-management) for more information. +::: #### Adding the React Output Target Install the `@stencil/react-output-target` dependency to your Stencil component library package. -```bash +```bash npm2yarn # Install dependency npm install @stencil/react-output-target --save-dev -# or if using yarn -yarn add @stencil/react-output-target --dev ``` In your project's `stencil.config.ts`, add the `reactOutputTarget` configuration to the `outputTargets` array: @@ -214,20 +210,20 @@ export const config: Config = { }; ``` -> The `proxiesFile` is the relative path to the file that will be generated with all of the React component wrappers. You will replace the -> file path to match your project's structure and respective names. You can generate any file name instead of `index.ts`. -> -> The `componentCorePackage` should match the `name` field in your Stencil project's `package.json`. +:::tip +The `proxiesFile` is the relative path to the file that will be generated with all of the React component wrappers. You will replace the +file path to match your project's structure and respective names. You can generate any file name instead of `index.ts`. + +The `componentCorePackage` should match the `name` field in your Stencil project's `package.json`. +::: See the [API section below](#api) for details on each of the output target's options. You can now build your Stencil component library to generate the component wrappers. -```bash +```bash npm2yarn # Build the library and wrappers npm run build -# or if using yarn -yarn run build ``` If the build is successful, you’ll see the new generated file in your React component library at the location specified by the `proxiesFile` argument. @@ -254,26 +250,24 @@ export * from "./components/stencil-generated"; ### Link Your Packages (Optional) -> If you are using a monorepo tool (Lerna, Nx, etc.), skip this section. +:::note +If you are using a monorepo tool (Lerna, Nx, etc.), skip this section. +::: Before you can successfully build a local version of your React component library, you will need to link the Stencil package to the React package. From your Stencil project's directory, run the following command: -```bash +```bash npm2yarn # Link the working directory npm link -# or if using yarn -yarn link ``` From your React component library's directory, run the following command: -```bash +```bash npm2yarn # Link the package name npm link name-of-your-stencil-package -# or if using yarn -yarn link name-of-your-stencil-package ``` The name of your Stencil package should match the `name` property from the Stencil component library's `package.json`. @@ -281,13 +275,18 @@ The name of your Stencil package should match the `name` property from the Stenc Your component libraries are now linked together. You can make changes in the Stencil component library and run `npm run build` to propagate the changes to the React component library. -> **NOTE:** As an alternative to `npm link` , you can also run `npm install` with a relative path to your Stencil component library. This strategy, however, will modify your `package.json` so it is important to make sure you do not commit those changes. +:::note +As an alternative to `npm link` , you can also run `npm install` with a relative path to your Stencil component library. This strategy, however, will +modify your `package.json` so it is important to make sure you do not commit those changes. +::: ## Consumer Usage ### Creating a Consumer React App -> If you already have a React app, skip this section. +:::note +If you already have a React app, skip this section. +::: From the `packages/` directory, run the following command to create a starter React app: @@ -313,8 +312,8 @@ This section covers how developers consuming your React component wrappers will Before you can consume your React proxy components, you'll need to build your React component library. From `packages/react-library` run: -```bash -yarn run build +```bash npm2yarn +npm run build ``` To make use of your React component library in your React application, import your components from your React component library in the file where you want to use them. @@ -352,7 +351,7 @@ This is used during compilation to write the correct imports for components. For a starter Stencil project generated by running: -```bash +```bash npm2yarn npm init stencil component my-component-lib ``` @@ -378,7 +377,10 @@ Which would result in an import path like: import { defineCustomElement as defineMyComponent } from 'my-component-lib/components/my-component.js'; ``` -> **NOTE:** Although this field is optional, it is _highly_ recommended that it always be defined to avoid potential issues with paths not being generated correctly when combining other API arguments. +:::note +Although this field is optional, it is _highly_ recommended that it always be defined to avoid potential issues with paths not being generated correctly +when combining other API arguments. +::: ### customElementsDir From 13985476d3518e919a9545f3fb3aef17fef22990 Mon Sep 17 00:00:00 2001 From: Tanner Reits Date: Tue, 31 Jan 2023 18:20:00 -0500 Subject: [PATCH 13/18] docs(react-integration): wordsmith API option description --- docs/framework-integration/react.md | 2 +- versioned_docs/version-v2/framework-integration/react.md | 2 +- versioned_docs/version-v3.0/framework-integration/react.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/framework-integration/react.md b/docs/framework-integration/react.md index 15c86e77c..8b156c6e1 100644 --- a/docs/framework-integration/react.md +++ b/docs/framework-integration/react.md @@ -346,7 +346,7 @@ export default App; **Type: `string`** -The title of the Stencil package where components are available for consumers (i.e. the `name` property value in your Stencil project's `package.json`). +The name of the Stencil package where components are available for consumers (i.e. the value of the `name` property in your Stencil component library's `package.json`). This is used during compilation to write the correct imports for components. For a starter Stencil project generated by running: diff --git a/versioned_docs/version-v2/framework-integration/react.md b/versioned_docs/version-v2/framework-integration/react.md index 15c86e77c..8b156c6e1 100644 --- a/versioned_docs/version-v2/framework-integration/react.md +++ b/versioned_docs/version-v2/framework-integration/react.md @@ -346,7 +346,7 @@ export default App; **Type: `string`** -The title of the Stencil package where components are available for consumers (i.e. the `name` property value in your Stencil project's `package.json`). +The name of the Stencil package where components are available for consumers (i.e. the value of the `name` property in your Stencil component library's `package.json`). This is used during compilation to write the correct imports for components. For a starter Stencil project generated by running: diff --git a/versioned_docs/version-v3.0/framework-integration/react.md b/versioned_docs/version-v3.0/framework-integration/react.md index 15c86e77c..8b156c6e1 100644 --- a/versioned_docs/version-v3.0/framework-integration/react.md +++ b/versioned_docs/version-v3.0/framework-integration/react.md @@ -346,7 +346,7 @@ export default App; **Type: `string`** -The title of the Stencil package where components are available for consumers (i.e. the `name` property value in your Stencil project's `package.json`). +The name of the Stencil package where components are available for consumers (i.e. the value of the `name` property in your Stencil component library's `package.json`). This is used during compilation to write the correct imports for components. For a starter Stencil project generated by running: From 5248d85c4a6437dac87d6576ddee101d2672468b Mon Sep 17 00:00:00 2001 From: Tanner Reits Date: Tue, 31 Jan 2023 18:23:47 -0500 Subject: [PATCH 14/18] fix(): restore docusaurus page metadata --- docs/framework-integration/react.md | 3 ++- versioned_docs/version-v2/framework-integration/react.md | 3 ++- versioned_docs/version-v3.0/framework-integration/react.md | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/docs/framework-integration/react.md b/docs/framework-integration/react.md index 8b156c6e1..b093ffbd0 100644 --- a/docs/framework-integration/react.md +++ b/docs/framework-integration/react.md @@ -1,7 +1,8 @@ --- title: React Integration with Stencil +sidebar_label: React description: Learn how to wrap your components so that people can use them natively in React -url: /docs/react +slug: /react contributors: - jthoms1 - adamdbradley diff --git a/versioned_docs/version-v2/framework-integration/react.md b/versioned_docs/version-v2/framework-integration/react.md index 8b156c6e1..b093ffbd0 100644 --- a/versioned_docs/version-v2/framework-integration/react.md +++ b/versioned_docs/version-v2/framework-integration/react.md @@ -1,7 +1,8 @@ --- title: React Integration with Stencil +sidebar_label: React description: Learn how to wrap your components so that people can use them natively in React -url: /docs/react +slug: /react contributors: - jthoms1 - adamdbradley diff --git a/versioned_docs/version-v3.0/framework-integration/react.md b/versioned_docs/version-v3.0/framework-integration/react.md index 8b156c6e1..b093ffbd0 100644 --- a/versioned_docs/version-v3.0/framework-integration/react.md +++ b/versioned_docs/version-v3.0/framework-integration/react.md @@ -1,7 +1,8 @@ --- title: React Integration with Stencil +sidebar_label: React description: Learn how to wrap your components so that people can use them natively in React -url: /docs/react +slug: /react contributors: - jthoms1 - adamdbradley From 140d233759cea1c2fb1a15520e469776d1a61f04 Mon Sep 17 00:00:00 2001 From: Tanner Reits Date: Tue, 14 Feb 2023 18:11:54 -0500 Subject: [PATCH 15/18] PR feedback --- docs/framework-integration/react.md | 5 +++-- versioned_docs/version-v2/framework-integration/react.md | 5 +++-- versioned_docs/version-v3.0/framework-integration/react.md | 5 +++-- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/docs/framework-integration/react.md b/docs/framework-integration/react.md index b093ffbd0..5b32daaf0 100644 --- a/docs/framework-integration/react.md +++ b/docs/framework-integration/react.md @@ -102,7 +102,7 @@ lerna create react-library # fill out the prompts accordingly cd packages/react-library # Install core dependencies -npm install react typescript @types/react --save-dev +npm install react react-dom typescript @types/react --save-dev ``` Lerna does not ship with a TypeScript configuration. At the root of the workspace, create a `tsconfig.json`: @@ -202,6 +202,7 @@ export const config: Config = { // React target { type: 'dist', + esmLoaderPath: '../loader', }, reactOutputTarget({ componentCorePackage: 'stencil-library', @@ -299,7 +300,7 @@ npx create-react-app my-app --template typescript ``` You'll also need to link your React component library as a dependency. This step makes it so your React app will be able to correctly resolve imports from your React library. This -is easily done by modifying your React app's `project.json` to include the following: +is easily done by modifying your React app's `package.json` to include the following: ```json "dependencies": { diff --git a/versioned_docs/version-v2/framework-integration/react.md b/versioned_docs/version-v2/framework-integration/react.md index b093ffbd0..5b32daaf0 100644 --- a/versioned_docs/version-v2/framework-integration/react.md +++ b/versioned_docs/version-v2/framework-integration/react.md @@ -102,7 +102,7 @@ lerna create react-library # fill out the prompts accordingly cd packages/react-library # Install core dependencies -npm install react typescript @types/react --save-dev +npm install react react-dom typescript @types/react --save-dev ``` Lerna does not ship with a TypeScript configuration. At the root of the workspace, create a `tsconfig.json`: @@ -202,6 +202,7 @@ export const config: Config = { // React target { type: 'dist', + esmLoaderPath: '../loader', }, reactOutputTarget({ componentCorePackage: 'stencil-library', @@ -299,7 +300,7 @@ npx create-react-app my-app --template typescript ``` You'll also need to link your React component library as a dependency. This step makes it so your React app will be able to correctly resolve imports from your React library. This -is easily done by modifying your React app's `project.json` to include the following: +is easily done by modifying your React app's `package.json` to include the following: ```json "dependencies": { diff --git a/versioned_docs/version-v3.0/framework-integration/react.md b/versioned_docs/version-v3.0/framework-integration/react.md index b093ffbd0..5b32daaf0 100644 --- a/versioned_docs/version-v3.0/framework-integration/react.md +++ b/versioned_docs/version-v3.0/framework-integration/react.md @@ -102,7 +102,7 @@ lerna create react-library # fill out the prompts accordingly cd packages/react-library # Install core dependencies -npm install react typescript @types/react --save-dev +npm install react react-dom typescript @types/react --save-dev ``` Lerna does not ship with a TypeScript configuration. At the root of the workspace, create a `tsconfig.json`: @@ -202,6 +202,7 @@ export const config: Config = { // React target { type: 'dist', + esmLoaderPath: '../loader', }, reactOutputTarget({ componentCorePackage: 'stencil-library', @@ -299,7 +300,7 @@ npx create-react-app my-app --template typescript ``` You'll also need to link your React component library as a dependency. This step makes it so your React app will be able to correctly resolve imports from your React library. This -is easily done by modifying your React app's `project.json` to include the following: +is easily done by modifying your React app's `package.json` to include the following: ```json "dependencies": { From 4d88bc3a9b31d628edce650bdb62cbb66793c77d Mon Sep 17 00:00:00 2001 From: Tanner Reits Date: Tue, 14 Feb 2023 18:19:13 -0500 Subject: [PATCH 16/18] remove usage of `create-react-app` --- docs/framework-integration/react.md | 16 +++++++++++++--- .../version-v2/framework-integration/react.md | 16 +++++++++++++--- .../version-v3.0/framework-integration/react.md | 16 +++++++++++++--- 3 files changed, 39 insertions(+), 9 deletions(-) diff --git a/docs/framework-integration/react.md b/docs/framework-integration/react.md index 5b32daaf0..99ea37e70 100644 --- a/docs/framework-integration/react.md +++ b/docs/framework-integration/react.md @@ -290,13 +290,23 @@ modify your `package.json` so it is important to make sure you do not commit tho If you already have a React app, skip this section. ::: -From the `packages/` directory, run the following command to create a starter React app: +From the `packages/` directory, run the following commands to create a starter React app: + + + ```bash # Create the React app -npx create-react-app my-app --template typescript --use-npm +npm create vite@latest my-app -- --template react-ts # of if using yarn -npx create-react-app my-app --template typescript +yarn create vite my-app --template react-ts + +cd ./my-app + +# install dependencies +npm install +# or if using yarn +yarn install ``` You'll also need to link your React component library as a dependency. This step makes it so your React app will be able to correctly resolve imports from your React library. This diff --git a/versioned_docs/version-v2/framework-integration/react.md b/versioned_docs/version-v2/framework-integration/react.md index 5b32daaf0..99ea37e70 100644 --- a/versioned_docs/version-v2/framework-integration/react.md +++ b/versioned_docs/version-v2/framework-integration/react.md @@ -290,13 +290,23 @@ modify your `package.json` so it is important to make sure you do not commit tho If you already have a React app, skip this section. ::: -From the `packages/` directory, run the following command to create a starter React app: +From the `packages/` directory, run the following commands to create a starter React app: + + + ```bash # Create the React app -npx create-react-app my-app --template typescript --use-npm +npm create vite@latest my-app -- --template react-ts # of if using yarn -npx create-react-app my-app --template typescript +yarn create vite my-app --template react-ts + +cd ./my-app + +# install dependencies +npm install +# or if using yarn +yarn install ``` You'll also need to link your React component library as a dependency. This step makes it so your React app will be able to correctly resolve imports from your React library. This diff --git a/versioned_docs/version-v3.0/framework-integration/react.md b/versioned_docs/version-v3.0/framework-integration/react.md index 5b32daaf0..99ea37e70 100644 --- a/versioned_docs/version-v3.0/framework-integration/react.md +++ b/versioned_docs/version-v3.0/framework-integration/react.md @@ -290,13 +290,23 @@ modify your `package.json` so it is important to make sure you do not commit tho If you already have a React app, skip this section. ::: -From the `packages/` directory, run the following command to create a starter React app: +From the `packages/` directory, run the following commands to create a starter React app: + + + ```bash # Create the React app -npx create-react-app my-app --template typescript --use-npm +npm create vite@latest my-app -- --template react-ts # of if using yarn -npx create-react-app my-app --template typescript +yarn create vite my-app --template react-ts + +cd ./my-app + +# install dependencies +npm install +# or if using yarn +yarn install ``` You'll also need to link your React component library as a dependency. This step makes it so your React app will be able to correctly resolve imports from your React library. This From 51dedb5711351fa568a8fb49f377c7898b23e3af Mon Sep 17 00:00:00 2001 From: Tanner Reits Date: Wed, 15 Feb 2023 17:54:33 -0500 Subject: [PATCH 17/18] update section heading level --- docs/framework-integration/react.md | 2 +- versioned_docs/version-v2/framework-integration/react.md | 2 +- versioned_docs/version-v3.0/framework-integration/react.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/framework-integration/react.md b/docs/framework-integration/react.md index 99ea37e70..fa78b5115 100644 --- a/docs/framework-integration/react.md +++ b/docs/framework-integration/react.md @@ -179,7 +179,7 @@ The `stencil-library` dependency is how Lerna knows to resolve the internal Sten [package dependency management](https://lerna.js.org/docs/getting-started#package-dependency-management) for more information. ::: -#### Adding the React Output Target +### Adding the React Output Target Install the `@stencil/react-output-target` dependency to your Stencil component library package. diff --git a/versioned_docs/version-v2/framework-integration/react.md b/versioned_docs/version-v2/framework-integration/react.md index 99ea37e70..fa78b5115 100644 --- a/versioned_docs/version-v2/framework-integration/react.md +++ b/versioned_docs/version-v2/framework-integration/react.md @@ -179,7 +179,7 @@ The `stencil-library` dependency is how Lerna knows to resolve the internal Sten [package dependency management](https://lerna.js.org/docs/getting-started#package-dependency-management) for more information. ::: -#### Adding the React Output Target +### Adding the React Output Target Install the `@stencil/react-output-target` dependency to your Stencil component library package. diff --git a/versioned_docs/version-v3.0/framework-integration/react.md b/versioned_docs/version-v3.0/framework-integration/react.md index 99ea37e70..fa78b5115 100644 --- a/versioned_docs/version-v3.0/framework-integration/react.md +++ b/versioned_docs/version-v3.0/framework-integration/react.md @@ -179,7 +179,7 @@ The `stencil-library` dependency is how Lerna knows to resolve the internal Sten [package dependency management](https://lerna.js.org/docs/getting-started#package-dependency-management) for more information. ::: -#### Adding the React Output Target +### Adding the React Output Target Install the `@stencil/react-output-target` dependency to your Stencil component library package. From 1bd790935b090f5bc8d21d68ffdd33629cc73286 Mon Sep 17 00:00:00 2001 From: Tanner Reits Date: Tue, 21 Feb 2023 14:46:58 -0500 Subject: [PATCH 18/18] PR feedback --- docs/framework-integration/react.md | 11 ++++++----- .../version-v2/framework-integration/react.md | 11 ++++++----- .../version-v3.0/framework-integration/react.md | 11 ++++++----- 3 files changed, 18 insertions(+), 15 deletions(-) diff --git a/docs/framework-integration/react.md b/docs/framework-integration/react.md index fa78b5115..5dd18875d 100644 --- a/docs/framework-integration/react.md +++ b/docs/framework-integration/react.md @@ -243,7 +243,7 @@ export * from './components/stencil-generated'; To register your web components for the lazy-loaded (hydrated) bundle, you'll need to expose a method for registering the underlying Stencil generated custom elements for the React proxy components to leverage. The easiest way to do this is to modify the React library's entry file to re-export the Stencil loader's `defineCustomElements()` method. In your React library's entry file (`packages/react-library/lib/index.ts`), -add the follow: +add the following: ```diff export * from "./components/stencil-generated"; @@ -277,7 +277,7 @@ The name of your Stencil package should match the `name` property from the Stenc Your component libraries are now linked together. You can make changes in the Stencil component library and run `npm run build` to propagate the changes to the React component library. -:::note +:::tip As an alternative to `npm link` , you can also run `npm install` with a relative path to your Stencil component library. This strategy, however, will modify your `package.json` so it is important to make sure you do not commit those changes. ::: @@ -415,7 +415,7 @@ the default directory. **Type: `string[]`** This lets you specify component tag names for which you don't want to generate React wrapper components. This is useful if you need to write framework-specific versions of components. For instance, in Ionic Framework, this is used for routing components - like tabs - so that -Ionic Framework can integrate better with React's Router. +Ionic Framework can integrate better with React Router. ### includeDefineCustomElements @@ -498,7 +498,7 @@ Now, all generated imports will point to the default directory for the custom el using the `dir` property for `dist-custom-elements`, you need to also specify that directory for the React output target. See [the API section](#customelementsdir) for more information. -In addition, all the Web Component will be automatically defined as the generated component modules are bootstrapped. +In addition, all the Web Components will be automatically defined as the generated component modules are bootstrapped. ### What is the best format to write event names? @@ -506,7 +506,8 @@ Event names shouldn’t include special characters when initially written in Ste ### How do I add IE11 or Edge support? -If you want your custom elements to be able to work on older browsers, you should add the `applyPolyfills()` that surround the `defineCustomElements()` function. +If you want your custom elements to work on older browsers, you should call the `applyPolyfills()` function before `defineCustomCustomElements()`. +`applyPolyfills()` returns a `Promise`, so you could call it like this: ```tsx import { applyPolyfills, defineCustomElements } from 'test-components/loader'; diff --git a/versioned_docs/version-v2/framework-integration/react.md b/versioned_docs/version-v2/framework-integration/react.md index fa78b5115..5dd18875d 100644 --- a/versioned_docs/version-v2/framework-integration/react.md +++ b/versioned_docs/version-v2/framework-integration/react.md @@ -243,7 +243,7 @@ export * from './components/stencil-generated'; To register your web components for the lazy-loaded (hydrated) bundle, you'll need to expose a method for registering the underlying Stencil generated custom elements for the React proxy components to leverage. The easiest way to do this is to modify the React library's entry file to re-export the Stencil loader's `defineCustomElements()` method. In your React library's entry file (`packages/react-library/lib/index.ts`), -add the follow: +add the following: ```diff export * from "./components/stencil-generated"; @@ -277,7 +277,7 @@ The name of your Stencil package should match the `name` property from the Stenc Your component libraries are now linked together. You can make changes in the Stencil component library and run `npm run build` to propagate the changes to the React component library. -:::note +:::tip As an alternative to `npm link` , you can also run `npm install` with a relative path to your Stencil component library. This strategy, however, will modify your `package.json` so it is important to make sure you do not commit those changes. ::: @@ -415,7 +415,7 @@ the default directory. **Type: `string[]`** This lets you specify component tag names for which you don't want to generate React wrapper components. This is useful if you need to write framework-specific versions of components. For instance, in Ionic Framework, this is used for routing components - like tabs - so that -Ionic Framework can integrate better with React's Router. +Ionic Framework can integrate better with React Router. ### includeDefineCustomElements @@ -498,7 +498,7 @@ Now, all generated imports will point to the default directory for the custom el using the `dir` property for `dist-custom-elements`, you need to also specify that directory for the React output target. See [the API section](#customelementsdir) for more information. -In addition, all the Web Component will be automatically defined as the generated component modules are bootstrapped. +In addition, all the Web Components will be automatically defined as the generated component modules are bootstrapped. ### What is the best format to write event names? @@ -506,7 +506,8 @@ Event names shouldn’t include special characters when initially written in Ste ### How do I add IE11 or Edge support? -If you want your custom elements to be able to work on older browsers, you should add the `applyPolyfills()` that surround the `defineCustomElements()` function. +If you want your custom elements to work on older browsers, you should call the `applyPolyfills()` function before `defineCustomCustomElements()`. +`applyPolyfills()` returns a `Promise`, so you could call it like this: ```tsx import { applyPolyfills, defineCustomElements } from 'test-components/loader'; diff --git a/versioned_docs/version-v3.0/framework-integration/react.md b/versioned_docs/version-v3.0/framework-integration/react.md index fa78b5115..5dd18875d 100644 --- a/versioned_docs/version-v3.0/framework-integration/react.md +++ b/versioned_docs/version-v3.0/framework-integration/react.md @@ -243,7 +243,7 @@ export * from './components/stencil-generated'; To register your web components for the lazy-loaded (hydrated) bundle, you'll need to expose a method for registering the underlying Stencil generated custom elements for the React proxy components to leverage. The easiest way to do this is to modify the React library's entry file to re-export the Stencil loader's `defineCustomElements()` method. In your React library's entry file (`packages/react-library/lib/index.ts`), -add the follow: +add the following: ```diff export * from "./components/stencil-generated"; @@ -277,7 +277,7 @@ The name of your Stencil package should match the `name` property from the Stenc Your component libraries are now linked together. You can make changes in the Stencil component library and run `npm run build` to propagate the changes to the React component library. -:::note +:::tip As an alternative to `npm link` , you can also run `npm install` with a relative path to your Stencil component library. This strategy, however, will modify your `package.json` so it is important to make sure you do not commit those changes. ::: @@ -415,7 +415,7 @@ the default directory. **Type: `string[]`** This lets you specify component tag names for which you don't want to generate React wrapper components. This is useful if you need to write framework-specific versions of components. For instance, in Ionic Framework, this is used for routing components - like tabs - so that -Ionic Framework can integrate better with React's Router. +Ionic Framework can integrate better with React Router. ### includeDefineCustomElements @@ -498,7 +498,7 @@ Now, all generated imports will point to the default directory for the custom el using the `dir` property for `dist-custom-elements`, you need to also specify that directory for the React output target. See [the API section](#customelementsdir) for more information. -In addition, all the Web Component will be automatically defined as the generated component modules are bootstrapped. +In addition, all the Web Components will be automatically defined as the generated component modules are bootstrapped. ### What is the best format to write event names? @@ -506,7 +506,8 @@ Event names shouldn’t include special characters when initially written in Ste ### How do I add IE11 or Edge support? -If you want your custom elements to be able to work on older browsers, you should add the `applyPolyfills()` that surround the `defineCustomElements()` function. +If you want your custom elements to work on older browsers, you should call the `applyPolyfills()` function before `defineCustomCustomElements()`. +`applyPolyfills()` returns a `Promise`, so you could call it like this: ```tsx import { applyPolyfills, defineCustomElements } from 'test-components/loader';