@alveole/storybook 2.0.0-alpha.1 → 2.0.0-alpha.11

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.
@@ -1 +1 @@
1
- {"version":3,"file":"BarreDeFiltres.d.ts","sourceRoot":"","sources":["../../src/components/BarreDeFiltres.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAKzC,MAAM,MAAM,mBAAmB,GAAG;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,KAAK,EAAE,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IACpC,gBAAgB,EAAE,aAAa,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC;IAC9C,YAAY,EAAE,CAAC,UAAU,EAAE,aAAa,CAAC,KAAK,CAAC,GAAG,IAAI,KAAK,IAAI,CAAC;CACjE,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,GAAI,qFAQ5B,mBAAmB,sBA2CrB,CAAC"}
1
+ {"version":3,"file":"BarreDeFiltres.d.ts","sourceRoot":"","sources":["../../src/components/BarreDeFiltres.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAKzC,MAAM,MAAM,mBAAmB,GAAG;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,KAAK,EAAE,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IACpC,gBAAgB,EAAE,aAAa,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC;IAC9C,YAAY,EAAE,CAAC,UAAU,EAAE,aAAa,CAAC,KAAK,CAAC,GAAG,IAAI,KAAK,IAAI,CAAC;CACjE,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,GAAI,qFAQ5B,mBAAmB,sBAiDrB,CAAC"}
@@ -1,5 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { Box } from '@alveole/components';
3
+ import { useTheme } from '@alveole/theme';
3
4
  import React from 'react';
4
5
  import { Platform, ScrollView } from 'react-native';
5
6
  import { ALL_STORY_FLAGS } from '../utils';
@@ -13,12 +14,17 @@ import { SearchField } from './SearchField';
13
14
  * l'ecran n'a besoin de savoir quel menu est ouvert.
14
15
  */
15
16
  export const BarreDeFiltres = ({ recherche, onRecherche, tags, tagChoisi, onTag, indicateurChoisi, onIndicateur, }) => {
17
+ const { isVariant, spacingValue } = useTheme();
18
+ const marge = isVariant('mobile') ? spacingValue('3W') : 0;
16
19
  const [menuOuvert, setMenuOuvert] = React.useState(null);
17
20
  const deroule = (menu) => ({
18
21
  ouvert: menuOuvert === menu,
19
22
  onOuvrir: (ouvert) => setMenuOuvert(ouvert ? menu : null),
20
23
  });
21
- return (_jsxs(ScrollView, { horizontal: true, nestedScrollEnabled: true, directionalLockEnabled: Platform.OS === 'ios', showsHorizontalScrollIndicator: false, contentContainerStyle: { flexDirection: 'row', gap: 8, alignItems: 'center' }, children: [_jsx(Box, { style: { minWidth: 200 }, children: _jsx(SearchField, { placeholder: "Button, Tabs, Card...", value: recherche, onChangeText: onRecherche, size: "sm" }) }), _jsx(FiltreDeroulant, { libelle: "Tags", options: tags.map(tag => ({ key: tag, label: tag })), choisi: tagChoisi, onChoisir: tag => {
24
+ return (_jsxs(ScrollView, { horizontal: true, nestedScrollEnabled: true, directionalLockEnabled: Platform.OS === 'ios', showsHorizontalScrollIndicator: false,
25
+ // La zone défile jusqu'aux bords ; seuls le premier et le dernier contrôle
26
+ // gardent la marge de ScreenZone, à l'intérieur du contenu défilant.
27
+ style: { marginHorizontal: -marge, flexGrow: 0, flexShrink: 0 }, contentInsetAdjustmentBehavior: "never", contentContainerStyle: { flexDirection: 'row', gap: 8, alignItems: 'center', paddingHorizontal: marge }, children: [_jsx(Box, { style: { minWidth: 200 }, children: _jsx(SearchField, { placeholder: "Button, Tabs, Card...", value: recherche, onChangeText: onRecherche, size: "sm" }) }), _jsx(FiltreDeroulant, { libelle: "Tags", options: tags.map(tag => ({ key: tag, label: tag })), choisi: tagChoisi, onChoisir: tag => {
22
28
  onTag(tag);
23
29
  setMenuOuvert(null);
24
30
  }, ...deroule('tags') }), _jsx(FiltreDeroulant, { libelle: "Indicateurs", options: ALL_STORY_FLAGS, choisi: indicateurChoisi, onChoisir: indicateur => {
@@ -1 +1 @@
1
- {"version":3,"file":"ExampleBlock.d.ts","sourceRoot":"","sources":["../../src/components/ExampleBlock.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,OAAO,CAAC;AA6F1B,MAAM,MAAM,iBAAiB,GAAG;IAC9B,0FAA0F;IAC1F,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,kFAAkF;IAClF,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,2FAA2F;IAC3F,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB,CAAC;AAEF,8EAA8E;AAC9E,eAAO,MAAM,YAAY,GAAI,kCAA0C,iBAAiB,sBAkCvF,CAAC"}
1
+ {"version":3,"file":"ExampleBlock.d.ts","sourceRoot":"","sources":["../../src/components/ExampleBlock.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,OAAO,CAAC;AA8F1B,MAAM,MAAM,iBAAiB,GAAG;IAC9B,0FAA0F;IAC1F,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,kFAAkF;IAClF,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,2FAA2F;IAC3F,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB,CAAC;AAEF,8EAA8E;AAC9E,eAAO,MAAM,YAAY,GAAI,kCAA0C,iBAAiB,sBAkCvF,CAAC"}
@@ -2,6 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
2
2
  import { Box, Button, Highlight, Typography } from '@alveole/components';
3
3
  import { useTheme } from '@alveole/theme';
4
4
  import React from 'react';
5
+ import { Platform } from 'react-native';
5
6
  import { decouperSource } from '../storySource';
6
7
  /** Au delà, la source prend plus de place que ce qu'elle documente. */
7
8
  const LIGNES_VISIBLES = 12;
@@ -16,7 +17,7 @@ const PAS_DE_LA_TRAME = 16;
16
17
  */
17
18
  const Scene = ({ children, pleinEcran }) => {
18
19
  const { color } = useTheme();
19
- return (_jsx(Box, { p: '150', style: {
20
+ return (_jsx(Box, { p: Platform.OS === 'web' ? '3W' : '1W', style: {
20
21
  backgroundColor: color.light.background['default-grey'],
21
22
  backgroundImage: `radial-gradient(circle, ${color.light.border['default-grey']} 1px, transparent 1px)`,
22
23
  backgroundSize: `${PAS_DE_LA_TRAME}px ${PAS_DE_LA_TRAME}px`,
@@ -40,8 +41,8 @@ const BarreDeSource = ({ onCopier }) => {
40
41
  justifyContent: 'space-between',
41
42
  // Les côtés s'alignent sur la colonne du code, qui est le contenu principal du bas
42
43
  // du bloc ; la hauteur reste au plus juste de ce que la barre porte.
43
- paddingLeft: spacingValue('2W'),
44
- paddingRight: spacingValue('2W'),
44
+ paddingLeft: spacingValue(Platform.OS === 'web' ? '2W' : '1W'),
45
+ paddingRight: spacingValue(Platform.OS === 'web' ? '2W' : '1W'),
45
46
  paddingTop: spacingValue('1W'),
46
47
  paddingBottom: spacingValue('1W'),
47
48
  }, children: [_jsx(Typography, { style: { ...text['Corps de texte'].XS.CapsBold, color: color.light.text['mention-grey'] }, children: "tsx" }), _jsx(Button, { title: "Copier", size: "sm", variant: "tertiary", leading: "Copy", onPress: onCopier })] }));
@@ -1 +1 @@
1
- {"version":3,"file":"ExemplesDeLaStory.d.ts","sourceRoot":"","sources":["../../src/components/ExemplesDeLaStory.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAiB,eAAe,EAAE,MAAM,UAAU,CAAC;AAuEnE,MAAM,MAAM,sBAAsB,GAAG;IACnC,KAAK,EAAE,eAAe,CAAC;IACvB,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,8FAA8F;IAC9F,OAAO,EAAE,OAAO,CAAC;CAClB,CAAC;AAEF,4FAA4F;AAC5F,eAAO,MAAM,iBAAiB,GAAI,8BAA8B,sBAAsB,gCAUrF,CAAC"}
1
+ {"version":3,"file":"ExemplesDeLaStory.d.ts","sourceRoot":"","sources":["../../src/components/ExemplesDeLaStory.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAiB,eAAe,EAAE,MAAM,UAAU,CAAC;AAiEnE,MAAM,MAAM,sBAAsB,GAAG;IACnC,KAAK,EAAE,eAAe,CAAC;IACvB,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,8FAA8F;IAC9F,OAAO,EAAE,OAAO,CAAC;CAClB,CAAC;AAEF,4FAA4F;AAC5F,eAAO,MAAM,iBAAiB,GAAI,8BAA8B,sBAAsB,gCAUrF,CAAC"}
@@ -1,6 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { AnchorHeading, Box, MarkdownDescription, Tag, Typography } from '@alveole/components';
3
- import { FOCUS_ATTRIBUTE, useTheme } from '@alveole/theme';
2
+ import { A, AnchorHeading, Box, MarkdownDescription, Tag, Typography } from '@alveole/components';
3
+ import { useTheme } from '@alveole/theme';
4
4
  import { descriptionDeLExemple, sourceDeLExemple } from '../screens/sourcesDExemples';
5
5
  import { getStoryFlags } from '../utils';
6
6
  import { ExampleBlock } from './ExampleBlock';
@@ -21,7 +21,7 @@ const UnExemple = ({ story, nom, Rendu, gabarit }) => {
21
21
  */
22
22
  const StatutDeLaFiche = ({ meta }) => {
23
23
  const { color, text } = useTheme();
24
- return (_jsxs(Box, { display: "flex", flexDirection: "row", style: { alignItems: 'center', justifyContent: 'space-between' }, children: [_jsxs(Box, { display: "flex", flexDirection: "row", flexWrap: "wrap", gap: 8, children: [meta.tags.map(tag => (_jsx(Tag, { size: "md", children: tag }, tag))), getStoryFlags(meta).map(flag => (_jsx(Tag, { size: "md", children: flag.label }, flag.key)))] }), meta.figmaURL ? (_jsx("a", { href: meta.figmaURL, rel: "noreferrer", style: { textDecoration: 'none' }, target: "_blank", [FOCUS_ATTRIBUTE]: 'ring', children: _jsx(Typography, { style: { ...text['Corps de texte'].SM.Bold, color: color.light.text['action-high-primary'] }, children: "Ouvrir Figma" }) })) : null] }));
24
+ return (_jsxs(Box, { display: "flex", flexDirection: "row", style: { alignItems: 'center', justifyContent: 'space-between' }, children: [_jsxs(Box, { display: "flex", flexDirection: "row", flexWrap: "wrap", gap: 8, children: [meta.tags.map(tag => (_jsx(Tag, { size: "md", children: tag }, tag))), getStoryFlags(meta).map(flag => (_jsx(Tag, { size: "md", children: flag.label }, flag.key)))] }), meta.figmaURL ? (_jsx(A, { href: meta.figmaURL, target: "_blank", children: _jsx(Typography, { style: { ...text['Corps de texte'].SM.Bold, color: color.light.text['action-high-primary'] }, children: "Ouvrir Figma" }) })) : null] }));
25
25
  };
26
26
  /** Les demonstrations d'une fiche, les unes sous les autres, sous le statut de la fiche. */
27
27
  export const ExemplesDeLaStory = ({ story, exemples, gabarit }) => (_jsxs(Box, { display: "flex", gap: 40, mt: '5W', children: [_jsx(StatutDeLaFiche, { meta: story.default }), exemples.map(([nom, Rendu]) => (_jsx(UnExemple, { story: story, nom: nom, Rendu: Rendu, gabarit: gabarit }, nom)))] }));
@@ -1 +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"}
1
+ {"version":3,"file":"StorySummary.d.ts","sourceRoot":"","sources":["../../src/components/StorySummary.tsx"],"names":[],"mappings":"AAIA,MAAM,MAAM,iBAAiB,GAAG;IAC9B,6EAA6E;IAC7E,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB,CAAC;AAEF,wFAAwF;AACxF,eAAO,MAAM,YAAY,GAAI,aAAa,iBAAiB,gCAqB1D,CAAC"}
@@ -1,8 +1,9 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { Box, toSlug, Typography } from '@alveole/components';
3
3
  import { FOCUS_ATTRIBUTE, useTheme } from '@alveole/theme';
4
+ import { styleDuLienBrut } from './styleDuLienBrut';
4
5
  /** Le sommaire d'une page : une entrée par section, vers l'ancre que pose son titre. */
5
6
  export const StorySummary = ({ entrees }) => {
6
7
  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
+ 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: styleDuLienBrut, [FOCUS_ATTRIBUTE]: 'ring', children: _jsx(Typography, { style: { ...text['Corps de texte'].SM.Regular, color: color.light.text['default-grey'] }, children: entree }) }, entree)))] }));
8
9
  };
@@ -10,6 +10,7 @@ export type UIKitTopBarItem = {
10
10
  export type UIKitTopBarProps = {
11
11
  activeKey: string;
12
12
  items: UIKitTopBarItem[];
13
+ logo?: React.ReactNode;
13
14
  /**
14
15
  * Niveau 2 de la rubrique courante. Sur desktop il est rendu par la colonne ; sous 992px
15
16
  * la colonne se replie et son contenu descend ici, pour que le menu de la barre reste la
@@ -17,5 +18,5 @@ export type UIKitTopBarProps = {
17
18
  */
18
19
  columnGroups?: UIKitColumnGroup[];
19
20
  };
20
- export declare const UIKitTopBar: ({ activeKey, items, columnGroups }: UIKitTopBarProps) => React.JSX.Element;
21
+ export declare const UIKitTopBar: ({ activeKey, items, columnGroups, logo }: UIKitTopBarProps) => React.JSX.Element;
21
22
  //# sourceMappingURL=UIKitTopBar.d.ts.map
@@ -1 +1 @@
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
+ {"version":3,"file":"UIKitTopBar.d.ts","sourceRoot":"","sources":["../../src/components/UIKitTopBar.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAA2E,MAAM,qBAAqB,CAAC;AAGjH,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,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,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB;;;;OAIG;IACH,YAAY,CAAC,EAAE,gBAAgB,EAAE,CAAC;CACnC,CAAC;AAsJF,eAAO,MAAM,WAAW,GAAI,0CAAsD,gBAAgB,sBAkBjG,CAAC"}
@@ -1,20 +1,10 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { A, Box, Divider, Header, LucideIcon, SidebarGroup, SidebarItem, Typography } from '@alveole/components';
3
3
  import { makeStyles, useTheme } from '@alveole/theme';
4
+ import { usePathname } from 'expo-router';
4
5
  import React from 'react';
5
- import { Pressable } from 'react-native';
6
- const AlveoleLogo = () => {
7
- const { color, radius, text } = useTheme();
8
- return (_jsx(Box, { style: {
9
- width: 32,
10
- height: 32,
11
- borderRadius: radius('md'),
12
- backgroundColor: color.light.background['action-high-primary'],
13
- display: 'flex',
14
- alignItems: 'center',
15
- justifyContent: 'center',
16
- }, children: _jsx(Typography, { style: { ...text['Corps de texte'].XS.Bold, color: '#fff' }, children: "A" }) }));
17
- };
6
+ import { Platform, Pressable, ScrollView, useWindowDimensions } from 'react-native';
7
+ import { useSafeAreaInsets } from 'react-native-safe-area-context';
18
8
  const useNavItemStyles = makeStyles(({ color, radius, spacingValue, text }) => {
19
9
  const activeLabelTypography = text['Corps de texte'].MD.Medium;
20
10
  return {
@@ -60,43 +50,39 @@ const useNavItemStyles = makeStyles(({ color, radius, spacingValue, text }) => {
60
50
  */
61
51
  const NavItem = ({ label, href, current, block = false }) => {
62
52
  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 }) })] }));
53
+ return (_jsxs(A, { href: href, direction: "replace", ariaCurrent: current ? 'page' : undefined, style: { ...styles.container, alignItems: block ? 'flex-start' : 'center' }, backgroundColor: { hover: styles.containerHover.backgroundColor }, 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
54
  };
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,
55
+ const MobileMenuItems = ({ activeKey, items, columnGroups }) => (_jsxs(_Fragment, { 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)))] }));
56
+ /** La barre mobile garde sa commande visible et fait défiler le menu sous celle-ci. */
57
+ const BarreMobile = ({ activeKey, items, columnGroups, logo }) => {
58
+ const { color, spacingValue } = useTheme();
59
+ const { height } = useWindowDimensions();
60
+ const { top, bottom } = useSafeAreaInsets();
61
+ const [barHeight, setBarHeight] = React.useState(0);
62
+ const [menuOpen, setMenuOpen] = React.useState(false);
63
+ const toggleMenu = () => setMenuOpen(open => !open);
64
+ // En natif, le menu remplit le bas de l'écran, zone de l'indicateur d'accueil comprise.
65
+ const menuHeight = Math.max(0, height - top - barHeight - (Platform.OS === 'web' ? bottom : 0));
66
+ const header = (_jsx(Header, { logo: logo, right: _jsx(Pressable, { accessibilityRole: "button", accessibilityLabel: menuOpen ? 'Fermer le menu' : 'Ouvrir le menu', accessibilityState: { expanded: menuOpen }, onPress: toggleMenu, style: { padding: 8 }, children: _jsx(LucideIcon, { name: menuOpen ? 'X' : 'Menu', size: "md", color: color.light.text['title-grey'] }) }) }));
67
+ return (_jsxs(_Fragment, { children: [_jsx(Box, { style: { position: Platform.OS === 'web' ? 'sticky' : 'relative', top: 0, zIndex: 100, flexShrink: 0 }, onLayout: event => setBarHeight(event.nativeEvent.layout.height), children: header }), menuOpen && (_jsx(Box, { style: {
68
+ position: Platform.OS === 'web' ? 'sticky' : 'relative',
69
+ top: Platform.OS === 'web' ? 64 : 0,
80
70
  left: 0,
81
71
  right: 0,
82
72
  zIndex: 99,
83
73
  backgroundColor: color.light.background['default-grey'],
84
74
  borderBottomWidth: 1,
85
75
  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)))] }))] }));
76
+ flexShrink: 0,
77
+ }, children: _jsx(ScrollView, { style: { ...(Platform.OS === 'web' ? { maxHeight: menuHeight } : { height: menuHeight }), flexGrow: 0 }, contentContainerStyle: { padding: spacingValue('2W'), gap: spacingValue('050') }, keyboardShouldPersistTaps: "handled", children: _jsx(MobileMenuItems, { activeKey: activeKey, items: items, columnGroups: columnGroups }) }) }))] }));
94
78
  };
95
- export const UIKitTopBar = ({ activeKey, items, columnGroups = [] }) => {
79
+ export const UIKitTopBar = ({ activeKey, items, columnGroups = [], logo = null }) => {
96
80
  const { isVariant } = useTheme();
81
+ const pathname = usePathname();
97
82
  if (isVariant('mobile')) {
98
- return _jsx(BarreMobile, { activeKey: activeKey, items: items, columnGroups: columnGroups });
83
+ // Toute nouvelle fiche repart avec un menu fermé, y compris dans la même rubrique.
84
+ return _jsx(BarreMobile, { activeKey: activeKey, items: items, columnGroups: columnGroups, logo: logo }, pathname);
99
85
  }
100
86
  const right = (_jsx(Box, { display: "flex", flexDirection: "row", flexWrap: "wrap", gap: 8, children: items.map(({ key, ...item }) => (_jsx(NavItem, { ...item, current: activeKey === key }, key))) }));
101
- return _jsx(Header, { logo: _jsx(AlveoleLogo, {}), title: "Alveole UI Kit", right: right });
87
+ return _jsx(Header, { logo: logo, title: "Alveole UI Kit", right: right });
102
88
  };
@@ -0,0 +1,9 @@
1
+ import type { CSSProperties } from 'react';
2
+ /**
3
+ * Le style d'un `<a>` brut du catalogue qui enveloppe un libellé. En flex, le libellé devient
4
+ * un bloc à sa propre hauteur de ligne : sinon le lien garde celle de la police que Tamagui v2
5
+ * remet sur chaque vue, plus haute, et décale son libellé. En colonne, le libellé s'étire à la
6
+ * largeur du lien et passe à la ligne, là où une rangée le laissait déborder.
7
+ */
8
+ export declare const styleDuLienBrut: CSSProperties;
9
+ //# sourceMappingURL=styleDuLienBrut.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"styleDuLienBrut.d.ts","sourceRoot":"","sources":["../../src/components/styleDuLienBrut.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAE3C;;;;;GAKG;AACH,eAAO,MAAM,eAAe,EAAE,aAAoF,CAAC"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Le style d'un `<a>` brut du catalogue qui enveloppe un libellé. En flex, le libellé devient
3
+ * un bloc à sa propre hauteur de ligne : sinon le lien garde celle de la police que Tamagui v2
4
+ * remet sur chaque vue, plus haute, et décale son libellé. En colonne, le libellé s'étire à la
5
+ * largeur du lien et passe à la ligne, là où une rangée le laissait déborder.
6
+ */
7
+ export const styleDuLienBrut = { display: 'flex', flexDirection: 'column', textDecoration: 'none' };
@@ -1 +1 @@
1
- {"version":3,"file":"migrationV2.d.ts","sourceRoot":"","sources":["../../src/pages/migrationV2.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,MAAM,kBAAkB,GAAG;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,eAAO,MAAM,4BAA4B,gfAKV,CAAC;AAEhC,eAAO,MAAM,wBAAwB,EAAE,SAAS,kBAAkB,EA6lBjE,CAAC"}
1
+ {"version":3,"file":"migrationV2.d.ts","sourceRoot":"","sources":["../../src/pages/migrationV2.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,MAAM,kBAAkB,GAAG;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,eAAO,MAAM,4BAA4B,gfAKV,CAAC;AAEhC,eAAO,MAAM,wBAAwB,EAAE,SAAS,kBAAkB,EAopBjE,CAAC"}
@@ -471,7 +471,7 @@ de la liste : \`options={[...selectedOption ? [selectedOption] : [], ...suggesti
471
471
  },
472
472
  {
473
473
  titre: '5. Icônes → leading / trailing',
474
- markdown: `Détail et justification : [leading-trailing.md](https://github.com/Captive-Studio/alveole-js/blob/main/docs/migrations/leading-trailing.md).
474
+ markdown: `Détail et justification : [leading-trailing.md](https://github.com/captive-studio/alveole-js/blob/main/docs/migrations/leading-trailing.md).
475
475
 
476
476
  \`\`\`bash
477
477
  git grep -nE "startIcon|endIcon|\\bicon[=:]"
@@ -597,7 +597,62 @@ Les clés de spacing dépréciées existent toujours (non cassant) mais leurs us
597
597
  l'échelle V/W quand on y passe.`,
598
598
  },
599
599
  {
600
- titre: '8. Vérification finale',
600
+ titre: '8. Tamagui v2',
601
+ markdown: `Détail, changements de rendu et relevé par application : [tamagui-v2.md](https://github.com/captive-studio/alveole-js/blob/main/docs/migrations/tamagui-v2.md).
602
+
603
+ Alveole 2.0 exige Tamagui 3 (section 8 bis) : une application en Tamagui 1 fait d'abord ce saut
604
+ vers la v2, puis celui vers la v3, dans cet ordre. Monter **tous** les paquets \`tamagui\` /
605
+ \`@tamagui/*\` de l'application au même numéro exact, et aligner la clé \`allowScripts\` sur la
606
+ version des paquets \`@alveole/*\` (version unique, ADR 0029).
607
+
608
+ \`\`\`bash
609
+ git grep -nE "[^a-zA-Z]animation=|onHover(In|Out)|disablePassBorderRadius"
610
+ \`\`\`
611
+
612
+ | Avant | Après |
613
+ | ------------------------------------------------------- | --------------------------------- |
614
+ | \`animation="…"\` sur un composant Tamagui | \`transition="…"\` |
615
+ | \`onHoverIn\` / \`onHoverOut\` sur Tamagui ou \`Box\` | \`onMouseEnter\` / \`onMouseLeave\` |
616
+ | \`disablePassBorderRadius\` | retirer |
617
+ | \`dataSet\` sur un composant Tamagui | attribut direct \`data-x="…"\` |
618
+
619
+ \`onHoverIn\` reste valable sur un \`Pressable\` React Native. Ne change pas : \`tag\` de \`Box\` et
620
+ \`Typography\`, et les éléments DOM rendus (un sélecteur CSS sur \`data-table\` reste valable).
621
+
622
+ Changements de rendu, invisibles au typecheck et en jsdom :
623
+
624
+ - **chaque vue reprend la police de l'app**, hauteur de ligne comprise : un style de texte posé sur
625
+ une vue ne descend plus aux enfants, et un texte sans hauteur de ligne prend celle de la config
626
+ (23 px en \`@tamagui/config\` v3). Les \`Typography\` d'Alveole posent \`normal\` par défaut ;
627
+ - **plus de \`position: relative\` par défaut** : poser \`position: 'relative'\` sur le conteneur d'un
628
+ enfant absolu, ou \`settings.defaultPosition: 'relative'\` ;
629
+ - **\`flex: 1\` devient \`1 1 0px\`** sur le web : \`flexGrow: 1\`, ou \`settings.styleCompat: 'legacy'\` ;
630
+ - \`Image\` rend un vrai \`<img>\` (\`alt\` exigé) ; \`Switch\` ne compte plus padding ni bordure.`,
631
+ },
632
+ {
633
+ titre: '8 bis. Tamagui v3',
634
+ markdown: `Détail, changements de rendu et relevé par application : [tamagui-v3.md](https://github.com/captive-studio/alveole-js/blob/main/docs/migrations/tamagui-v3.md).
635
+
636
+ Les peer dependencies Tamagui d'Alveole sont en \`^3.0.0\` seul.
637
+
638
+ - **config** : \`@tamagui/config/v3\` et \`/v4\` n'existent plus ; passer à \`@tamagui/config/v5\` avec
639
+ les animations de \`@tamagui/config/v5-css\` ;
640
+ - **\`SafeAreaProvider\`** enveloppe \`TamaguiProvider\`, tests compris ;
641
+ - **\`@tamagui/babel-plugin\`** n'a pas de version 3 : le retirer de \`package.json\` et de
642
+ \`babel.config.js\` ;
643
+ - **pseudo-états en clauses** : \`hoverStyle\` et ses voisins disparaissent, de \`Box\` et
644
+ \`Typography\` aussi (ADR 0031). La valeur de repos et sa clause vivent sur la même prop :
645
+ \`backgroundColor={{ default: repos, hover: survol }}\`, propriété sortie de \`style\`.
646
+
647
+ \`\`\`bash
648
+ git grep -nwE "hoverStyle|pressStyle|focusStyle|focusVisibleStyle|enterStyle|exitStyle|disabledStyle"
649
+ \`\`\`
650
+
651
+ Ce qu'Alveole ne prend pas en charge suit le guide officiel :
652
+ [How to upgrade](https://tamagui.dev/docs/guides/how-to-upgrade).`,
653
+ },
654
+ {
655
+ titre: '9. Vérification finale',
601
656
  markdown: `\`\`\`bash
602
657
  git grep -nE "\\b(TextField|TextareaField|EmailField|EmailInput|PasswordField|PhoneField|PhoneInput|NumberField|OtpField|FileField|SelectMultiple|Autocomplete\\w*|NativePicker|SelectInput)\\b|startIcon|endIcon|variant=['\\"]link['\\"]|size=['\\"]xs['\\"]|noPadding|borderNone|leftAlign|\\boptional(Text)?[=:]|onActions|actionsIcon|<Tag\\b[^>]*\\bcolor=|Inter-|Barlow-"
603
658
  \`\`\`
@@ -1 +1 @@
1
- {"version":3,"file":"ThemeTypographyScreen.d.ts","sourceRoot":"","sources":["../../src/screens/ThemeTypographyScreen.tsx"],"names":[],"mappings":"AAKA,MAAM,MAAM,0BAA0B,GAAG;IACvC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,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;AAwGF,eAAO,MAAM,qBAAqB,GAAI,4EAOnC,0BAA0B,gCAqC5B,CAAC"}
1
+ {"version":3,"file":"ThemeTypographyScreen.d.ts","sourceRoot":"","sources":["../../src/screens/ThemeTypographyScreen.tsx"],"names":[],"mappings":"AAUA,MAAM,MAAM,0BAA0B,GAAG;IACvC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,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;AAwGF,eAAO,MAAM,qBAAqB,GAAI,4EAOnC,0BAA0B,gCAqC5B,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alveole/storybook",
3
- "version": "2.0.0-alpha.1",
3
+ "version": "2.0.0-alpha.11",
4
4
  "description": "Catalog screens and helpers for Alveole stories and theme tokens.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -20,8 +20,8 @@
20
20
  "devDependencies": {
21
21
  "@alveole/eslint-config": "file:../eslint-config",
22
22
  "@testing-library/react": "16.3.3",
23
- "babel-preset-expo": "57.0.14",
24
- "eslint": "10.10.0",
23
+ "babel-preset-expo": "57.0.16",
24
+ "eslint": "10.13.0",
25
25
  "jest": "29.7.0",
26
26
  "jest-environment-jsdom": "30.5.2",
27
27
  "jest-expo": "57.0.5",
@@ -29,7 +29,7 @@
29
29
  "react-dom": "19.2.3",
30
30
  "react-native": "0.86.3",
31
31
  "react-native-web": "0.21.4",
32
- "tamagui": "1.144.4"
32
+ "tamagui": "3.0.18"
33
33
  },
34
34
  "peerDependencies": {
35
35
  "@alveole/components": "*",