@alveole/storybook 1.9.0 → 2.0.0-alpha

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 (138) hide show
  1. package/dist/components/BarreDeFiltres.d.ts +20 -0
  2. package/dist/components/BarreDeFiltres.d.ts.map +1 -0
  3. package/dist/components/BarreDeFiltres.js +28 -0
  4. package/dist/components/ColorSwatch.d.ts +10 -0
  5. package/dist/components/ColorSwatch.d.ts.map +1 -0
  6. package/dist/components/ColorSwatch.js +37 -0
  7. package/dist/components/DocFooter.d.ts.map +1 -1
  8. package/dist/components/DocFooter.js +1 -1
  9. package/dist/components/EcranDeCatalogue.d.ts +18 -0
  10. package/dist/components/EcranDeCatalogue.d.ts.map +1 -0
  11. package/dist/components/EcranDeCatalogue.js +16 -0
  12. package/dist/components/EnTeteDeFiche.d.ts +10 -0
  13. package/dist/components/EnTeteDeFiche.d.ts.map +1 -0
  14. package/dist/components/EnTeteDeFiche.js +13 -0
  15. package/dist/components/ExampleBlock.d.ts +12 -0
  16. package/dist/components/ExampleBlock.d.ts.map +1 -0
  17. package/dist/components/ExampleBlock.js +69 -0
  18. package/dist/components/ExemplesDeLaStory.d.ts +10 -0
  19. package/dist/components/ExemplesDeLaStory.d.ts.map +1 -0
  20. package/dist/components/ExemplesDeLaStory.js +27 -0
  21. package/dist/components/FiltreDeroulant.d.ts +22 -0
  22. package/dist/components/FiltreDeroulant.d.ts.map +1 -0
  23. package/dist/components/FiltreDeroulant.js +10 -0
  24. package/dist/components/GrilleDeFiches.d.ts +15 -0
  25. package/dist/components/GrilleDeFiches.d.ts.map +1 -0
  26. package/dist/components/GrilleDeFiches.js +14 -0
  27. package/dist/components/MenuCard.d.ts +9 -0
  28. package/dist/components/MenuCard.d.ts.map +1 -0
  29. package/dist/components/MenuCard.js +8 -0
  30. package/dist/components/PageTitle.d.ts +19 -0
  31. package/dist/components/PageTitle.d.ts.map +1 -0
  32. package/dist/components/PageTitle.js +16 -0
  33. package/dist/components/ScreenZone.d.ts +19 -0
  34. package/dist/components/ScreenZone.d.ts.map +1 -0
  35. package/dist/components/ScreenZone.js +35 -0
  36. package/dist/components/StoryCard.d.ts.map +1 -1
  37. package/dist/components/StoryCard.js +3 -1
  38. package/dist/components/StoryLayout.d.ts +14 -0
  39. package/dist/components/StoryLayout.d.ts.map +1 -0
  40. package/dist/components/StoryLayout.js +21 -0
  41. package/dist/components/StorySummary.d.ts +7 -0
  42. package/dist/components/StorySummary.d.ts.map +1 -0
  43. package/dist/components/StorySummary.js +8 -0
  44. package/dist/components/UIKitColumn.d.ts +25 -0
  45. package/dist/components/UIKitColumn.d.ts.map +1 -0
  46. package/dist/components/UIKitColumn.js +24 -0
  47. package/dist/components/UIKitTopBar.d.ts +11 -2
  48. package/dist/components/UIKitTopBar.d.ts.map +1 -1
  49. package/dist/components/UIKitTopBar.js +84 -27
  50. package/dist/components/choixDuFiltre.d.ts +14 -0
  51. package/dist/components/choixDuFiltre.d.ts.map +1 -0
  52. package/dist/components/choixDuFiltre.js +10 -0
  53. package/dist/components/hauteurDeCarte.d.ts +6 -0
  54. package/dist/components/hauteurDeCarte.d.ts.map +1 -0
  55. package/dist/components/hauteurDeCarte.js +5 -0
  56. package/dist/index.d.ts +3 -0
  57. package/dist/index.d.ts.map +1 -1
  58. package/dist/index.js +3 -0
  59. package/dist/navigation.d.ts +6 -0
  60. package/dist/navigation.d.ts.map +1 -0
  61. package/dist/navigation.js +3 -0
  62. package/dist/pages/InstallationPage.d.ts +8 -0
  63. package/dist/pages/InstallationPage.d.ts.map +1 -0
  64. package/dist/pages/InstallationPage.js +13 -0
  65. package/dist/pages/PhilosophyPage.d.ts +2 -1
  66. package/dist/pages/PhilosophyPage.d.ts.map +1 -1
  67. package/dist/pages/PhilosophyPage.js +7 -7
  68. package/dist/pages/UIKitHomePage.d.ts.map +1 -1
  69. package/dist/pages/UIKitHomePage.js +3 -7
  70. package/dist/pages/UIKitPage.d.ts +3 -4
  71. package/dist/pages/UIKitPage.d.ts.map +1 -1
  72. package/dist/pages/UIKitPage.js +59 -36
  73. package/dist/pages/UIKitThemePage.d.ts +6 -1
  74. package/dist/pages/UIKitThemePage.d.ts.map +1 -1
  75. package/dist/pages/UIKitThemePage.js +4 -8
  76. package/dist/pages/ecransDuKit.d.ts +18 -0
  77. package/dist/pages/ecransDuKit.d.ts.map +1 -0
  78. package/dist/pages/ecransDuKit.js +11 -0
  79. package/dist/pages/installation.d.ts +18 -0
  80. package/dist/pages/installation.d.ts.map +1 -0
  81. package/dist/pages/installation.js +218 -0
  82. package/dist/pages/installationOutillage.d.ts +7 -0
  83. package/dist/pages/installationOutillage.d.ts.map +1 -0
  84. package/dist/pages/installationOutillage.js +152 -0
  85. package/dist/pages/philosophie.d.ts +10 -0
  86. package/dist/pages/philosophie.d.ts.map +1 -0
  87. package/dist/pages/philosophie.js +46 -0
  88. package/dist/pressePapiers.d.ts +10 -0
  89. package/dist/pressePapiers.d.ts.map +1 -0
  90. package/dist/pressePapiers.js +14 -0
  91. package/dist/screens/StoriesScreen.d.ts +2 -1
  92. package/dist/screens/StoriesScreen.d.ts.map +1 -1
  93. package/dist/screens/StoriesScreen.js +18 -35
  94. package/dist/screens/StoryDetailScreen.d.ts +2 -1
  95. package/dist/screens/StoryDetailScreen.d.ts.map +1 -1
  96. package/dist/screens/StoryDetailScreen.js +24 -74
  97. package/dist/screens/ThemeCSSVariablesScreen.d.ts +2 -1
  98. package/dist/screens/ThemeCSSVariablesScreen.d.ts.map +1 -1
  99. package/dist/screens/ThemeCSSVariablesScreen.js +7 -97
  100. package/dist/screens/ThemeConstantDetailScreen.d.ts +2 -1
  101. package/dist/screens/ThemeConstantDetailScreen.d.ts.map +1 -1
  102. package/dist/screens/ThemeConstantDetailScreen.js +4 -4
  103. package/dist/screens/ThemeConstantsScreen.d.ts +2 -1
  104. package/dist/screens/ThemeConstantsScreen.d.ts.map +1 -1
  105. package/dist/screens/ThemeConstantsScreen.js +7 -8
  106. package/dist/screens/ThemePaletteScreen.d.ts +2 -1
  107. package/dist/screens/ThemePaletteScreen.d.ts.map +1 -1
  108. package/dist/screens/ThemePaletteScreen.js +11 -92
  109. package/dist/screens/ThemeTypographyScreen.d.ts +2 -1
  110. package/dist/screens/ThemeTypographyScreen.d.ts.map +1 -1
  111. package/dist/screens/ThemeTypographyScreen.js +6 -6
  112. package/dist/screens/colonnesDeFiches.d.ts +6 -0
  113. package/dist/screens/colonnesDeFiches.d.ts.map +1 -0
  114. package/dist/screens/colonnesDeFiches.js +20 -0
  115. package/dist/screens/paletteSections.d.ts +30 -0
  116. package/dist/screens/paletteSections.d.ts.map +1 -0
  117. package/dist/screens/paletteSections.js +76 -0
  118. package/dist/screens/sourcesDExemples.d.ts +17 -0
  119. package/dist/screens/sourcesDExemples.d.ts.map +1 -0
  120. package/dist/screens/sourcesDExemples.js +27 -0
  121. package/dist/screens/variablesCSSDuTheme.d.ts +12 -0
  122. package/dist/screens/variablesCSSDuTheme.d.ts.map +1 -0
  123. package/dist/screens/variablesCSSDuTheme.js +77 -0
  124. package/dist/screens/variablesDeTypographie.d.ts +8 -0
  125. package/dist/screens/variablesDeTypographie.d.ts.map +1 -0
  126. package/dist/screens/variablesDeTypographie.js +23 -0
  127. package/dist/storySource.d.ts +7 -0
  128. package/dist/storySource.d.ts.map +1 -0
  129. package/dist/storySource.js +7 -0
  130. package/dist/types.d.ts +2 -1
  131. package/dist/types.d.ts.map +1 -1
  132. package/dist/utils.d.ts +11 -3
  133. package/dist/utils.d.ts.map +1 -1
  134. package/dist/utils.js +20 -4
  135. package/package.json +19 -9
  136. package/dist/styles.d.ts +0 -7
  137. package/dist/styles.d.ts.map +0 -1
  138. package/dist/styles.js +0 -6
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StorySummary.d.ts","sourceRoot":"","sources":["../../src/components/StorySummary.tsx"],"names":[],"mappings":"AAGA,MAAM,MAAM,iBAAiB,GAAG;IAC9B,6EAA6E;IAC7E,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB,CAAC;AAEF,wFAAwF;AACxF,eAAO,MAAM,YAAY,GAAI,aAAa,iBAAiB,gCA0B1D,CAAC"}
@@ -0,0 +1,8 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Box, toSlug, Typography } from '@alveole/components';
3
+ import { FOCUS_ATTRIBUTE, useTheme } from '@alveole/theme';
4
+ /** Le sommaire d'une page : une entrée par section, vers l'ancre que pose son titre. */
5
+ export const StorySummary = ({ entrees }) => {
6
+ const { color, text } = useTheme();
7
+ return (_jsxs(Box, { display: "flex", gap: 8, children: [_jsx(Typography, { style: { ...text['Corps de texte'].XS.CapsBold, color: color.light.text['mention-grey'] }, children: "Sur cette page" }), entrees.map(entree => (_jsx("a", { href: `#${toSlug(entree)}`, style: { textDecoration: 'none' }, [FOCUS_ATTRIBUTE]: 'ring', children: _jsx(Typography, { style: { ...text['Corps de texte'].SM.Regular, color: color.light.text['default-grey'] }, children: entree }) }, entree)))] }));
8
+ };
@@ -0,0 +1,25 @@
1
+ import { A } from '@alveole/components';
2
+ import React from 'react';
3
+ export type UIKitColumnItem = {
4
+ key: string;
5
+ title: string;
6
+ /** Typé depuis `A` pour ne pas dépendre d'expo-router ici. */
7
+ href: React.ComponentProps<typeof A>['href'];
8
+ };
9
+ export type UIKitColumnGroup = {
10
+ title: string;
11
+ items: UIKitColumnItem[];
12
+ };
13
+ export type UIKitColumnProps = {
14
+ groups: UIKitColumnGroup[];
15
+ };
16
+ /**
17
+ * Navigation verticale du catalogue, sous la barre : elle liste le contenu de la rubrique
18
+ * courante. Voir docs/adr/0007.
19
+ *
20
+ * Elle monte le `Sidebar` publié tel quel, sans logo - il est déjà dans la barre. Primer et
21
+ * Atlassian font de même : ils réutilisent le composant de liste de leur design system et ne
22
+ * fabriquent à la main que le conteneur.
23
+ */
24
+ export declare const UIKitColumn: ({ groups }: UIKitColumnProps) => React.JSX.Element | null;
25
+ //# sourceMappingURL=UIKitColumn.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UIKitColumn.d.ts","sourceRoot":"","sources":["../../src/components/UIKitColumn.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAsD,MAAM,qBAAqB,CAAC;AAE5F,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,MAAM,eAAe,GAAG;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,8DAA8D;IAC9D,IAAI,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;CAC9C,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,eAAe,EAAE,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,MAAM,EAAE,gBAAgB,EAAE,CAAC;CAC5B,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,WAAW,GAAI,YAAY,gBAAgB,6BA4BvD,CAAC"}
@@ -0,0 +1,24 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Sidebar, SidebarDivider, SidebarGroup, SidebarItem } from '@alveole/components';
3
+ import { useTheme } from '@alveole/theme';
4
+ import React from 'react';
5
+ /**
6
+ * Navigation verticale du catalogue, sous la barre : elle liste le contenu de la rubrique
7
+ * courante. Voir docs/adr/0007.
8
+ *
9
+ * Elle monte le `Sidebar` publié tel quel, sans logo - il est déjà dans la barre. Primer et
10
+ * Atlassian font de même : ils réutilisent le composant de liste de leur design system et ne
11
+ * fabriquent à la main que le conteneur.
12
+ */
13
+ export const UIKitColumn = ({ groups }) => {
14
+ const { isVariant } = useTheme();
15
+ // Sous 992px la colonne se replie dans le menu de la barre, qui reste le seul contrôle.
16
+ // Primer et Atlassian replient la leur dès 900px.
17
+ if (!isVariant('desktop'))
18
+ return null;
19
+ // Une rubrique d'une seule page n'a pas de niveau 2 : le contenu reprend la pleine largeur
20
+ // plutôt que de longer une colonne vide.
21
+ if (groups.length === 0)
22
+ return null;
23
+ return (_jsx(Sidebar, { children: groups.map((group, rang) => (_jsxs(React.Fragment, { children: [rang > 0 && _jsx(SidebarDivider, {}), _jsx(SidebarGroup, { title: group.title, children: group.items.map(item => (_jsx(SidebarItem, { title: item.title, href: item.href }, item.key))) })] }, group.title))) }));
24
+ };
@@ -1,12 +1,21 @@
1
+ import { A } from '@alveole/components';
1
2
  import React from 'react';
