@madojs/mado 0.5.0 → 0.6.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.
Files changed (122) hide show
  1. package/AGENTS.md +49 -1
  2. package/CHANGELOG.md +188 -0
  3. package/MADO_V1_PLAN.md +179 -0
  4. package/README.md +53 -14
  5. package/ROADMAP.md +36 -5
  6. package/TODO.md +72 -0
  7. package/dist/src/forms.d.ts +41 -7
  8. package/dist/src/forms.js +334 -59
  9. package/dist/src/forms.js.map +1 -1
  10. package/dist/src/html/bindings.d.ts +41 -0
  11. package/dist/src/html/bindings.js +163 -6
  12. package/dist/src/html/bindings.js.map +1 -1
  13. package/dist/src/html.d.ts +2 -0
  14. package/dist/src/html.js +1 -0
  15. package/dist/src/html.js.map +1 -1
  16. package/dist/src/index.d.ts +6 -6
  17. package/dist/src/index.js +2 -2
  18. package/dist/src/index.js.map +1 -1
  19. package/dist/src/page.d.ts +56 -0
  20. package/dist/src/page.js +17 -0
  21. package/dist/src/page.js.map +1 -1
  22. package/dist/src/router/manifest.d.ts +16 -1
  23. package/dist/src/router/manifest.js +181 -38
  24. package/dist/src/router/manifest.js.map +1 -1
  25. package/dist/src/router/match.d.ts +7 -2
  26. package/dist/src/router/match.js +14 -4
  27. package/dist/src/router/match.js.map +1 -1
  28. package/dist/src/router/navigation.d.ts +10 -0
  29. package/dist/src/router/navigation.js +73 -12
  30. package/dist/src/router/navigation.js.map +1 -1
  31. package/dist/src/signal.d.ts +15 -1
  32. package/dist/src/signal.js +112 -16
  33. package/dist/src/signal.js.map +1 -1
  34. package/docs/en/02-project-layout.md +99 -40
  35. package/docs/en/05-why-mado.md +1 -1
  36. package/docs/en/06-for-backenders.md +1 -1
  37. package/docs/en/07-llm-pitfalls.md +1 -1
  38. package/docs/en/09-shadow-vs-light-dom.md +60 -0
  39. package/docs/en/10-app-architecture.md +141 -0
  40. package/docs/en/11-layouts.md +115 -0
  41. package/docs/en/12-auth-and-api.md +217 -0
  42. package/docs/en/13-deployment.md +192 -0
  43. package/docs/en/14-testing.md +82 -0
  44. package/docs/en/15-error-handling.md +100 -0
  45. package/docs/en/16-bake-cookbook.md +93 -0
  46. package/docs/en/README.md +7 -0
  47. package/docs/fr/05-why-mado.md +1 -1
  48. package/docs/fr/06-for-backenders.md +1 -1
  49. package/docs/fr/07-llm-pitfalls.md +1 -1
  50. package/docs/fr/09-shadow-vs-light-dom.md +63 -0
  51. package/docs/fr/10-app-architecture.md +61 -0
  52. package/docs/fr/11-layouts.md +35 -0
  53. package/docs/fr/12-auth-and-api.md +35 -0
  54. package/docs/fr/13-deployment.md +39 -0
  55. package/docs/fr/14-testing.md +41 -0
  56. package/docs/fr/15-error-handling.md +50 -0
  57. package/docs/fr/16-bake-cookbook.md +35 -0
  58. package/docs/fr/README.md +7 -0
  59. package/docs/ru/05-why-mado.md +2 -2
  60. package/docs/ru/06-for-backenders.md +1 -1
  61. package/docs/ru/09-shadow-vs-light-dom.md +60 -0
  62. package/docs/ru/10-app-architecture.md +100 -0
  63. package/docs/ru/11-layouts.md +47 -0
  64. package/docs/ru/12-auth-and-api.md +53 -0
  65. package/docs/ru/13-deployment.md +60 -0
  66. package/docs/ru/14-testing.md +50 -0
  67. package/docs/ru/15-error-handling.md +56 -0
  68. package/docs/ru/16-bake-cookbook.md +55 -0
  69. package/docs/ru/README.md +7 -0
  70. package/docs/uk/06-for-backenders.md +2 -2
  71. package/docs/uk/09-shadow-vs-light-dom.md +91 -24
  72. package/docs/uk/10-app-architecture.md +56 -0
  73. package/docs/uk/11-layouts.md +34 -0
  74. package/docs/uk/12-auth-and-api.md +34 -0
  75. package/docs/uk/13-deployment.md +39 -0
  76. package/docs/uk/14-testing.md +34 -0
  77. package/docs/uk/15-error-handling.md +32 -0
  78. package/docs/uk/16-bake-cookbook.md +36 -0
  79. package/docs/uk/README.md +7 -0
  80. package/llms.txt +24 -1
  81. package/package.json +3 -1
  82. package/scripts/_config.mjs +224 -0
  83. package/scripts/bake.mjs +217 -120
  84. package/scripts/bundle.mjs +110 -67
  85. package/scripts/cli.mjs +127 -16
  86. package/scripts/preview.mjs +22 -12
  87. package/server/serve.mjs +101 -11
  88. package/starters/admin/README.md +63 -0
  89. package/starters/admin/index.html +21 -0
  90. package/starters/admin/mado.config.json +22 -0
  91. package/starters/admin/package.json +22 -0
  92. package/starters/admin/public/favicon.svg +4 -0
  93. package/starters/admin/src/components/x-button.ts +55 -0
  94. package/starters/admin/src/components/x-input.ts +74 -0
  95. package/starters/admin/src/layouts/app.ts +101 -0
  96. package/starters/admin/src/layouts/auth.ts +41 -0
  97. package/starters/admin/src/lib/api.ts +133 -0
  98. package/starters/admin/src/lib/auth.ts +83 -0
  99. package/starters/admin/src/main.ts +15 -0
  100. package/starters/admin/src/pages/admin/dashboard.ts +48 -0
  101. package/starters/admin/src/pages/admin/order-detail.ts +78 -0
  102. package/starters/admin/src/pages/admin/orders.ts +117 -0
  103. package/starters/admin/src/pages/home.ts +25 -0
  104. package/starters/admin/src/pages/login.ts +70 -0
  105. package/starters/admin/src/pages/not-found.ts +12 -0
  106. package/starters/admin/src/routes.ts +40 -0
  107. package/starters/admin/src/styles/global.ts +86 -0
  108. package/starters/admin/tsconfig.json +15 -0
  109. package/starters/crud/README.md +14 -2
  110. package/starters/crud/mado.config.json +20 -0
  111. package/starters/crud/package.json +9 -4
  112. package/starters/crud/src/components/app-shell.ts +13 -8
  113. package/starters/crud/src/main.ts +1 -4
  114. package/starters/crud/src/pages/ticket-detail.ts +1 -0
  115. package/starters/crud/src/pages/ticket-new.ts +1 -0
  116. package/starters/crud/src/pages/tickets.ts +1 -0
  117. package/starters/crud/src/routes.ts +4 -2
  118. package/starters/minimal/README.md +4 -2
  119. package/starters/minimal/mado.config.json +20 -0
  120. package/starters/minimal/package.json +8 -3
  121. package/starters/minimal/src/components/app-counter.ts +1 -1
  122. package/starters/minimal/src/routes.ts +4 -2
