@mostajs/crud-ui 0.1.0 → 0.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/CHANGELOG.md +16 -0
- package/README.md +5 -0
- package/llms.txt +6 -1
- package/package.json +15 -7
- package/src/html/index.js +1 -1
- package/src/html/panel.js +35 -8
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,22 @@
|
|
|
3
3
|
Format [Keep a Changelog](https://keepachangelog.com/fr/1.0.0/) · [SemVer](https://semver.org/lang/fr/).
|
|
4
4
|
Auteur : Dr Hamid MADANI <drmdh@msn.com>
|
|
5
5
|
|
|
6
|
+
## [0.2.0] — 2026-10-08
|
|
7
|
+
|
|
8
|
+
### Added
|
|
9
|
+
- `panel({ labels })` : `{ fiche, actions, ajouter, creer }` fournis par l'app — « Actions » et « 📋 Fiche »
|
|
10
|
+
restaient en français dans une page anglaise ou arabe.
|
|
11
|
+
- `panel({ style: 'classes' })` : aucun style en ligne, panneau enveloppé dans `.cu-panel` ; `detailLink(href, label, { style })`.
|
|
12
|
+
- `CU_CSS` : feuille du mode `classes` sur les jetons de Palette Studio (`--brand`, `--link`, `--ink`, `--line`,
|
|
13
|
+
`--surface`, `--surface-alt`), avec replis ; couvre le balisage d'`@mostajs/app-shell-ui` (table, h1, .sub, .back, .act).
|
|
14
|
+
- `panel({ cell })` : rendu d'une cellule délégué à l'app (transmis à `table`).
|
|
15
|
+
|
|
16
|
+
### Fixed
|
|
17
|
+
- Dépendances `workspace:^` remplacées par des plages publiables (`npm publish` ne les réécrit pas).
|
|
18
|
+
|
|
19
|
+
### Tests
|
|
20
|
+
- `test-scripts/unit/style.test.mjs` (T-STY-1 à 4).
|
|
21
|
+
|
|
6
22
|
## [0.1.0] — 2026-06-20
|
|
7
23
|
|
|
8
24
|
### Added
|
package/README.md
CHANGED
|
@@ -44,6 +44,11 @@ Génère : formulaire `POST /m/companies/create`, table avec lien détail `GET /
|
|
|
44
44
|
|
|
45
45
|
> **Sécurité** : valeurs/route/labels échappés (via `app-shell-ui`). `note`/`extra`/`create.extra` = HTML brut (responsabilité de l'appelant).
|
|
46
46
|
|
|
47
|
+
## Habillage et langue (0.2.0)
|
|
48
|
+
`panel({ labels: { fiche, actions, ajouter, creer }, style: 'classes', cell })` : libellés fournis par l'app
|
|
49
|
+
(défauts français), aucun style en ligne en mode `classes` (poser `CU_CSS`, sur les jetons de Palette Studio),
|
|
50
|
+
rendu de cellule délégué.
|
|
51
|
+
|
|
47
52
|
## Tests & exemple
|
|
48
53
|
|
|
49
54
|
```bash
|
package/llms.txt
CHANGED
|
@@ -13,11 +13,16 @@ PRINCIPE
|
|
|
13
13
|
COMPOSE
|
|
14
14
|
@mostajs/app-shell-ui OBLIGATOIRE (dep). Fournit table/form/pageTitle/back/esc + thème.
|
|
15
15
|
|
|
16
|
+
HABILLAGE ET LANGUE (0.2.0)
|
|
17
|
+
panel({ …, labels:{fiche,actions,ajouter,creer}, style:'inline'|'classes', cell?(row,col) }) ; détails :
|
|
18
|
+
style 'classes' → aucun style en ligne, enveloppe .cu-panel ; poser CU_CSS (jetons Palette Studio) ou sa feuille.
|
|
19
|
+
Sans labels, les libellés par défaut sont FRANÇAIS : une app multilingue les fournit toujours.
|
|
20
|
+
|
|
16
21
|
EXPORTS (".", "./html")
|
|
17
22
|
panel({ title?, sub?, back?={href,label}, note?, rows, cols?, hidden?=['id','_status'], routeBase='',
|
|
18
23
|
detail?=false|(row)=>href, actions?=[{id,label,show?(row)}], create?={fields,title?,submit?,enctype?,extra?},
|
|
19
24
|
extra?, empty? }) -> htmlString // CORPS du panneau (à enrober via app-shell-ui.page())
|
|
20
|
-
detailLink(href, label?='📋 Fiche') ; actionForm(routeBase, action, row) ; actionsCell(routeBase, actions, row)
|
|
25
|
+
detailLink(href, label?='📋 Fiche', {style}?) ; CU_CSS ; actionForm(routeBase, action, row) ; actionsCell(routeBase, actions, row)
|
|
21
26
|
|
|
22
27
|
DÉTAILS
|
|
23
28
|
- create.fields = format app-shell-ui `form` ({name,label,type?,value?,required?,options?,list?}) ; l'app résout les
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mostajs/crud-ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Panneau CRUD générique (rendu HTML-string, zéro dépendance) : spec déclaratif + lignes → formulaire de création + table (lien détail + actions POST). Compose @mostajs/app-shell-ui. Membre de mosta-ui-html-stack.",
|
|
5
5
|
"license": "AGPL-3.0-or-later",
|
|
6
6
|
"author": "Dr Hamid MADANI <drmdh@msn.com>",
|
|
@@ -16,6 +16,11 @@
|
|
|
16
16
|
".": "./src/html/index.js",
|
|
17
17
|
"./html": "./src/html/index.js"
|
|
18
18
|
},
|
|
19
|
+
"scripts": {
|
|
20
|
+
"test": "bash test-scripts/run-tests.sh",
|
|
21
|
+
"example": "node examples/run.mjs",
|
|
22
|
+
"clean": "rm -f examples/out.html test-report.html"
|
|
23
|
+
},
|
|
19
24
|
"keywords": [
|
|
20
25
|
"mostajs",
|
|
21
26
|
"ui",
|
|
@@ -30,11 +35,14 @@
|
|
|
30
35
|
"@mostajs/app-shell-ui": "^0.1.0"
|
|
31
36
|
},
|
|
32
37
|
"devDependencies": {
|
|
33
|
-
"@mostajs/mjs-unit": "^0.
|
|
38
|
+
"@mostajs/mjs-unit": "^0.7.0"
|
|
34
39
|
},
|
|
35
|
-
"
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
"
|
|
40
|
+
"mostajs": {
|
|
41
|
+
"niveau": "N2",
|
|
42
|
+
"nature": "compose",
|
|
43
|
+
"reutilisabilite": "multi-domaine",
|
|
44
|
+
"depend_de": [
|
|
45
|
+
"@mostajs/app-shell-ui"
|
|
46
|
+
]
|
|
39
47
|
}
|
|
40
|
-
}
|
|
48
|
+
}
|
package/src/html/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// @mostajs/crud-ui — barrel ./html. Author: Dr Hamid MADANI <drmdh@msn.com>
|
|
2
|
-
export { panel, detailLink, actionForm, actionsCell } from './panel.js';
|
|
2
|
+
export { panel, detailLink, actionForm, actionsCell, CU_CSS } from './panel.js';
|
package/src/html/panel.js
CHANGED
|
@@ -3,9 +3,34 @@
|
|
|
3
3
|
// COMPOSE @mostajs/app-shell-ui (table/form/pageTitle/back/esc) — aucune primitive bas-niveau ni accès données ici.
|
|
4
4
|
import { esc, table, form, pageTitle, back as backLink } from '@mostajs/app-shell-ui';
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* 0.2.0 — DEUX HABILLAGES. `inline` (défaut, inchangé) : le lien porte son style. `classes` : aucun style en ligne,
|
|
8
|
+
* la page habille par les classes `cu-*` (avec `CU_CSS` ou sa propre feuille). Demande du fondateur, 08/10/2026 :
|
|
9
|
+
* un style imposé en ligne ne se surcharge qu'à coups de `!important`.
|
|
10
|
+
*/
|
|
11
|
+
const LIBELLES = { fiche: '📋 Fiche', actions: 'Actions', ajouter: '➕ Ajouter', creer: 'Créer' };
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* La feuille du mode `classes`, sur les jetons de Palette Studio (ceux que pose @mostajs/wagon-ui), avec replis.
|
|
15
|
+
* Elle couvre aussi le balisage d'@mostajs/app-shell-ui que le panneau compose (table, h1, .sub, .back, .act).
|
|
16
|
+
*/
|
|
17
|
+
export const CU_CSS = `.cu-panel{--cu-accent:var(--brand,#1B3FA0);--cu-ink:var(--ink,var(--text,#16223f));--cu-line:var(--line,#e2e8f0);--cu-fond:var(--surface,#fff);--cu-doux:var(--surface-alt,#f8fafc);--cu-radius:1rem}
|
|
18
|
+
.cu-panel h1{margin:.2rem 0 .3rem;color:var(--cu-ink)}
|
|
19
|
+
.cu-panel .sub{margin:0 0 1rem;opacity:.7}
|
|
20
|
+
.cu-panel a.back{display:inline-block;margin-bottom:.6rem;color:var(--link,var(--cu-accent));text-decoration:none;font-weight:600}
|
|
21
|
+
.cu-panel table{width:100%;border-collapse:separate;border-spacing:0;background:var(--cu-fond);border:1px solid var(--cu-line);border-radius:var(--cu-radius);overflow:hidden}
|
|
22
|
+
.cu-panel th{text-align:start;font-size:.8rem;text-transform:uppercase;letter-spacing:.03em;opacity:.7;background:var(--cu-doux);padding:.65rem .8rem;border-bottom:1px solid var(--cu-line)}
|
|
23
|
+
.cu-panel td{padding:.65rem .8rem;border-bottom:1px solid var(--cu-line);vertical-align:middle}
|
|
24
|
+
.cu-panel tr:last-child td{border-bottom:0}
|
|
25
|
+
.cu-panel .cu-fiche{color:var(--link,var(--cu-accent));font-weight:600;text-decoration:none;white-space:nowrap}
|
|
26
|
+
.cu-panel button.act{background:transparent;border:1px solid var(--cu-line);border-radius:999px;padding:.25rem .8rem;cursor:pointer;font:inherit}
|
|
27
|
+
.cu-panel form{display:inline}`;
|
|
28
|
+
|
|
6
29
|
/** Lien de détail (cellule de tête de ligne). */
|
|
7
|
-
export function detailLink(href, label = '
|
|
8
|
-
return
|
|
30
|
+
export function detailLink(href, label = LIBELLES.fiche, { style = 'inline' } = {}) {
|
|
31
|
+
return style === 'classes'
|
|
32
|
+
? `<a class="cu-fiche" href="${esc(href)}">${esc(label)}</a>`
|
|
33
|
+
: `<a href="${esc(href)}" style="color:var(--blue);font-weight:600;text-decoration:none">${esc(label)}</a>`;
|
|
9
34
|
}
|
|
10
35
|
|
|
11
36
|
/** Mini-formulaire POST pour une action de ligne → `${routeBase}/act/${action.id}`. */
|
|
@@ -24,20 +49,22 @@ export function actionsCell(routeBase, actions, row) {
|
|
|
24
49
|
*/
|
|
25
50
|
export function panel({
|
|
26
51
|
title, sub = '', back, note = '', rows = [], cols, hidden = ['id', '_status'],
|
|
27
|
-
routeBase = '', detail = false, actions, create, extra = '', empty,
|
|
52
|
+
routeBase = '', detail = false, actions, create, extra = '', empty, cell,
|
|
53
|
+
labels = {}, style = 'inline',
|
|
28
54
|
} = {}) {
|
|
55
|
+
const L = { ...LIBELLES, ...labels };
|
|
29
56
|
const parts = [];
|
|
30
57
|
if (back) parts.push(backLink(back.href, back.label));
|
|
31
58
|
if (title) parts.push(pageTitle(title, sub));
|
|
32
59
|
if (note) parts.push(note);
|
|
33
60
|
if (create) parts.push(form(create.fields, {
|
|
34
61
|
action: `${routeBase}/create`, method: 'post',
|
|
35
|
-
title: create.title ||
|
|
62
|
+
title: create.title || L.ajouter, submit: create.submit || L.creer,
|
|
36
63
|
enctype: create.enctype, extra: create.extra,
|
|
37
64
|
}));
|
|
38
|
-
const lead = detail ? (r) => detailLink(typeof detail === 'function' ? detail(r) : `${routeBase}/${r.id}
|
|
39
|
-
const trail = actions ? { header:
|
|
40
|
-
parts.push(table(rows, { cols, hidden, lead, trail, empty }));
|
|
65
|
+
const lead = detail ? (r) => detailLink(typeof detail === 'function' ? detail(r) : `${routeBase}/${r.id}`, L.fiche, { style }) : undefined;
|
|
66
|
+
const trail = actions ? { header: L.actions, render: (r) => actionsCell(routeBase, actions, r) } : undefined;
|
|
67
|
+
parts.push(table(rows, { cols, hidden, lead, trail, empty, cell }));
|
|
41
68
|
if (extra) parts.push(extra);
|
|
42
|
-
return parts.join('\n');
|
|
69
|
+
return style === 'classes' ? `<div class="cu-panel">${parts.join('\n')}</div>` : parts.join('\n');
|
|
43
70
|
}
|