3
+ import type { UIKitColumnGroup } from './UIKitColumn';
2
4
  export type UIKitTopBarItem = {
3
5
  key: string;
4
6
  label: string;
5
- onPress: () => void;
7
+ /** Typé depuis `A` pour ne pas dépendre d'expo-router ici. */
8
+ href: React.ComponentProps<typeof A>['href'];
6
9
  };
7
10
  export type UIKitTopBarProps = {
8
11
  activeKey: string;
9
12
  items: UIKitTopBarItem[];
13
+ /**
14
+ * Niveau 2 de la rubrique courante. Sur desktop il est rendu par la colonne ; sous 992px
15
+ * la colonne se replie et son contenu descend ici, pour que le menu de la barre reste la
16
+ * seule commande de navigation. Voir docs/adr/0007.
17
+ */
18
+ columnGroups?: UIKitColumnGroup[];
10
19
  };
11
- export declare const UIKitTopBar: ({ activeKey, items }: UIKitTopBarProps) => React.JSX.Element;
20
+ export declare const UIKitTopBar: ({ activeKey, items, columnGroups }: UIKitTopBarProps) => React.JSX.Element;
12
21
  //# sourceMappingURL=UIKitTopBar.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"UIKitTopBar.d.ts","sourceRoot":"","sources":["../../src/components/UIKitTopBar.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,MAAM,MAAM,eAAe,GAAG;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,eAAe,EAAE,CAAC;CAC1B,CAAC;AAqBF,eAAO,MAAM,WAAW,GAAI,sBAAsB,gBAAgB,sBAoEjE,CAAC"}