@@ -0,0 +1,86 @@
1
+ // Global design tokens + a tiny utility layer for admin UIs.
2
+ //
3
+ // Tokens are CSS custom properties on :root so layouts and components can pick
4
+ // them up without a CSS preprocessor. Light/dark via prefers-color-scheme.
5
+ //
6
+ // Keep this file intentionally small. Components should style themselves with
7
+ // Shadow DOM. Light DOM utilities (.row, .stack, .card) are here only because
8
+ // they show up in every admin page and would be noisy to redefine per component.
9
+
10
+ const css = `
11
+ :root {
12
+ color-scheme: light dark;
13
+
14
+ --bg: #ffffff;
15
+ --bg-elevated: #f7f8fa;
16
+ --fg: #0f172a;
17
+ --fg-muted: #475569;
18
+ --border: #e2e8f0;
19
+ --accent: #1f6feb;
20
+ --accent-fg: #ffffff;
21
+ --danger: #b91c1c;
22
+ --success: #15803d;
23
+
24
+ --radius: 8px;
25
+ --radius-sm: 6px;
26
+ --space-1: 4px;
27
+ --space-2: 8px;
28
+ --space-3: 12px;
29
+ --space-4: 16px;
30
+ --space-5: 24px;
31
+ --space-6: 32px;
32
+
33
+ --font-sans: ui-sans-serif, system-ui, -apple-system, "Segoe UI",
34
+ Roboto, Inter, Helvetica, Arial, sans-serif;
35
+
36
+ --shadow-1: 0 1px 2px rgba(15, 23, 42, .05),
37
+ 0 1px 1px rgba(15, 23, 42, .04);
38
+ }
39
+
40
+ @media (prefers-color-scheme: dark) {
41
+ :root {
42
+ --bg: #0b1220;
43
+ --bg-elevated: #111a2e;
44
+ --fg: #e6eefc;
45
+ --fg-muted: #9aa6bd;
46
+ --border: #1f2a44;
47
+ --accent: #3b82f6;
48
+ --accent-fg: #0b1220;
49
+ }
50
+ }
51
+
52
+ * { box-sizing: border-box; }
53
+ html, body { margin: 0; padding: 0; }
54
+ body {
55
+ background: var(--bg);
56
+ color: var(--fg);
57
+ font-family: var(--font-sans);
58
+ font-size: 14px;
59
+ line-height: 1.5;
60
+ min-height: 100vh;
61
+ }
62
+
63
+ a { color: var(--accent); text-decoration: none; }
64
+ a:hover { text-decoration: underline; }
65
+
66
+ .row { display: flex; align-items: center; gap: var(--space-3); }
67
+ .stack { display: flex; flex-direction: column; gap: var(--space-3); }
68
+ .spacer { flex: 1; }
69
+
70
+ .card {
71
+ background: var(--bg-elevated);
72
+ border: 1px solid var(--border);
73
+ border-radius: var(--radius);
74
+ padding: var(--space-5);
75
+ box-shadow: var(--shadow-1);
76
+ }
77
+
78
+ .muted { color: var(--fg-muted); }
79
+ `;
80
+
81
+ if (typeof document !== "undefined" && !document.getElementById("admin-global-style")) {
82
+ const tag = document.createElement("style");
83
+ tag.id = "admin-global-style";
84
+ tag.textContent = css;
85
+ document.head.appendChild(tag);
86
+ }
@@ -0,0 +1,15 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "NodeNext",
5
+ "moduleResolution": "NodeNext",
6
+ "lib": ["ES2022", "DOM"],
7
+ "strict": true,
8
+ "skipLibCheck": true,
9
+ "outDir": "dist",
10
+ "rootDir": "src",
11
+ "declaration": false,
12
+ "sourceMap": true
13
+ },
14
+ "include": ["src/**/*.ts"]
15
+ }
@@ -4,18 +4,30 @@ Generated with the Mado CRUD starter.
4
4
 
