@alveole/theme 1.10.0 → 2.0.0-alpha.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.
Files changed (98) hide show
  1. package/README.md +15 -15
  2. package/dist/WebThemeStyles.web.d.ts.map +1 -1
  3. package/dist/WebThemeStyles.web.js +4 -6
  4. package/dist/constants/Color.d.ts +0 -116
  5. package/dist/constants/Color.d.ts.map +1 -1
  6. package/dist/constants/Color.js +0 -116
  7. package/dist/constants/Control.d.ts +105 -0
  8. package/dist/constants/Control.d.ts.map +1 -0
  9. package/dist/constants/Control.js +28 -0
  10. package/dist/constants/Elevation.d.ts +8 -8
  11. package/dist/constants/Elevation.d.ts.map +1 -1
  12. package/dist/constants/Focus.d.ts +72 -0
  13. package/dist/constants/Focus.d.ts.map +1 -0
  14. package/dist/constants/Focus.js +79 -0
  15. package/dist/constants/FocusProps.d.ts +22 -0
  16. package/dist/constants/FocusProps.d.ts.map +1 -0
  17. package/dist/constants/FocusProps.js +15 -0
  18. package/dist/constants/Font.d.ts +13 -8
  19. package/dist/constants/Font.d.ts.map +1 -1
  20. package/dist/constants/Font.js +27 -27
  21. package/dist/constants/Grille.d.ts +9 -1
  22. package/dist/constants/Grille.d.ts.map +1 -1
  23. package/dist/constants/Grille.js +9 -1
  24. package/dist/constants/Link.d.ts +8 -0
  25. package/dist/constants/Link.d.ts.map +1 -0
  26. package/dist/constants/Link.js +8 -0
  27. package/dist/constants/LinkProps.d.ts +10 -0
  28. package/dist/constants/LinkProps.d.ts.map +1 -0
  29. package/dist/constants/LinkProps.js +9 -0
  30. package/dist/constants/Palette.d.ts +2 -10
  31. package/dist/constants/Palette.d.ts.map +1 -1
  32. package/dist/constants/Palette.js +2 -10
  33. package/dist/constants/Pill.d.ts +41 -0
  34. package/dist/constants/Pill.d.ts.map +1 -0
  35. package/dist/constants/Pill.js +26 -0
  36. package/dist/constants/Radius.d.ts +1 -1
  37. package/dist/constants/Radius.d.ts.map +1 -1
  38. package/dist/constants/Spacing.d.ts +4 -4
  39. package/dist/constants/Spacing.d.ts.map +1 -1
  40. package/dist/constants/Spacing.js +4 -4
  41. package/dist/constants/Typography.d.ts +25 -1
  42. package/dist/constants/Typography.d.ts.map +1 -1
  43. package/dist/constants/Typography.js +53 -29
  44. package/dist/constants/dataSetAttribute.d.ts +6 -0
  45. package/dist/constants/dataSetAttribute.d.ts.map +1 -0
  46. package/dist/constants/dataSetAttribute.js +5 -0
  47. package/dist/constants/index.d.ts +4 -0
  48. package/dist/constants/index.d.ts.map +1 -1
  49. package/dist/constants/index.js +4 -0
  50. package/dist/default.css +76 -176
  51. package/dist/helpers/alphaColor.d.ts.map +1 -1
  52. package/dist/helpers/alphaColor.js +2 -11
  53. package/dist/helpers/contrastColor.d.ts +12 -0
  54. package/dist/helpers/contrastColor.d.ts.map +1 -0
  55. package/dist/helpers/contrastColor.js +51 -0
  56. package/dist/helpers/cssVarPalette.d.ts +14 -0
  57. package/dist/helpers/cssVarPalette.d.ts.map +1 -0
  58. package/dist/helpers/cssVarPalette.js +9 -0
  59. package/dist/helpers/cssVarTypography.d.ts +12 -0
  60. package/dist/helpers/cssVarTypography.d.ts.map +1 -0
  61. package/dist/helpers/cssVarTypography.js +33 -0
  62. package/dist/helpers/darkenColor.d.ts.map +1 -1
  63. package/dist/helpers/darkenColor.js +5 -12
  64. package/dist/helpers/deepMerge.d.ts +12 -2
  65. package/dist/helpers/deepMerge.d.ts.map +1 -1
  66. package/dist/helpers/deepMerge.js +24 -14
  67. package/dist/helpers/elevationStyle.d.ts +1 -1
  68. package/dist/helpers/focusRingCSS.d.ts +15 -0
  69. package/dist/helpers/focusRingCSS.d.ts.map +1 -0
  70. package/dist/helpers/focusRingCSS.js +26 -0
  71. package/dist/helpers/hexToRgb.d.ts +6 -0
  72. package/dist/helpers/hexToRgb.d.ts.map +1 -0
  73. package/dist/helpers/hexToRgb.js +13 -0
  74. package/dist/helpers/injectVariableCSS.d.ts +14 -4
  75. package/dist/helpers/injectVariableCSS.d.ts.map +1 -1
  76. package/dist/helpers/injectVariableCSS.js +19 -42
  77. package/dist/helpers/isRecord.d.ts +3 -0
  78. package/dist/helpers/isRecord.d.ts.map +1 -0
  79. package/dist/helpers/isRecord.js +2 -0
  80. package/dist/helpers/linkCSS.d.ts +2 -0
  81. package/dist/helpers/linkCSS.d.ts.map +1 -0
  82. package/dist/helpers/linkCSS.js +2 -0
  83. package/dist/helpers/mapValues.d.ts +15 -0
  84. package/dist/helpers/mapValues.d.ts.map +1 -0
  85. package/dist/helpers/mapValues.js +11 -0
  86. package/dist/helpers/removeUnsupportedCSSProperties.d.ts.map +1 -1
  87. package/dist/helpers/removeUnsupportedCSSProperties.js +6 -10
  88. package/dist/helpers/typographyVariables.d.ts +22 -0
  89. package/dist/helpers/typographyVariables.d.ts.map +1 -0
  90. package/dist/helpers/typographyVariables.js +49 -0
  91. package/dist/helpers/useThemeBuilder.d.ts.map +1 -1
  92. package/dist/helpers/useThemeBuilder.js +10 -46
  93. package/dist/index.d.ts +1 -0
  94. package/dist/index.d.ts.map +1 -1
  95. package/dist/index.js +1 -0
  96. package/dist/type/Theme.d.ts +4 -0
  97. package/dist/type/Theme.d.ts.map +1 -1
  98. package/package.json +12 -12
