@kirana-style/angular 0.1.0 → 0.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/CHANGELOG.md +63 -0
- package/LICENSE +21 -0
- package/README.md +1 -1
- package/package.json +8 -3
- package/src/application.d.ts +2 -3
- package/src/application.js +4 -1
- package/src/builders.d.ts +9 -7
- package/src/builders.js +56 -72
- package/src/dev-server.d.ts +2 -3
- package/src/dev-server.js +4 -1
- package/src/fesm2022/directive.d.ts +20 -31
- package/src/fesm2022/directive.js +61 -54
- package/src/index.d.ts +3 -3
- package/src/index.js +3 -2
- package/src/mirror.d.ts +15 -23
- package/src/mirror.js +86 -95
- package/src/sx.d.ts +8 -12
- package/src/sx.js +31 -32
- package/src/vite.d.ts +5 -4
- package/src/vite.js +18 -13
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## [0.2.1](https://github.com/kirana-style/kirana/compare/v0.2.0...v0.2.1) (2026-10-16)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* deno in kirana-style init and doctor, and doctor finds kirana-style ([#33](https://github.com/kirana-style/kirana/issues/33)) ([3730d82](https://github.com/kirana-style/kirana/commit/3730d827815164ab32e22f09ad739e0b92502ad3))
|
|
9
|
+
* **site:** mobile scenes, release changelog, blog and roadmap redesign ([#34](https://github.com/kirana-style/kirana/issues/34)) ([f9330a8](https://github.com/kirana-style/kirana/commit/f9330a8b8788847609bfcd6b5ea2b795ffbc86f9))
|
|
10
|
+
* **site:** read every benchmark number from kirana-lab's runs ([#39](https://github.com/kirana-style/kirana/issues/39)) ([718f253](https://github.com/kirana-style/kirana/commit/718f253dd8ef64d95f3299c2256463458283ec20))
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### Bug fixes
|
|
14
|
+
|
|
15
|
+
* compile the scales preset from node_modules without listing it ([#37](https://github.com/kirana-style/kirana/issues/37)) ([12d8b67](https://github.com/kirana-style/kirana/commit/12d8b67f4fc9359a9534af68ea10f51c0a2a637d))
|
|
16
|
+
* let the dev example check look again after the page reloads ([#31](https://github.com/kirana-style/kirana/issues/31)) ([8d21bfd](https://github.com/kirana-style/kirana/commit/8d21bfd39d8b95327f346e1bc38ed2e433be1879))
|
|
17
|
+
* pin vitest 4 in the qwik example, inside qwik's peer range ([#36](https://github.com/kirana-style/kirana/issues/36)) ([5317eed](https://github.com/kirana-style/kirana/commit/5317eed4f0293b2befe64bbfda00b18601b3d24b))
|
|
18
|
+
|
|
19
|
+
## [0.2.0](https://github.com/kirana-style/kirana/compare/v0.1.0...v0.2.0) (2026-10-15)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
### ⚠ BREAKING CHANGES
|
|
23
|
+
|
|
24
|
+
* one command name, kirana-style ([#29](https://github.com/kirana-style/kirana/issues/29))
|
|
25
|
+
|
|
26
|
+
### Features
|
|
27
|
+
|
|
28
|
+
* **editor:** real editor output on the site, open vsx trusted publishing ([#21](https://github.com/kirana-style/kirana/issues/21)) ([350fa4e](https://github.com/kirana-style/kirana/commit/350fa4ec0d8054a082d6c7dcdae2b5be53f8d98a))
|
|
29
|
+
* one command name, kirana-style ([#29](https://github.com/kirana-style/kirana/issues/29)) ([b3f3154](https://github.com/kirana-style/kirana/commit/b3f3154662589dd1bd43fd0ff2341acf4f3df628))
|
|
30
|
+
* **site:** paper, ink, scenery and type for one identity ([#27](https://github.com/kirana-style/kirana/issues/27)) ([5da3c6f](https://github.com/kirana-style/kirana/commit/5da3c6f0f1c8cbfdb450b36a6609a3ab4b20e358))
|
|
31
|
+
* **site:** reorganise the homepage, product pages and docs ([#28](https://github.com/kirana-style/kirana/issues/28)) ([88b5209](https://github.com/kirana-style/kirana/commit/88b52093488b2aa0112b458ca04b836c83d03954))
|
|
32
|
+
* **site:** scenery gradients, logo downloads, pixel k, glass icons ([#25](https://github.com/kirana-style/kirana/issues/25)) ([2953dc1](https://github.com/kirana-style/kirana/commit/2953dc126f47b68257ebfdb33c61992984708c49))
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
### Bug fixes
|
|
36
|
+
|
|
37
|
+
* hold emnapi at 2.0.0-alpha.6, the wasi engine fails on the beta ([#26](https://github.com/kirana-style/kirana/issues/26)) ([8aa33e1](https://github.com/kirana-style/kirana/commit/8aa33e1dbccaefa15b87f6487ac0a346bbf6581a))
|
|
38
|
+
* settle the ember dev check, resolve code scanning findings ([#23](https://github.com/kirana-style/kirana/issues/23)) ([0c266c8](https://github.com/kirana-style/kirana/commit/0c266c8428c1453892beeeb5f98918cbc0eae6ff))
|
|
39
|
+
* **site:** keep syntax colours in the production build ([#22](https://github.com/kirana-style/kirana/issues/22)) ([621f2fc](https://github.com/kirana-style/kirana/commit/621f2fcf67dada773ca66110e295ab7ac5605f56))
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
### Documentation
|
|
43
|
+
|
|
44
|
+
* fix the extension's settings table ([#13](https://github.com/kirana-style/kirana/issues/13)) ([457e06d](https://github.com/kirana-style/kirana/commit/457e06d12f9e3b005e0820aab36faac5bf3f80b3))
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
### Dependencies
|
|
48
|
+
|
|
49
|
+
* bump the minor-and-patch group across 1 directory with 3 updates ([#19](https://github.com/kirana-style/kirana/issues/19)) ([7ea00ed](https://github.com/kirana-style/kirana/commit/7ea00edcc5cc02b9ab5e41b13f152ae344ea448f))
|
|
50
|
+
* emnapi 2.0.0-beta.1, minor and patch updates ([#24](https://github.com/kirana-style/kirana/issues/24)) ([a399fa7](https://github.com/kirana-style/kirana/commit/a399fa78e53dcfd7f41f249ccee1133809e66544))
|
|
51
|
+
|
|
52
|
+
## [0.1.0](https://github.com/kirana-style/kirana/compare/v0.1.0...v0.1.0) (2026-10-13)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
### Features
|
|
56
|
+
|
|
57
|
+
* kirana goes public — write objects, read classes, ship css ([79732ed](https://github.com/kirana-style/kirana/commit/79732edd5cab419169ab74ad59e1c70053dfa57d))
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
### Dependencies
|
|
61
|
+
|
|
62
|
+
* bump the minor-and-patch group in /packages/kirana with 6 updates ([#10](https://github.com/kirana-style/kirana/issues/10)) ([0deaf9f](https://github.com/kirana-style/kirana/commit/0deaf9f3e75ebc377d764c294250bd2577d53844))
|
|
63
|
+
* bump the oxc group in /packages/kirana with 7 updates ([#9](https://github.com/kirana-style/kirana/issues/9)) ([a3ca94c](https://github.com/kirana-style/kirana/commit/a3ca94c170b2ca49c9691abf5ad48c3ef4ac8620))
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Kirana authors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -30,4 +30,4 @@ export class Card {
|
|
|
30
30
|
source root into `.kirana/` (ignore it), hand Angular the copy through `fileReplacements`, and add
|
|
31
31
|
`.kirana/kirana.css` to `styles`.
|
|
32
32
|
|
|
33
|
-
`kirana init` sets up either. How it works and what it costs: `design-notes/angular.md`.
|
|
33
|
+
`kirana-style init` sets up either. How it works and what it costs: `design-notes/angular.md`.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kirana-style/angular",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "Kirana for Angular: the [sx] directive, the Analog (Vite) plugin and Angular CLI builders.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "The Kirana authors",
|
|
@@ -14,6 +14,9 @@
|
|
|
14
14
|
"url": "https://github.com/kirana-style/kirana/issues"
|
|
15
15
|
},
|
|
16
16
|
"type": "module",
|
|
17
|
+
"publishConfig": {
|
|
18
|
+
"access": "public"
|
|
19
|
+
},
|
|
17
20
|
"exports": {
|
|
18
21
|
".": {
|
|
19
22
|
"types": "./src/index.d.ts",
|
|
@@ -27,8 +30,8 @@
|
|
|
27
30
|
"./builders.json": "./builders.json"
|
|
28
31
|
},
|
|
29
32
|
"dependencies": {
|
|
30
|
-
"@kirana-style/compiler": "0.1
|
|
31
|
-
"@kirana-style/core": "0.1
|
|
33
|
+
"@kirana-style/compiler": "0.2.1",
|
|
34
|
+
"@kirana-style/core": "0.2.1"
|
|
32
35
|
},
|
|
33
36
|
"peerDependencies": {
|
|
34
37
|
"@angular/core": ">=20.0.0",
|
|
@@ -54,6 +57,8 @@
|
|
|
54
57
|
"*.d.ts",
|
|
55
58
|
"*.css",
|
|
56
59
|
"README.md",
|
|
60
|
+
"CHANGELOG.md",
|
|
61
|
+
"LICENSE",
|
|
57
62
|
"builders.json",
|
|
58
63
|
"schemas",
|
|
59
64
|
"gatsby-node.mjs",
|
package/src/application.d.ts
CHANGED
|
@@ -1,3 +1,2 @@
|
|
|
1
|
-
import { applicationBuilder } from "./builders.
|
|
2
|
-
|
|
3
|
-
export default applicationBuilder;
|
|
1
|
+
import { applicationBuilder } from "./builders.js";
|
|
2
|
+
export { applicationBuilder as default };
|
package/src/application.js
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
1
|
import { applicationBuilder } from "./builders.js";
|
|
2
|
+
//#region src/application.ts
|
|
2
3
|
/** `@kirana-style/angular:application`, loaded by the Angular CLI from builders.json. */
|
|
3
|
-
|
|
4
|
+
var application_default = applicationBuilder;
|
|
5
|
+
//#endregion
|
|
6
|
+
export { application_default as default };
|
package/src/builders.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import
|
|
1
|
+
import { Mirror } from "./mirror.js";
|
|
2
|
+
import { Builder, BuilderContext, BuilderOutput } from "@angular-devkit/architect";
|
|
3
|
+
import { ApplicationBuilderOptions, DevServerBuilderOptions } from "@angular/build";
|
|
4
|
+
//#region src/builders.d.ts
|
|
4
5
|
/**
|
|
5
6
|
* Application options with the mirror's replacements and the stylesheet added. The entry files
|
|
6
7
|
* (`browser`, `server`) are not replaced: Angular type-checks only the files its tsconfig lists, and
|
|
@@ -8,12 +9,13 @@ import type { Mirror } from "./mirror.ts";
|
|
|
8
9
|
* Angular app; the components it imports are replaced.
|
|
9
10
|
*/
|
|
10
11
|
export declare function withMirror<Options extends {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
fileReplacements?: unknown[];
|
|
13
|
+
styles?: unknown[];
|
|
14
|
+
browser?: unknown;
|
|
15
|
+
server?: unknown;
|
|
15
16
|
}>(options: Options, mirror: Mirror): Options;
|
|
16
17
|
export declare function application(options: ApplicationBuilderOptions, context: BuilderContext): AsyncIterable<BuilderOutput>;
|
|
17
18
|
export declare function devServer(options: DevServerBuilderOptions, context: BuilderContext): AsyncIterable<BuilderOutput>;
|
|
18
19
|
export declare const applicationBuilder: Builder;
|
|
19
20
|
export declare const devServerBuilder: Builder;
|
|
21
|
+
//#endregion
|
package/src/builders.js
CHANGED
|
@@ -1,85 +1,69 @@
|
|
|
1
|
-
|
|
2
|
-
* The Angular CLI builders (`@kirana-style/angular:application`, `@kirana-style/angular:dev-server`): Angular's
|
|
3
|
-
* own, given Kirana's mirror (`mirror.ts`) as `fileReplacements` and its stylesheet in `styles`.
|
|
4
|
-
*
|
|
5
|
-
* "build": { "builder": "@kirana-style/angular:application", "options": { … as before … } }
|
|
6
|
-
* "serve": { "builder": "@kirana-style/angular:dev-server", … }
|
|
7
|
-
*
|
|
8
|
-
* The dev server is Angular's, run with a context whose build target's options carry the mirror:
|
|
9
|
-
* Angular reads those options itself and compiles them with its internal application build.
|
|
10
|
-
*/
|
|
1
|
+
import { STYLESHEET, createMirror, watchMirror } from "./mirror.js";
|
|
11
2
|
import path from "node:path";
|
|
12
3
|
import { createBuilder } from "@angular-devkit/architect";
|
|
13
4
|
import { buildApplication, executeDevServerBuilder } from "@angular/build";
|
|
14
|
-
|
|
5
|
+
//#region src/builders.ts
|
|
6
|
+
/**
|
|
7
|
+
* The Angular CLI builders (`@kirana-style/angular:application`, `@kirana-style/angular:dev-server`): Angular's
|
|
8
|
+
* own, given Kirana's mirror (`mirror.ts`) as `fileReplacements` and its stylesheet in `styles`.
|
|
9
|
+
*
|
|
10
|
+
* "build": { "builder": "@kirana-style/angular:application", "options": { … as before … } }
|
|
11
|
+
* "serve": { "builder": "@kirana-style/angular:dev-server", … }
|
|
12
|
+
*
|
|
13
|
+
* The dev server is Angular's, run with a context whose build target's options carry the mirror:
|
|
14
|
+
* Angular reads those options itself and compiles them with its internal application build.
|
|
15
|
+
*/
|
|
15
16
|
/** The project's source folder, from its configuration (`src` unless it says otherwise). */
|
|
16
17
|
async function sourceRootOf(context) {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
? metadata.sourceRoot
|
|
22
|
-
: path.join(root, "src");
|
|
18
|
+
const project = context.target?.project;
|
|
19
|
+
const metadata = project ? await context.getProjectMetadata(project) : {};
|
|
20
|
+
const root = typeof metadata.root === "string" ? metadata.root : "";
|
|
21
|
+
return typeof metadata.sourceRoot === "string" ? metadata.sourceRoot : path.join(root, "src");
|
|
23
22
|
}
|
|
24
23
|
/**
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
],
|
|
38
|
-
styles: [...(options.styles ?? []), STYLESHEET],
|
|
39
|
-
};
|
|
24
|
+
* Application options with the mirror's replacements and the stylesheet added. The entry files
|
|
25
|
+
* (`browser`, `server`) are not replaced: Angular type-checks only the files its tsconfig lists, and
|
|
26
|
+
* an entry it reads from a replacement it would bundle unchecked. An entry holds no styles in an
|
|
27
|
+
* Angular app; the components it imports are replaced.
|
|
28
|
+
*/
|
|
29
|
+
function withMirror(options, mirror) {
|
|
30
|
+
const entries = new Set([options.browser, options.server].map((entry) => path.normalize(String(entry))));
|
|
31
|
+
return {
|
|
32
|
+
...options,
|
|
33
|
+
fileReplacements: [...options.fileReplacements ?? [], ...mirror.replacements.filter((replacement) => !entries.has(path.normalize(replacement.replace)))],
|
|
34
|
+
styles: [...options.styles ?? [], STYLESHEET]
|
|
35
|
+
};
|
|
40
36
|
}
|
|
41
37
|
/** Prints the mirror's warnings and errors through the builder's logger (infos stay quiet). */
|
|
42
38
|
function report(context, mirror) {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
context.logger.error(message);
|
|
46
|
-
else if (message.startsWith("warning"))
|
|
47
|
-
context.logger.warn(message);
|
|
39
|
+
for (const message of mirror.messages()) if (message.startsWith("error")) context.logger.error(message);
|
|
40
|
+
else if (message.startsWith("warning")) context.logger.warn(message);
|
|
48
41
|
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
yield* buildApplication(withMirror(options, mirror), context);
|
|
60
|
-
}
|
|
61
|
-
finally {
|
|
62
|
-
watcher?.close();
|
|
63
|
-
}
|
|
42
|
+
async function* application(options, context) {
|
|
43
|
+
const sourceRoot = await sourceRootOf(context);
|
|
44
|
+
const mirror = await createMirror(context.workspaceRoot, sourceRoot, { minify: options.optimization !== false });
|
|
45
|
+
report(context, mirror);
|
|
46
|
+
const watcher = options.watch ? watchMirror(context.workspaceRoot, sourceRoot, mirror, () => report(context, mirror)) : void 0;
|
|
47
|
+
try {
|
|
48
|
+
yield* buildApplication(withMirror(options, mirror), context);
|
|
49
|
+
} finally {
|
|
50
|
+
watcher?.close();
|
|
51
|
+
}
|
|
64
52
|
}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
}
|
|
78
|
-
finally {
|
|
79
|
-
watcher.close();
|
|
80
|
-
}
|
|
53
|
+
async function* devServer(options, context) {
|
|
54
|
+
const sourceRoot = await sourceRootOf(context);
|
|
55
|
+
const mirror = await createMirror(context.workspaceRoot, sourceRoot);
|
|
56
|
+
report(context, mirror);
|
|
57
|
+
const watcher = watchMirror(context.workspaceRoot, sourceRoot, mirror, () => report(context, mirror));
|
|
58
|
+
const getTargetOptions = context.getTargetOptions.bind(context);
|
|
59
|
+
const wrapped = Object.assign(Object.create(context), { getTargetOptions: async (target) => withMirror(await getTargetOptions(target), mirror) });
|
|
60
|
+
try {
|
|
61
|
+
yield* executeDevServerBuilder(options, wrapped);
|
|
62
|
+
} finally {
|
|
63
|
+
watcher.close();
|
|
64
|
+
}
|
|
81
65
|
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
export
|
|
66
|
+
const applicationBuilder = createBuilder(application);
|
|
67
|
+
const devServerBuilder = createBuilder(devServer);
|
|
68
|
+
//#endregion
|
|
69
|
+
export { application, applicationBuilder, devServer, devServerBuilder, withMirror };
|
package/src/dev-server.d.ts
CHANGED
|
@@ -1,3 +1,2 @@
|
|
|
1
|
-
import { devServerBuilder } from "./builders.
|
|
2
|
-
|
|
3
|
-
export default devServerBuilder;
|
|
1
|
+
import { devServerBuilder } from "./builders.js";
|
|
2
|
+
export { devServerBuilder as default };
|
package/src/dev-server.js
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
1
|
import { devServerBuilder } from "./builders.js";
|
|
2
|
+
//#region src/dev-server.ts
|
|
2
3
|
/** `@kirana-style/angular:dev-server`, loaded by the Angular CLI from builders.json. */
|
|
3
|
-
|
|
4
|
+
var dev_server_default = devServerBuilder;
|
|
5
|
+
//#endregion
|
|
6
|
+
export { dev_server_default as default };
|
|
@@ -1,39 +1,28 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* `[sx]` for Angular templates (D-068). A template reaches only its component's members, so `sx`
|
|
3
|
-
* cannot be compiled away there as it is in JSX and in Vue, Svelte or Astro templates: this
|
|
4
|
-
* directive merges the handles at runtime with Kirana's runtime instead, and keeps the element's own
|
|
5
|
-
* classes and styles.
|
|
6
|
-
*
|
|
7
|
-
* The class carries Angular's partial declarations (`ɵɵngDeclareFactory`, `ɵɵngDeclareDirective`),
|
|
8
|
-
* the form `ngc` emits for a library and Angular's linker compiles in every app build. They are
|
|
9
|
-
* written here rather than generated because this workspace's TypeScript (7) has no JavaScript API
|
|
10
|
-
* for `ngc` to run on; the Analog and Angular CLI examples build them in CI. The static types are the
|
|
11
|
-
* ones `ngc` would declare, so templates type-check `[sx]` against `Sx`. The file sits under
|
|
12
|
-
* `fesm2022/`, the Angular Package Format's folder, because Analog links only files on such a path.
|
|
13
|
-
*/
|
|
14
1
|
import * as i0 from "@angular/core";
|
|
15
|
-
import
|
|
16
|
-
import
|
|
2
|
+
import { Handle } from "@kirana-style/core/internal";
|
|
3
|
+
import { Sx } from "@kirana-style/core";
|
|
4
|
+
//#region src/fesm2022/directive.d.ts
|
|
17
5
|
/** The class-name prefix (`names.prefix`); `k` unless the app provides another (`provideKirana`). */
|
|
18
6
|
export declare const KIRANA_PREFIX: i0.InjectionToken<string>;
|
|
19
7
|
/** Providers for an app whose `kirana.config` sets another class-name prefix. */
|
|
20
8
|
export declare function provideKirana(options: {
|
|
21
|
-
|
|
9
|
+
prefix: string;
|
|
22
10
|
}): i0.Provider[];
|
|
23
11
|
export declare class SxDirective implements i0.OnChanges {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
12
|
+
#private;
|
|
13
|
+
/**
|
|
14
|
+
* The handles: one, or an array with falsy guards (`[styles.card, active && styles.on]`). Compiled
|
|
15
|
+
* handles are class strings (the Angular CLI builders type-check the compiled copy), so both are
|
|
16
|
+
* accepted.
|
|
17
|
+
*/
|
|
18
|
+
sx: Sx | Handle;
|
|
19
|
+
ngOnChanges(): void;
|
|
20
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<SxDirective, never>;
|
|
21
|
+
static ɵdir: i0.ɵɵDirectiveDeclaration<SxDirective, "[sx]", never, {
|
|
22
|
+
sx: {
|
|
23
|
+
alias: "sx";
|
|
24
|
+
required: false;
|
|
25
|
+
};
|
|
26
|
+
}, {}, never, never, true, never>;
|
|
39
27
|
}
|
|
28
|
+
//#endregion
|
|
@@ -1,59 +1,66 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* `[sx]` for Angular templates (D-068). A template reaches only its component's members, so `sx`
|
|
3
|
-
* cannot be compiled away there as it is in JSX and in Vue, Svelte or Astro templates: this
|
|
4
|
-
* directive merges the handles at runtime with Kirana's runtime instead, and keeps the element's own
|
|
5
|
-
* classes and styles.
|
|
6
|
-
*
|
|
7
|
-
* The class carries Angular's partial declarations (`ɵɵngDeclareFactory`, `ɵɵngDeclareDirective`),
|
|
8
|
-
* the form `ngc` emits for a library and Angular's linker compiles in every app build. They are
|
|
9
|
-
* written here rather than generated because this workspace's TypeScript (7) has no JavaScript API
|
|
10
|
-
* for `ngc` to run on; the Analog and Angular CLI examples build them in CI. The static types are the
|
|
11
|
-
* ones `ngc` would declare, so templates type-check `[sx]` against `Sx`. The file sits under
|
|
12
|
-
* `fesm2022/`, the Angular Package Format's folder, because Analog links only files on such a path.
|
|
13
|
-
*/
|
|
14
|
-
import * as i0 from "@angular/core";
|
|
15
1
|
import { applySx } from "../sx.js";
|
|
2
|
+
import * as i0 from "@angular/core";
|
|
3
|
+
//#region src/fesm2022/directive.ts
|
|
4
|
+
/**
|
|
5
|
+
* `[sx]` for Angular templates (D-068). A template reaches only its component's members, so `sx`
|
|
6
|
+
* cannot be compiled away there as it is in JSX and in Vue, Svelte or Astro templates: this
|
|
7
|
+
* directive merges the handles at runtime with Kirana's runtime instead, and keeps the element's own
|
|
8
|
+
* classes and styles.
|
|
9
|
+
*
|
|
10
|
+
* The class carries Angular's partial declarations (`ɵɵngDeclareFactory`, `ɵɵngDeclareDirective`),
|
|
11
|
+
* the form `ngc` emits for a library and Angular's linker compiles in every app build. They are
|
|
12
|
+
* written here rather than generated because this workspace's TypeScript (7) has no JavaScript API
|
|
13
|
+
* for `ngc` to run on; the Analog and Angular CLI examples build them in CI. The static types are the
|
|
14
|
+
* ones `ngc` would declare, so templates type-check `[sx]` against `Sx`. The file sits under
|
|
15
|
+
* `fesm2022/`, the Angular Package Format's folder, because Analog links only files on such a path.
|
|
16
|
+
*/
|
|
16
17
|
/** The class-name prefix (`names.prefix`); `k` unless the app provides another (`provideKirana`). */
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
const KIRANA_PREFIX = new i0.InjectionToken("kirana prefix", {
|
|
19
|
+
providedIn: "root",
|
|
20
|
+
factory: () => "k"
|
|
20
21
|
});
|
|
21
22
|
/** Providers for an app whose `kirana.config` sets another class-name prefix. */
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
* The handles: one, or an array with falsy guards (`[styles.card, active && styles.on]`). Compiled
|
|
28
|
-
* handles are class strings (the Angular CLI builders type-check the compiled copy), so both are
|
|
29
|
-
* accepted.
|
|
30
|
-
*/
|
|
31
|
-
sx;
|
|
32
|
-
#element = i0.inject(i0.ElementRef).nativeElement;
|
|
33
|
-
#renderer = i0.inject(i0.Renderer2);
|
|
34
|
-
#prefix = i0.inject(KIRANA_PREFIX);
|
|
35
|
-
#applied = { classes: new Set(), styles: new Set() };
|
|
36
|
-
ngOnChanges() {
|
|
37
|
-
this.#applied = applySx(this.#renderer, this.#element, this.#applied, this.sx, this.#prefix);
|
|
38
|
-
}
|
|
39
|
-
static ɵfac = i0.ɵɵngDeclareFactory({
|
|
40
|
-
minVersion: "12.0.0",
|
|
41
|
-
// A literal, as the linker reads it: the Angular version these were written against.
|
|
42
|
-
version: "22.2.1",
|
|
43
|
-
ngImport: i0,
|
|
44
|
-
type: SxDirective,
|
|
45
|
-
deps: [],
|
|
46
|
-
target: i0.ɵɵFactoryTarget.Directive,
|
|
47
|
-
});
|
|
48
|
-
static ɵdir = i0.ɵɵngDeclareDirective({
|
|
49
|
-
minVersion: "14.0.0",
|
|
50
|
-
// A literal, as the linker reads it: the Angular version these were written against.
|
|
51
|
-
version: "22.2.1",
|
|
52
|
-
type: SxDirective,
|
|
53
|
-
isStandalone: true,
|
|
54
|
-
selector: "[sx]",
|
|
55
|
-
inputs: { sx: "sx" },
|
|
56
|
-
usesOnChanges: true,
|
|
57
|
-
ngImport: i0,
|
|
58
|
-
});
|
|
23
|
+
function provideKirana(options) {
|
|
24
|
+
return [{
|
|
25
|
+
provide: KIRANA_PREFIX,
|
|
26
|
+
useValue: options.prefix
|
|
27
|
+
}];
|
|
59
28
|
}
|
|
29
|
+
var SxDirective = class SxDirective {
|
|
30
|
+
/**
|
|
31
|
+
* The handles: one, or an array with falsy guards (`[styles.card, active && styles.on]`). Compiled
|
|
32
|
+
* handles are class strings (the Angular CLI builders type-check the compiled copy), so both are
|
|
33
|
+
* accepted.
|
|
34
|
+
*/
|
|
35
|
+
sx;
|
|
36
|
+
#element = i0.inject(i0.ElementRef).nativeElement;
|
|
37
|
+
#renderer = i0.inject(i0.Renderer2);
|
|
38
|
+
#prefix = i0.inject(KIRANA_PREFIX);
|
|
39
|
+
#applied = {
|
|
40
|
+
classes: /* @__PURE__ */ new Set(),
|
|
41
|
+
styles: /* @__PURE__ */ new Set()
|
|
42
|
+
};
|
|
43
|
+
ngOnChanges() {
|
|
44
|
+
this.#applied = applySx(this.#renderer, this.#element, this.#applied, this.sx, this.#prefix);
|
|
45
|
+
}
|
|
46
|
+
static ɵfac = i0.ɵɵngDeclareFactory({
|
|
47
|
+
minVersion: "12.0.0",
|
|
48
|
+
version: "22.2.1",
|
|
49
|
+
ngImport: i0,
|
|
50
|
+
type: SxDirective,
|
|
51
|
+
deps: [],
|
|
52
|
+
target: i0.ɵɵFactoryTarget.Directive
|
|
53
|
+
});
|
|
54
|
+
static ɵdir = i0.ɵɵngDeclareDirective({
|
|
55
|
+
minVersion: "14.0.0",
|
|
56
|
+
version: "22.2.1",
|
|
57
|
+
type: SxDirective,
|
|
58
|
+
isStandalone: true,
|
|
59
|
+
selector: "[sx]",
|
|
60
|
+
inputs: { sx: "sx" },
|
|
61
|
+
usesOnChanges: true,
|
|
62
|
+
ngImport: i0
|
|
63
|
+
});
|
|
64
|
+
};
|
|
65
|
+
//#endregion
|
|
66
|
+
export { KIRANA_PREFIX, SxDirective, provideKirana };
|
package/src/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
export type
|
|
1
|
+
import { KIRANA_PREFIX, SxDirective, provideKirana } from "./fesm2022/directive.js";
|
|
2
|
+
import { Applied, Renderer, applySx, runtimeFor } from "./sx.js";
|
|
3
|
+
export { type Applied, KIRANA_PREFIX, type Renderer, SxDirective, applySx, provideKirana, runtimeFor };
|
package/src/index.js
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import { applySx, runtimeFor } from "./sx.js";
|
|
2
|
+
import { KIRANA_PREFIX, SxDirective, provideKirana } from "./fesm2022/directive.js";
|
|
3
|
+
export { KIRANA_PREFIX, SxDirective, applySx, provideKirana, runtimeFor };
|
package/src/mirror.d.ts
CHANGED
|
@@ -1,14 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
* compiles TypeScript from its own program and offers no hook to change a source first, but it
|
|
4
|
-
* honours `fileReplacements`, by redirecting module resolution to the replacement file. So the
|
|
5
|
-
* builders keep a mirror of the source folder in `.kirana/`: every file copied, the ones that hold
|
|
6
|
-
* styles compiled by Kirana. A replacement's relative imports and `templateUrl`s then resolve inside
|
|
7
|
-
* the mirror, where every file exists. Every TypeScript file is replaced, the stylesheet is written
|
|
8
|
-
* beside the mirror, and in watch mode each change is mirrored again — Angular, which watches the
|
|
9
|
-
* replacements, rebuilds from there.
|
|
10
|
-
*/
|
|
11
|
-
import { watch as fsWatch } from "node:fs";
|
|
1
|
+
import { watch } from "node:fs";
|
|
2
|
+
//#region src/mirror.d.ts
|
|
12
3
|
/** Where the mirror lives, under the workspace root. */
|
|
13
4
|
export declare const MIRROR = ".kirana";
|
|
14
5
|
/** The stylesheet the builders add to `styles`. */
|
|
@@ -16,21 +7,22 @@ export declare const STYLESHEET: string;
|
|
|
16
7
|
/** Every file under `directory`, relative to it, without installed packages or hidden folders. */
|
|
17
8
|
export declare function walk(directory: string, prefix?: string): string[];
|
|
18
9
|
export type Mirror = {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
10
|
+
/** `fileReplacements` for every TypeScript file of the source folder. */
|
|
11
|
+
replacements: {
|
|
12
|
+
replace: string;
|
|
13
|
+
with: string;
|
|
14
|
+
}[];
|
|
15
|
+
/** Mirrors one changed or deleted file (and what read from it); returns whether anything changed. */
|
|
16
|
+
update: (file: string) => boolean;
|
|
17
|
+
/** Diagnostics from the last pass, formatted. */
|
|
18
|
+
messages: () => string[];
|
|
28
19
|
};
|
|
29
20
|
/** Builds the mirror of `sourceRoot` (relative to `root`) and writes the stylesheet. */
|
|
30
21
|
export declare function createMirror(root: string, sourceRoot: string, options?: {
|
|
31
|
-
|
|
22
|
+
minify?: boolean;
|
|
32
23
|
}): Promise<Mirror>;
|
|
33
24
|
/** Mirrors every change under the source folder until closed (watch builds and the dev server). */
|
|
34
|
-
export declare function watchMirror(root: string, sourceRoot: string, mirror: Mirror, onUpdate: () => void, watch?: typeof
|
|
35
|
-
|
|
25
|
+
export declare function watchMirror(root: string, sourceRoot: string, mirror: Mirror, onUpdate: () => void, watch?: typeof watch): {
|
|
26
|
+
close: () => void;
|
|
36
27
|
};
|
|
28
|
+
//#endregion
|
package/src/mirror.js
CHANGED
|
@@ -1,107 +1,98 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Kirana for the Angular CLI (D-068, `design-notes/angular.md`). Angular's application builder
|
|
3
|
-
* compiles TypeScript from its own program and offers no hook to change a source first, but it
|
|
4
|
-
* honours `fileReplacements`, by redirecting module resolution to the replacement file. So the
|
|
5
|
-
* builders keep a mirror of the source folder in `.kirana/`: every file copied, the ones that hold
|
|
6
|
-
* styles compiled by Kirana. A replacement's relative imports and `templateUrl`s then resolve inside
|
|
7
|
-
* the mirror, where every file exists. Every TypeScript file is replaced, the stylesheet is written
|
|
8
|
-
* beside the mirror, and in watch mode each change is mirrored again — Angular, which watches the
|
|
9
|
-
* replacements, rebuilds from there.
|
|
10
|
-
*/
|
|
11
|
-
import { copyFileSync, existsSync, mkdirSync, readFileSync, readdirSync, rmSync, watch as fsWatch, writeFileSync, } from "node:fs";
|
|
12
1
|
import path from "node:path";
|
|
2
|
+
import { copyFileSync, existsSync, mkdirSync, readFileSync, readdirSync, rmSync, watch, writeFileSync } from "node:fs";
|
|
13
3
|
import { Driver, formatDiagnostic } from "@kirana-style/compiler";
|
|
14
4
|
import { SKIPPED, shouldCompile } from "@kirana-style/compiler/host";
|
|
5
|
+
//#region src/mirror.ts
|
|
6
|
+
/**
|
|
7
|
+
* Kirana for the Angular CLI (D-068, `design-notes/angular.md`). Angular's application builder
|
|
8
|
+
* compiles TypeScript from its own program and offers no hook to change a source first, but it
|
|
9
|
+
* honours `fileReplacements`, by redirecting module resolution to the replacement file. So the
|
|
10
|
+
* builders keep a mirror of the source folder in `.kirana/`: every file copied, the ones that hold
|
|
11
|
+
* styles compiled by Kirana. A replacement's relative imports and `templateUrl`s then resolve inside
|
|
12
|
+
* the mirror, where every file exists. Every TypeScript file is replaced, the stylesheet is written
|
|
13
|
+
* beside the mirror, and in watch mode each change is mirrored again — Angular, which watches the
|
|
14
|
+
* replacements, rebuilds from there.
|
|
15
|
+
*/
|
|
15
16
|
/** Where the mirror lives, under the workspace root. */
|
|
16
|
-
|
|
17
|
+
const MIRROR = ".kirana";
|
|
17
18
|
/** The stylesheet the builders add to `styles`. */
|
|
18
|
-
|
|
19
|
+
const STYLESHEET = path.join(MIRROR, "kirana.css");
|
|
19
20
|
/** Every file under `directory`, relative to it, without installed packages or hidden folders. */
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
}
|
|
30
|
-
else
|
|
31
|
-
out.push(relative);
|
|
32
|
-
}
|
|
33
|
-
return out;
|
|
21
|
+
function walk(directory, prefix = "") {
|
|
22
|
+
const out = [];
|
|
23
|
+
for (const entry of readdirSync(path.join(directory, prefix), { withFileTypes: true })) {
|
|
24
|
+
const relative = path.join(prefix, entry.name);
|
|
25
|
+
if (entry.isDirectory()) {
|
|
26
|
+
if (!SKIPPED.has(entry.name) && !entry.name.startsWith(".")) out.push(...walk(directory, relative));
|
|
27
|
+
} else out.push(relative);
|
|
28
|
+
}
|
|
29
|
+
return out;
|
|
34
30
|
}
|
|
35
31
|
const SCRIPT = /\.[cm]?tsx?$/;
|
|
36
32
|
/** Builds the mirror of `sourceRoot` (relative to `root`) and writes the stylesheet. */
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
},
|
|
92
|
-
messages: () => reported.map((diagnostic) => formatDiagnostic(diagnostic, texts.get(diagnostic.file))),
|
|
93
|
-
};
|
|
33
|
+
async function createMirror(root, sourceRoot, options = {}) {
|
|
34
|
+
const driver = await Driver.create({ root });
|
|
35
|
+
const source = path.join(root, sourceRoot);
|
|
36
|
+
const target = path.join(root, MIRROR, sourceRoot);
|
|
37
|
+
const reported = [];
|
|
38
|
+
const texts = /* @__PURE__ */ new Map();
|
|
39
|
+
const mirror = (relative) => {
|
|
40
|
+
const from = path.join(source, relative);
|
|
41
|
+
const to = path.join(target, relative);
|
|
42
|
+
if (!existsSync(from)) {
|
|
43
|
+
driver.remove(from);
|
|
44
|
+
rmSync(to, { force: true });
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
mkdirSync(path.dirname(to), { recursive: true });
|
|
48
|
+
const text = SCRIPT.test(relative) ? readFileSync(from, "utf8") : void 0;
|
|
49
|
+
if (text === void 0 || !shouldCompile(from, text, driver.libraries)) {
|
|
50
|
+
copyFileSync(from, to);
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
const result = driver.transform(from, text);
|
|
54
|
+
texts.set(path.relative(root, from).replaceAll("\\", "/"), text);
|
|
55
|
+
reported.push(...result.diagnostics);
|
|
56
|
+
writeFileSync(to, result.code ?? text);
|
|
57
|
+
};
|
|
58
|
+
const stylesheet = () => {
|
|
59
|
+
reported.push(...driver.diagnostics());
|
|
60
|
+
const css = driver.stylesheet(options.minify ?? false);
|
|
61
|
+
const file = path.join(root, STYLESHEET);
|
|
62
|
+
const changed = !existsSync(file) || readFileSync(file, "utf8") !== css;
|
|
63
|
+
if (changed) writeFileSync(file, css);
|
|
64
|
+
return changed;
|
|
65
|
+
};
|
|
66
|
+
rmSync(target, {
|
|
67
|
+
recursive: true,
|
|
68
|
+
force: true
|
|
69
|
+
});
|
|
70
|
+
const files = walk(source);
|
|
71
|
+
for (const relative of files) mirror(relative);
|
|
72
|
+
stylesheet();
|
|
73
|
+
return {
|
|
74
|
+
replacements: files.filter((relative) => SCRIPT.test(relative) && !relative.endsWith(".d.ts")).map((relative) => ({
|
|
75
|
+
replace: path.join(sourceRoot, relative),
|
|
76
|
+
with: path.join(MIRROR, sourceRoot, relative)
|
|
77
|
+
})),
|
|
78
|
+
update(file) {
|
|
79
|
+
reported.length = 0;
|
|
80
|
+
const absolute = path.resolve(root, file);
|
|
81
|
+
const affected = [absolute, ...driver.invalidate(absolute)];
|
|
82
|
+
for (const changed of affected) mirror(path.relative(source, changed));
|
|
83
|
+
return stylesheet();
|
|
84
|
+
},
|
|
85
|
+
messages: () => reported.map((diagnostic) => formatDiagnostic(diagnostic, texts.get(diagnostic.file)))
|
|
86
|
+
};
|
|
94
87
|
}
|
|
95
88
|
/** Mirrors every change under the source folder until closed (watch builds and the dev server). */
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
return;
|
|
104
|
-
mirror.update(path.join(sourceRoot, relative));
|
|
105
|
-
onUpdate();
|
|
106
|
-
});
|
|
89
|
+
function watchMirror(root, sourceRoot, mirror, onUpdate, watch$1 = watch) {
|
|
90
|
+
return watch$1(path.join(root, sourceRoot), { recursive: true }, (_, name) => {
|
|
91
|
+
const relative = String(name);
|
|
92
|
+
if (relative.split(/[\\/]/).some((part) => part.startsWith(".") || SKIPPED.has(part))) return;
|
|
93
|
+
mirror.update(path.join(sourceRoot, relative));
|
|
94
|
+
onUpdate();
|
|
95
|
+
});
|
|
107
96
|
}
|
|
97
|
+
//#endregion
|
|
98
|
+
export { MIRROR, STYLESHEET, createMirror, walk, watchMirror };
|
package/src/sx.d.ts
CHANGED
|
@@ -1,21 +1,16 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* What `[sx]` does to an element, without Angular: merge the handles with Kirana's runtime (the same
|
|
3
|
-
* one compiled modules call), then bring the element's classes and custom properties from what the
|
|
4
|
-
* last value applied to what this one applies. Only what `[sx]` added is ever removed, so the
|
|
5
|
-
* element's own `class` and `style` stay.
|
|
6
|
-
*/
|
|
7
1
|
import { runtime } from "@kirana-style/core/internal";
|
|
2
|
+
//#region src/sx.d.ts
|
|
8
3
|
/** The part of Angular's `Renderer2` this needs. */
|
|
9
4
|
export type Renderer = {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
5
|
+
addClass: (element: unknown, name: string) => void;
|
|
6
|
+
removeClass: (element: unknown, name: string) => void;
|
|
7
|
+
setStyle: (element: unknown, name: string, value: string, flags?: number) => void;
|
|
8
|
+
removeStyle: (element: unknown, name: string, flags?: number) => void;
|
|
14
9
|
};
|
|
15
10
|
/** What the last value applied: its classes and its custom properties. */
|
|
16
11
|
export type Applied = {
|
|
17
|
-
|
|
18
|
-
|
|
12
|
+
classes: Set<string>;
|
|
13
|
+
styles: Set<string>;
|
|
19
14
|
};
|
|
20
15
|
/** `RendererStyleFlags2.DashCase`: the name is a custom property, set as written. */
|
|
21
16
|
export declare const DASH_CASE = 2;
|
|
@@ -23,3 +18,4 @@ export declare const DASH_CASE = 2;
|
|
|
23
18
|
export declare function runtimeFor(prefix: string): ReturnType<typeof runtime>;
|
|
24
19
|
/** Applies `value` (a handle, or an array of handles and falsy guards); returns what is applied now. */
|
|
25
20
|
export declare function applySx(renderer: Renderer, element: unknown, previous: Applied, value: unknown, prefix: string): Applied;
|
|
21
|
+
//#endregion
|
package/src/sx.js
CHANGED
|
@@ -1,38 +1,37 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* What `[sx]` does to an element, without Angular: merge the handles with Kirana's runtime (the same
|
|
3
|
-
* one compiled modules call), then bring the element's classes and custom properties from what the
|
|
4
|
-
* last value applied to what this one applies. Only what `[sx]` added is ever removed, so the
|
|
5
|
-
* element's own `class` and `style` stay.
|
|
6
|
-
*/
|
|
7
1
|
import { runtime } from "@kirana-style/core/internal";
|
|
2
|
+
//#region src/sx.ts
|
|
3
|
+
/**
|
|
4
|
+
* What `[sx]` does to an element, without Angular: merge the handles with Kirana's runtime (the same
|
|
5
|
+
* one compiled modules call), then bring the element's classes and custom properties from what the
|
|
6
|
+
* last value applied to what this one applies. Only what `[sx]` added is ever removed, so the
|
|
7
|
+
* element's own `class` and `style` stay.
|
|
8
|
+
*/
|
|
8
9
|
/** `RendererStyleFlags2.DashCase`: the name is a custom property, set as written. */
|
|
9
|
-
|
|
10
|
-
const runtimes = new Map();
|
|
10
|
+
const DASH_CASE = 2;
|
|
11
|
+
const runtimes = /* @__PURE__ */ new Map();
|
|
11
12
|
/** One runtime per class-name prefix, as each compiled module creates one. */
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
13
|
+
function runtimeFor(prefix) {
|
|
14
|
+
let created = runtimes.get(prefix);
|
|
15
|
+
if (!created) {
|
|
16
|
+
created = runtime(prefix, "class");
|
|
17
|
+
runtimes.set(prefix, created);
|
|
18
|
+
}
|
|
19
|
+
return created;
|
|
19
20
|
}
|
|
20
21
|
/** Applies `value` (a handle, or an array of handles and falsy guards); returns what is applied now. */
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
renderer.removeStyle(element, name, DASH_CASE);
|
|
35
|
-
for (const [name, setting] of Object.entries(styles))
|
|
36
|
-
renderer.setStyle(element, name, setting, DASH_CASE);
|
|
37
|
-
return { classes, styles: new Set(Object.keys(styles)) };
|
|
22
|
+
function applySx(renderer, element, previous, value, prefix) {
|
|
23
|
+
const handles = Array.isArray(value) ? value : [value];
|
|
24
|
+
const props = runtimeFor(prefix).sx(handles, [], []);
|
|
25
|
+
const classes = new Set((props.class ?? "").split(" ").filter(Boolean));
|
|
26
|
+
const styles = props.style ?? {};
|
|
27
|
+
for (const name of previous.classes) if (!classes.has(name)) renderer.removeClass(element, name);
|
|
28
|
+
for (const name of classes) if (!previous.classes.has(name)) renderer.addClass(element, name);
|
|
29
|
+
for (const name of previous.styles) if (!(name in styles)) renderer.removeStyle(element, name, 2);
|
|
30
|
+
for (const [name, setting] of Object.entries(styles)) renderer.setStyle(element, name, setting, 2);
|
|
31
|
+
return {
|
|
32
|
+
classes,
|
|
33
|
+
styles: new Set(Object.keys(styles))
|
|
34
|
+
};
|
|
38
35
|
}
|
|
36
|
+
//#endregion
|
|
37
|
+
export { DASH_CASE, applySx, runtimeFor };
|
package/src/vite.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
|
|
1
|
+
import { KiranaViteOptions } from "@kirana-style/vite";
|
|
2
|
+
import { Plugin } from "vite";
|
|
3
|
+
//#region src/vite.d.ts
|
|
4
4
|
export declare function kiranaAngular(options?: KiranaViteOptions): Plugin[];
|
|
5
|
-
|
|
5
|
+
//#endregion
|
|
6
|
+
export { type KiranaViteOptions as KiranaAngularOptions, kiranaAngular as default };
|
package/src/vite.js
CHANGED
|
@@ -1,15 +1,20 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Kirana for Analog, Angular on Vite (D-068). Angular compiles each TypeScript file from its own
|
|
3
|
-
* program on disk, so a plugin that ran first would change nothing it reads. This is Kirana's Vite
|
|
4
|
-
* plugin run after Angular's instead: it compiles the JavaScript Angular emitted for each module,
|
|
5
|
-
* where `css()` calls and their imports are as written. The stylesheet and its hot updates work as
|
|
6
|
-
* they do in every Vite app.
|
|
7
|
-
*
|
|
8
|
-
* plugins: [analog(), kiranaAngular()]
|
|
9
|
-
*/
|
|
10
1
|
import kirana from "@kirana-style/vite";
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
2
|
+
//#region src/vite.ts
|
|
3
|
+
/**
|
|
4
|
+
* Kirana for Analog, Angular on Vite (D-068). Angular compiles each TypeScript file from its own
|
|
5
|
+
* program on disk, so a plugin that ran first would change nothing it reads. This is Kirana's Vite
|
|
6
|
+
* plugin run after Angular's instead: it compiles the JavaScript Angular emitted for each module,
|
|
7
|
+
* where `css()` calls and their imports are as written. The stylesheet and its hot updates work as
|
|
8
|
+
* they do in every Vite app.
|
|
9
|
+
*
|
|
10
|
+
* plugins: [analog(), kiranaAngular()]
|
|
11
|
+
*/
|
|
12
|
+
function kiranaAngular(options = {}) {
|
|
13
|
+
const [main, late] = kirana(options);
|
|
14
|
+
return [{
|
|
15
|
+
...main,
|
|
16
|
+
enforce: "post"
|
|
17
|
+
}, late];
|
|
14
18
|
}
|
|
15
|
-
|
|
19
|
+
//#endregion
|
|
20
|
+
export { kiranaAngular as default, kiranaAngular };
|