1
+ {"version":3,"file":"UIKitTopBar.d.ts","sourceRoot":"","sources":["../../src/components/UIKitTopBar.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAA2E,MAAM,qBAAqB,CAAC;AAEjH,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEtD,MAAM,MAAM,eAAe,GAAG;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,8DAA8D;IAC9D,IAAI,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;CAC9C,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,eAAe,EAAE,CAAC;IACzB;;;;OAIG;IACH,YAAY,CAAC,EAAE,gBAAgB,EAAE,CAAC;CACnC,CAAC;AAwJF,eAAO,MAAM,WAAW,GAAI,oCAAyC,gBAAgB,sBAgBpF,CAAC"}
@@ -1,6 +1,6 @@
1
- import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { Box, Button, Header, LucideIcon, Typography } from '@alveole/components';
3
- import { useTheme } from '@alveole/theme';
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { A, Box, Divider, Header, LucideIcon, SidebarGroup, SidebarItem, Typography } from '@alveole/components';
3
+ import { makeStyles, useTheme } from '@alveole/theme';
4
4
  import React from 'react';
5
5
  import { Pressable } from 'react-native';
6
6
  const AlveoleLogo = () => {
@@ -15,31 +15,88 @@ const AlveoleLogo = () => {
15
15
  justifyContent: 'center',
16
16
  }, children: _jsx(Typography, { style: { ...text['Corps de texte'].XS.Bold, color: '#fff' }, children: "A" }) }));
17
17
  };