@@ -5,7 +5,7 @@ import { ElevationKey } from '../constants';
5
5
  * @returns
6
6
  */
7
7
  export declare const elevationStyle: (level: ElevationKey) => {
8
- shadowColor: import("..").Color;
8
+ shadowColor: string;
9
9
  shadowOffset: {
10
10
  width: number;
11
11
  height: number;
@@ -0,0 +1,15 @@
1
+ /**
2
+ * La bague de focus du kit, en CSS plutot qu'en style de composant.
3
+ *
4
+ * Elle nait de `:focus-visible`, le seul selecteur qui distingue une arrivee au clavier d'un
5
+ * clic : c'est la regle commune a Primer, a `@atlaskit/focus-ring` et a Base. Un style pose
6
+ * depuis un state React branche sur `onFocus` ne le peut pas, `Pressable` de react-native-web
7
+ * n'exposant qu'un `focused` brut, sans notion de modalite. C'est ce contournement, adopte
8
+ * parce que jsdom ne resout pas `:focus`, qui faisait apparaitre la bague au clic sur les
9
+ * boutons et les onglets.
10
+ *
11
+ * Elle ne s'applique qu'aux elements portant `FOCUS_ATTRIBUTE`, jamais a la page entiere :
12
+ * cf. ADR 0008.
13
+ */
14
+ export declare const generateFocusRingCSS: () => string;
15
+ //# sourceMappingURL=focusRingCSS.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"focusRingCSS.d.ts","sourceRoot":"","sources":["../../src/helpers/focusRingCSS.ts"],"names":[],"mappings":"AAKA;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,oBAAoB,QAAO,MAU1B,CAAC"}
@@ -0,0 +1,26 @@
1
+ import { FOCUS_ATTRIBUTE, focusBorder, FocusRingMetrics } from '../constants/Focus';
2
+ /** Un seul point de construction du selecteur : l'attribut ne s'ecrit qu'ici. */
3
+ const marque = (variante) => (variante ? `[${FOCUS_ATTRIBUTE}='${variante}']` : `[${FOCUS_ATTRIBUTE}]`);
4
+ /**
5
+ * La bague de focus du kit, en CSS plutot qu'en style de composant.
6
+ *
7
+ * Elle nait de `:focus-visible`, le seul selecteur qui distingue une arrivee au clavier d'un
8
+ * clic : c'est la regle commune a Primer, a `@atlaskit/focus-ring` et a Base. Un style pose
9
+ * depuis un state React branche sur `onFocus` ne le peut pas, `Pressable` de react-native-web
10
+ * n'exposant qu'un `focused` brut, sans notion de modalite. C'est ce contournement, adopte
11
+ * parce que jsdom ne resout pas `:focus`, qui faisait apparaitre la bague au clic sur les
12
+ * boutons et les onglets.
13
+ *
14
+ * Elle ne s'applique qu'aux elements portant `FOCUS_ATTRIBUTE`, jamais a la page entiere :
15
+ * cf. ADR 0008.
16
+ */
17
+ export const generateFocusRingCSS = () => [
18
+ // `!important` : Tamagui laisse un `outline: none` en style inline sur certains de ses
19
+ // conteneurs, et un style inline bat toute feuille de style. Sans lui, la `Tabs.List` -
20
+ // point d'entree au clavier du composant - restait un arret invisible. Sans danger, la
21
+ // regle ne touchant que ce qui a demande la bague : un champ, qui eteint son contour au
22
+ // profit de sa bordure (ADR 0016), ne porte pas la marque.
23
+ `${marque()}:focus-visible { outline: ${FocusRingMetrics.width}px solid ${focusBorder().borderColor} !important; outline-offset: ${FocusRingMetrics.offset}px !important; }`,
24
+ `${marque()}:focus:not(:focus-visible) { outline: none !important; }`,
25
+ `${marque('inset')}:focus-visible { outline-offset: ${FocusRingMetrics.insetOffset}px !important; }`,
26
+ ].join('\n');
@@ -0,0 +1,6 @@
1
+ import { Color } from '../constants';
2
+ type Rgb = [number, number, number];
3
+ /** Decompose une couleur hexadecimale, courte (`#369`) ou longue (`#336699`), en ses trois canaux. */
4
+ export declare const hexToRgb: (hexadecimalColor: Color) => Rgb;
5
+ export {};
6
+ //# sourceMappingURL=hexToRgb.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hexToRgb.d.ts","sourceRoot":"","sources":["../../src/helpers/hexToRgb.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAErC,KAAK,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;AAEpC,sGAAsG;AACtG,eAAO,MAAM,QAAQ,GAAI,kBAAkB,KAAK,KAAG,GAUlD,CAAC"}
@@ -0,0 +1,13 @@
1
+ /** Decompose une couleur hexadecimale, courte (`#369`) ou longue (`#336699`), en ses trois canaux. */
2
+ export const hexToRgb = (hexadecimalColor) => {
3
+ let digits = hexadecimalColor.replace(/^#/, '');
4
+ if (digits.length === 3)
5
+ digits = digits
6
+ .split('')
7
+ .map(c => c + c)
8
+ .join('');
9
+ if (digits.length !== 6)
10
+ throw new Error('Invalid hex color');
11
+ const channel = (start) => parseInt(digits.slice(start, start + 2), 16);
12
+ return [channel(0), channel(2), channel(4)];
13
+ };
@@ -1,7 +1,17 @@
1
1
  import { Theme } from '../type';
2
- export declare const generateCSSVariables: (theme: Theme) => string;
3
- export declare const injectVariableCSS: (theme: Theme) => void;
2
+ /** Ce que la generation du CSS lit du theme : le theme par defaut n'a besoin de rien d'autre. */
3
+ type SourceDuCSS = {
4
+ color: Pick<Theme['color'], '_constants' | '_rawLight'>;
5
+ };
6
+ export declare const generateCSSVariables: (theme: SourceDuCSS) => string;
7
+ export declare const injectVariableCSS: (theme: SourceDuCSS) => void;
4
8
  export declare const generateFontFaceCSS: () => string;
5
- export declare const generateFontSmoothingCSS: () => string;
6
- export declare const generateDefaultThemeCSS: () => string;
9
+ /**
10
+ * Le CSS que le paquet emet sur le web, en morceaux ordonnes. Les deux assembleurs
11
+ * (le `<style>` de WebThemeStyles et le `dist/default.css` du script de build) passent
12
+ * par ici : sans ce point unique, la liste serait tenue en phase a la main dans deux
13
+ * fichiers dont l'un est un script que personne ne relit.
14
+ */
15
+ export declare const generateThemeCSSParts: (theme?: SourceDuCSS) => string[];
16
+ export {};
7
17
  //# sourceMappingURL=injectVariableCSS.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"injectVariableCSS.d.ts","sourceRoot":"","sources":["../../src/helpers/injectVariableCSS.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AA6BhC,eAAO,MAAM,oBAAoB,GAAI,OAAO,KAAK,KAAG,MA+CnD,CAAC;AA8CF,eAAO,MAAM,iBAAiB,GAAI,OAAO,KAAK,SAY7C,CAAC;AAEF,eAAO,MAAM,mBAAmB,QAAO,MAYtC,CAAC;AAEF,eAAO,MAAM,wBAAwB,QAAO,MAC6E,CAAC;AAE1H,eAAO,MAAM,uBAAuB,QAAO,MAM9B,CAAC"}
1
+ {"version":3,"file":"injectVariableCSS.d.ts","sourceRoot":"","sources":["../../src/helpers/injectVariableCSS.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAMhC,iGAAiG;AACjG,KAAK,WAAW,GAAG;IAAE,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,YAAY,GAAG,WAAW,CAAC,CAAA;CAAE,CAAC;AAwB/E,eAAO,MAAM,oBAAoB,GAAI,OAAO,WAAW,KAAG,MA8CzD,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAAI,OAAO,WAAW,SAYnD,CAAC;AAEF,eAAO,MAAM,mBAAmB,QAAO,MAYtC,CAAC;AASF;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,GAAI,QAAO,WAA0B,KAAG,MAAM,EAK/E,CAAC"}
@@ -3,7 +3,10 @@ import { Elevations } from '../constants/Elevation';
3
3
  import { FontWeightMap } from '../constants/Font';
4
4
  import { RadiusList } from '../constants/Radius';
5
5
  import { CustomTypography } from '../constants/Typography';
6
+ import { generateFocusRingCSS } from './focusRingCSS';
7
+ import { generateLinkCSS } from './linkCSS';
6
8
  import { sanitizeCSSKey } from './sanitizeCSSKey';
9
+ import { typographyVariableLines } from './typographyVariables';
7
10
  const buildColorVarMap = (constants) => {
8
11
  const map = new Map();
9
12
  Object.entries(constants).forEach(([name, shades]) => {
@@ -54,10 +57,9 @@ export const generateCSSVariables = (theme) => {
54
57
  lines.push(` --font-${key}-weight: ${weight};`);
55
58
  });
56
59
  // Semantic tokens typographiques (--typography-{...}-font-size, etc.)
57
- collectTypographyLines([], CustomTypography, fontReverseMap, lines);
60
+ lines.push(...typographyVariableLines(CustomTypography, fontReverseMap));
58
61
  // Semantic tokens light (--{category}-{token}: var(--color-...))
59
- const light = theme.color._rawLight;
60
- Object.entries(light).forEach(([category, tokens]) => {
62
+ Object.entries(theme.color._rawLight).forEach(([category, tokens]) => {
61
63
  if (typeof tokens !== 'object' || tokens === null)
62
64
  return;
63
65
  lines.push(...generateSemanticTokenLines(category, tokens, colorVarMap));
@@ -65,42 +67,6 @@ export const generateCSSVariables = (theme) => {
65
67
  const rootBlock = `:root {\n${lines.join('\n')}\n}`;
66
68
  return rootBlock;
67
69
  };
68
- const collectTypographyLines = (path, node, fontReverseMap, lines) => {
69
- if (typeof node !== 'object' || node === null)
70
- return;
71
- const obj = node;
72
- if (typeof obj.fontSize === 'number') {
73
- const prefix = ` --typography-${path.map(sanitizeCSSKey).join('-')}`;
74
- if (typeof obj.fontFamily === 'string') {
75
- const weight = typeof obj.fontWeight === 'string' ? obj.fontWeight : '';
76
- const fontKey = fontReverseMap.get(`${obj.fontFamily}__${weight}`) ??
77
- (obj.fontFamily in FontWeightMap ? obj.fontFamily : undefined);
78
- if (fontKey) {
79
- lines.push(`${prefix}-font-family: var(--font-${fontKey}-family);`);
80
- lines.push(`${prefix}-font-weight: var(--font-${fontKey}-weight);`);
81
- }
82
- else {
83
- lines.push(`${prefix}-font-family: ${obj.fontFamily};`);
84
- if (weight)
85
- lines.push(`${prefix}-font-weight: ${weight};`);
86
- }
87
- }
88
- lines.push(`${prefix}-font-size: ${obj.fontSize}px;`);
89
- if (typeof obj.lineHeight === 'number') {
90
- lines.push(`${prefix}-line-height: ${obj.lineHeight}px;`);
91
- }
92
- if (typeof obj.letterSpacing === 'number' && obj.letterSpacing !== 0) {
93
- lines.push(`${prefix}-letter-spacing: ${obj.letterSpacing}px;`);
94
- }
95
- if (typeof obj.textTransform === 'string') {
96
- lines.push(`${prefix}-text-transform: ${obj.textTransform};`);
97
- }
98
- return;
99
- }
100
- Object.entries(obj).forEach(([key, value]) => {
101
- collectTypographyLines([...path, key], value, fontReverseMap, lines);
102
- });
103
- };
104
70
  export const injectVariableCSS = (theme) => {
105
71
  if (typeof document === 'undefined')
106
72
  return;
@@ -125,10 +91,21 @@ export const generateFontFaceCSS = () => {
125
91
  .join('&');
126
92
  return `@import url('https://fonts.googleapis.com/css2?${families}&display=swap');`;
127
93
  };
128
- export const generateFontSmoothingCSS = () => 'body { -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-rendering: optimizeLegibility; }';
129
- export const generateDefaultThemeCSS = () => generateCSSVariables({
94
+ const DefaultTheme = {
130
95
  color: {
131
96
  _constants: Colors,
132
97
  _rawLight: CustomPalette.light,
133
98
  },
134
- });
99
+ };
100
+ /**
101
+ * Le CSS que le paquet emet sur le web, en morceaux ordonnes. Les deux assembleurs
102
+ * (le `<style>` de WebThemeStyles et le `dist/default.css` du script de build) passent
103
+ * par ici : sans ce point unique, la liste serait tenue en phase a la main dans deux
104
+ * fichiers dont l'un est un script que personne ne relit.
105
+ */
106
+ export const generateThemeCSSParts = (theme = DefaultTheme) => [
107
+ generateFontFaceCSS(),
108
+ generateCSSVariables(theme),
109
+ generateFocusRingCSS(),
110
+ generateLinkCSS(),
111
+ ];
@@ -0,0 +1,3 @@
1
+ /** Vrai pour un objet indexable par chaine (ni `null`, ni primitive, ni tableau ecarte a l'usage). */
2
+ export declare const isRecord: (value: unknown) => value is Record<string, unknown>;
3
+ //# sourceMappingURL=isRecord.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"isRecord.d.ts","sourceRoot":"","sources":["../../src/helpers/isRecord.ts"],"names":[],"mappings":"AAAA,sGAAsG;AACtG,eAAO,MAAM,QAAQ,GAAI,OAAO,OAAO,KAAG,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAC5B,CAAC"}
@@ -0,0 +1,2 @@
1
+ /** Vrai pour un objet indexable par chaine (ni `null`, ni primitive, ni tableau ecarte a l'usage). */
2
+ export const isRecord = (value) => typeof value === 'object' && value !== null;
@@ -0,0 +1,2 @@
1
+ export declare const generateLinkCSS: () => string;
2
+ //# sourceMappingURL=linkCSS.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"linkCSS.d.ts","sourceRoot":"","sources":["../../src/helpers/linkCSS.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,eAAe,QAAO,MAAiE,CAAC"}
@@ -0,0 +1,2 @@
1
+ import { LINK_ATTRIBUTE } from '../constants/Link';
2
+ export const generateLinkCSS = () => `[${LINK_ATTRIBUTE}] { text-underline-offset: 0.2em; }`;
@@ -0,0 +1,15 @@
1
+ type MapValues = <T extends object, R>(objet: T, transformation: (valeur: T[keyof T], cle: keyof T & string) => R) => {
2
+ [K in keyof T]: R;
3
+ };
4
+ /**
5
+ * Transforme chaque valeur d'un objet en gardant ses cles, et le dit dans son type.
6
+ *
7
+ * `Object.fromEntries` rend un `Record<string, R>` : TypeScript ne sait pas prouver que les
8
+ * cles ressortent identiques. Cette preuve, faite ici par construction (on ne parcourt que les
9
+ * cles de l'entree), est la seule assertion de type que le depot tolere : les parcours du theme
10
+ * passent tous par cette fonction plutot que de porter chacun la leur.
11
+ * Elle est exemptee de la regle par un override de la config ESLint, pas par une directive.
12
+ */
13
+ export declare const mapValues: MapValues;
14
+ export {};
15
+ //# sourceMappingURL=mapValues.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mapValues.d.ts","sourceRoot":"","sources":["../../src/helpers/mapValues.ts"],"names":[],"mappings":"AAAA,KAAK,SAAS,GAAG,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,EACnC,KAAK,EAAE,CAAC,EACR,cAAc,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,MAAM,KAAK,CAAC,KAC7D;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC;CAAE,CAAC;AAU3B;;;;;;;;GAQG;AACH,eAAO,MAAM,SAAS,EAA6B,SAAS,CAAC"}
@@ -0,0 +1,11 @@
1
+ const transformeChaqueValeur = (objet, transformation) => Object.fromEntries(Object.entries(objet).map(([cle, valeur]) => [cle, transformation(valeur, cle)]));
2
+ /**
3
+ * Transforme chaque valeur d'un objet en gardant ses cles, et le dit dans son type.
4
+ *
5
+ * `Object.fromEntries` rend un `Record<string, R>` : TypeScript ne sait pas prouver que les
6
+ * cles ressortent identiques. Cette preuve, faite ici par construction (on ne parcourt que les
7
+ * cles de l'entree), est la seule assertion de type que le depot tolere : les parcours du theme
8
+ * passent tous par cette fonction plutot que de porter chacun la leur.
9
+ * Elle est exemptee de la regle par un override de la config ESLint, pas par une directive.
10
+ */
11
+ export const mapValues = transformeChaqueValeur;
@@ -1 +1 @@
1
- {"version":3,"file":"removeUnsupportedCSSProperties.d.ts","sourceRoot":"","sources":["../../src/helpers/removeUnsupportedCSSProperties.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE/C;;;;GAIG;AACH,wBAAgB,8BAA8B,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC,GAAG,CAAC,CAUjG"}
1
+ {"version":3,"file":"removeUnsupportedCSSProperties.d.ts","sourceRoot":"","sources":["../../src/helpers/removeUnsupportedCSSProperties.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAM/C;;;;GAIG;AACH,wBAAgB,8BAA8B,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC,GAAG,CAAC,CAMjG"}
@@ -1,20 +1,16 @@
1
1
  import { Platform } from 'react-native';
2
2
  import { UnsupportedCSSProperties } from '../constants';
3
+ /** Les propriétés interdites sur la plateforme courante, chacune ramenée à `undefined`. */
4
+ const annulations = () => Object.fromEntries((UnsupportedCSSProperties[Platform.OS] ?? []).map(propriete => [propriete, undefined]));
3
5
  /**
4
6
  * Retire les propriétés CSS non supportées pour une platforme
5
7
  * @param styles Styles appliqués
6
8
  * @returns Les styles sans les propriétés exclues pour la platform
7
9
  */
8
10
  export function removeUnsupportedCSSProperties(styles) {
9
- const platform = Platform.OS;
10
- const blocklist = UnsupportedCSSProperties[platform] ?? [];
11
- const cleaned = {};
12
- for (const key in styles) {
13
- const style = { ...styles[key] };
14
- for (const prop of blocklist)
15
- if (prop in style)
16
- style[prop] = undefined;
17
- cleaned[key] = style;
18
- }
11
+ const interdites = annulations();
12
+ const cleaned = { ...styles };
13
+ for (const key in cleaned)
14
+ cleaned[key] = { ...cleaned[key], ...interdites };
19
15
  return cleaned;
20
16
  }
@@ -0,0 +1,22 @@
1
+ /** Couple `${famille}__${poids}` vers la cle de police du catalogue. */
2
+ export type FontCatalogue = Map<string, string>;
3
+ /** La police d'un cran typographique : ses deux attributs ne voyagent jamais l'un sans l'autre. */
4
+ export type Police = {
5
+ fontFamily: string;
6
+ fontWeight: string;
7
+ };
8
+ export declare const fontVariableLines: (prefix: string, { fontFamily, fontWeight }: Police, catalogue: FontCatalogue) => string[];
9
+ export type TypographyMetrics = {
10
+ fontSize: number;
11
+ lineHeight?: unknown;
12
+ letterSpacing?: unknown;
13
+ textTransform?: unknown;
14
+ };
15
+ export declare const metricVariableLines: (prefix: string, metrics: TypographyMetrics) => string[];
16
+ /**
17
+ * Traduit l'arbre des jetons typographiques en declarations CSS. Chaque feuille est
18
+ * reconnue a son `fontSize` : au-dessus, ce sont des regroupements dont le nom se
19
+ * concatene pour former celui de la variable.
20
+ */
21
+ export declare const typographyVariableLines: (typography: unknown, catalogue: FontCatalogue, path?: string[]) => string[];
22
+ //# sourceMappingURL=typographyVariables.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"typographyVariables.d.ts","sourceRoot":"","sources":["../../src/helpers/typographyVariables.ts"],"names":[],"mappings":"AAGA,wEAAwE;AACxE,MAAM,MAAM,aAAa,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAUhD,mGAAmG;AACnG,MAAM,MAAM,MAAM,GAAG;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC;AAEhE,eAAO,MAAM,iBAAiB,GAC5B,QAAQ,MAAM,EACd,4BAA4B,MAAM,EAClC,WAAW,aAAa,KACvB,MAAM,EAWR,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAAI,QAAQ,MAAM,EAAE,SAAS,iBAAiB,KAAG,MAAM,EAOtF,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,uBAAuB,GAClC,YAAY,OAAO,EACnB,WAAW,aAAa,EACxB,OAAM,MAAM,EAAO,KAClB,MAAM,EAwBR,CAAC"}
@@ -0,0 +1,49 @@
1
+ import { isRecord } from './isRecord';
2
+ import { sanitizeCSSKey } from './sanitizeCSSKey';
3
+ const resolveFontKey = (fontFamily, fontWeight, catalogue) => {
4
+ const byFamilyAndWeight = catalogue.get(`${fontFamily}__${fontWeight}`);
5
+ if (byFamilyAndWeight)
6
+ return byFamilyAndWeight;
7
+ // Hors web, `fontStyle` pose la cle du catalogue directement dans `fontFamily`.
8
+ return Array.from(catalogue.values()).find(key => key === fontFamily);
9
+ };
10
+ export const fontVariableLines = (prefix, { fontFamily, fontWeight }, catalogue) => {
11
+ const fontKey = resolveFontKey(fontFamily, fontWeight, catalogue);
12
+ if (fontKey) {
13
+ return [
14
+ `${prefix}-font-family: var(--font-${fontKey}-family);`,
15
+ `${prefix}-font-weight: var(--font-${fontKey}-weight);`,
16
+ ];
17
+ }
18
+ return [`${prefix}-font-family: ${fontFamily};`, ...(fontWeight ? [`${prefix}-font-weight: ${fontWeight};`] : [])];
19
+ };
20
+ export const metricVariableLines = (prefix, metrics) => [
21
+ `${prefix}-font-size: ${metrics.fontSize}px;`,
22
+ ...(typeof metrics.lineHeight === 'number' ? [`${prefix}-line-height: ${metrics.lineHeight}px;`] : []),
23
+ ...(typeof metrics.letterSpacing === 'number' && metrics.letterSpacing !== 0
24
+ ? [`${prefix}-letter-spacing: ${metrics.letterSpacing}px;`]
25
+ : []),
26
+ ...(typeof metrics.textTransform === 'string' ? [`${prefix}-text-transform: ${metrics.textTransform};`] : []),
27
+ ];
28
+ /**
29
+ * Traduit l'arbre des jetons typographiques en declarations CSS. Chaque feuille est
30
+ * reconnue a son `fontSize` : au-dessus, ce sont des regroupements dont le nom se
31
+ * concatene pour former celui de la variable.
32
+ */
33
+ export const typographyVariableLines = (typography, catalogue, path = []) => {
34
+ if (!isRecord(typography))
35
+ return [];
36
+ if (typeof typography.fontSize !== 'number') {
37
+ return Object.entries(typography).flatMap(([key, value]) => typographyVariableLines(value, catalogue, [...path, key]));
38
+ }
39
+ const prefix = ` --typography-${path.map(sanitizeCSSKey).join('-')}`;
40
+ return [
41
+ ...(typeof typography.fontFamily === 'string'
42
+ ? fontVariableLines(prefix, {
43
+ fontFamily: typography.fontFamily,
44
+ fontWeight: typeof typography.fontWeight === 'string' ? typography.fontWeight : '',
45
+ }, catalogue)
46
+ : []),
47
+ ...metricVariableLines(prefix, { ...typography, fontSize: typography.fontSize }),
48
+ ];
49
+ };
@@ -1 +1 @@
1
- {"version":3,"file":"useThemeBuilder.d.ts","sourceRoot":"","sources":["../../src/helpers/useThemeBuilder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAKrC,OAAO,EAKL,WAAW,EAKX,OAAO,EAGR,MAAM,cAAc,CAAC;AAOtB,MAAM,MAAM,aAAa,GAAG;IAC1B,KAAK,CAAC,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC;CAC9B,CAAC;AAgDF,wBAAgB,eAAe,CAAC,MAAM,EAAE,aAAa,GAAG,KAAK,GAAG;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE,CA0EnF"}
1
+ {"version":3,"file":"useThemeBuilder.d.ts","sourceRoot":"","sources":["../../src/helpers/useThemeBuilder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAKrC,OAAO,EAKL,WAAW,EAKX,OAAO,EAGR,MAAM,cAAc,CAAC;AAWtB,MAAM,MAAM,aAAa,GAAG;IAC1B,KAAK,CAAC,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC;CAC9B,CAAC;AAEF,wBAAgB,eAAe,CAAC,MAAM,EAAE,aAAa,GAAG,KAAK,GAAG;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE,CA6EnF"}
@@ -2,53 +2,15 @@ import { useFonts } from 'expo-font';
2
2
  import { useCallback, useMemo } from 'react';
3
3
  import { Platform, useWindowDimensions } from 'react-native';
4
4
  import { breakpointToVariant, Colors, CustomPalette, CustomTypography, Fonts, FontsMap, Grilles, Heights, Sizes, Spacings, } from '../constants';
5
+ import { controlSizesFor } from '../constants/Control';
6
+ import { pillSizeFor } from '../constants/Pill';
5
7
  import { RadiusList } from '../constants/Radius';
6
8
  import { alpha } from './alphaColor';
9
+ import { toCSSVarPalette } from './cssVarPalette';
10
+ import { toCSSVarTypography } from './cssVarTypography';
7
11
  import { deepMerge } from './deepMerge';
8
12
  import { elevationStyle } from './elevationStyle';
9
13
  import { sanitizeCSSKey } from './sanitizeCSSKey';
10
- const toCSSVarPalette = (palette) => {
11
- if (Platform.OS !== 'web')
12
- return palette;
13
- const light = palette.light;
14
- const webLight = {};
15
- Object.entries(light).forEach(([category, tokens]) => {
16
- if (typeof tokens !== 'object' || tokens === null) {
17
- webLight[category] = tokens;
18
- return;
19
- }
20
- webLight[category] = {};
21
- Object.entries(tokens).forEach(([token, value]) => {
22
- webLight[category][token] = typeof value === 'string' ? `var(--${category}-${token})` : value;
23
- });
24
- });
25
- return { ...palette, light: webLight };
26
- };
27
- const toCSSVarTypography = (node, path = []) => {
28
- if (typeof node.fontSize === 'number') {
29
- const prefix = path.map(sanitizeCSSKey).join('-');
30
- const result = { ...node };
31
- result.fontFamily = `var(--typography-${prefix}-font-family)`;
32
- result.fontWeight = `var(--typography-${prefix}-font-weight)`;
33
- result.fontSize = `var(--typography-${prefix}-font-size)`;
34
- result.lineHeight = `var(--typography-${prefix}-line-height)`;
35
- if (typeof node.letterSpacing === 'number' && node.letterSpacing !== 0) {
36
- result.letterSpacing = `var(--typography-${prefix}-letter-spacing)`;
37
- }
38
- if (typeof node.textTransform === 'string') {
39
- result.textTransform = `var(--typography-${prefix}-text-transform)`;
40
- }
41
- return result;
42
- }
43
- const result = {};
44
- Object.entries(node).forEach(([key, value]) => {
45
- result[key] =
46
- typeof value === 'object' && value !== null
47
- ? toCSSVarTypography(value, [...path, key])
48
- : value;
49
- });
50
- return result;
51
- };
52
14
  export function useThemeBuilder(params) {
53
15
  const { width } = useWindowDimensions();
54
16
  // Sur web, les fonts sont chargées via @font-face (generateFontFaceCSS), pas via expo-font,
@@ -56,16 +18,14 @@ export function useThemeBuilder(params) {
56
18
  const [loadedFonts] = useFonts(Platform.OS === 'web' ? {} : FontsMap);
57
19
  const variant = useMemo(() => breakpointToVariant(width), [width]);
58
20
  const rawMergedPalette = useMemo(() => deepMerge(CustomPalette, params.color), [params.color]);
59
- const mergedPalette = useMemo(() => toCSSVarPalette(rawMergedPalette), [rawMergedPalette]);
21
+ const mergedPalette = useMemo(() => (Platform.OS === 'web' ? toCSSVarPalette(rawMergedPalette) : rawMergedPalette), [rawMergedPalette]);
60
22
  const isReady = useMemo(() => width != null && variant != null && width > 0 && loadedFonts, [loadedFonts, variant, width]);
61
23
  const externalPadding = useCallback(() => Platform.OS === 'web'
62
24
  ? `var(--spacing-${sanitizeCSSKey(variant === 'mobile' ? '2W' : '3W')})`
63
25
  : variant === 'mobile'
64
26
  ? Spacings['2W']
65
27
  : Spacings['3W'], [variant]);
66
- const webTypography = useMemo(() => Platform.OS === 'web'
67
- ? toCSSVarTypography(CustomTypography)
68
- : CustomTypography, []);
28
+ const webTypography = useMemo(() => (Platform.OS === 'web' ? toCSSVarTypography(CustomTypography) : CustomTypography), []);
69
29
  return {
70
30
  // Spacings
71
31
  spacing: key => (Platform.OS === 'web' ? `var(--spacing-${sanitizeCSSKey(key)})` : Spacings[key]),
@@ -73,6 +33,10 @@ export function useThemeBuilder(params) {
73
33
  externalPadding,
74
34
  // Radius
75
35
  radius: key => (Platform.OS === 'web' ? `var(--radius-${key})` : RadiusList[key]),
36
+ // Dimensions des controles : la densite suit la largeur d'ecran, comme externalPadding
37
+ control: key => controlSizesFor(variant)[key],
38
+ // Dimensions des puces : une seule densite, une puce n'etant pas une cible tactile
39
+ pill: pillSizeFor,
76
40
  // Grilles
77
41
  grilles: Grilles,
78
42
  // Breakpoints
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export * from './constants';
2
+ export * from './helpers/contrastColor';
2
3
  export * from './helpers/deepMerge';
3
4
  export * from './helpers/grayscaleStyle';
4
5
  export * from './helpers/injectVariableCSS';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,qBAAqB,CAAC;AACpC,cAAc,0BAA0B,CAAC;AACzC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,wBAAwB,CAAC;AACvC,cAAc,sBAAsB,CAAC;AACrC,cAAc,0BAA0B,CAAC;AACzC,cAAc,iBAAiB,CAAC;AAChC,cAAc,QAAQ,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,yBAAyB,CAAC;AACxC,cAAc,qBAAqB,CAAC;AACpC,cAAc,0BAA0B,CAAC;AACzC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,wBAAwB,CAAC;AACvC,cAAc,sBAAsB,CAAC;AACrC,cAAc,0BAA0B,CAAC;AACzC,cAAc,iBAAiB,CAAC;AAChC,cAAc,QAAQ,CAAC"}
package/dist/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  export * from './constants';
2
+ export * from './helpers/contrastColor';
2
3
  export * from './helpers/deepMerge';
3
4
  export * from './helpers/grayscaleStyle';
4
5
  export * from './helpers/injectVariableCSS';
@@ -1,4 +1,6 @@
1
1
  import type { Colors, CustomTypography, Fonts, Grilles, Palette, Spacing, SpacingKey, Variant } from '../constants';
2
+ import type { ControlSize, ControlSizeKey } from '../constants/Control';
3
+ import type { PillSize, PillSizeKey } from '../constants/Pill';
2
4
  import { Radius, RadiusKey } from '../constants/Radius';
3
5
  import { alpha } from '../helpers/alphaColor';
4
6
  import { elevationStyle } from '../helpers/elevationStyle';
@@ -14,6 +16,8 @@ export interface Theme {
14
16
  isVariant: (variant: Variant) => boolean;
15
17
  shadows: typeof elevationStyle;
16
18
  radius: (key: RadiusKey) => Radius;
19
+ control: (key: ControlSizeKey) => ControlSize;
20
+ pill: (key: PillSizeKey) => PillSize;
17
21
  grilles: typeof Grilles;
18
22
  text: Typography & typeof CustomTypography;
19
23
  font: typeof Fonts;
@@ -1 +1 @@
1
- {"version":3,"file":"Theme.d.ts","sourceRoot":"","sources":["../../src/type/Theme.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,gBAAgB,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACpH,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE/C,MAAM,WAAW,KAAK;IAEpB,mHAAmH;IACnH,OAAO,EAAE,CAAC,GAAG,EAAE,UAAU,KAAK,MAAM,GAAG,MAAM,CAAC;IAC9C,wHAAwH;IACxH,YAAY,EAAE,CAAC,GAAG,EAAE,UAAU,KAAK,OAAO,CAAC;IAC3C,mEAAmE;IACnE,eAAe,EAAE,MAAM,MAAM,GAAG,MAAM,CAAC;IAGvC,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC;IAGzC,OAAO,EAAE,OAAO,cAAc,CAAC;IAG/B,MAAM,EAAE,CAAC,GAAG,EAAE,SAAS,KAAK,MAAM,CAAC;IAGnC,OAAO,EAAE,OAAO,OAAO,CAAC;IAGxB,IAAI,EAAE,UAAU,GAAG,OAAO,gBAAgB,CAAC;IAG3C,IAAI,EAAE,OAAO,KAAK,CAAC;IAGnB,KAAK,EAAE;QACL,sCAAsC;QACtC,UAAU,EAAE,OAAO,MAAM,CAAC;QAC1B,4EAA4E;QAC5E,SAAS,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;KAC7B,GAAG,OAAO,GAAG;QACV,KAAK,EAAE,OAAO,KAAK,CAAC;KACrB,CAAC;CACL"}
1
+ {"version":3,"file":"Theme.d.ts","sourceRoot":"","sources":["../../src/type/Theme.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,gBAAgB,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACpH,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACxE,OAAO,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAC/D,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE/C,MAAM,WAAW,KAAK;IAEpB,mHAAmH;IACnH,OAAO,EAAE,CAAC,GAAG,EAAE,UAAU,KAAK,MAAM,GAAG,MAAM,CAAC;IAC9C,wHAAwH;IACxH,YAAY,EAAE,CAAC,GAAG,EAAE,UAAU,KAAK,OAAO,CAAC;IAC3C,mEAAmE;IACnE,eAAe,EAAE,MAAM,MAAM,GAAG,MAAM,CAAC;IAGvC,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC;IAGzC,OAAO,EAAE,OAAO,cAAc,CAAC;IAG/B,MAAM,EAAE,CAAC,GAAG,EAAE,SAAS,KAAK,MAAM,CAAC;IAGnC,OAAO,EAAE,CAAC,GAAG,EAAE,cAAc,KAAK,WAAW,CAAC;IAG9C,IAAI,EAAE,CAAC,GAAG,EAAE,WAAW,KAAK,QAAQ,CAAC;IAGrC,OAAO,EAAE,OAAO,OAAO,CAAC;IAGxB,IAAI,EAAE,UAAU,GAAG,OAAO,gBAAgB,CAAC;IAG3C,IAAI,EAAE,OAAO,KAAK,CAAC;IAGnB,KAAK,EAAE;QACL,sCAAsC;QACtC,UAAU,EAAE,OAAO,MAAM,CAAC;QAC1B,4EAA4E;QAC5E,SAAS,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;KAC7B,GAAG,OAAO,GAAG;QACV,KAAK,EAAE,OAAO,KAAK,CAAC;KACrB,CAAC;CACL"}
package/package.json CHANGED
@@ -1,22 +1,19 @@
1
1
  {
2
2
  "name": "@alveole/theme",
3
- "version": "1.10.0",
3
+ "version": "2.0.0-alpha.1",
4
4
  "description": "Shared theme tokens and utilities.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "files": [
8
8
  "dist",
9
+ "!dist/.tsbuildinfo",
9
10
  "README.md"
10
11
  ],
11
12
  "sideEffects": false,
12
- "scripts": {
13
- "build": "tsc -p tsconfig.build.json && node scripts/build-css.mjs",
14
- "lint": "eslint .",
15
- "typecheck": "tsc -p tsconfig.build.json --noEmit"
16
- },
17
13
  "devDependencies": {
18
14
  "@alveole/eslint-config": "file:../eslint-config",
19
- "eslint": "9.39.5",
15
+ "esbuild": "0.28.2",
16
+ "eslint": "10.10.0",
20
17
  "react": "19.2.3",
21
18
  "react-native": "0.86.3"
22
19
  },
@@ -31,9 +28,12 @@
31
28
  "access": "public"
32
29
  },
33
30
  "dependencies": {
34
- "@expo-google-fonts/barlow": "0.4.1",
35
- "@expo-google-fonts/inter": "0.4.2",
36
- "@uiw/react-signature": "1.3.5",
37
- "react-native-signature-canvas": "5.1.1"
31
+ "@expo-google-fonts/geist": "0.4.2"
32
+ },
33
+ "scripts": {
34
+ "build": "tsc -p tsconfig.build.json && node scripts/build-css.mjs",
35
+ "lint": "eslint . --cache --cache-strategy content",
36
+ "test:unit": "jest --coverage --runInBand --ci",
37
+ "typecheck": "tsc -p tsconfig.typecheck.json --noEmit"
38
38
  }
39
- }
39
+ }