@fieldia/viewer 0.9.2 → 0.11.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/README.md +145 -1
- package/bundle/fieldia.ar.js +3 -0
- package/bundle/fieldia.ar.js.map +7 -0
- package/bundle/fieldia.de.js +3 -0
- package/bundle/fieldia.de.js.map +7 -0
- package/bundle/fieldia.fr.js +3 -0
- package/bundle/fieldia.fr.js.map +7 -0
- package/bundle/fieldia.js +4 -4
- package/bundle/fieldia.js.map +4 -4
- package/package.json +6 -3
- package/src/index.d.mts +4 -0
- package/src/index.d.ts +4 -0
- package/src/index.js +12 -0
- package/src/index.js.map +1 -1
- package/src/index.mjs +4 -0
- package/src/index.mjs.map +1 -1
- package/src/lib/add-language.d.mts +20 -0
- package/src/lib/add-language.d.ts +20 -0
- package/src/lib/add-language.js +19 -0
- package/src/lib/add-language.js.map +1 -0
- package/src/lib/add-language.mjs +16 -0
- package/src/lib/add-language.mjs.map +1 -0
- package/src/lib/dialog.d.mts +35 -3
- package/src/lib/dialog.d.ts +35 -3
- package/src/lib/dialog.js +109 -47
- package/src/lib/dialog.js.map +1 -1
- package/src/lib/dialog.mjs +107 -47
- package/src/lib/dialog.mjs.map +1 -1
- package/src/lib/dom.d.mts +10 -0
- package/src/lib/dom.d.ts +10 -0
- package/src/lib/dom.js +26 -0
- package/src/lib/dom.js.map +1 -1
- package/src/lib/dom.mjs +23 -1
- package/src/lib/dom.mjs.map +1 -1
- package/src/lib/focus-trap.d.mts +2 -0
- package/src/lib/focus-trap.d.ts +2 -0
- package/src/lib/focus-trap.js +7 -0
- package/src/lib/focus-trap.js.map +1 -0
- package/src/lib/focus-trap.mjs +3 -0
- package/src/lib/focus-trap.mjs.map +1 -0
- package/src/lib/labels.d.mts +27 -0
- package/src/lib/labels.d.ts +27 -0
- package/src/lib/labels.js +109 -277
- package/src/lib/labels.js.map +1 -1
- package/src/lib/labels.mjs +108 -277
- package/src/lib/labels.mjs.map +1 -1
- package/src/lib/list-styles.d.mts +1 -1
- package/src/lib/list-styles.d.ts +1 -1
- package/src/lib/list-styles.js +3 -2
- package/src/lib/list-styles.js.map +1 -1
- package/src/lib/list-styles.mjs +3 -2
- package/src/lib/list-styles.mjs.map +1 -1
- package/src/lib/list.d.mts +3 -2
- package/src/lib/list.d.ts +3 -2
- package/src/lib/list.js +5 -5
- package/src/lib/list.js.map +1 -1
- package/src/lib/list.mjs +5 -5
- package/src/lib/list.mjs.map +1 -1
- package/src/lib/locales/all.d.mts +8 -0
- package/src/lib/locales/all.d.ts +8 -0
- package/src/lib/locales/all.js +13 -0
- package/src/lib/locales/all.js.map +1 -0
- package/src/lib/locales/all.mjs +10 -0
- package/src/lib/locales/all.mjs.map +1 -0
- package/src/lib/locales/ar.d.mts +3 -0
- package/src/lib/locales/ar.d.ts +3 -0
- package/src/lib/locales/ar.js +80 -0
- package/src/lib/locales/ar.js.map +1 -0
- package/src/lib/locales/ar.mjs +77 -0
- package/src/lib/locales/ar.mjs.map +1 -0
- package/src/lib/locales/de.d.mts +3 -0
- package/src/lib/locales/de.d.ts +3 -0
- package/src/lib/locales/de.js +80 -0
- package/src/lib/locales/de.js.map +1 -0
- package/src/lib/locales/de.mjs +77 -0
- package/src/lib/locales/de.mjs.map +1 -0
- package/src/lib/locales/fr.d.mts +3 -0
- package/src/lib/locales/fr.d.ts +3 -0
- package/src/lib/locales/fr.js +80 -0
- package/src/lib/locales/fr.js.map +1 -0
- package/src/lib/locales/fr.mjs +77 -0
- package/src/lib/locales/fr.mjs.map +1 -0
- package/src/lib/look.d.mts +25 -0
- package/src/lib/look.d.ts +25 -0
- package/src/lib/look.js +141 -0
- package/src/lib/look.js.map +1 -0
- package/src/lib/look.mjs +136 -0
- package/src/lib/look.mjs.map +1 -0
- package/src/lib/open.d.mts +24 -0
- package/src/lib/open.d.ts +24 -0
- package/src/lib/open.js +81 -0
- package/src/lib/open.js.map +1 -0
- package/src/lib/open.mjs +78 -0
- package/src/lib/open.mjs.map +1 -0
- package/src/lib/place.d.mts +35 -0
- package/src/lib/place.d.ts +35 -0
- package/src/lib/place.js +37 -0
- package/src/lib/place.js.map +1 -0
- package/src/lib/place.mjs +33 -0
- package/src/lib/place.mjs.map +1 -0
- package/src/lib/related.d.mts +19 -0
- package/src/lib/related.d.ts +19 -0
- package/src/lib/related.js +17 -3
- package/src/lib/related.js.map +1 -1
- package/src/lib/related.mjs +16 -3
- package/src/lib/related.mjs.map +1 -1
- package/src/lib/say.d.mts +9 -0
- package/src/lib/say.d.ts +9 -0
- package/src/lib/say.js +45 -0
- package/src/lib/say.js.map +1 -0
- package/src/lib/say.mjs +42 -0
- package/src/lib/say.mjs.map +1 -0
- package/src/lib/viewer.d.mts +43 -7
- package/src/lib/viewer.d.ts +43 -7
- package/src/lib/viewer.js +513 -225
- package/src/lib/viewer.js.map +1 -1
- package/src/lib/viewer.mjs +516 -228
- package/src/lib/viewer.mjs.map +1 -1
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.fr = void 0;
|
|
4
|
+
/** The viewer’s own words in French. */
|
|
5
|
+
exports.fr = {
|
|
6
|
+
save: 'Enregistrer',
|
|
7
|
+
edit: 'Modifier',
|
|
8
|
+
done: 'Terminé',
|
|
9
|
+
discard: 'Annuler les modifications',
|
|
10
|
+
saving: 'Enregistrement…',
|
|
11
|
+
saved: 'Enregistré',
|
|
12
|
+
submit: 'Envoyer',
|
|
13
|
+
next: 'Suivant',
|
|
14
|
+
back: 'Retour',
|
|
15
|
+
skip: 'Passer',
|
|
16
|
+
steps: 'Étapes',
|
|
17
|
+
stepOf: 'Étape {n} sur {total}',
|
|
18
|
+
submitted: 'Merci. Vos réponses ont été envoyées.',
|
|
19
|
+
submitAnother: 'Envoyer une autre réponse',
|
|
20
|
+
draftFound: 'Vous avez des réponses non enregistrées du {time}.',
|
|
21
|
+
restore: 'Restaurer',
|
|
22
|
+
discardDraft: 'Ignorer',
|
|
23
|
+
ok: 'OK',
|
|
24
|
+
cancel: 'Annuler',
|
|
25
|
+
loading: 'Chargement…',
|
|
26
|
+
saveClose: 'Enregistrer et fermer',
|
|
27
|
+
close: 'Fermer',
|
|
28
|
+
discardChanges: 'Abandonner vos modifications ?',
|
|
29
|
+
dismiss: 'Masquer',
|
|
30
|
+
retry: 'Réessayer',
|
|
31
|
+
notSaved: 'Non enregistré',
|
|
32
|
+
notSent: 'Non envoyé',
|
|
33
|
+
checkFields: '{what}. À vérifier : {fields}',
|
|
34
|
+
offline: 'Le serveur est injoignable. Vos modifications sont toujours là.',
|
|
35
|
+
previousPage: 'Page précédente',
|
|
36
|
+
nextPage: 'Page suivante',
|
|
37
|
+
range: '{from}–{to} / {total}',
|
|
38
|
+
selected: '{n} sélectionné(s)',
|
|
39
|
+
clearSelection: 'Désélectionner',
|
|
40
|
+
selectAll: 'Tout sélectionner',
|
|
41
|
+
selectRecord: 'Sélectionner {name}',
|
|
42
|
+
noRecords: 'Aucun enregistrement ne correspond.',
|
|
43
|
+
loadFailed: 'Impossible de charger les enregistrements.',
|
|
44
|
+
search: 'Rechercher…',
|
|
45
|
+
searchLabel: 'Rechercher',
|
|
46
|
+
searchFor: 'Rechercher {field} : {text}',
|
|
47
|
+
searchOptions: 'Options de recherche',
|
|
48
|
+
filters: 'Filtres',
|
|
49
|
+
groupBy: 'Regrouper par',
|
|
50
|
+
favourites: 'Favoris',
|
|
51
|
+
or: 'ou',
|
|
52
|
+
removeFacet: 'Retirer {label}',
|
|
53
|
+
addCustomFilter: 'Ajouter un filtre personnalisé',
|
|
54
|
+
field: 'Champ',
|
|
55
|
+
condition: 'Condition',
|
|
56
|
+
value: 'Valeur',
|
|
57
|
+
apply: 'Appliquer',
|
|
58
|
+
saveSearch: 'Enregistrer la recherche',
|
|
59
|
+
searchName: 'Nom de la recherche',
|
|
60
|
+
useByDefault: 'Utiliser par défaut',
|
|
61
|
+
deleteFavourite: 'Supprimer {name}',
|
|
62
|
+
noFavourites: 'Aucune recherche enregistrée.',
|
|
63
|
+
opIs: 'est',
|
|
64
|
+
opIsNot: 'n’est pas',
|
|
65
|
+
opContains: 'contient',
|
|
66
|
+
opGreater: 'supérieur à',
|
|
67
|
+
opLess: 'inférieur à',
|
|
68
|
+
opSet: 'est défini',
|
|
69
|
+
opNotSet: 'n’est pas défini',
|
|
70
|
+
yes: 'Oui',
|
|
71
|
+
no: 'Non',
|
|
72
|
+
none: 'Aucun',
|
|
73
|
+
loadMore: 'Afficher {n} de plus',
|
|
74
|
+
formMissing: 'Le formulaire enregistré « {page} » est introuvable.',
|
|
75
|
+
formInItself: 'Le formulaire enregistré « {page} » n’est pas affiché ici : il serait placé dans lui-même ({chain}).',
|
|
76
|
+
formNotPlaceable: 'Le formulaire enregistré « {page} » ne peut pas être placé ici : seul un formulaire de sections ou d’onglets le peut.',
|
|
77
|
+
formBroken: 'Le formulaire enregistré « {page} » ne peut pas être affiché.',
|
|
78
|
+
pageMissing: 'La page « {page} » est introuvable.',
|
|
79
|
+
};
|
|
80
|
+
//# sourceMappingURL=fr.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fr.js","sourceRoot":"","sources":["../../../../../../libs/viewer/src/lib/locales/fr.ts"],"names":[],"mappings":";;;AAEA,wCAAwC;AAC3B,QAAA,EAAE,GAAiB;IAC9B,IAAI,EAAE,aAAa;IACnB,IAAI,EAAE,UAAU;IAChB,IAAI,EAAE,SAAS;IACf,OAAO,EAAE,2BAA2B;IACpC,MAAM,EAAE,iBAAiB;IACzB,KAAK,EAAE,YAAY;IACnB,MAAM,EAAE,SAAS;IACjB,IAAI,EAAE,SAAS;IACf,IAAI,EAAE,QAAQ;IACd,IAAI,EAAE,QAAQ;IACd,KAAK,EAAE,QAAQ;IACf,MAAM,EAAE,uBAAuB;IAC/B,SAAS,EAAE,uCAAuC;IAClD,aAAa,EAAE,2BAA2B;IAC1C,UAAU,EAAE,oDAAoD;IAChE,OAAO,EAAE,WAAW;IACpB,YAAY,EAAE,SAAS;IACvB,EAAE,EAAE,IAAI;IACR,MAAM,EAAE,SAAS;IACjB,OAAO,EAAE,aAAa;IACtB,SAAS,EAAE,uBAAuB;IAClC,KAAK,EAAE,QAAQ;IACf,cAAc,EAAE,gCAAgC;IAChD,OAAO,EAAE,SAAS;IAClB,KAAK,EAAE,WAAW;IAClB,QAAQ,EAAE,gBAAgB;IAC1B,OAAO,EAAE,YAAY;IACrB,WAAW,EAAE,+BAA+B;IAC5C,OAAO,EAAE,iEAAiE;IAC1E,YAAY,EAAE,iBAAiB;IAC/B,QAAQ,EAAE,eAAe;IACzB,KAAK,EAAE,uBAAuB;IAC9B,QAAQ,EAAE,oBAAoB;IAC9B,cAAc,EAAE,gBAAgB;IAChC,SAAS,EAAE,mBAAmB;IAC9B,YAAY,EAAE,qBAAqB;IACnC,SAAS,EAAE,qCAAqC;IAChD,UAAU,EAAE,4CAA4C;IACxD,MAAM,EAAE,aAAa;IACrB,WAAW,EAAE,YAAY;IACzB,SAAS,EAAE,6BAA6B;IACxC,aAAa,EAAE,sBAAsB;IACrC,OAAO,EAAE,SAAS;IAClB,OAAO,EAAE,eAAe;IACxB,UAAU,EAAE,SAAS;IACrB,EAAE,EAAE,IAAI;IACR,WAAW,EAAE,iBAAiB;IAC9B,eAAe,EAAE,gCAAgC;IACjD,KAAK,EAAE,OAAO;IACd,SAAS,EAAE,WAAW;IACtB,KAAK,EAAE,QAAQ;IACf,KAAK,EAAE,WAAW;IAClB,UAAU,EAAE,0BAA0B;IACtC,UAAU,EAAE,qBAAqB;IACjC,YAAY,EAAE,qBAAqB;IACnC,eAAe,EAAE,kBAAkB;IACnC,YAAY,EAAE,+BAA+B;IAC7C,IAAI,EAAE,KAAK;IACX,OAAO,EAAE,WAAW;IACpB,UAAU,EAAE,UAAU;IACtB,SAAS,EAAE,aAAa;IACxB,MAAM,EAAE,aAAa;IACrB,KAAK,EAAE,YAAY;IACnB,QAAQ,EAAE,kBAAkB;IAC5B,GAAG,EAAE,KAAK;IACV,EAAE,EAAE,KAAK;IACT,IAAI,EAAE,OAAO;IACb,QAAQ,EAAE,sBAAsB;IAChC,WAAW,EAAE,sDAAsD;IACnE,YAAY,EAAE,sGAAsG;IACpH,gBAAgB,EAAE,uHAAuH;IACzI,UAAU,EAAE,+DAA+D;IAC3E,WAAW,EAAE,qCAAqC;CACnD,CAAC"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/** The viewer’s own words in French. */
|
|
2
|
+
export const fr = {
|
|
3
|
+
save: 'Enregistrer',
|
|
4
|
+
edit: 'Modifier',
|
|
5
|
+
done: 'Terminé',
|
|
6
|
+
discard: 'Annuler les modifications',
|
|
7
|
+
saving: 'Enregistrement…',
|
|
8
|
+
saved: 'Enregistré',
|
|
9
|
+
submit: 'Envoyer',
|
|
10
|
+
next: 'Suivant',
|
|
11
|
+
back: 'Retour',
|
|
12
|
+
skip: 'Passer',
|
|
13
|
+
steps: 'Étapes',
|
|
14
|
+
stepOf: 'Étape {n} sur {total}',
|
|
15
|
+
submitted: 'Merci. Vos réponses ont été envoyées.',
|
|
16
|
+
submitAnother: 'Envoyer une autre réponse',
|
|
17
|
+
draftFound: 'Vous avez des réponses non enregistrées du {time}.',
|
|
18
|
+
restore: 'Restaurer',
|
|
19
|
+
discardDraft: 'Ignorer',
|
|
20
|
+
ok: 'OK',
|
|
21
|
+
cancel: 'Annuler',
|
|
22
|
+
loading: 'Chargement…',
|
|
23
|
+
saveClose: 'Enregistrer et fermer',
|
|
24
|
+
close: 'Fermer',
|
|
25
|
+
discardChanges: 'Abandonner vos modifications ?',
|
|
26
|
+
dismiss: 'Masquer',
|
|
27
|
+
retry: 'Réessayer',
|
|
28
|
+
notSaved: 'Non enregistré',
|
|
29
|
+
notSent: 'Non envoyé',
|
|
30
|
+
checkFields: '{what}. À vérifier : {fields}',
|
|
31
|
+
offline: 'Le serveur est injoignable. Vos modifications sont toujours là.',
|
|
32
|
+
previousPage: 'Page précédente',
|
|
33
|
+
nextPage: 'Page suivante',
|
|
34
|
+
range: '{from}–{to} / {total}',
|
|
35
|
+
selected: '{n} sélectionné(s)',
|
|
36
|
+
clearSelection: 'Désélectionner',
|
|
37
|
+
selectAll: 'Tout sélectionner',
|
|
38
|
+
selectRecord: 'Sélectionner {name}',
|
|
39
|
+
noRecords: 'Aucun enregistrement ne correspond.',
|
|
40
|
+
loadFailed: 'Impossible de charger les enregistrements.',
|
|
41
|
+
search: 'Rechercher…',
|
|
42
|
+
searchLabel: 'Rechercher',
|
|
43
|
+
searchFor: 'Rechercher {field} : {text}',
|
|
44
|
+
searchOptions: 'Options de recherche',
|
|
45
|
+
filters: 'Filtres',
|
|
46
|
+
groupBy: 'Regrouper par',
|
|
47
|
+
favourites: 'Favoris',
|
|
48
|
+
or: 'ou',
|
|
49
|
+
removeFacet: 'Retirer {label}',
|
|
50
|
+
addCustomFilter: 'Ajouter un filtre personnalisé',
|
|
51
|
+
field: 'Champ',
|
|
52
|
+
condition: 'Condition',
|
|
53
|
+
value: 'Valeur',
|
|
54
|
+
apply: 'Appliquer',
|
|
55
|
+
saveSearch: 'Enregistrer la recherche',
|
|
56
|
+
searchName: 'Nom de la recherche',
|
|
57
|
+
useByDefault: 'Utiliser par défaut',
|
|
58
|
+
deleteFavourite: 'Supprimer {name}',
|
|
59
|
+
noFavourites: 'Aucune recherche enregistrée.',
|
|
60
|
+
opIs: 'est',
|
|
61
|
+
opIsNot: 'n’est pas',
|
|
62
|
+
opContains: 'contient',
|
|
63
|
+
opGreater: 'supérieur à',
|
|
64
|
+
opLess: 'inférieur à',
|
|
65
|
+
opSet: 'est défini',
|
|
66
|
+
opNotSet: 'n’est pas défini',
|
|
67
|
+
yes: 'Oui',
|
|
68
|
+
no: 'Non',
|
|
69
|
+
none: 'Aucun',
|
|
70
|
+
loadMore: 'Afficher {n} de plus',
|
|
71
|
+
formMissing: 'Le formulaire enregistré « {page} » est introuvable.',
|
|
72
|
+
formInItself: 'Le formulaire enregistré « {page} » n’est pas affiché ici : il serait placé dans lui-même ({chain}).',
|
|
73
|
+
formNotPlaceable: 'Le formulaire enregistré « {page} » ne peut pas être placé ici : seul un formulaire de sections ou d’onglets le peut.',
|
|
74
|
+
formBroken: 'Le formulaire enregistré « {page} » ne peut pas être affiché.',
|
|
75
|
+
pageMissing: 'La page « {page} » est introuvable.',
|
|
76
|
+
};
|
|
77
|
+
//# sourceMappingURL=fr.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fr.mjs","sourceRoot":"","sources":["../../../../../../libs/viewer/src/lib/locales/fr.ts"],"names":[],"mappings":"AAEA,wCAAwC;AACxC,MAAM,CAAC,MAAM,EAAE,GAAiB;IAC9B,IAAI,EAAE,aAAa;IACnB,IAAI,EAAE,UAAU;IAChB,IAAI,EAAE,SAAS;IACf,OAAO,EAAE,2BAA2B;IACpC,MAAM,EAAE,iBAAiB;IACzB,KAAK,EAAE,YAAY;IACnB,MAAM,EAAE,SAAS;IACjB,IAAI,EAAE,SAAS;IACf,IAAI,EAAE,QAAQ;IACd,IAAI,EAAE,QAAQ;IACd,KAAK,EAAE,QAAQ;IACf,MAAM,EAAE,uBAAuB;IAC/B,SAAS,EAAE,uCAAuC;IAClD,aAAa,EAAE,2BAA2B;IAC1C,UAAU,EAAE,oDAAoD;IAChE,OAAO,EAAE,WAAW;IACpB,YAAY,EAAE,SAAS;IACvB,EAAE,EAAE,IAAI;IACR,MAAM,EAAE,SAAS;IACjB,OAAO,EAAE,aAAa;IACtB,SAAS,EAAE,uBAAuB;IAClC,KAAK,EAAE,QAAQ;IACf,cAAc,EAAE,gCAAgC;IAChD,OAAO,EAAE,SAAS;IAClB,KAAK,EAAE,WAAW;IAClB,QAAQ,EAAE,gBAAgB;IAC1B,OAAO,EAAE,YAAY;IACrB,WAAW,EAAE,+BAA+B;IAC5C,OAAO,EAAE,iEAAiE;IAC1E,YAAY,EAAE,iBAAiB;IAC/B,QAAQ,EAAE,eAAe;IACzB,KAAK,EAAE,uBAAuB;IAC9B,QAAQ,EAAE,oBAAoB;IAC9B,cAAc,EAAE,gBAAgB;IAChC,SAAS,EAAE,mBAAmB;IAC9B,YAAY,EAAE,qBAAqB;IACnC,SAAS,EAAE,qCAAqC;IAChD,UAAU,EAAE,4CAA4C;IACxD,MAAM,EAAE,aAAa;IACrB,WAAW,EAAE,YAAY;IACzB,SAAS,EAAE,6BAA6B;IACxC,aAAa,EAAE,sBAAsB;IACrC,OAAO,EAAE,SAAS;IAClB,OAAO,EAAE,eAAe;IACxB,UAAU,EAAE,SAAS;IACrB,EAAE,EAAE,IAAI;IACR,WAAW,EAAE,iBAAiB;IAC9B,eAAe,EAAE,gCAAgC;IACjD,KAAK,EAAE,OAAO;IACd,SAAS,EAAE,WAAW;IACtB,KAAK,EAAE,QAAQ;IACf,KAAK,EAAE,WAAW;IAClB,UAAU,EAAE,0BAA0B;IACtC,UAAU,EAAE,qBAAqB;IACjC,YAAY,EAAE,qBAAqB;IACnC,eAAe,EAAE,kBAAkB;IACnC,YAAY,EAAE,+BAA+B;IAC7C,IAAI,EAAE,KAAK;IACX,OAAO,EAAE,WAAW;IACpB,UAAU,EAAE,UAAU;IACtB,SAAS,EAAE,aAAa;IACxB,MAAM,EAAE,aAAa;IACrB,KAAK,EAAE,YAAY;IACnB,QAAQ,EAAE,kBAAkB;IAC5B,GAAG,EAAE,KAAK;IACV,EAAE,EAAE,KAAK;IACT,IAAI,EAAE,OAAO;IACb,QAAQ,EAAE,sBAAsB;IAChC,WAAW,EAAE,sDAAsD;IACnE,YAAY,EAAE,sGAAsG;IACpH,gBAAgB,EAAE,uHAAuH;IACzI,UAAU,EAAE,+DAA+D;IAC3E,WAAW,EAAE,qCAAqC;CACnD,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { PageLook } from '@fieldia/core';
|
|
2
|
+
/** How well one colour reads on another: 1 (not at all) to 21 (black on white). */
|
|
3
|
+
export declare function contrast(a: string, b: string): number;
|
|
4
|
+
export interface AccentShades {
|
|
5
|
+
/** The accent on a light page: as the page gives it, or darkened, when it has to be, until it reads there. */
|
|
6
|
+
accent: string;
|
|
7
|
+
/** What is written on it: a primary button's words. */
|
|
8
|
+
accentText: string;
|
|
9
|
+
/** The accent on a dark page: lightened, when it has to be, until it reads there. */
|
|
10
|
+
dark: string;
|
|
11
|
+
darkText: string;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* The accent, and what goes with it in either scheme. Each is moved, in small
|
|
15
|
+
* steps and only as far as it has to be, until words in it and on it read at
|
|
16
|
+
* 4.5:1 — darker on a light page, lighter on a dark one — on the page and on
|
|
17
|
+
* any `grounds` of its parts. The softer and hover shades are mixed from these
|
|
18
|
+
* by the stylesheet.
|
|
19
|
+
*/
|
|
20
|
+
export declare function accentShades(hex: string, grounds?: {
|
|
21
|
+
light: string[];
|
|
22
|
+
dark: string[];
|
|
23
|
+
}): AccentShades;
|
|
24
|
+
/** Put the page's look on the form's root. */
|
|
25
|
+
export declare function applyLook(root: HTMLElement, look: PageLook | undefined): void;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { PageLook } from '@fieldia/core';
|
|
2
|
+
/** How well one colour reads on another: 1 (not at all) to 21 (black on white). */
|
|
3
|
+
export declare function contrast(a: string, b: string): number;
|
|
4
|
+
export interface AccentShades {
|
|
5
|
+
/** The accent on a light page: as the page gives it, or darkened, when it has to be, until it reads there. */
|
|
6
|
+
accent: string;
|
|
7
|
+
/** What is written on it: a primary button's words. */
|
|
8
|
+
accentText: string;
|
|
9
|
+
/** The accent on a dark page: lightened, when it has to be, until it reads there. */
|
|
10
|
+
dark: string;
|
|
11
|
+
darkText: string;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* The accent, and what goes with it in either scheme. Each is moved, in small
|
|
15
|
+
* steps and only as far as it has to be, until words in it and on it read at
|
|
16
|
+
* 4.5:1 — darker on a light page, lighter on a dark one — on the page and on
|
|
17
|
+
* any `grounds` of its parts. The softer and hover shades are mixed from these
|
|
18
|
+
* by the stylesheet.
|
|
19
|
+
*/
|
|
20
|
+
export declare function accentShades(hex: string, grounds?: {
|
|
21
|
+
light: string[];
|
|
22
|
+
dark: string[];
|
|
23
|
+
}): AccentShades;
|
|
24
|
+
/** Put the page's look on the form's root. */
|
|
25
|
+
export declare function applyLook(root: HTMLElement, look: PageLook | undefined): void;
|
package/src/lib/look.js
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.contrast = contrast;
|
|
4
|
+
exports.accentShades = accentShades;
|
|
5
|
+
exports.applyLook = applyLook;
|
|
6
|
+
/**
|
|
7
|
+
* The page's look, worn by the form: what the page says about its accent,
|
|
8
|
+
* font, room, corners, labels and colour scheme becomes attributes and tokens
|
|
9
|
+
* on the form's root, and the stylesheet turns them into the form's own
|
|
10
|
+
* colours and sizes — so every widget follows, in either skin, light or dark.
|
|
11
|
+
* A look for a kind of part (text boxes, choices, groups, buttons, tables)
|
|
12
|
+
* becomes tokens of that kind, worn by it alone. A page with no look is left
|
|
13
|
+
* exactly as its skin draws it.
|
|
14
|
+
*/
|
|
15
|
+
/** Words written on a light accent, and on the dark page's accent. */
|
|
16
|
+
const INK = '#111418';
|
|
17
|
+
/** The dark scheme's surface, which the dark page's accent has to read on. */
|
|
18
|
+
const DARK_SURFACE = '#1f2329';
|
|
19
|
+
/** The darkest ground of a light page (the underline skin's), which the light page's accent has to read on. */
|
|
20
|
+
const LIGHT_GROUND = '#f2f3f5';
|
|
21
|
+
/** WCAG's contrast for normal text (1.4.3, AA): the accent is words on the page, and has words on it. */
|
|
22
|
+
const READABLE = 4.5;
|
|
23
|
+
const channels = (hex) => [1, 3, 5].map((at) => parseInt(hex.slice(at, at + 2), 16));
|
|
24
|
+
const toHex = (rgb) => `#${rgb.map((c) => Math.round(c).toString(16).padStart(2, '0')).join('')}`;
|
|
25
|
+
/** How bright a colour looks, as WCAG measures it: 0 for black, 1 for white. */
|
|
26
|
+
function luminance(hex) {
|
|
27
|
+
const [r, g, b] = channels(hex).map((c) => {
|
|
28
|
+
const s = c / 255;
|
|
29
|
+
return s <= 0.03928 ? s / 12.92 : ((s + 0.055) / 1.055) ** 2.4;
|
|
30
|
+
});
|
|
31
|
+
return 0.2126 * r + 0.7152 * g + 0.0722 * b;
|
|
32
|
+
}
|
|
33
|
+
/** How well one colour reads on another: 1 (not at all) to 21 (black on white). */
|
|
34
|
+
function contrast(a, b) {
|
|
35
|
+
const [light, dark] = [luminance(a), luminance(b)].sort((x, y) => y - x);
|
|
36
|
+
return (light + 0.05) / (dark + 0.05);
|
|
37
|
+
}
|
|
38
|
+
/** White on a colour, as buttons are usually written; ink where white would read poorly. */
|
|
39
|
+
const textOn = (hex) => (contrast(hex, '#ffffff') >= READABLE ? '#ffffff' : INK);
|
|
40
|
+
/** On a dark page the accent is light: whichever of ink or white reads better on it. */
|
|
41
|
+
const textOnDark = (hex) => (contrast(hex, INK) >= contrast(hex, '#ffffff') ? INK : '#ffffff');
|
|
42
|
+
/** A colour taken towards another by `amount` (0 to 1). */
|
|
43
|
+
const towards = (hex, to, amount) => toHex(channels(hex).map((c, i) => c + (channels(to)[i] - c) * amount));
|
|
44
|
+
/** The accent's softer shade on a surface, as the stylesheet mixes it: 12% of the accent. */
|
|
45
|
+
const softOn = (hex, surface) => towards(surface, hex, 0.12);
|
|
46
|
+
/** Reads as words on a surface, on the lightest ground there, and on its own softer shade (a picked tab, a chip). */
|
|
47
|
+
const readsOn = (hex, grounds) => [...grounds, softOn(hex, grounds[0])].every((ground) => contrast(hex, ground) >= READABLE);
|
|
48
|
+
/** A colour moved towards `to` in small steps, only as far as it has to be, until it `reads`; at worst it is `to`. */
|
|
49
|
+
function moved(hex, to, reads) {
|
|
50
|
+
let colour = hex;
|
|
51
|
+
for (let step = 1; step <= 40 && !reads(colour); step++)
|
|
52
|
+
colour = towards(hex, to, step / 40);
|
|
53
|
+
return colour;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* The accent, and what goes with it in either scheme. Each is moved, in small
|
|
57
|
+
* steps and only as far as it has to be, until words in it and on it read at
|
|
58
|
+
* 4.5:1 — darker on a light page, lighter on a dark one — on the page and on
|
|
59
|
+
* any `grounds` of its parts. The softer and hover shades are mixed from these
|
|
60
|
+
* by the stylesheet.
|
|
61
|
+
*/
|
|
62
|
+
function accentShades(hex, grounds = { light: [], dark: [] }) {
|
|
63
|
+
const given = hex.toLowerCase();
|
|
64
|
+
const accent = moved(given, '#000000', (colour) => readsOn(colour, ['#ffffff', LIGHT_GROUND, ...grounds.light]));
|
|
65
|
+
const dark = moved(given, '#ffffff', (colour) => readsOn(colour, [DARK_SURFACE, ...grounds.dark]));
|
|
66
|
+
return { accent, accentText: textOn(accent), dark, darkText: textOnDark(dark) };
|
|
67
|
+
}
|
|
68
|
+
/** Each scheme's words that every ground of a part must keep readable: its text, muted words and errors. */
|
|
69
|
+
const LIGHT_WORDS = ['#212529', '#636976', '#c63c3d'];
|
|
70
|
+
const DARK_WORDS = ['#e8eaed', '#a3a9b2', '#ff8a7a'];
|
|
71
|
+
/** The skins' own accent where the page names none: outlined's, the lighter of the two, which has the most to read on. */
|
|
72
|
+
const SKIN_ACCENT = { accent: '#1365d9', dark: '#5aa2ff' };
|
|
73
|
+
/** What a part's settings are called on the form, `data-inputs="bg radius"`, and in its tokens, `--fd-inputs-bg`. */
|
|
74
|
+
const NAMES = { background: 'bg', border: 'border', corners: 'radius', textSize: 'size', accent: 'accent' };
|
|
75
|
+
const SIZES = { small: '13px', large: '16px' };
|
|
76
|
+
/** The corners of a box, and of a group, in pixels: the page's own (`data-corners`) for each. */
|
|
77
|
+
const RADII = { square: [0, 0], soft: [6, 10], round: [12, 16] };
|
|
78
|
+
/**
|
|
79
|
+
* A look for each kind of part, as its own tokens on the form, each worked out
|
|
80
|
+
* for the page's scheme (both, for auto, as `light-dark()`): a ground moved
|
|
81
|
+
* until the page's words and accent read on it — lighter on a light page,
|
|
82
|
+
* towards the dark surface on a dark one; an accent moved until words in it
|
|
83
|
+
* and on it read, on the page and on every ground given; an edge as given.
|
|
84
|
+
*/
|
|
85
|
+
function applyParts(root, look) {
|
|
86
|
+
const wear = (light, dark) => (look.scheme === 'dark' ? dark : look.scheme === 'auto' ? `light-dark(${light}, ${dark})` : light);
|
|
87
|
+
const page = look.accent ? accentShades(look.accent) : SKIN_ACCENT;
|
|
88
|
+
const parts = Object.entries(look.parts ?? {});
|
|
89
|
+
const set = (kind, name, value) => root.style.setProperty(`--fd-${kind}-${name}`, value);
|
|
90
|
+
// The grounds first: every accent has to read on each of them.
|
|
91
|
+
const grounds = { light: [], dark: [] };
|
|
92
|
+
const readsAll = (words) => (colour) => words.every((word) => contrast(word, colour) >= READABLE);
|
|
93
|
+
for (const [kind, part] of parts) {
|
|
94
|
+
const given = part.background?.toLowerCase();
|
|
95
|
+
if (!given)
|
|
96
|
+
continue;
|
|
97
|
+
const light = moved(given, '#ffffff', readsAll([...LIGHT_WORDS, page.accent]));
|
|
98
|
+
const dark = moved(given, DARK_SURFACE, readsAll([...DARK_WORDS, page.dark]));
|
|
99
|
+
grounds.light.push(light);
|
|
100
|
+
grounds.dark.push(dark);
|
|
101
|
+
set(kind, 'bg', wear(light, dark));
|
|
102
|
+
}
|
|
103
|
+
for (const [kind, part] of parts) {
|
|
104
|
+
const names = Object.keys(NAMES).filter((name) => part[name]).map((name) => NAMES[name]);
|
|
105
|
+
if (names.length)
|
|
106
|
+
root.setAttribute(`data-${kind}`, names.join(' '));
|
|
107
|
+
if (part.border)
|
|
108
|
+
set(kind, 'border', part.border);
|
|
109
|
+
if (part.corners)
|
|
110
|
+
set(kind, 'radius', `${RADII[part.corners][kind === 'groups' ? 1 : 0]}px`);
|
|
111
|
+
if (part.textSize)
|
|
112
|
+
set(kind, 'size', SIZES[part.textSize]);
|
|
113
|
+
if (part.accent) {
|
|
114
|
+
const shades = accentShades(part.accent, grounds);
|
|
115
|
+
set(kind, 'accent', wear(shades.accent, shades.dark));
|
|
116
|
+
set(kind, 'accent-text', wear(shades.accentText, shades.darkText));
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
/** Put the page's look on the form's root. */
|
|
121
|
+
function applyLook(root, look) {
|
|
122
|
+
if (!look)
|
|
123
|
+
return;
|
|
124
|
+
for (const name of ['font', 'density', 'corners', 'scheme']) {
|
|
125
|
+
const value = look[name];
|
|
126
|
+
if (value)
|
|
127
|
+
root.setAttribute(`data-${name}`, value);
|
|
128
|
+
}
|
|
129
|
+
if (look.labelWidth)
|
|
130
|
+
root.style.setProperty('--fd-label-width', `${look.labelWidth}px`);
|
|
131
|
+
if (look.accent) {
|
|
132
|
+
const shades = accentShades(look.accent);
|
|
133
|
+
root.setAttribute('data-accent', '');
|
|
134
|
+
root.style.setProperty('--fd-look-accent', shades.accent);
|
|
135
|
+
root.style.setProperty('--fd-look-accent-text', shades.accentText);
|
|
136
|
+
root.style.setProperty('--fd-look-accent-dark', shades.dark);
|
|
137
|
+
root.style.setProperty('--fd-look-accent-dark-text', shades.darkText);
|
|
138
|
+
}
|
|
139
|
+
applyParts(root, look);
|
|
140
|
+
}
|
|
141
|
+
//# sourceMappingURL=look.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"look.js","sourceRoot":"","sources":["../../../../../libs/viewer/src/lib/look.ts"],"names":[],"mappings":"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"}
|
package/src/lib/look.mjs
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The page's look, worn by the form: what the page says about its accent,
|
|
3
|
+
* font, room, corners, labels and colour scheme becomes attributes and tokens
|
|
4
|
+
* on the form's root, and the stylesheet turns them into the form's own
|
|
5
|
+
* colours and sizes — so every widget follows, in either skin, light or dark.
|
|
6
|
+
* A look for a kind of part (text boxes, choices, groups, buttons, tables)
|
|
7
|
+
* becomes tokens of that kind, worn by it alone. A page with no look is left
|
|
8
|
+
* exactly as its skin draws it.
|
|
9
|
+
*/
|
|
10
|
+
/** Words written on a light accent, and on the dark page's accent. */
|
|
11
|
+
const INK = '#111418';
|
|
12
|
+
/** The dark scheme's surface, which the dark page's accent has to read on. */
|
|
13
|
+
const DARK_SURFACE = '#1f2329';
|
|
14
|
+
/** The darkest ground of a light page (the underline skin's), which the light page's accent has to read on. */
|
|
15
|
+
const LIGHT_GROUND = '#f2f3f5';
|
|
16
|
+
/** WCAG's contrast for normal text (1.4.3, AA): the accent is words on the page, and has words on it. */
|
|
17
|
+
const READABLE = 4.5;
|
|
18
|
+
const channels = (hex) => [1, 3, 5].map((at) => parseInt(hex.slice(at, at + 2), 16));
|
|
19
|
+
const toHex = (rgb) => `#${rgb.map((c) => Math.round(c).toString(16).padStart(2, '0')).join('')}`;
|
|
20
|
+
/** How bright a colour looks, as WCAG measures it: 0 for black, 1 for white. */
|
|
21
|
+
function luminance(hex) {
|
|
22
|
+
const [r, g, b] = channels(hex).map((c) => {
|
|
23
|
+
const s = c / 255;
|
|
24
|
+
return s <= 0.03928 ? s / 12.92 : ((s + 0.055) / 1.055) ** 2.4;
|
|
25
|
+
});
|
|
26
|
+
return 0.2126 * r + 0.7152 * g + 0.0722 * b;
|
|
27
|
+
}
|
|
28
|
+
/** How well one colour reads on another: 1 (not at all) to 21 (black on white). */
|
|
29
|
+
export function contrast(a, b) {
|
|
30
|
+
const [light, dark] = [luminance(a), luminance(b)].sort((x, y) => y - x);
|
|
31
|
+
return (light + 0.05) / (dark + 0.05);
|
|
32
|
+
}
|
|
33
|
+
/** White on a colour, as buttons are usually written; ink where white would read poorly. */
|
|
34
|
+
const textOn = (hex) => (contrast(hex, '#ffffff') >= READABLE ? '#ffffff' : INK);
|
|
35
|
+
/** On a dark page the accent is light: whichever of ink or white reads better on it. */
|
|
36
|
+
const textOnDark = (hex) => (contrast(hex, INK) >= contrast(hex, '#ffffff') ? INK : '#ffffff');
|
|
37
|
+
/** A colour taken towards another by `amount` (0 to 1). */
|
|
38
|
+
const towards = (hex, to, amount) => toHex(channels(hex).map((c, i) => c + (channels(to)[i] - c) * amount));
|
|
39
|
+
/** The accent's softer shade on a surface, as the stylesheet mixes it: 12% of the accent. */
|
|
40
|
+
const softOn = (hex, surface) => towards(surface, hex, 0.12);
|
|
41
|
+
/** Reads as words on a surface, on the lightest ground there, and on its own softer shade (a picked tab, a chip). */
|
|
42
|
+
const readsOn = (hex, grounds) => [...grounds, softOn(hex, grounds[0])].every((ground) => contrast(hex, ground) >= READABLE);
|
|
43
|
+
/** A colour moved towards `to` in small steps, only as far as it has to be, until it `reads`; at worst it is `to`. */
|
|
44
|
+
function moved(hex, to, reads) {
|
|
45
|
+
let colour = hex;
|
|
46
|
+
for (let step = 1; step <= 40 && !reads(colour); step++)
|
|
47
|
+
colour = towards(hex, to, step / 40);
|
|
48
|
+
return colour;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* The accent, and what goes with it in either scheme. Each is moved, in small
|
|
52
|
+
* steps and only as far as it has to be, until words in it and on it read at
|
|
53
|
+
* 4.5:1 — darker on a light page, lighter on a dark one — on the page and on
|
|
54
|
+
* any `grounds` of its parts. The softer and hover shades are mixed from these
|
|
55
|
+
* by the stylesheet.
|
|
56
|
+
*/
|
|
57
|
+
export function accentShades(hex, grounds = { light: [], dark: [] }) {
|
|
58
|
+
const given = hex.toLowerCase();
|
|
59
|
+
const accent = moved(given, '#000000', (colour) => readsOn(colour, ['#ffffff', LIGHT_GROUND, ...grounds.light]));
|
|
60
|
+
const dark = moved(given, '#ffffff', (colour) => readsOn(colour, [DARK_SURFACE, ...grounds.dark]));
|
|
61
|
+
return { accent, accentText: textOn(accent), dark, darkText: textOnDark(dark) };
|
|
62
|
+
}
|
|
63
|
+
/** Each scheme's words that every ground of a part must keep readable: its text, muted words and errors. */
|
|
64
|
+
const LIGHT_WORDS = ['#212529', '#636976', '#c63c3d'];
|
|
65
|
+
const DARK_WORDS = ['#e8eaed', '#a3a9b2', '#ff8a7a'];
|
|
66
|
+
/** The skins' own accent where the page names none: outlined's, the lighter of the two, which has the most to read on. */
|
|
67
|
+
const SKIN_ACCENT = { accent: '#1365d9', dark: '#5aa2ff' };
|
|
68
|
+
/** What a part's settings are called on the form, `data-inputs="bg radius"`, and in its tokens, `--fd-inputs-bg`. */
|
|
69
|
+
const NAMES = { background: 'bg', border: 'border', corners: 'radius', textSize: 'size', accent: 'accent' };
|
|
70
|
+
const SIZES = { small: '13px', large: '16px' };
|
|
71
|
+
/** The corners of a box, and of a group, in pixels: the page's own (`data-corners`) for each. */
|
|
72
|
+
const RADII = { square: [0, 0], soft: [6, 10], round: [12, 16] };
|
|
73
|
+
/**
|
|
74
|
+
* A look for each kind of part, as its own tokens on the form, each worked out
|
|
75
|
+
* for the page's scheme (both, for auto, as `light-dark()`): a ground moved
|
|
76
|
+
* until the page's words and accent read on it — lighter on a light page,
|
|
77
|
+
* towards the dark surface on a dark one; an accent moved until words in it
|
|
78
|
+
* and on it read, on the page and on every ground given; an edge as given.
|
|
79
|
+
*/
|
|
80
|
+
function applyParts(root, look) {
|
|
81
|
+
const wear = (light, dark) => (look.scheme === 'dark' ? dark : look.scheme === 'auto' ? `light-dark(${light}, ${dark})` : light);
|
|
82
|
+
const page = look.accent ? accentShades(look.accent) : SKIN_ACCENT;
|
|
83
|
+
const parts = Object.entries(look.parts ?? {});
|
|
84
|
+
const set = (kind, name, value) => root.style.setProperty(`--fd-${kind}-${name}`, value);
|
|
85
|
+
// The grounds first: every accent has to read on each of them.
|
|
86
|
+
const grounds = { light: [], dark: [] };
|
|
87
|
+
const readsAll = (words) => (colour) => words.every((word) => contrast(word, colour) >= READABLE);
|
|
88
|
+
for (const [kind, part] of parts) {
|
|
89
|
+
const given = part.background?.toLowerCase();
|
|
90
|
+
if (!given)
|
|
91
|
+
continue;
|
|
92
|
+
const light = moved(given, '#ffffff', readsAll([...LIGHT_WORDS, page.accent]));
|
|
93
|
+
const dark = moved(given, DARK_SURFACE, readsAll([...DARK_WORDS, page.dark]));
|
|
94
|
+
grounds.light.push(light);
|
|
95
|
+
grounds.dark.push(dark);
|
|
96
|
+
set(kind, 'bg', wear(light, dark));
|
|
97
|
+
}
|
|
98
|
+
for (const [kind, part] of parts) {
|
|
99
|
+
const names = Object.keys(NAMES).filter((name) => part[name]).map((name) => NAMES[name]);
|
|
100
|
+
if (names.length)
|
|
101
|
+
root.setAttribute(`data-${kind}`, names.join(' '));
|
|
102
|
+
if (part.border)
|
|
103
|
+
set(kind, 'border', part.border);
|
|
104
|
+
if (part.corners)
|
|
105
|
+
set(kind, 'radius', `${RADII[part.corners][kind === 'groups' ? 1 : 0]}px`);
|
|
106
|
+
if (part.textSize)
|
|
107
|
+
set(kind, 'size', SIZES[part.textSize]);
|
|
108
|
+
if (part.accent) {
|
|
109
|
+
const shades = accentShades(part.accent, grounds);
|
|
110
|
+
set(kind, 'accent', wear(shades.accent, shades.dark));
|
|
111
|
+
set(kind, 'accent-text', wear(shades.accentText, shades.darkText));
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
/** Put the page's look on the form's root. */
|
|
116
|
+
export function applyLook(root, look) {
|
|
117
|
+
if (!look)
|
|
118
|
+
return;
|
|
119
|
+
for (const name of ['font', 'density', 'corners', 'scheme']) {
|
|
120
|
+
const value = look[name];
|
|
121
|
+
if (value)
|
|
122
|
+
root.setAttribute(`data-${name}`, value);
|
|
123
|
+
}
|
|
124
|
+
if (look.labelWidth)
|
|
125
|
+
root.style.setProperty('--fd-label-width', `${look.labelWidth}px`);
|
|
126
|
+
if (look.accent) {
|
|
127
|
+
const shades = accentShades(look.accent);
|
|
128
|
+
root.setAttribute('data-accent', '');
|
|
129
|
+
root.style.setProperty('--fd-look-accent', shades.accent);
|
|
130
|
+
root.style.setProperty('--fd-look-accent-text', shades.accentText);
|
|
131
|
+
root.style.setProperty('--fd-look-accent-dark', shades.dark);
|
|
132
|
+
root.style.setProperty('--fd-look-accent-dark-text', shades.darkText);
|
|
133
|
+
}
|
|
134
|
+
applyParts(root, look);
|
|
135
|
+
}
|
|
136
|
+
//# sourceMappingURL=look.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"look.mjs","sourceRoot":"","sources":["../../../../../libs/viewer/src/lib/look.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { OpenRequest, OpenResult, Page } from '@fieldia/core';
|
|
2
|
+
import { type ViewerOptions } from './viewer.mjs';
|
|
3
|
+
/** What opening a page needs of the viewer that opens it. */
|
|
4
|
+
export interface Opener {
|
|
5
|
+
options: ViewerOptions;
|
|
6
|
+
/** The element the viewer is in: a page opened in its place goes there. */
|
|
7
|
+
place: HTMLElement;
|
|
8
|
+
/** The viewer's own form element, which steps aside meanwhile. */
|
|
9
|
+
root: HTMLElement;
|
|
10
|
+
/** The page's title as the viewer shows it: in its language, through the app's translator. */
|
|
11
|
+
title(page: Page): string;
|
|
12
|
+
/** "Back", in the page's language. */
|
|
13
|
+
back: string;
|
|
14
|
+
/** Why a page cannot be opened: the app has none by that id. */
|
|
15
|
+
missing(page: string): string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Open a page as a step asks, for the viewer's host: the app's own way first
|
|
19
|
+
* (`onOpen`), else found through `pages` and opened in a dialog, a side panel
|
|
20
|
+
* (from the side the step names) or this form's place — with the same data
|
|
21
|
+
* source, pages, words and look.
|
|
22
|
+
* Resolves with how it ended; the saved record named by its page's title field.
|
|
23
|
+
*/
|
|
24
|
+
export declare function openPage(opener: Opener, request: OpenRequest): Promise<OpenResult>;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { OpenRequest, OpenResult, Page } from '@fieldia/core';
|
|
2
|
+
import { type ViewerOptions } from './viewer';
|
|
3
|
+
/** What opening a page needs of the viewer that opens it. */
|
|
4
|
+
export interface Opener {
|
|
5
|
+
options: ViewerOptions;
|
|
6
|
+
/** The element the viewer is in: a page opened in its place goes there. */
|
|
7
|
+
place: HTMLElement;
|
|
8
|
+
/** The viewer's own form element, which steps aside meanwhile. */
|
|
9
|
+
root: HTMLElement;
|
|
10
|
+
/** The page's title as the viewer shows it: in its language, through the app's translator. */
|
|
11
|
+
title(page: Page): string;
|
|
12
|
+
/** "Back", in the page's language. */
|
|
13
|
+
back: string;
|
|
14
|
+
/** Why a page cannot be opened: the app has none by that id. */
|
|
15
|
+
missing(page: string): string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Open a page as a step asks, for the viewer's host: the app's own way first
|
|
19
|
+
* (`onOpen`), else found through `pages` and opened in a dialog, a side panel
|
|
20
|
+
* (from the side the step names) or this form's place — with the same data
|
|
21
|
+
* source, pages, words and look.
|
|
22
|
+
* Resolves with how it ended; the saved record named by its page's title field.
|
|
23
|
+
*/
|
|
24
|
+
export declare function openPage(opener: Opener, request: OpenRequest): Promise<OpenResult>;
|