18
- export const UIKitTopBar = ({ activeKey, items }) => {
19
- const { color, isVariant, spacing } = useTheme();
20
- const [menuOpen, setMenuOpen] = React.useState(false);
18
+ const useNavItemStyles = makeStyles(({ color, radius, spacingValue, text }) => {
19
+ const activeLabelTypography = text['Corps de texte'].MD.Medium;
20
+ return {
21
+ container: {
22
+ height: 32,
23
+ paddingLeft: spacingValue('3V'),
24
+ paddingRight: spacingValue('3V'),
25
+ borderRadius: radius('md'),
26
+ display: 'flex',
27
+ flexDirection: 'column',
28
+ justifyContent: 'center',
29
+ transitionProperty: 'background-color',
30
+ transitionDuration: '0.12s',
31
+ transitionTimingFunction: 'ease-out',
32
+ },
33
+ containerHover: {
34
+ backgroundColor: color.light.background['transparent-hover'],
35
+ },
36
+ label: {
37
+ ...text['Corps de texte'].MD.Regular,
38
+ color: color.light.text['mention-grey'],
39
+ },
40
+ labelCurrent: {
41
+ ...activeLabelTypography,
42
+ color: color.light.text['title-grey'],
43
+ },
44
+ // Copie invisible du libellé actif : elle réserve la largeur que prendra l'item
45
+ // une fois courant, sinon toute la barre se décale au changement de page. Repris de
46
+ // UnderlineTabbedInterface, chez Primer.
47
+ labelGhost: {
48
+ ...activeLabelTypography,
49
+ height: 0,
50
+ overflow: 'hidden',
51
+ },
52
+ };
53
+ });
54
+ /**
55
+ * Item de navigation de la barre : aucun remplissage à l'état courant, qui se signale
56
+ * par le contraste et la graisse seuls. Le fond neutre est réservé au survol.
57
+ *
58
+ * Bâti sur `A` pour obtenir une vraie ancre : clic milieu, ouverture en nouvel onglet et
59
+ * aperçu de la cible dans la barre d'état ne s'obtiennent pas avec un `Pressable` seul.
60
+ */
61
+ const NavItem = ({ label, href, current, block = false }) => {
62
+ const styles = useNavItemStyles();
63
+ return (_jsxs(A, { href: href, direction: "replace", ariaCurrent: current ? 'page' : undefined, style: { ...styles.container, alignItems: block ? 'flex-start' : 'center' }, hoverStyle: styles.containerHover, children: [_jsx(Typography, { style: current ? styles.labelCurrent : styles.label, children: label }), _jsx(Box, { "aria-hidden": true, children: _jsx(Typography, { style: styles.labelGhost, children: label }) })] }));
64
+ };
65
+ /**
66
+ * La barre en version mobile : un menu qui se deplie sous l'entete. L'etat d'ouverture vit ici,
67
+ * avec le seul rendu qui s'en sert, plutot que dans la barre qui n'en a pas besoin autrement.
68
+ */
69
+ const BarreMobile = ({ activeKey, items, columnGroups }) => {
70
+ const { color, spacing } = useTheme();
71
+ // Les items sont des ancres : la navigation ne passe plus par un callback qui pourrait
72
+ // refermer le menu au clic. On retient donc la page pour laquelle le menu a été ouvert,
73
+ // et il se referme de lui-même dès qu'on arrive ailleurs, sans effet de synchronisation.
74
+ const [openedFor, setOpenedFor] = React.useState(null);
75
+ const menuOpen = openedFor === activeKey;
76
+ const toggleMenu = () => setOpenedFor(menuOpen ? null : activeKey);
77
+ return (_jsxs(_Fragment, { children: [_jsx(Header, { logo: _jsx(AlveoleLogo, {}), right: _jsx(Pressable, { accessibilityRole: "button", onPress: toggleMenu, style: { padding: 8 }, children: _jsx(LucideIcon, { name: menuOpen ? 'X' : 'Menu', size: "md", color: color.light.text['title-grey'] }) }) }), menuOpen && (_jsxs(Box, { style: {
78
+ position: 'sticky',
79
+ top: 64,
80
+ left: 0,
81
+ right: 0,
82
+ zIndex: 99,
83
+ backgroundColor: color.light.background['default-grey'],
84
+ borderBottomWidth: 1,
85
+ borderBottomColor: color.light.border['default-grey'],
86
+ paddingTop: spacing('2W'),
87
+ paddingBottom: spacing('2W'),
88
+ paddingLeft: spacing('2W'),
89
+ paddingRight: spacing('2W'),
90
+ display: 'flex',
91
+ flexDirection: 'column',
92
+ gap: spacing('050'),
93
+ }, children: [items.map(({ key, ...item }) => (_jsx(NavItem, { ...item, current: activeKey === key, block: true }, key))), columnGroups.length > 0 && _jsx(Divider, {}), columnGroups.map(group => (_jsx(SidebarGroup, { title: group.title, children: group.items.map(item => (_jsx(SidebarItem, { title: item.title, href: item.href }, item.key))) }, group.title)))] }))] }));
94
+ };
95
+ export const UIKitTopBar = ({ activeKey, items, columnGroups = [] }) => {
96
+ const { isVariant } = useTheme();
21
97
  if (isVariant('mobile')) {
22
- return (_jsxs(_Fragment, { children: [_jsx(Header, { logo: _jsx(AlveoleLogo, {}), right: _jsx(Pressable, { onPress: () => setMenuOpen(v => !v), style: { padding: 8 }, children: _jsx(LucideIcon, { name: menuOpen ? 'X' : 'Menu', size: "md", color: color.light.text['title-grey'] }) }) }), menuOpen && (_jsx(Box, { style: {
23
- position: 'sticky',
24
- top: 64,
25
- left: 0,
26
- right: 0,
27
- zIndex: 99,
28
- backgroundColor: color.light.background['default-grey'],
29
- borderBottomWidth: 1,
30
- borderBottomColor: color.light.border['default-grey'],
31
- paddingTop: spacing('2W'),
32
- paddingBottom: spacing('2W'),
33
- paddingLeft: spacing('2W'),
34
- paddingRight: spacing('2W'),
35
- display: 'flex',
36
- flexDirection: 'column',
37
- gap: spacing('050'),
38
- }, children: items.map(item => (_jsx(Button, { variant: activeKey === item.key ? 'primary' : 'tertiary', title: item.label, size: "sm", onPress: () => {
39
- item.onPress();
40
- setMenuOpen(false);
41
- } }, item.key))) }))] }));
98
+ return _jsx(BarreMobile, { activeKey: activeKey, items: items, columnGroups: columnGroups });
42
99
  }
43
- const right = (_jsx(Box, { display: "flex", flexDirection: "row", flexWrap: "wrap", gap: 8, children: items.map(item => (_jsx(Button, { variant: activeKey === item.key ? 'primary' : 'tertiary', title: item.label, size: "sm", onPress: item.onPress }, item.key))) }));
100
+ const right = (_jsx(Box, { display: "flex", flexDirection: "row", flexWrap: "wrap", gap: 8, children: items.map(({ key, ...item }) => (_jsx(NavItem, { ...item, current: activeKey === key }, key))) }));
44
101
  return _jsx(Header, { logo: _jsx(AlveoleLogo, {}), title: "Alveole UI Kit", right: right });
45
102
  };
@@ -0,0 +1,14 @@
1
+ import type { FiltreDeroulantProps } from './FiltreDeroulant';
2
+ /**
3
+ * Le choix d'un filtre a choix unique apres qu'on a presse une option. Reprendre l'option deja
4
+ * choisie l'annule, sans quoi on ne pourrait plus revenir a la liste entiere.
5
+ */
6
+ export declare const choixApres: <Cle extends string>(choisi: Cle | null, option: Cle) => Cle | null;
7
+ type Filtre<Cle extends string> = Pick<FiltreDeroulantProps<Cle>, 'libelle' | 'options' | 'choisi'>;
8
+ /**
9
+ * Ce que le bouton du filtre annonce : l'option choisie plutot que son libelle generique, car
10
+ * une fois le menu referme c'est la seule trace du filtre actif.
11
+ */
12
+ export declare const libelleDuFiltre: <Cle extends string>({ libelle, options, choisi }: Filtre<Cle>) => string;
13
+ export {};
14
+ //# sourceMappingURL=choixDuFiltre.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"choixDuFiltre.d.ts","sourceRoot":"","sources":["../../src/components/choixDuFiltre.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAE9D;;;GAGG;AACH,eAAO,MAAM,UAAU,GAAI,GAAG,SAAS,MAAM,EAAE,QAAQ,GAAG,GAAG,IAAI,EAAE,QAAQ,GAAG,KAAG,GAAG,GAAG,IACpD,CAAC;AAEpC,KAAK,MAAM,CAAC,GAAG,SAAS,MAAM,IAAI,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,EAAE,SAAS,GAAG,SAAS,GAAG,QAAQ,CAAC,CAAC;AAEpG;;;GAGG;AACH,eAAO,MAAM,eAAe,GAAI,GAAG,SAAS,MAAM,EAAE,8BAA8B,MAAM,CAAC,GAAG,CAAC,KAAG,MAC/B,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Le choix d'un filtre a choix unique apres qu'on a presse une option. Reprendre l'option deja
3
+ * choisie l'annule, sans quoi on ne pourrait plus revenir a la liste entiere.
4
+ */
5
+ export const choixApres = (choisi, option) => choisi === option ? null : option;
6
+ /**
7
+ * Ce que le bouton du filtre annonce : l'option choisie plutot que son libelle generique, car
8
+ * une fois le menu referme c'est la seule trace du filtre actif.
9
+ */
10
+ export const libelleDuFiltre = ({ libelle, options, choisi }) => options.find(option => option.key === choisi)?.label ?? libelle;
@@ -0,0 +1,6 @@
1
+ /**
2
+ * La hauteur d'une carte de fiche. Hors mobile, les cartes d'une rangee s'etirent a la plus
3
+ * haute pour aligner leurs bas ; sur mobile, empilees, chacune garde celle de son contenu.
4
+ */
5
+ export declare const hauteurDeCarte: (mobile: boolean) => "100%" | undefined;
6
+ //# sourceMappingURL=hauteurDeCarte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hauteurDeCarte.d.ts","sourceRoot":"","sources":["../../src/components/hauteurDeCarte.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,eAAO,MAAM,cAAc,GAAI,QAAQ,OAAO,KAAG,MAAM,GAAG,SAA0C,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * La hauteur d'une carte de fiche. Hors mobile, les cartes d'une rangee s'etirent a la plus
3
+ * haute pour aligner leurs bas ; sur mobile, empilees, chacune garde celle de son contenu.
4
+ */
5
+ export const hauteurDeCarte = (mobile) => (mobile ? undefined : '100%');
package/dist/index.d.ts CHANGED
@@ -1,6 +1,9 @@
1
1
  export * from './components/DocFooter';
2
2
  export * from './components/JsonBlock';
3
+ export * from './components/UIKitColumn';
3
4
  export * from './components/UIKitTopBar';
5
+ export * from './navigation';
6
+ export * from './pages/InstallationPage';
4
7
  export * from './pages/PhilosophyPage';
5
8
  export * from './pages/UIKitHomePage';
6
9
  export * from './pages/UIKitPage';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,wBAAwB,CAAC;AACvC,cAAc,wBAAwB,CAAC;AACvC,cAAc,0BAA0B,CAAC;AACzC,cAAc,wBAAwB,CAAC;AACvC,cAAc,uBAAuB,CAAC;AACtC,cAAc,mBAAmB,CAAC;AAClC,cAAc,wBAAwB,CAAC;AACvC,cAAc,yBAAyB,CAAC;AACxC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,qCAAqC,CAAC;AACpD,cAAc,gCAAgC,CAAC;AAC/C,cAAc,mCAAmC,CAAC;AAClD,cAAc,8BAA8B,CAAC;AAC7C,cAAc,iCAAiC,CAAC;AAChD,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,wBAAwB,CAAC;AACvC,cAAc,wBAAwB,CAAC;AACvC,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AACzC,cAAc,cAAc,CAAC;AAC7B,cAAc,0BAA0B,CAAC;AACzC,cAAc,wBAAwB,CAAC;AACvC,cAAc,uBAAuB,CAAC;AACtC,cAAc,mBAAmB,CAAC;AAClC,cAAc,wBAAwB,CAAC;AACvC,cAAc,yBAAyB,CAAC;AACxC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,qCAAqC,CAAC;AACpD,cAAc,gCAAgC,CAAC;AAC/C,cAAc,mCAAmC,CAAC;AAClD,cAAc,8BAA8B,CAAC;AAC7C,cAAc,iCAAiC,CAAC;AAChD,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC"}
package/dist/index.js CHANGED
@@ -1,6 +1,9 @@
1
1
  export * from './components/DocFooter';
2
2
  export * from './components/JsonBlock';
3
+ export * from './components/UIKitColumn';
3
4
  export * from './components/UIKitTopBar';
5
+ export * from './navigation';
6
+ export * from './pages/InstallationPage';
4
7
  export * from './pages/PhilosophyPage';
5
8
  export * from './pages/UIKitHomePage';
6
9
  export * from './pages/UIKitPage';
@@ -0,0 +1,6 @@
1
+ export type RubriqueRoute = {
2
+ key: string;
3
+ href: string;
4
+ };
5
+ export declare const findCurrentRubriqueKey: (rubriques: RubriqueRoute[], pathname: string) => string;
6
+ //# sourceMappingURL=navigation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"navigation.d.ts","sourceRoot":"","sources":["../src/navigation.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,aAAa,GAAG;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,eAAO,MAAM,sBAAsB,GAAI,WAAW,aAAa,EAAE,EAAE,UAAU,MAAM,WAGX,CAAC"}
@@ -0,0 +1,3 @@
1
+ export const findCurrentRubriqueKey = (rubriques, pathname) => rubriques
2
+ .filter(rubrique => pathname.startsWith(rubrique.href))
3
+ .sort((left, right) => right.href.length - left.href.length)[0]?.key;
@@ -0,0 +1,8 @@
1
+ import React from 'react';
2
+ export type InstallationPageProps = {
3
+ beforeContent?: React.ReactNode;
4
+ sidebar?: React.ReactNode;
5
+ footerContent?: React.ReactNode;
6
+ };
7
+ export declare const InstallationPage: ({ beforeContent, sidebar, footerContent }: InstallationPageProps) => React.JSX.Element;
8
+ //# sourceMappingURL=InstallationPage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InstallationPage.d.ts","sourceRoot":"","sources":["../../src/pages/InstallationPage.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,OAAO,CAAC;AA0B1B,MAAM,MAAM,qBAAqB,GAAG;IAClC,aAAa,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAChC,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,aAAa,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CACjC,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAAI,2CAA2C,qBAAqB,sBAiBhG,CAAC"}
@@ -0,0 +1,13 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { AnchorHeading, Box, Typography } from '@alveole/components';
3
+ import { useTheme } from '@alveole/theme';
4
+ import { EcranDeCatalogue } from '../components/EcranDeCatalogue';
5
+ import { JsonBlock } from '../components/JsonBlock';
6
+ import { ETAPES_D_INSTALLATION } from './installation';
7
+ const EtapeDInstallationSection = ({ titre, paragraphes, extraits = [] }) => {
8
+ const { text } = useTheme();
9
+ return (_jsxs(Box, { display: "flex", gap: 8, mb: '400', children: [_jsx(AnchorHeading, { style: text.Titres['H4 - SM'], children: titre }), paragraphes.map(paragraphe => (_jsx(Typography, { style: text['Corps de texte'].MD.Regular, children: paragraphe }, paragraphe))), extraits.map(({ langage, fichier, source }) => (_jsxs(Box, { display: "flex", gap: 4, children: [fichier ? _jsx(Typography, { style: text['Corps de texte'].SM.Bold, children: fichier }) : null, _jsx(JsonBlock, { language: langage, value: source })] }, source)))] }));
10
+ };
11
+ export const InstallationPage = ({ beforeContent, sidebar, footerContent }) => {
12
+ return (_jsx(EcranDeCatalogue, { title: "Installation", description: "Installer et configurer Alveole dans une application Expo", sidebar: sidebar, beforeContent: beforeContent, footerContent: footerContent, sommaire: ETAPES_D_INSTALLATION.map(({ titre }) => titre), children: _jsx(Box, { display: "flex", gap: 0, children: ETAPES_D_INSTALLATION.map(etape => (_jsx(EtapeDInstallationSection, { ...etape }, etape.titre))) }) }));
13
+ };
@@ -1,7 +1,8 @@
1
1
  import React from 'react';
2
2
  export type PhilosophyPageProps = {
3
3
  beforeContent?: React.ReactNode;
4
+ sidebar?: React.ReactNode;
4
5
  footerContent?: React.ReactNode;
5
6
  };
6
- export declare const PhilosophyPage: ({ beforeContent, footerContent }: PhilosophyPageProps) => React.JSX.Element;
7
+ export declare const PhilosophyPage: ({ beforeContent, sidebar, footerContent }: PhilosophyPageProps) => React.JSX.Element;
7
8
  //# sourceMappingURL=PhilosophyPage.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"PhilosophyPage.d.ts","sourceRoot":"","sources":["../../src/pages/PhilosophyPage.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,OAAO,CAAC;AAmB1B,MAAM,MAAM,mBAAmB,GAAG;IAChC,aAAa,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAChC,aAAa,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CACjC,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,kCAAkC,mBAAmB,sBAyFnF,CAAC"}
1
+ {"version":3,"file":"PhilosophyPage.d.ts","sourceRoot":"","sources":["../../src/pages/PhilosophyPage.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,OAAO,CAAC;AAmB1B,MAAM,MAAM,mBAAmB,GAAG;IAChC,aAAa,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAChC,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,aAAa,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CACjC,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,2CAA2C,mBAAmB,sBAiB5F,CAAC"}
@@ -1,12 +1,12 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { Box, Page, PageHeader, Section, Typography } from '@alveole/components';
2
+ import { AnchorHeading, Box, Typography } from '@alveole/components';
3
3
  import { useTheme } from '@alveole/theme';
4
- import { screenContent } from '../styles';
5
- const PhilosophySection = ({ title, children }) => {
4
+ import { EcranDeCatalogue } from '../components/EcranDeCatalogue';
5
+ import { SECTIONS_DE_PHILOSOPHIE } from './philosophie';
6
+ const PhilosophySection = ({ titre, paragraphes }) => {
6
7
  const { text } = useTheme();
7
- return (_jsxs(Box, { display: "flex", gap: 8, mb: '400', children: [_jsx(Typography, { style: text.Titres['H4 - SM'], children: title }), children] }));
8
+ return (_jsxs(Box, { display: "flex", gap: 8, mb: '400', children: [_jsx(AnchorHeading, { style: text.Titres['H4 - SM'], children: titre }), paragraphes.map(paragraphe => (_jsx(Typography, { style: text['Corps de texte'].MD.Regular, children: paragraphe }, paragraphe)))] }));
8
9
  };
9
- export const PhilosophyPage = ({ beforeContent, footerContent }) => {
10
- const { text } = useTheme();
11
- return (_jsx(Page, { scrollable: true, title: "Philosophie", description: "Les principes qui guident Alveole", beforeContent: beforeContent, footerContent: footerContent, children: _jsxs(Box, { ...screenContent, children: [_jsx(Section, { withPaddingY: false, children: _jsx(PageHeader, { title: "Philosophie" }) }), _jsx(Section, { withPaddingY: false, children: _jsxs(Box, { display: "flex", gap: 0, style: { maxWidth: 720 }, children: [_jsx(PhilosophySection, { title: "Objectif", children: _jsxs(Typography, { style: text['Corps de texte'].MD.Regular, children: ["Alveole est un framework de composants conçu pour accélérer la construction d'outils B2B. L'ambition est", ' de proposer une expérience clé en main : installer les packages, utiliser les composants, livrer. Pas de', ' configuration interminable, pas de décisions de design à prendre à chaque écran.'] }) }), _jsx(PhilosophySection, { title: "Convention plut\u00F4t que configuration", children: _jsxs(Typography, { style: text['Corps de texte'].MD.Regular, children: ["Alveole s'inspire du principe ", _jsx(Typography, { style: text['Corps de texte'].MD.Regular, children: "Convention over Configuration" }), ' : le thème par défaut est pensé pour fonctionner sans ajustement. La customisation reste possible — palette,', ' typographie, espacements — mais elle est optionnelle et ciblée. Le but est de ne pas passer du temps à', ' configurer ce qui fonctionne déjà bien.'] }) }), _jsx(PhilosophySection, { title: "Des composants pens\u00E9s pour l'UX", children: _jsxs(Typography, { style: text['Corps de texte'].MD.Regular, children: ["Chaque composant embarque les meilleures pratiques UI et UX de sa catégorie. L'objectif n'est pas de", " fournir une brique neutre que chaque projet devra affiner, mais un composant fini qui propose d'emblée la", " meilleure expérience pour l'utilisateur final. Il ne faut pas réinventer la roue à chaque projet."] }) }), _jsx(PhilosophySection, { title: "Des choix assum\u00E9s", children: _jsxs(Typography, { style: text['Corps de texte'].MD.Regular, children: ['Certaines décisions ne sont pas exposées en configuration. Par exemple, les icônes Lucide utilisent', ' systématiquement un ', _jsx(Typography, { style: text['Corps de texte'].MD.Regular, children: "strokeWidth \u00E0 1.5" }), " — cette valeur n'est pas modifiable par le consommateur du composant. Ce type de choix garantit la cohérence", " visuelle de l'ensemble : un design system qui offre trop de flexibilité cesse d'être un design system."] }) }), _jsx(PhilosophySection, { title: "Inspirations", children: _jsxs(Typography, { style: text['Corps de texte'].MD.Regular, children: ["Alveole s'inspire de deux systèmes de design de référence dans l'écosystème B2B et open source :", " l'Atlassian Design System, reconnu pour sa rigueur dans les outils professionnels, et Primer, le design", ' system de GitHub, apprécié pour sa clarté et sa cohérence à grande échelle.'] }) }), _jsx(PhilosophySection, { title: "Construit dans la dur\u00E9e par Captive", children: _jsxs(Typography, { style: text['Corps de texte'].MD.Regular, children: ['Alveole est maintenu par Captive et évolue au fil des projets réels. Chaque composant est extrait,', ' généralisé et affiné à partir de besoins concrets. Le framework grandit progressivement, avec une', " attention constante à la qualité plutôt qu'à l'exhaustivité."] }) })] }) })] }) }));
10
+ export const PhilosophyPage = ({ beforeContent, sidebar, footerContent }) => {
11
+ return (_jsx(EcranDeCatalogue, { title: "Philosophie", description: "Les principes qui guident Alveole", sidebar: sidebar, beforeContent: beforeContent, footerContent: footerContent, sommaire: SECTIONS_DE_PHILOSOPHIE.map(({ titre }) => titre), children: _jsx(Box, { display: "flex", gap: 0, children: SECTIONS_DE_PHILOSOPHIE.map(section => (_jsx(PhilosophySection, { ...section }, section.titre))) }) }));
12
12
  };
@@ -1 +1 @@
1
- {"version":3,"file":"UIKitHomePage.d.ts","sourceRoot":"","sources":["../../src/pages/UIKitHomePage.tsx"],"names":[],"mappings":"AAsBA,MAAM,MAAM,kBAAkB,GAAG;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,IAAI,CAAC;IAC7B,WAAW,EAAE,MAAM,IAAI,CAAC;IACxB,eAAe,EAAE,MAAM,IAAI,CAAC;CAC7B,CAAC;AAEF,eAAO,MAAM,aAAa,GAAI,yEAM3B,kBAAkB,gCAwBpB,CAAC"}
1
+ {"version":3,"file":"UIKitHomePage.d.ts","sourceRoot":"","sources":["../../src/pages/UIKitHomePage.tsx"],"names":[],"mappings":"AAGA,MAAM,MAAM,kBAAkB,GAAG;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,IAAI,CAAC;IAC7B,WAAW,EAAE,MAAM,IAAI,CAAC;IACxB,eAAe,EAAE,MAAM,IAAI,CAAC;CAC7B,CAAC;AAEF,eAAO,MAAM,aAAa,GAAI,yEAM3B,kBAAkB,gCAwBpB,CAAC"}
@@ -1,10 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { Box, Card, Page, Section, Typography } from '@alveole/components';
3
- import { useTheme } from '@alveole/theme';
4
- const HomeCard = ({ title, description, onPress }) => {
5
- const { text } = useTheme();
6
- return (_jsx(Card, { onPress: onPress, children: _jsxs(Box, { display: "flex", gap: 8, p: '150', children: [_jsx(Typography, { style: text.Titres['H4 - SM'], children: title }), _jsx(Typography, { style: text['Corps de texte'].SM.Regular, children: description })] }) }));
7
- };
2
+ import { Box, Page, Section } from '@alveole/components';
3
+ import { MenuCard } from '../components/MenuCard';
8
4
  export const UIKitHomePage = ({ title = 'UI Kit', description = 'Documentation du design system', onOpenComponents, onOpenTheme, onOpenConstants, }) => {
9
- return (_jsx(Page, { scrollable: true, title: title, description: description, children: _jsx(Section, { withPaddingY: true, children: _jsxs(Box, { display: "flex", gap: 16, children: [_jsx(HomeCard, { title: "Composants", description: "Liste des composants disponibles pour le d\u00E9veloppement.", onPress: onOpenComponents }), _jsx(HomeCard, { title: "Th\u00E8me", description: "Th\u00E8me de l\u2019application, liste des tokens issus du design system.", onPress: onOpenTheme }), _jsx(HomeCard, { title: "Constantes", description: "Liste des constantes de th\u00E8me expos\u00E9es par la librairie.", onPress: onOpenConstants })] }) }) }));
5
+ return (_jsx(Page, { scrollable: true, title: title, description: description, children: _jsx(Section, { withPaddingY: true, children: _jsxs(Box, { display: "flex", gap: 16, children: [_jsx(MenuCard, { title: "Composants", description: "Liste des composants disponibles pour le d\u00E9veloppement.", onPress: onOpenComponents }), _jsx(MenuCard, { title: "Th\u00E8me", description: "Th\u00E8me de l\u2019application, liste des tokens issus du design system.", onPress: onOpenTheme }), _jsx(MenuCard, { title: "Constantes", description: "Liste des constantes de th\u00E8me expos\u00E9es par la librairie.", onPress: onOpenConstants })] }) }) }));
10
6
  };
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
  import { StorybookModule } from '../types';
3
- type BlankPage = {
3
+ export type BlankPage = {
4
4
  title?: string;
5
5
  description?: string;
6
6
  render: () => React.ReactNode;
@@ -8,12 +8,11 @@ type BlankPage = {
8
8
  export type UIKitPageProps = {
9
9
  stories: StorybookModule[];
10
10
  constants: Record<string, unknown>;
11
- palette?: Record<string, any>;
11
+ palette?: Record<string, unknown>;
12
12
  typography?: Record<string, unknown>;
13
13
  title?: string;
14
14
  description?: string;
15
15
  blankPage?: BlankPage;
16
16
  };
17
- export declare const UIKitPage: ({ stories, constants, palette, typography, title, description, blankPage, }: UIKitPageProps) => React.JSX.Element | null;
18
- export {};
17
+ export declare const UIKitPage: ({ stories, constants, palette, typography, title, description, blankPage, }: UIKitPageProps) => React.ReactNode;
19
18
  //# sourceMappingURL=UIKitPage.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"UIKitPage.d.ts","sourceRoot":"","sources":["../../src/pages/UIKitPage.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,OAAO,CAAC;AAO1B,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAG3C,KAAK,SAAS,GAAG;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,KAAK,CAAC,SAAS,CAAC;CAC/B,CAAC;AAcF,MAAM,MAAM,cAAc,GAAG;IAC3B,OAAO,EAAE,eAAe,EAAE,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC9B,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,SAAS,CAAC;CACvB,CAAC;AA2GF,eAAO,MAAM,SAAS,GAAI,6EAQvB,cAAc,6BAwHhB,CAAC"}
1
+ {"version":3,"file":"UIKitPage.d.ts","sourceRoot":"","sources":["../../src/pages/UIKitPage.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,OAAO,CAAC;AAO1B,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAK3C,MAAM,MAAM,SAAS,GAAG;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,KAAK,CAAC,SAAS,CAAC;CAC/B,CAAC;AAcF,MAAM,MAAM,cAAc,GAAG;IAC3B,OAAO,EAAE,eAAe,EAAE,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,SAAS,CAAC;CACvB,CAAC;AAsKF,eAAO,MAAM,SAAS,GAAI,6EAQvB,cAAc,oBAqBhB,CAAC"}
@@ -1,6 +1,6 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { Box, Button, Card, Page, Section, Typography } from '@alveole/components';
3
- import { CustomPalette, CustomTypography, useTheme } from '@alveole/theme';
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { Page, Section } from '@alveole/components';
3
+ import { CustomPalette, CustomTypography } from '@alveole/theme';
4
4
  import React from 'react';
5
5
  import { StoriesScreen } from '../screens/StoriesScreen';
6
6
  import { StoryDetailScreen } from '../screens/StoryDetailScreen';
@@ -8,62 +8,85 @@ import { ThemeConstantDetailScreen } from '../screens/ThemeConstantDetailScreen'
8
8
  import { ThemeConstantsScreen } from '../screens/ThemeConstantsScreen';
9
9
  import { ThemePaletteScreen } from '../screens/ThemePaletteScreen';
10
10
  import { ThemeTypographyScreen } from '../screens/ThemeTypographyScreen';
11
+ import { HomeScreen, InternalHeader } from './ecransDuKit';
11
12
  import { PhilosophyPage } from './PhilosophyPage';
12
- const MenuCard = ({ title, description, onPress }) => {
13
- const { text } = useTheme();
14
- return (_jsx(Card, { onPress: onPress, children: _jsxs(Box, { display: "flex", gap: 8, p: '150', children: [_jsx(Typography, { style: text.Titres['H4 - SM'], children: title }), _jsx(Typography, { style: text['Corps de texte'].SM.Regular, children: description })] }) }));
15
- };
16
- const InternalHeader = ({ canGoBack, onBack }) => {
17
- if (!canGoBack)
18
- return null;
19
- return (_jsx(Section, { withPaddingY: true, children: _jsx(Box, { children: _jsx(Button, { title: "Retour", variant: "tertiary", size: "sm", onPress: onBack }) }) }));
20
- };
21
- const HomeScreen = ({ title, description, blankPage, onOpenComponents, onOpenTheme, onOpenConstants, onOpenBlank, onOpenPhilosophy, }) => {
22
- return (_jsx(Page, { scrollable: true, title: title, description: description, children: _jsx(Section, { withPaddingY: true, children: _jsxs(Box, { display: "flex", gap: 16, children: [_jsx(MenuCard, { title: "Composants", description: "Catalogue des composants et de leurs variantes.", onPress: onOpenComponents }), _jsx(MenuCard, { title: "Th\u00E8me", description: "Couleurs et typographies du design system.", onPress: onOpenTheme }), _jsx(MenuCard, { title: "Constantes", description: "Constantes expos\u00E9es par le th\u00E8me.", onPress: onOpenConstants }), _jsx(MenuCard, { title: "Philosophie", description: "Les principes qui guident Alveole.", onPress: onOpenPhilosophy }), blankPage ? (_jsx(MenuCard, { title: blankPage.title ?? 'Page vierge', description: blankPage.description ?? 'Espace de test libre pour expérimenter.', onPress: onOpenBlank })) : null] }) }) }));
23
- };
24
- const ThemeHomeScreen = ({ onOpenColors, onOpenTypography, beforeContent, }) => {
25
- return (_jsx(Page, { scrollable: true, title: "UI Kit - Th\u00E8me", description: "Tokens du th\u00E8me", beforeContent: beforeContent, children: _jsx(Section, { withPaddingY: true, children: _jsxs(Box, { display: "flex", gap: 16, children: [_jsx(MenuCard, { title: "Couleurs", description: "Palette et couleurs du th\u00E8me.", onPress: onOpenColors }), _jsx(MenuCard, { title: "Typographies", description: "Styles de texte et hi\u00E9rarchie typographique.", onPress: onOpenTypography })] }) }) }));
26
- };
27
- export const UIKitPage = ({ stories, constants, palette = CustomPalette, typography = CustomTypography, title = 'UI Kit', description = 'Documentation du design system', blankPage, }) => {
13
+ import { UIKitThemePage } from './UIKitThemePage';
14
+ /**
15
+ * La pile de navigation du kit. Elle vit ici et non dans le composant : la page n'a pas a savoir
16
+ * comment on empile des routes pour savoir laquelle afficher.
17
+ */
18
+ const useNavigationDuKit = () => {
28
19
  const [history, setHistory] = React.useState([{ name: 'home' }]);
29
- const route = history[history.length - 1];
30
- const canGoBack = history.length > 1;
31
20
  const push = React.useCallback((nextRoute) => {
32
21
  setHistory(current => [...current, nextRoute]);
33
22
  }, []);
34
23
  const goBack = React.useCallback(() => {
35
24
  setHistory(current => (current.length > 1 ? current.slice(0, -1) : current));
36
25
  }, []);
37
- const beforeContent = _jsx(InternalHeader, { canGoBack: canGoBack, onBack: goBack });
26
+ return { route: history[history.length - 1], canGoBack: history.length > 1, push, goBack };
27
+ };
28
+ /**
29
+ * Chaque famille d'ecrans rend la route qui la concerne, et `null` sinon : c'est ce `null` qui
30
+ * passe la main a la suivante. Decouper le routage par domaine plutot qu'en une seule chaine
31
+ * garde chaque branche lisible et laisse TypeScript affiner la route sur son `name`.
32
+ */
33
+ const ecranDAccueil = (route, ctx) => {
38
34
  if (route.name === 'home') {
39
- return (_jsx(HomeScreen, { title: title, description: description, blankPage: blankPage, onOpenComponents: () => push({ name: 'components' }), onOpenTheme: () => push({ name: 'theme-home' }), onOpenConstants: () => push({ name: 'constants' }), onOpenBlank: () => push({ name: 'blank' }), onOpenPhilosophy: () => push({ name: 'philosophy' }) }));
35
+ return (_jsx(HomeScreen, { title: ctx.title, description: ctx.description, blankPage: ctx.blankPage, onOpenComponents: () => ctx.push({ name: 'components' }), onOpenTheme: () => ctx.push({ name: 'theme-home' }), onOpenConstants: () => ctx.push({ name: 'constants' }), onOpenBlank: () => ctx.push({ name: 'blank' }), onOpenPhilosophy: () => ctx.push({ name: 'philosophy' }) }));
36
+ }
37
+ if (route.name === 'philosophy')
38
+ return _jsx(PhilosophyPage, { beforeContent: ctx.beforeContent });
39
+ if (route.name === 'blank' && ctx.blankPage) {
40
+ const { blankPage } = ctx;
41
+ return (_jsx(Page, { scrollable: true, title: blankPage.title ?? 'Page vierge', description: blankPage.description ?? 'Zone de test libre', beforeContent: ctx.beforeContent, children: _jsx(Section, { withPaddingY: true, children: blankPage.render() }) }));
40
42
  }
43
+ return null;
44
+ };
45
+ const ecranDesComposants = (route, ctx) => {
41
46
  if (route.name === 'components') {
42
- return (_jsx(StoriesScreen, { beforeContent: beforeContent, stories: stories, title: "UI Kit - Composants", description: "Catalogue des composants", createLabel: blankPage ? (blankPage.title ?? 'Page vierge') : undefined, onCreatePress: blankPage ? () => push({ name: 'blank' }) : undefined, getStoryHref: story => `/components/${encodeURIComponent(story.default.title)}` }));
47
+ return (_jsx(StoriesScreen, { beforeContent: ctx.beforeContent, stories: ctx.stories, title: "UI Kit - Composants", description: "Catalogue des composants", createLabel: ctx.blankPage ? (ctx.blankPage.title ?? 'Page vierge') : undefined, onCreatePress: ctx.blankPage ? () => ctx.push({ name: 'blank' }) : undefined, getStoryHref: story => `/components/${encodeURIComponent(story.default.title)}` }));
43
48
  }
44
49
  if (route.name === 'component-detail') {
45
- return (_jsx(StoryDetailScreen, { beforeContent: beforeContent, story: route.story, notFoundMessage: "Composant introuvable" }));
50
+ return (_jsx(StoryDetailScreen, { beforeContent: ctx.beforeContent, story: route.story, notFoundMessage: "Composant introuvable" }));
46
51
  }
52
+ return null;
53
+ };
54
+ const ecranDuTheme = (route, ctx) => {
47
55
  if (route.name === 'theme-home') {
48
- return (_jsx(ThemeHomeScreen, { beforeContent: beforeContent, onOpenColors: () => push({ name: 'theme-colors' }), onOpenTypography: () => push({ name: 'theme-typography' }) }));
56
+ return (_jsx(UIKitThemePage, { beforeContent: ctx.beforeContent, onOpenColors: () => ctx.push({ name: 'theme-colors' }), onOpenTypography: () => ctx.push({ name: 'theme-typography' }) }));
49
57
  }
50
58
  if (route.name === 'theme-colors') {
51
- return (_jsx(ThemePaletteScreen, { beforeContent: beforeContent, palette: palette, title: "UI Kit - Couleurs du th\u00E8me", description: "Palette et couleurs du th\u00E8me" }));
59
+ return (_jsx(ThemePaletteScreen, { beforeContent: ctx.beforeContent, palette: ctx.palette, title: "UI Kit - Couleurs du th\u00E8me", description: "Palette et couleurs du th\u00E8me" }));
52
60
  }
53
61
  if (route.name === 'theme-typography') {
54
- return (_jsx(ThemeTypographyScreen, { beforeContent: beforeContent, typography: typography, title: "UI Kit - Textes du th\u00E8me", description: "Styles de texte du th\u00E8me" }));
62
+ return (_jsx(ThemeTypographyScreen, { beforeContent: ctx.beforeContent, typography: ctx.typography, title: "UI Kit - Textes du th\u00E8me", description: "Styles de texte du th\u00E8me" }));
55
63
  }
64
+ return null;
65
+ };
66
+ const ecranDesConstantes = (route, ctx) => {
56
67
  if (route.name === 'constants') {
57
- return (_jsx(ThemeConstantsScreen, { beforeContent: beforeContent, constants: constants, title: "UI Kit - Constantes", description: "Constantes expos\u00E9es par le th\u00E8me", onSelectConstant: ({ name, value }) => push({ name: 'constant-detail', constantName: name, constantValue: value }) }));
68
+ return (_jsx(ThemeConstantsScreen, { beforeContent: ctx.beforeContent, constants: ctx.constants, title: "UI Kit - Constantes", description: "Constantes expos\u00E9es par le th\u00E8me", onSelectConstant: ({ name, value }) => ctx.push({ name: 'constant-detail', constantName: name, constantValue: value }) }));
58
69
  }
59
70
  if (route.name === 'constant-detail') {
60
- return (_jsx(ThemeConstantDetailScreen, { beforeContent: beforeContent, name: route.constantName, value: route.constantValue }));
61
- }
62
- if (route.name === 'philosophy') {
63
- return _jsx(PhilosophyPage, { beforeContent: beforeContent });
64
- }
65
- if (route.name === 'blank' && blankPage) {
66
- return (_jsx(Page, { scrollable: true, title: blankPage.title ?? 'Page vierge', description: blankPage.description ?? 'Zone de test libre', beforeContent: beforeContent, children: _jsx(Section, { withPaddingY: true, children: blankPage.render() }) }));
71
+ return (_jsx(ThemeConstantDetailScreen, { beforeContent: ctx.beforeContent, name: route.constantName, value: route.constantValue }));
67
72
  }
68
73
  return null;
69
74
  };
75
+ export const UIKitPage = ({ stories, constants, palette = CustomPalette, typography = CustomTypography, title = 'UI Kit', description = 'Documentation du design system', blankPage, }) => {
76
+ const { route, canGoBack, push, goBack } = useNavigationDuKit();
77
+ const ctx = {
78
+ stories,
79
+ constants,
80
+ palette,
81
+ typography,
82
+ title,
83
+ description,
84
+ blankPage,
85
+ beforeContent: _jsx(InternalHeader, { canGoBack: canGoBack, onBack: goBack }),
86
+ push,
87
+ };
88
+ return (ecranDAccueil(route, ctx) ??
89
+ ecranDesComposants(route, ctx) ??
90
+ ecranDuTheme(route, ctx) ??
91
+ ecranDesConstantes(route, ctx));
92
+ };
@@ -1,8 +1,13 @@
1
+ import React from 'react';
1
2
  export type UIKitThemePageProps = {
2
3
  title?: string;
3
4
  description?: string;
4
5
  onOpenColors: () => void;
5
6
  onOpenTypography: () => void;
7
+ onOpenCSSVariables?: () => void;
8
+ sidebar?: React.ReactNode;
9
+ footerContent?: React.ReactNode;
10
+ beforeContent?: React.ReactNode;
6
11
  };
7
- export declare const UIKitThemePage: ({ title, description, onOpenColors, onOpenTypography, }: UIKitThemePageProps) => import("react").JSX.Element;
12
+ export declare const UIKitThemePage: ({ title, description, onOpenColors, onOpenTypography, onOpenCSSVariables, sidebar, footerContent, beforeContent, }: UIKitThemePageProps) => React.JSX.Element;
8
13
  //# sourceMappingURL=UIKitThemePage.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"UIKitThemePage.d.ts","sourceRoot":"","sources":["../../src/pages/UIKitThemePage.tsx"],"names":[],"mappings":"AAsBA,MAAM,MAAM,mBAAmB,GAAG;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,gBAAgB,EAAE,MAAM,IAAI,CAAC;CAC9B,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,yDAK5B,mBAAmB,gCAerB,CAAC"}
1
+ {"version":3,"file":"UIKitThemePage.d.ts","sourceRoot":"","sources":["../../src/pages/UIKitThemePage.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,MAAM,MAAM,mBAAmB,GAAG;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,gBAAgB,EAAE,MAAM,IAAI,CAAC;IAC7B,kBAAkB,CAAC,EAAE,MAAM,IAAI,CAAC;IAChC,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,aAAa,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAChC,aAAa,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CACjC,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,oHAS5B,mBAAmB,sBA6BrB,CAAC"}