Skip to content

Commit 0de75af

Browse files
feat(custom-elements): add experimental custom elements build (#22863)
Co-authored-by: Liam DeBeasi <[email protected]>
1 parent 19d63f6 commit 0de75af

File tree

61 files changed

+7258
-9441
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

61 files changed

+7258
-9441
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,10 @@ prerender-static.html
5959
angular/css/
6060
packages/react/css/
6161
packages/vue/css/
62+
core/components/
6263
core/css/
6364
core/hydrate/
6465
core/loader/
6566
core/www/
6667
.stencil/
6768
angular/build/
68-
core/components/

.scripts/common.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ const rootDir = path.join(__dirname, '../');
1010

1111
const packages = [
1212
'core',
13+
'core/components',
1314
'docs',
1415
'angular',
1516
'packages/react',

.scripts/test-dist.js

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,25 @@ const fs = require('fs');
77
[
88
// core
99
{
10-
files: ['../core/dist/index.js', '../core/dist/ionic/index.esm.js']
10+
files: [
11+
'../core/css/core.css',
12+
'../core/css/core.css.map',
13+
'../core/css/normalize.css',
14+
'../core/css/normalize.css.map',
15+
'../core/components/index.js',
16+
'../core/components/index.d.ts',
17+
'../core/components/package.json',
18+
'../core/dist/index.js',
19+
'../core/dist/ionic/index.esm.js',
20+
]
21+
},
22+
// hydrate
23+
{
24+
files: [
25+
'../core/hydrate/index.js',
26+
'../core/hydrate/index.d.ts',
27+
'../core/hydrate/package.json'
28+
]
1129
},
1230
// angular
1331
{

angular/src/directives/navigation/ion-router-outlet.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { Location } from '@angular/common';
22
import { Attribute, ComponentFactoryResolver, ComponentRef, Directive, ElementRef, EventEmitter, Injector, NgZone, OnDestroy, OnInit, Optional, Output, SkipSelf, ViewContainerRef } from '@angular/core';
33
import { ActivatedRoute, ChildrenOutletContexts, OutletContext, PRIMARY_OUTLET, Router } from '@angular/router';
4+
import { componentOnReady } from '@ionic/core';
45
import { BehaviorSubject, Observable } from 'rxjs';
56
import { distinctUntilChanged, filter, switchMap } from 'rxjs/operators';
67

@@ -96,13 +97,12 @@ export class IonRouterOutlet implements OnDestroy, OnInit {
9697
this.activateWith(context.route, context.resolver || null);
9798
}
9899
}
99-
if ((this.nativeEl as any).componentOnReady) {
100-
this.nativeEl.componentOnReady().then(() => {
101-
if (this._swipeGesture === undefined) {
102-
this.swipeGesture = this.config.getBoolean('swipeBackEnabled', (this.nativeEl as any).mode === 'ios');
103-
}
104-
});
105-
}
100+
101+
new Promise(resolve => componentOnReady(this.nativeEl, resolve)).then(() => {
102+
if (this._swipeGesture === undefined) {
103+
this.swipeGesture = this.config.getBoolean('swipeBackEnabled', (this.nativeEl as any).mode === 'ios');
104+
}
105+
});
106106
}
107107

108108
get isActivated(): boolean {

angular/src/directives/proxies.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -278,8 +278,8 @@ export class IonHeader {
278278
}
279279
export declare interface IonIcon extends Components.IonIcon {
280280
}
281-
@ProxyCmp({ inputs: ["ariaLabel", "color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "size", "src"] })
282-
@Component({ selector: "ion-icon", changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-content></ng-content>", inputs: ["ariaLabel", "color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "size", "src"] })
281+
@ProxyCmp({ inputs: ["ariaHidden", "ariaLabel", "color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] })
282+
@Component({ selector: "ion-icon", changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-content></ng-content>", inputs: ["ariaHidden", "ariaLabel", "color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] })
283283
export class IonIcon {
284284
protected el: HTMLElement;
285285
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {

angular/src/types/interfaces.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,6 @@ export interface IonicWindow extends Window {
1010
}
1111

1212
export interface HTMLStencilElement extends HTMLElement {
13-
componentOnReady(): Promise<this>;
14-
forceUpdate(): void;
13+
componentOnReady?(): Promise<this>;
14+
forceUpdate?(): void;
1515
}

core/README.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,24 @@ The `@ionic/core` package can by used in simple HTML, or by vanilla JavaScript w
4040
* [@ionic/angular](https://www.npmjs.com/package/@ionic/angular)
4141

4242

43+
## Custom Elements Build (Experimental)
44+
45+
In addition to the default, self lazy-loading components built by Stencil, this package also comes with each component exported as a stand-alone custom element within `@ionic/core/components`. Each component extends `HTMLElement`, and does not lazy-load itself. Instead, this package is useful for projects already using a bundler such as Webpack or Rollup. While all components are available to be imported, the custom elements build also ensures bundlers only import what's used, and tree-shakes any unused components.
46+
47+
Below is an example of importing `ion-toggle`, and initializing Ionic so it's able to correctly load the "mode", such as Material Design or iOS. Additionally, the `initialize({...})` function can receive the Ionic config.
48+
49+
```typescript
50+
import { IonBadge } from "@ionic/core/components/ion-badge";
51+
import { initialize } from "@ionic/core/components";
52+
53+
initialize();
54+
55+
customElements.define("ion-badge", IonBadge);
56+
```
57+
58+
Notice how `IonBadge` is imported from `@ionic/core/components/ion-badge` rather than just `@ionic/core/components`. Additionally, the `initialize` function is imported from `@ionic/core/components` rather than `@ionic/core`. All of this helps to ensure bundlers do not pull in more code than is needed.
59+
60+
4361
## How to contribute
4462

4563
[Check out the CONTRIBUTE guide](CONTRIBUTING.md)

0 commit comments

Comments
 (0)