5
5
  ```bash
6
6
  npm install
7
- npm run build
8
- npm run serve
7
+ npm run dev
9
8
  ```
10
9
 
11
10
  Open http://localhost:5173.
12
11
 
12
+ Use `npm run build` for a production TypeScript build and `npm run serve` to
13
+ serve an already-built app.
14
+
13
15
  This starter demonstrates:
14
16
 
15
17
  - lazy routes;
16
18
  - Web Components through `component()`;
19
+ - an app shell component with Shadow DOM and `<slot>`;
17
20
  - query params through `queryParam()`;
18
21
  - async data through `resource()`;
19
22
  - mutations with invalidation;
20
23
  - forms through `useForm()`;
21
24
  - keyed tables through `each()`.
25
+
26
+ `x-app-shell` uses Shadow DOM because it owns the page frame and projects route
27
+ pages through `<slot>`. Page/table/form components can still use global styles:
28
+ slotted route pages remain normal document DOM.
29
+
30
+ Component imports are explicit registration side effects. `main.ts` imports the
31
+ global app shell. Feature pages import the components they render, for example
32
+ `src/pages/tickets.ts` imports `../components/ticket-list.js` before rendering
33
+ `<ticket-list>`.
@@ -0,0 +1,20 @@
1
+ {
2
+ "dev": {
3
+ "port": 5173,
4
+ "proxy": {}
5
+ },
6
+ "build": {
7
+ "out": "out",
8
+ "dist": "dist",
9
+ "publicDir": "public"
10
+ },
11
+ "bake": {
12
+ "entry": "src/routes.ts",
13
+ "template": "index.html",
14
+ "baseUrl": "https://example.com"
15
+ },
16
+ "bundle": {
17
+ "splitting": true,
18
+ "compress": ["gz", "br"]
19
+ }
20
+ }
@@ -4,9 +4,14 @@
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "scripts": {
7
- "build": "tsc -p tsconfig.json",
8
- "typecheck": "tsc -p tsconfig.json --noEmit",
9
- "serve": "mado serve"
7
+ "build": "mado build",
8
+ "typecheck": "mado typecheck",
9
+ "dev": "mado dev",
10
+ "serve": "mado serve",
11
+ "bundle": "mado bundle",
12
+ "bake": "mado bake",
13
+ "release": "mado release",
14
+ "preview": "mado preview"
10
15
  },
