@blotch/angular-lynx 0.0.0-stage → 22.2.1
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 +181 -2
- package/package.json +50 -3
- package/schematics/add-i18n/schema.json +18 -0
- package/schematics/add-tailwind/schema.json +18 -0
- package/schematics/add-testing/schema.json +18 -0
- package/schematics/collection.json +30 -0
- package/schematics/component/schema.json +59 -0
- package/schematics/files/lynx.config.ts.template +17 -0
- package/schematics/files/src/rspeedy-env.d.ts.template +1 -0
- package/schematics/ng-add/schema.json +24 -0
package/README.md
CHANGED
|
@@ -1,3 +1,182 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @blotch/angular-lynx
|
|
2
2
|
|
|
3
|
-
|
|
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": "
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"version": "22.2.1",
|
|
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
|
+
}
|