@blotch/angular-lynx 0.0.0-stage → 22.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,3 +1,182 @@
1
- # Temporary Holding Version
1
+ # @blotch/angular-lynx
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Angular renderer for [Lynx](https://lynxjs.org/). Write Angular components, render to native iOS, Android, and Web via the Lynx engine.
4
+
5
+ ## Quick Start
6
+
7
+ ```bash
8
+ npm create angular-lynx my-app
9
+ ```
10
+
11
+ Or add to an existing Angular project:
12
+
13
+ ```bash
14
+ ng add @blotch/angular-lynx
15
+ ```
16
+
17
+ ## Features
18
+
19
+ - Standalone components with signals, `@if`/`@for`/`@switch`, DI, and pipes
20
+ - Zoneless change detection — signals as the primary reactivity model
21
+ - Full Angular Router with in-memory navigation for Lynx
22
+ - Gestures — tap, pan, long-press, fling, pinch, rotation with composition
23
+ - Animations — CSS transitions, keyframes, and programmatic `animate()` API
24
+ - Content projection, portals, `@defer`, and lazy-loaded routes
25
+ - Tailwind CSS via `@lynx-js/tailwind-preset`
26
+
27
+ ## Documentation
28
+
29
+ Full docs and guides at [angularlynx.dev](https://angularlynx.dev).
30
+
31
+ ---
32
+
33
+ ## Animation API
34
+
35
+ Three animation approaches are available, all running natively on the Lynx engine.
36
+
37
+ ### CSS Transitions
38
+
39
+ Apply `transition` in your stylesheet. Lynx interpolates property changes automatically.
40
+
41
+ ```css
42
+ .box {
43
+ background-color: #6200ee;
44
+ transition: background-color 0.5s ease-in-out;
45
+ }
46
+
47
+ .box-active {
48
+ background-color: #03dac6;
49
+ }
50
+ ```
51
+
52
+ ```html
53
+ <view class="box" [class.box-active]="isActive()" (bindtap)="toggle()">
54
+ <text>Tap me</text>
55
+ </view>
56
+ ```
57
+
58
+ ### CSS Keyframe Animations
59
+
60
+ Define `@keyframes` in your stylesheet and apply via class toggle.
61
+
62
+ ```css
63
+ @keyframes rotate {
64
+ 0% {
65
+ transform: rotate(0deg);
66
+ }
67
+ 100% {
68
+ transform: rotate(360deg);
69
+ }
70
+ }
71
+
72
+ .spinning {
73
+ animation: rotate 2s linear infinite;
74
+ }
75
+ ```
76
+
77
+ ```html
78
+ <view class="box" [class.spinning]="spin()">
79
+ <text>Rotating</text>
80
+ </view>
81
+ ```
82
+
83
+ ### JavaScript Animate API
84
+
85
+ Use `element.animate()` on a native element reference for programmatic control. Calls the Lynx `__ElementAnimate` PAPI under the hood.
86
+
87
+ ```typescript
88
+ import { Component, viewChild, type ElementRef } from '@angular/core';
89
+ import { type LynxAnimation } from '@blotch/angular-lynx';
90
+
91
+ @Component({
92
+ selector: 'app-example',
93
+ template: `
94
+ <view #box class="box" (bindtap)="runAnimation()">
95
+ <text>Tap to animate</text>
96
+ </view>
97
+ `,
98
+ })
99
+ export class ExampleComponent {
100
+ boxRef = viewChild<ElementRef>('box');
101
+ #animation: LynxAnimation | null = null;
102
+
103
+ runAnimation(): void {
104
+ setTimeout(() => {
105
+ const el = this.boxRef();
106
+ if (!el) return;
107
+
108
+ // Cancel previous animation before starting a new one.
109
+ this.#animation?.cancel();
110
+
111
+ this.#animation = el.nativeElement.animate(
112
+ [
113
+ { transform: 'scale(1)', opacity: 1 },
114
+ { transform: 'scale(1.3)', opacity: 0.7 },
115
+ { transform: 'scale(1)', opacity: 1 },
116
+ ],
117
+ {
118
+ duration: 600,
119
+ easing: 'ease-in-out',
120
+ },
121
+ );
122
+ }, 0);
123
+ }
124
+ }
125
+ ```
126
+
127
+ #### `animate()` API
128
+
129
+ ```typescript
130
+ element.nativeElement.animate(
131
+ keyframes: Record<string, string | number>[],
132
+ options?: number | LynxAnimationOptions,
133
+ ): LynxAnimation
134
+ ```
135
+
136
+ **Parameters:**
137
+
138
+ | Parameter | Type | Description |
139
+ | ----------- | ------------------------------------ | ------------------------------------------------------------------------- |
140
+ | `keyframes` | `Record<string, string \| number>[]` | Array of keyframe objects. Each object maps CSS property names to values. |
141
+ | `options` | `number \| LynxAnimationOptions` | Duration in ms (shorthand) or full options object. |
142
+
143
+ **`LynxAnimationOptions`:**
144
+
145
+ | Option | Type | Description |
146
+ | ------------------------------- | ------------------ | -------------------------------------------------------------------------------------- |
147
+ | `duration` | `number \| string` | Animation duration in milliseconds. |
148
+ | `delay` | `number \| string` | Delay before animation starts. |
149
+ | `iterations` / `iterationCount` | `number \| string` | Number of repetitions. Use `Infinity` for infinite. |
150
+ | `easing` / `timingFunction` | `string` | Easing function (`linear`, `ease-in`, `ease-out`, `ease-in-out`, `cubic-bezier(...)`). |
151
+ | `fill` / `fillMode` | `string` | How styles persist after animation (`none`, `forwards`, `backwards`, `both`). |
152
+ | `direction` | `string` | Play direction (`normal`, `reverse`, `alternate`, `alternate-reverse`). |
153
+ | `name` | `string` | Optional animation name (auto-generated if omitted). |
154
+
155
+ **Returns:** `LynxAnimation` with control methods:
156
+
157
+ | Method | Description |
158
+ | ---------- | ---------------------------------- |
159
+ | `play()` | Resume a paused animation. |
160
+ | `pause()` | Pause the animation. |
161
+ | `cancel()` | Cancel and clean up the animation. |
162
+
163
+ #### Animation Events
164
+
165
+ Lynx fires standard animation events on elements. Listen in templates using bind-prefixed event names:
166
+
167
+ ```html
168
+ <view
169
+ class="animated-box"
170
+ (bindanimationend)="onAnimationEnd($event)"
171
+ (bindtransitionend)="onTransitionEnd($event)"
172
+ >
173
+ <text>Animated</text>
174
+ </view>
175
+ ```
176
+
177
+ Available events: `animationstart`, `animationend`, `animationcancel`, `animationiteration`, `transitionstart`, `transitionend`, `transitioncancel`.
178
+
179
+ #### Important Notes
180
+
181
+ - The `animate()` API is **main-thread only**. Calling it on the background thread throws an error.
182
+ - Wrap `animate()` calls inside `setTimeout(() => { ... }, 0)` when triggered from Lynx event callbacks to avoid mutating the element tree inside a worklet.
package/package.json CHANGED
@@ -1,6 +1,53 @@
1
1
  {
2
2
  "name": "@blotch/angular-lynx",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
3
+ "version": "22.2.0",
4
+ "description": "Angular renderer for the Lynx cross-platform native UI framework",
5
+ "homepage": "https://github.com/Blotch-Smart-Frames/AngularLynx#readme",
6
+ "bugs": {
7
+ "url": "https://github.com/Blotch-Smart-Frames/AngularLynx/issues"
8
+ },
9
+ "license": "MIT",
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "git+https://github.com/Blotch-Smart-Frames/AngularLynx.git",
13
+ "directory": "packages/runtime"
14
+ },
15
+ "files": [
16
+ "dist",
17
+ "schematics",
18
+ "README.md"
19
+ ],
20
+ "sideEffects": false,
21
+ "exports": {
22
+ "./package.json": {
23
+ "default": "./package.json"
24
+ },
25
+ ".": {
26
+ "types": "./types/blotch-angular-lynx.d.ts",
27
+ "default": "./fesm2022/blotch-angular-lynx.mjs"
28
+ }
29
+ },
30
+ "dependencies": {
31
+ "tslib": "^2.3.0"
32
+ },
33
+ "peerDependencies": {
34
+ "@angular/common": "^22.2.0",
35
+ "@angular/core": "^22.2.0",
36
+ "@angular/forms": "^22.2.0",
37
+ "@angular/localize": "^22.2.0",
38
+ "@angular/platform-browser": "^22.2.0",
39
+ "@angular/router": "^22.2.0"
40
+ },
41
+ "peerDependenciesMeta": {
42
+ "@angular/forms": {
43
+ "optional": true
44
+ },
45
+ "@angular/localize": {
46
+ "optional": true
47
+ }
48
+ },
49
+ "schematics": "./schematics/collection.json",
50
+ "module": "fesm2022/blotch-angular-lynx.mjs",
51
+ "typings": "types/blotch-angular-lynx.d.ts",
52
+ "type": "module"
6
53
  }
@@ -0,0 +1,18 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema",
3
+ "$id": "SchematicsAngularLynxAddI18n",
4
+ "title": "AngularLynx add-i18n schematic",
5
+ "type": "object",
6
+ "additionalProperties": false,
7
+ "description": "Adds Angular i18n support with @angular/localize and provideLocale() to an existing project.",
8
+ "properties": {
9
+ "project": {
10
+ "type": "string",
11
+ "description": "The name of the project to add i18n support to.",
12
+ "$default": {
13
+ "$source": "projectName"
14
+ }
15
+ }
16
+ },
17
+ "required": []
18
+ }
@@ -0,0 +1,18 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema",
3
+ "$id": "SchematicsAngularLynxAddTailwind",
4
+ "title": "AngularLynx add-tailwind schematic",
5
+ "type": "object",
6
+ "additionalProperties": false,
7
+ "description": "Adds Tailwind CSS with @lynx-js/tailwind-preset to an existing AngularLynx project.",
8
+ "properties": {
9
+ "project": {
10
+ "type": "string",
11
+ "description": "The name of the project to add Tailwind CSS to.",
12
+ "$default": {
13
+ "$source": "projectName"
14
+ }
15
+ }
16
+ },
17
+ "required": []
18
+ }
@@ -0,0 +1,18 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema",
3
+ "$id": "SchematicsAngularLynxAddTesting",
4
+ "title": "AngularLynx add-testing schematic",
5
+ "type": "object",
6
+ "additionalProperties": false,
7
+ "description": "Adds AngularLynx Testing Library with Vitest to an existing project.",
8
+ "properties": {
9
+ "project": {
10
+ "type": "string",
11
+ "description": "The name of the project to add testing to.",
12
+ "$default": {
13
+ "$source": "projectName"
14
+ }
15
+ }
16
+ },
17
+ "required": []
18
+ }
@@ -0,0 +1,30 @@
1
+ {
2
+ "schematics": {
3
+ "ng-add": {
4
+ "description": "Transforms an Angular project into a Lynx-native application",
5
+ "factory": "./ng-add/index",
6
+ "schema": "./ng-add/schema.json"
7
+ },
8
+ "add-tailwind": {
9
+ "description": "Adds Tailwind CSS with @lynx-js/tailwind-preset to an existing project",
10
+ "factory": "./add-tailwind/index",
11
+ "schema": "./add-tailwind/schema.json"
12
+ },
13
+ "add-testing": {
14
+ "description": "Adds AngularLynx Testing Library with Vitest to an existing project",
15
+ "factory": "./add-testing/index",
16
+ "schema": "./add-testing/schema.json"
17
+ },
18
+ "add-i18n": {
19
+ "description": "Adds Angular i18n support with @angular/localize and provideLocale() to an existing project",
20
+ "factory": "./add-i18n/index",
21
+ "schema": "./add-i18n/schema.json"
22
+ },
23
+ "component": {
24
+ "description": "Generates a standalone Angular component with Lynx element template",
25
+ "factory": "./component/index",
26
+ "schema": "./component/schema.json",
27
+ "aliases": ["c"]
28
+ }
29
+ }
30
+ }
@@ -0,0 +1,59 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema",
3
+ "$id": "SchematicsAngularLynxComponent",
4
+ "title": "AngularLynx component schematic",
5
+ "type": "object",
6
+ "additionalProperties": false,
7
+ "description": "Generates a standalone Angular component with Lynx element template.",
8
+ "properties": {
9
+ "name": {
10
+ "type": "string",
11
+ "description": "The name of the component.",
12
+ "$default": {
13
+ "$source": "argv",
14
+ "index": 0
15
+ },
16
+ "x-prompt": "What name would you like to use for the component?"
17
+ },
18
+ "path": {
19
+ "type": "string",
20
+ "format": "path",
21
+ "description": "The path at which to create the component, relative to the source root.",
22
+ "visible": false
23
+ },
24
+ "project": {
25
+ "type": "string",
26
+ "description": "The name of the project.",
27
+ "$default": {
28
+ "$source": "projectName"
29
+ }
30
+ },
31
+ "prefix": {
32
+ "type": "string",
33
+ "description": "The selector prefix to use. Defaults to the project prefix from angular.json."
34
+ },
35
+ "inlineStyle": {
36
+ "type": "boolean",
37
+ "description": "Include styles inline in the component.ts file.",
38
+ "default": true,
39
+ "alias": "s"
40
+ },
41
+ "inlineTemplate": {
42
+ "type": "boolean",
43
+ "description": "Include template inline in the component.ts file.",
44
+ "default": true,
45
+ "alias": "t"
46
+ },
47
+ "skipTests": {
48
+ "type": "boolean",
49
+ "description": "Do not generate a spec file.",
50
+ "default": false
51
+ },
52
+ "flat": {
53
+ "type": "boolean",
54
+ "description": "Create the component files at the top level of the path, without a subdirectory.",
55
+ "default": false
56
+ }
57
+ },
58
+ "required": ["name"]
59
+ }
@@ -0,0 +1,17 @@
1
+ import { pluginAngularLynx } from '@blotch/rsbuild-plugin-angular-lynx';
2
+ import { pluginQRCode } from '@lynx-js/qrcode-rsbuild-plugin';
3
+ import { defineConfig } from '@lynx-js/rspeedy';
4
+
5
+ export default defineConfig({
6
+ source: {
7
+ entry: './src/main.ts',
8
+ },
9
+ plugins: [
10
+ pluginQRCode({
11
+ schema(url) {
12
+ return `${url}?fullscreen=true`;
13
+ },
14
+ }),
15
+ pluginAngularLynx(),
16
+ ],
17
+ });
@@ -0,0 +1 @@
1
+ /// <reference types="@lynx-js/rspeedy/client" />
@@ -0,0 +1,24 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema",
3
+ "$id": "SchematicsAngularLynxNgAdd",
4
+ "title": "AngularLynx ng-add schematic",
5
+ "type": "object",
6
+ "additionalProperties": false,
7
+ "description": "Transforms an Angular project into a Lynx-native application.",
8
+ "properties": {
9
+ "project": {
10
+ "type": "string",
11
+ "description": "The name of the project to transform.",
12
+ "$default": {
13
+ "$source": "projectName"
14
+ }
15
+ },
16
+ "tailwind": {
17
+ "type": "boolean",
18
+ "description": "Whether to add Tailwind CSS with @lynx-js/tailwind-preset.",
19
+ "default": true,
20
+ "x-prompt": "Would you like to add Tailwind CSS with Lynx preset?"
21
+ }
22
+ },
23
+ "required": []
24
+ }