11
16
  "dependencies": {
12
17
  "@madojs/mado": "__MADOJS_VERSION__"
@@ -14,4 +19,4 @@
14
19
  "devDependencies": {
15
20
  "typescript": "^6.0.3"
16
21
  }
17
- }
22
+ }
@@ -1,7 +1,7 @@
1
1
  import { component, css, html } from "@madojs/mado";
2
2
 
3
3
  component(
4
- "app-shell",
4
+ "x-app-shell",
5
5
  () => () => html`
6
6
  <header>
7
7
  <a class="brand" href="/" data-link>__APP_NAME__</a>
@@ -11,17 +11,18 @@ component(
11
11
  <a href="/tickets/new" data-link>New ticket</a>
12
12
  </nav>
13
13
  </header>
14
- <slot></slot>
14
+ <main>
15
+ <slot></slot>
16
+ </main>
15
17
  `,
16
18
  {
17
- shadow: false,
18
19
  styles: css`
19
- app-shell {
20
+ :host {
20
21
  min-height: 100vh;
21
22
  display: block;
22
23
  }
23
24
 
24
- app-shell header {
25
+ header {
25
26
  display: flex;
26
27
  align-items: center;
27
28
  justify-content: space-between;
@@ -31,18 +32,22 @@ component(
31
32
  padding: 0.9rem 1.25rem;
32
33
  }
33
34
 
34
- app-shell nav {
35
+ main {
36
+ display: block;
37
+ }
38
+
39
+ nav {
35
40
  display: flex;
36
41
  gap: 0.75rem;
37
42
  flex-wrap: wrap;
38
43
  }
39
44
 
40
- app-shell a {
45
+ a {
41
46
  color: #334155;
42
47
  text-decoration: none;
43
48
  }
44
49
 
45
- app-shell .brand {
50
+ .brand {
46
51
  color: #111827;
47
52
  font-weight: 800;
48
53
  }
@@ -1,12 +1,9 @@
1
1
  import { html, render } from "@madojs/mado";
2
2
  import "./styles/global.js";
3
3
  import "./components/app-shell.js";
4
- import "./components/ticket-list.js";
5
- import "./components/ticket-form.js";
6
- import "./components/ticket-detail.js";
7
4
  import router from "./routes.js";
8
5
 
9
6
  const app = document.getElementById("app");
10
7
  if (!app) throw new Error("#app not found");
11
8
 
12
- render(html`<app-shell>${router.view}</app-shell>`, app);
9
+ render(html`<x-app-shell>${router.view}</x-app-shell>`, app);
@@ -1,4 +1,5 @@
1
1
  import { html, page } from "@madojs/mado";
2
+ import "../components/ticket-detail.js";
2
3
 
3
4
  export default page<{ id: string }>({
4
5
  title: ({ id }) => `Ticket ${id}`,
@@ -1,4 +1,5 @@
1
1
  import { html, page } from "@madojs/mado";
2
+ import "../components/ticket-form.js";
2
3
 
3
4
  export default page({
4
5
  title: "New ticket",
@@ -1,4 +1,5 @@
1
1
  import { html, page } from "@madojs/mado";
2
+ import "../components/ticket-list.js";
2
3
 
3
4
  export default page({
4
5
  title: "Tickets",
@@ -1,9 +1,11 @@
1
1
  import { routes } from "@madojs/mado";
2
2
 
3
- export default routes({
3
+ export const manifest = {
4
4
  "/": () => import("./pages/home.js"),
5
5
  "/tickets": () => import("./pages/tickets.js"),
6
6
  "/tickets/new": () => import("./pages/ticket-new.js"),
7
7
  "/tickets/:id": () => import("./pages/ticket-detail.js"),
8
8
  "*": () => import("./pages/not-found.js"),
9
- });
9
+ };
10
+
11
+ export default routes(manifest);
@@ -4,12 +4,14 @@ Generated with Mado __MADO_VERSION__.
4
4
 
5
5
  ```bash
6
6
  npm install
7
- npm run build
8
- npm run serve
7
+ npm run dev
9
8
  ```
10
9
 
11
10
  Open http://localhost:5173.
12
11
 
12
+ Use `npm run build` for a production TypeScript build and `npm run serve` to
13
+ serve an already-built app.
14
+
13
15
  ## Files
14
16
 
15
17
  - `src/main.ts` mounts the router into `#app`.
@@ -0,0 +1,20 @@
1
+ {
2
+ "dev": {
3
+ "port": 5173,
4
+ "proxy": {}
5
+ },
6
+ "build": {
7
+ "out": "out",
8
+ "dist": "dist",
9
+ "publicDir": "public"
10
+ },
11
+ "bake": {
12
+ "entry": "src/routes.ts",
13
+ "template": "index.html",
14
+ "baseUrl": "https://example.com"
15
+ },
16
+ "bundle": {
17
+ "splitting": true,
18
+ "compress": ["gz", "br"]
19
+ }
20
+ }
@@ -4,9 +4,14 @@
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "scripts": {
7
- "build": "tsc -p tsconfig.json",
8
- "typecheck": "tsc -p tsconfig.json --noEmit",
9
- "serve": "mado serve"
7
+ "build": "mado build",
8
+ "typecheck": "mado typecheck",
9
+ "dev": "mado dev",
10
+ "serve": "mado serve",
11
+ "bundle": "mado bundle",
12
+ "bake": "mado bake",
13
+ "release": "mado release",
14
+ "preview": "mado preview"
10
15
  },
11
16
  "dependencies": {
12
17
  "@madojs/mado": "__MADOJS_VERSION__"
@@ -1,7 +1,7 @@
1
1
  import { component, css, html, signal } from "@madojs/mado";
2
2
 
3
3
  component(
4
- "app-counter",
4
+ "x-app-counter",
5
5
  () => {
6
6
  const count = signal(0);
7
7
  return () => html`
@@ -1,6 +1,8 @@
1
1
  import { routes } from "@madojs/mado";
2
2
 
3
- export default routes({
3
+ export const manifest = {
4
4
  "/": () => import("./pages/home.js"),
5
5
  "*": () => import("./pages/not-found.js"),
6
- });
6
+ };
7
+
8
+ export default routes(manifest);