@aircloudhq/web 1.0.0 → 1.0.2
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 +119 -0
- package/package.json +26 -4
package/README.md
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
# @aircloudhq/web
|
|
2
|
+
|
|
3
|
+
The application package of an Air-Cloud product: what a product's site and its JavaScript functions
|
|
4
|
+
import to render pages, format values and speak the product's languages. It brings the Rails Action View
|
|
5
|
+
helpers to the browser and to functions, one module per Rails helper module, under the names a Rails
|
|
6
|
+
developer already knows (`numberToCurrency`, `timeAgoInWords`, `t`, `l`, and the `LinkTo` and
|
|
7
|
+
`FormWith` components).
|
|
8
|
+
|
|
9
|
+
- **Pages from your models.** `resourcePage("pet")` renders list, show, create, edit and delete for an
|
|
10
|
+
entity from the resource projection the platform derives from `db/schema/pet.toml`. Adding a field to
|
|
11
|
+
the schema changes the page with no edit to the view.
|
|
12
|
+
- **I18n.** Translations come from the locale bundle the platform compiles from `config/locales/`, with
|
|
13
|
+
Rails' lazy lookup: `t(".title")` in `pages/home/index.jsx` reads `home.index.title`. Plurals, dates,
|
|
14
|
+
numbers and currencies follow CLDR for every locale the product declares.
|
|
15
|
+
- **The same helpers in functions.** `@aircloudhq/web/function` gives a function the caller's locale,
|
|
16
|
+
so its error messages answer in the language of the request.
|
|
17
|
+
- **React bindings.** `@aircloudhq/web/react` carries the router, layouts, links and form components.
|
|
18
|
+
|
|
19
|
+
A product created with `aircloud new` already depends on this package, at the version the platform
|
|
20
|
+
builds and tests with. You rarely add it by hand.
|
|
21
|
+
|
|
22
|
+
## Install
|
|
23
|
+
|
|
24
|
+
```sh
|
|
25
|
+
npm install @aircloudhq/web
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
It needs the Node.js release its `engines` field names (the platform's pinned line), and React 19.2.7 or later for
|
|
29
|
+
the React bindings.
|
|
30
|
+
|
|
31
|
+
## Usage
|
|
32
|
+
|
|
33
|
+
The site entry point `aircloud new` generates (`app/site/src/main.jsx`) renders the product's routes
|
|
34
|
+
inside its layouts, with the locale bundle and the resource projection:
|
|
35
|
+
|
|
36
|
+
```jsx
|
|
37
|
+
import { StrictMode } from "react";
|
|
38
|
+
import { createRoot } from "react-dom/client";
|
|
39
|
+
import { I18nProvider, SiteRouter } from "@aircloudhq/web/react";
|
|
40
|
+
import bundle from "../.aircloud/locale-bundle.json";
|
|
41
|
+
import projection from "../.aircloud/resource-projection.json";
|
|
42
|
+
import routes from "./routes.js";
|
|
43
|
+
|
|
44
|
+
// Every src/layouts/<name>.jsx, by name (`application` is the default layout).
|
|
45
|
+
const layouts = Object.fromEntries(
|
|
46
|
+
Object.entries(import.meta.glob("./layouts/*.jsx", { eager: true })).map(([file, module]) => [
|
|
47
|
+
file.slice(file.lastIndexOf("/") + 1, -4),
|
|
48
|
+
module.default,
|
|
49
|
+
]),
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
createRoot(document.getElementById("root")).render(
|
|
53
|
+
<StrictMode>
|
|
54
|
+
<I18nProvider bundle={bundle}>
|
|
55
|
+
<SiteRouter routes={routes} layouts={layouts} projection={projection} />
|
|
56
|
+
</I18nProvider>
|
|
57
|
+
</StrictMode>,
|
|
58
|
+
);
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
A page reads its strings by lazy lookup (`app/site/src/pages/home/index.jsx`):
|
|
62
|
+
|
|
63
|
+
```jsx
|
|
64
|
+
import { useT } from "@aircloudhq/web/react";
|
|
65
|
+
|
|
66
|
+
export default function HomePage() {
|
|
67
|
+
const t = useT();
|
|
68
|
+
return (
|
|
69
|
+
<section>
|
|
70
|
+
<h1>{t(".title")}</h1>
|
|
71
|
+
<p>{t(".intro")}</p>
|
|
72
|
+
</section>
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
The resource page `aircloud generate scaffold pet` writes is one line (`app/site/src/pages/pet/index.jsx`):
|
|
78
|
+
|
|
79
|
+
```jsx
|
|
80
|
+
import { resourcePage } from "@aircloudhq/web/react";
|
|
81
|
+
|
|
82
|
+
export default resourcePage("pet");
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
A function answers in the caller's locale (`app/functions/pet/index.js`):
|
|
86
|
+
|
|
87
|
+
```js
|
|
88
|
+
import { i18nFor } from "@aircloudhq/web/function";
|
|
89
|
+
|
|
90
|
+
async function methodNotAllowed(request) {
|
|
91
|
+
// functions.pet.errors.method_not_allowed, in the locale the request negotiates
|
|
92
|
+
const i18n = await i18nFor(request, { function: "pet" });
|
|
93
|
+
return Response.json({ error: { code: "method_not_allowed", message: i18n.t(".errors.method_not_allowed", { method: request.method }) } }, { status: 405 });
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## Modules
|
|
98
|
+
|
|
99
|
+
| Import | What it carries |
|
|
100
|
+
|---|---|
|
|
101
|
+
| `@aircloudhq/web/react` | `SiteRouter`, `I18nProvider`, `useT`, `useSite`, `LinkTo`, `FormWith`, `resourcePage` |
|
|
102
|
+
| `@aircloudhq/web/helpers/number` | `numberToCurrency`, `numberToPercentage`, `numberWithDelimiter`, … |
|
|
103
|
+
| `@aircloudhq/web/helpers/date` | `timeAgoInWords`, `distanceOfTimeInWords`, `distanceOfTimeInWordsToNow` |
|
|
104
|
+
| `@aircloudhq/web/helpers/text`, `…/tag`, `…/url`, `…/form`, `…/sanitize`, `…/navigation` | the Action View helper modules of the same name |
|
|
105
|
+
| `@aircloudhq/web/helpers/translation` | `t` and `l` |
|
|
106
|
+
| `@aircloudhq/web/i18n` | `createI18n`, the runtime of the locale bundle |
|
|
107
|
+
| `@aircloudhq/web/model` | `modelName` and the model naming helpers |
|
|
108
|
+
| `@aircloudhq/web/function` | `i18nFor`, for functions |
|
|
109
|
+
|
|
110
|
+
## Documentation
|
|
111
|
+
|
|
112
|
+
The full Rails-to-Air-Cloud map — every Action View helper and where it lives here — is the
|
|
113
|
+
*Rails to Air-Cloud* reference in the Air-Cloud documentation. Its tests in a product run with
|
|
114
|
+
`@aircloudhq/testing`. Questions and bug reports go to this package's issue tracker (the `bugs` link
|
|
115
|
+
on its npm page).
|
|
116
|
+
|
|
117
|
+
## License
|
|
118
|
+
|
|
119
|
+
MIT
|
package/package.json
CHANGED
|
@@ -1,11 +1,31 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aircloudhq/web",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"description": "The
|
|
3
|
+
"version": "1.0.2",
|
|
4
|
+
"description": "The application package of an Air-Cloud product: the Rails Action View helpers, i18n over the product's locale bundle, resource pages over its models, and React bindings, for its site and its JavaScript functions.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"aircloud",
|
|
7
|
+
"rails",
|
|
8
|
+
"action-view",
|
|
9
|
+
"helpers",
|
|
10
|
+
"i18n",
|
|
11
|
+
"react",
|
|
12
|
+
"site",
|
|
13
|
+
"functions"
|
|
14
|
+
],
|
|
15
|
+
"homepage": "https://github.com/aircloudhq/packages/tree/main/aircloud-web#readme",
|
|
16
|
+
"bugs": {
|
|
17
|
+
"url": "https://github.com/aircloudhq/packages/issues"
|
|
18
|
+
},
|
|
19
|
+
"repository": {
|
|
20
|
+
"type": "git",
|
|
21
|
+
"url": "git+https://github.com/aircloudhq/packages.git",
|
|
22
|
+
"directory": "aircloud-web"
|
|
23
|
+
},
|
|
24
|
+
"author": "Air-Cloud",
|
|
5
25
|
"license": "MIT",
|
|
6
26
|
"type": "module",
|
|
7
27
|
"engines": {
|
|
8
|
-
"node": "
|
|
28
|
+
"node": "^24.21.0"
|
|
9
29
|
},
|
|
10
30
|
"exports": {
|
|
11
31
|
".": "./src/index.js",
|
|
@@ -27,7 +47,9 @@
|
|
|
27
47
|
"./package.json": "./package.json"
|
|
28
48
|
},
|
|
29
49
|
"files": [
|
|
30
|
-
"src/"
|
|
50
|
+
"src/",
|
|
51
|
+
"README.md",
|
|
52
|
+
"LICENSE"
|
|
31
53
|
],
|
|
32
54
|
"sideEffects": false,
|
|
33
55
|
"dependencies": {
|