@portnet/ui 6.0.1 → 6.0.2

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 (158) hide show
  1. package/CHANGELOG.md +85 -0
  2. package/dist/esm/index.js +18 -0
  3. package/dist/esm/index.js.map +1 -1
  4. package/dist/esm/v2/__tests__/FieldError.test.js +0 -1
  5. package/dist/esm/v2/__tests__/FieldError.test.js.map +1 -1
  6. package/dist/esm/v2/__tests__/FieldWidth.test.js +146 -0
  7. package/dist/esm/v2/__tests__/FieldWidth.test.js.map +1 -0
  8. package/dist/esm/v2/__tests__/FileCard.test.js +0 -1
  9. package/dist/esm/v2/__tests__/FileCard.test.js.map +1 -1
  10. package/dist/esm/v2/__tests__/FormikCheckbox.test.js +265 -0
  11. package/dist/esm/v2/__tests__/FormikCheckbox.test.js.map +1 -0
  12. package/dist/esm/v2/__tests__/FormikDateTimePicker.test.js +248 -0
  13. package/dist/esm/v2/__tests__/FormikDateTimePicker.test.js.map +1 -0
  14. package/dist/esm/v2/__tests__/FormikRadioGroup.test.js +380 -0
  15. package/dist/esm/v2/__tests__/FormikRadioGroup.test.js.map +1 -0
  16. package/dist/esm/v2/__tests__/MobileRowCard.test.js +0 -1
  17. package/dist/esm/v2/__tests__/MobileRowCard.test.js.map +1 -1
  18. package/dist/esm/v2/__tests__/SectionErrorBoundary.test.js.map +1 -1
  19. package/dist/esm/v2/__tests__/labels-merge.test.js +0 -1
  20. package/dist/esm/v2/__tests__/labels-merge.test.js.map +1 -1
  21. package/dist/esm/v2/components/DateTimePicker.js +37 -4
  22. package/dist/esm/v2/components/DateTimePicker.js.map +1 -1
  23. package/dist/esm/v2/components/Field.js +63 -1
  24. package/dist/esm/v2/components/Field.js.map +1 -1
  25. package/dist/esm/v2/components/index.js +27 -0
  26. package/dist/esm/v2/components/index.js.map +1 -1
  27. package/dist/esm/v2/index.js +12 -1
  28. package/dist/esm/v2/index.js.map +1 -1
  29. package/dist/esm/v2/patterns/FavoriteColumn.js +14 -61
  30. package/dist/esm/v2/patterns/FavoriteColumn.js.map +1 -1
  31. package/dist/esm/v2/patterns/FormikCheckbox.js +140 -0
  32. package/dist/esm/v2/patterns/FormikCheckbox.js.map +1 -0
  33. package/dist/esm/v2/patterns/FormikCombobox.js +5 -2
  34. package/dist/esm/v2/patterns/FormikCombobox.js.map +1 -1
  35. package/dist/esm/v2/patterns/FormikDatePicker.js +13 -47
  36. package/dist/esm/v2/patterns/FormikDatePicker.js.map +1 -1
  37. package/dist/esm/v2/patterns/FormikDateTimePicker.js +150 -0
  38. package/dist/esm/v2/patterns/FormikDateTimePicker.js.map +1 -0
  39. package/dist/esm/v2/patterns/FormikInput.js +5 -2
  40. package/dist/esm/v2/patterns/FormikInput.js.map +1 -1
  41. package/dist/esm/v2/patterns/FormikRadioGroup.js +141 -0
  42. package/dist/esm/v2/patterns/FormikRadioGroup.js.map +1 -0
  43. package/dist/esm/v2/patterns/FormikSelect.js +5 -2
  44. package/dist/esm/v2/patterns/FormikSelect.js.map +1 -1
  45. package/dist/esm/v2/patterns/FormikTextarea.js +5 -2
  46. package/dist/esm/v2/patterns/FormikTextarea.js.map +1 -1
  47. package/dist/esm/v2/patterns/KeyboardShortcutsHelp.js +25 -8
  48. package/dist/esm/v2/patterns/KeyboardShortcutsHelp.js.map +1 -1
  49. package/dist/esm/v2/patterns/RowFavoriteToggle.js +122 -0
  50. package/dist/esm/v2/patterns/RowFavoriteToggle.js.map +1 -0
  51. package/dist/esm/v2/patterns/_pickerSerialisation.js +74 -0
  52. package/dist/esm/v2/patterns/_pickerSerialisation.js.map +1 -0
  53. package/dist/esm/v2/patterns/index.js +83 -0
  54. package/dist/esm/v2/patterns/index.js.map +1 -1
  55. package/dist/esm/v2/personalization/capabilities/gridPreferences.js +209 -0
  56. package/dist/esm/v2/personalization/capabilities/gridPreferences.js.map +1 -0
  57. package/dist/esm/v2/personalization/capabilities/index.js +5 -0
  58. package/dist/esm/v2/personalization/capabilities/index.js.map +1 -1
  59. package/dist/esm/v2/personalization/index.js +18 -0
  60. package/dist/esm/v2/personalization/index.js.map +1 -1
  61. package/dist/index.d.ts +2 -0
  62. package/dist/index.d.ts.map +1 -1
  63. package/dist/index.js +14 -0
  64. package/dist/index.js.map +1 -1
  65. package/dist/v2/__tests__/FieldError.test.js +26 -30
  66. package/dist/v2/__tests__/FieldError.test.js.map +1 -1
  67. package/dist/v2/__tests__/FieldWidth.test.js +150 -0
  68. package/dist/v2/__tests__/FieldWidth.test.js.map +1 -0
  69. package/dist/v2/__tests__/FileCard.test.js +25 -29
  70. package/dist/v2/__tests__/FileCard.test.js.map +1 -1
  71. package/dist/v2/__tests__/FormikCheckbox.test.js +268 -0
  72. package/dist/v2/__tests__/FormikCheckbox.test.js.map +1 -0
  73. package/dist/v2/__tests__/FormikDateTimePicker.test.js +247 -0
  74. package/dist/v2/__tests__/FormikDateTimePicker.test.js.map +1 -0
  75. package/dist/v2/__tests__/FormikRadioGroup.test.js +381 -0
  76. package/dist/v2/__tests__/FormikRadioGroup.test.js.map +1 -0
  77. package/dist/v2/__tests__/MobileRowCard.test.js +52 -56
  78. package/dist/v2/__tests__/MobileRowCard.test.js.map +1 -1
  79. package/dist/v2/__tests__/SectionErrorBoundary.test.js.map +1 -1
  80. package/dist/v2/__tests__/labels-merge.test.js +20 -24
  81. package/dist/v2/__tests__/labels-merge.test.js.map +1 -1
  82. package/dist/v2/components/DateTimePicker.d.ts.map +1 -1
  83. package/dist/v2/components/DateTimePicker.js +37 -4
  84. package/dist/v2/components/DateTimePicker.js.map +1 -1
  85. package/dist/v2/components/Field.d.ts +59 -1
  86. package/dist/v2/components/Field.d.ts.map +1 -1
  87. package/dist/v2/components/Field.js +62 -2
  88. package/dist/v2/components/Field.js.map +1 -1
  89. package/dist/v2/components/index.d.ts +27 -0
  90. package/dist/v2/components/index.d.ts.map +1 -1
  91. package/dist/v2/components/index.js.map +1 -1
  92. package/dist/v2/index.d.ts.map +1 -1
  93. package/dist/v2/index.js.map +1 -1
  94. package/dist/v2/patterns/FavoriteColumn.d.ts +9 -9
  95. package/dist/v2/patterns/FavoriteColumn.d.ts.map +1 -1
  96. package/dist/v2/patterns/FavoriteColumn.js +14 -61
  97. package/dist/v2/patterns/FavoriteColumn.js.map +1 -1
  98. package/dist/v2/patterns/FormikCheckbox.d.ts +77 -0
  99. package/dist/v2/patterns/FormikCheckbox.d.ts.map +1 -0
  100. package/dist/v2/patterns/FormikCheckbox.js +147 -0
  101. package/dist/v2/patterns/FormikCheckbox.js.map +1 -0
  102. package/dist/v2/patterns/FormikCombobox.d.ts +7 -1
  103. package/dist/v2/patterns/FormikCombobox.d.ts.map +1 -1
  104. package/dist/v2/patterns/FormikCombobox.js +5 -2
  105. package/dist/v2/patterns/FormikCombobox.js.map +1 -1
  106. package/dist/v2/patterns/FormikDatePicker.d.ts +13 -1
  107. package/dist/v2/patterns/FormikDatePicker.d.ts.map +1 -1
  108. package/dist/v2/patterns/FormikDatePicker.js +33 -66
  109. package/dist/v2/patterns/FormikDatePicker.js.map +1 -1
  110. package/dist/v2/patterns/FormikDateTimePicker.d.ts +111 -0
  111. package/dist/v2/patterns/FormikDateTimePicker.d.ts.map +1 -0
  112. package/dist/v2/patterns/FormikDateTimePicker.js +158 -0
  113. package/dist/v2/patterns/FormikDateTimePicker.js.map +1 -0
  114. package/dist/v2/patterns/FormikInput.d.ts +11 -1
  115. package/dist/v2/patterns/FormikInput.d.ts.map +1 -1
  116. package/dist/v2/patterns/FormikInput.js +5 -2
  117. package/dist/v2/patterns/FormikInput.js.map +1 -1
  118. package/dist/v2/patterns/FormikRadioGroup.d.ts +80 -0
  119. package/dist/v2/patterns/FormikRadioGroup.d.ts.map +1 -0
  120. package/dist/v2/patterns/FormikRadioGroup.js +148 -0
  121. package/dist/v2/patterns/FormikRadioGroup.js.map +1 -0
  122. package/dist/v2/patterns/FormikSelect.d.ts +9 -1
  123. package/dist/v2/patterns/FormikSelect.d.ts.map +1 -1
  124. package/dist/v2/patterns/FormikSelect.js +5 -2
  125. package/dist/v2/patterns/FormikSelect.js.map +1 -1
  126. package/dist/v2/patterns/FormikTextarea.d.ts +9 -1
  127. package/dist/v2/patterns/FormikTextarea.d.ts.map +1 -1
  128. package/dist/v2/patterns/FormikTextarea.js +5 -2
  129. package/dist/v2/patterns/FormikTextarea.js.map +1 -1
  130. package/dist/v2/patterns/KeyboardShortcutsHelp.d.ts +14 -1
  131. package/dist/v2/patterns/KeyboardShortcutsHelp.d.ts.map +1 -1
  132. package/dist/v2/patterns/KeyboardShortcutsHelp.js +25 -8
  133. package/dist/v2/patterns/KeyboardShortcutsHelp.js.map +1 -1
  134. package/dist/v2/patterns/RowFavoriteToggle.d.ts +92 -0
  135. package/dist/v2/patterns/RowFavoriteToggle.d.ts.map +1 -0
  136. package/dist/v2/patterns/RowFavoriteToggle.js +127 -0
  137. package/dist/v2/patterns/RowFavoriteToggle.js.map +1 -0
  138. package/dist/v2/patterns/_pickerSerialisation.d.ts +44 -0
  139. package/dist/v2/patterns/_pickerSerialisation.d.ts.map +1 -0
  140. package/dist/v2/patterns/_pickerSerialisation.js +81 -0
  141. package/dist/v2/patterns/_pickerSerialisation.js.map +1 -0
  142. package/dist/v2/patterns/index.d.ts +87 -0
  143. package/dist/v2/patterns/index.d.ts.map +1 -1
  144. package/dist/v2/patterns/index.js +34 -0
  145. package/dist/v2/patterns/index.js.map +1 -1
  146. package/dist/v2/personalization/capabilities/gridPreferences.d.ts +100 -0
  147. package/dist/v2/personalization/capabilities/gridPreferences.d.ts.map +1 -0
  148. package/dist/v2/personalization/capabilities/gridPreferences.js +215 -0
  149. package/dist/v2/personalization/capabilities/gridPreferences.js.map +1 -0
  150. package/dist/v2/personalization/capabilities/index.d.ts +6 -0
  151. package/dist/v2/personalization/capabilities/index.d.ts.map +1 -1
  152. package/dist/v2/personalization/capabilities/index.js +13 -0
  153. package/dist/v2/personalization/capabilities/index.js.map +1 -1
  154. package/dist/v2/personalization/index.d.ts +18 -0
  155. package/dist/v2/personalization/index.d.ts.map +1 -1
  156. package/dist/v2/personalization/index.js +13 -0
  157. package/dist/v2/personalization/index.js.map +1 -1
  158. package/package.json +1 -1
@@ -120,12 +120,31 @@ function KeyboardShortcutsHelp(_ref2) {
120
120
  shortcuts = _ref2$shortcuts === void 0 ? [] : _ref2$shortcuts,
121
121
  _ref2$title = _ref2.title,
122
122
  title = _ref2$title === void 0 ? "Raccourcis clavier" : _ref2$title,
123
- labels = _ref2.labels;
123
+ labels = _ref2.labels,
124
+ open = _ref2.open,
125
+ onOpenChange = _ref2.onOpenChange;
124
126
  var _React$useState = React.useState(false),
125
127
  _React$useState2 = _slicedToArray(_React$useState, 2),
126
- isOpen = _React$useState2[0],
127
- setIsOpen = _React$useState2[1];
128
+ uncontrolledOpen = _React$useState2[0],
129
+ setUncontrolledOpen = _React$useState2[1];
130
+ var isControlled = open !== undefined;
131
+ var isOpen = isControlled ? open : uncontrolledOpen;
128
132
  var L = (0, _mergeLabels.mergeLabels)(DEFAULT_LABELS, labels);
133
+
134
+ /* Refs so the "?" listener can stay on a `[]` dependency list — it must not
135
+ * be torn down and re-added on every open/close, and in controlled mode there
136
+ * is no functional-update form to fall back on. */
137
+ var isOpenRef = React.useRef(isOpen);
138
+ isOpenRef.current = isOpen;
139
+ var onOpenChangeRef = React.useRef(onOpenChange);
140
+ onOpenChangeRef.current = onOpenChange;
141
+ var isControlledRef = React.useRef(isControlled);
142
+ isControlledRef.current = isControlled;
143
+ var requestOpen = React.useCallback(function (next) {
144
+ var _onOpenChangeRef$curr;
145
+ if (!isControlledRef.current) setUncontrolledOpen(next);
146
+ (_onOpenChangeRef$curr = onOpenChangeRef.current) === null || _onOpenChangeRef$curr === void 0 ? void 0 : _onOpenChangeRef$curr.call(onOpenChangeRef, next);
147
+ }, []);
129
148
  React.useEffect(function () {
130
149
  var handler = function handler(event) {
131
150
  // Only react to "?" (Shift+/ on US, AltGr+, on many AZERTY layouts).
@@ -138,15 +157,13 @@ function KeyboardShortcutsHelp(_ref2) {
138
157
  // User is typing in a text field — let "?" through.
139
158
  if (isFocusOnTextEntry()) return;
140
159
  event.preventDefault();
141
- setIsOpen(function (prev) {
142
- return !prev;
143
- });
160
+ requestOpen(!isOpenRef.current);
144
161
  };
145
162
  window.addEventListener("keydown", handler);
146
163
  return function () {
147
164
  return window.removeEventListener("keydown", handler);
148
165
  };
149
- }, []);
166
+ }, [requestOpen]);
150
167
  if (!Array.isArray(shortcuts) || shortcuts.length === 0) {
151
168
  return null;
152
169
  }
@@ -154,7 +171,7 @@ function KeyboardShortcutsHelp(_ref2) {
154
171
  open: isOpen,
155
172
  title: title,
156
173
  onClose: function onClose() {
157
- return setIsOpen(false);
174
+ return requestOpen(false);
158
175
  },
159
176
  size: "md",
160
177
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("dl", {
@@ -1 +1 @@
1
- {"version":3,"file":"KeyboardShortcutsHelp.js","names":["React","_interopRequireWildcard","require","_Modal","_interopRequireDefault","_mergeLabels","_jsxRuntime","obj","__esModule","_getRequireWildcardCache","nodeInterop","WeakMap","cacheBabelInterop","cacheNodeInterop","_typeof","cache","has","get","newObj","hasPropertyDescriptor","Object","defineProperty","getOwnPropertyDescriptor","key","prototype","hasOwnProperty","call","desc","set","_slicedToArray","arr","i","_arrayWithHoles","_iterableToArrayLimit","_unsupportedIterableToArray","_nonIterableRest","TypeError","o","minLen","_arrayLikeToArray","n","toString","slice","constructor","name","Array","from","test","len","length","arr2","_i","Symbol","iterator","_s","_e","_x","_r","_arr","_n","_d","next","done","push","value","err","isArray","isFocusOnTextEntry","el","document","activeElement","tag","tagName","HTMLElement","isContentEditable","ShortcutKey","_ref","children","jsx","style","display","minWidth","padding","background","border","borderBottomColor","borderRadius","boxShadow","fontFamily","fontSize","textAlign","lineHeight","color","SHORTCUT_ROW_SX","gridTemplateColumns","gap","alignItems","borderBottom","SHORTCUT_KEYS_SX","flexWrap","HELP_FOOTNOTE_SX","marginTop","paddingTop","borderTop","DEFAULT_LABELS","freeze","footnoteIntro","footnoteOutro","listAriaLabel","keyJoiner","KeyboardShortcutsHelp","_ref2","_ref2$shortcuts","shortcuts","_ref2$title","title","labels","_React$useState","useState","_React$useState2","isOpen","setIsOpen","L","mergeLabels","useEffect","handler","event","ctrlKey","metaKey","altKey","preventDefault","prev","window","addEventListener","removeEventListener","jsxs","open","onClose","size","margin","map","sc","keys","k","j","Fragment","description","_default","exports"],"sources":["../../../src/lib/v2/patterns/KeyboardShortcutsHelp.tsx"],"sourcesContent":["import * as React from \"react\";\r\nimport Modal from \"../components/Modal\";\r\nimport { mergeLabels } from \"../utils/mergeLabels\";\r\n\r\n/* ── Body-only focus guard ────────────────────────────────────────\r\n * The \"?\" key is a printable character. If a user types \"?\" inside an\r\n * Input / Textarea / contentEditable element we must NOT hijack the\r\n * keypress to open the help — they're trying to type a question mark.\r\n *\r\n * BUTTON / A focus is NOT blocking by design: when the user has tabbed\r\n * onto an interactive non-text element, hitting \"?\" makes sense as a\r\n * help affordance (navigation mode, not text-entry mode).\r\n */\r\nfunction isFocusOnTextEntry(): boolean {\r\n const el = typeof document !== \"undefined\" ? document.activeElement : null;\r\n if (!el) return false;\r\n const tag = el.tagName;\r\n if (tag === \"INPUT\" || tag === \"TEXTAREA\" || tag === \"SELECT\") return true;\r\n if (el instanceof HTMLElement && el.isContentEditable) return true;\r\n return false;\r\n}\r\n\r\nfunction ShortcutKey({ children }: { children?: React.ReactNode }) {\r\n return (\r\n <kbd\r\n style={{\r\n display: \"inline-block\",\r\n minWidth: \"1.75em\",\r\n padding: \"0.15em 0.5em\",\r\n background: \"var(--bg-subtle)\",\r\n border: \"1px solid var(--border)\",\r\n borderBottomColor: \"var(--border-strong, var(--border))\",\r\n borderRadius: \"var(--r-sm)\",\r\n boxShadow: \"inset 0 -1px 0 var(--border)\",\r\n fontFamily: \"var(--font-mono, monospace)\",\r\n fontSize: \"var(--text-sm)\",\r\n textAlign: \"center\",\r\n lineHeight: 1.4,\r\n color: \"var(--fg)\",\r\n }}\r\n >\r\n {children}\r\n </kbd>\r\n );\r\n}\r\n\r\nconst SHORTCUT_ROW_SX: React.CSSProperties = {\r\n display: \"grid\",\r\n gridTemplateColumns: \"auto 1fr\",\r\n gap: \"var(--s-4)\",\r\n alignItems: \"center\",\r\n padding: \"var(--s-2) 0\",\r\n borderBottom: \"1px solid var(--border-subtle, var(--border))\",\r\n};\r\n\r\nconst SHORTCUT_KEYS_SX: React.CSSProperties = {\r\n display: \"flex\",\r\n gap: \"var(--s-1)\",\r\n alignItems: \"center\",\r\n flexWrap: \"wrap\",\r\n};\r\n\r\nconst HELP_FOOTNOTE_SX: React.CSSProperties = {\r\n marginTop: \"var(--s-4)\",\r\n paddingTop: \"var(--s-3)\",\r\n borderTop: \"1px solid var(--border)\",\r\n fontSize: \"var(--text-xs)\",\r\n color: \"var(--fg-subtle)\",\r\n lineHeight: 1.5,\r\n};\r\n\r\nconst DEFAULT_LABELS = Object.freeze({\r\n /* Footnote rendered below the shortcut list. Split into two parts so the\r\n * keycap can be embedded in the middle without forcing the i18n string to\r\n * carry HTML tags. */\r\n footnoteIntro: \"Astuce : appuyez sur\",\r\n footnoteOutro:\r\n \"à tout moment pour ouvrir ou fermer cette aide. Les raccourcis s'activent uniquement quand votre curseur n'est pas dans un champ de saisie.\",\r\n /* aria-label on the <dl> listing every shortcut. */\r\n listAriaLabel: \"Liste des raccourcis clavier disponibles sur cette page\",\r\n /* Joiner rendered between alternative keys for the same shortcut. */\r\n keyJoiner: \"ou\",\r\n});\r\n\r\n/**\r\n * KeyboardShortcutsHelp — Portnet UI v2\r\n *\r\n * Charter §5.2 SHOULD — discoverable help overlay for page-level keyboard\r\n * shortcuts. Listens globally for \"?\" and opens a v2.Modal listing every\r\n * shortcut as <kbd> elements (WCAG 1.3.1 semantic).\r\n *\r\n * Self-contained: the host page only declares the shortcuts array and renders\r\n * <KeyboardShortcutsHelp shortcuts={…} /> once.\r\n *\r\n * Localisation (FR / EN / AR):\r\n * <KeyboardShortcutsHelp\r\n * title=\"Keyboard shortcuts\"\r\n * labels={{\r\n * footnoteIntro: \"Tip: press\",\r\n * footnoteOutro: \"anytime to toggle this help…\",\r\n * listAriaLabel: \"List of keyboard shortcuts available on this page\",\r\n * keyJoiner: \"or\",\r\n * }}\r\n * shortcuts={…}\r\n * />\r\n *\r\n * Charter §5.2 SHOULD + WCAG 1.3.1 (semantic <kbd>) + 2.1.1 (keyboard\r\n * reachable) + R-M.* (modal focus trap inherited from v2.Modal).\r\n */\r\n\r\nexport interface KeyboardShortcut {\r\n keys: string[];\r\n description: React.ReactNode;\r\n}\r\n\r\nexport interface KeyboardShortcutsHelpLabels {\r\n footnoteIntro?: string | undefined;\r\n footnoteOutro?: string | undefined;\r\n listAriaLabel?: string | undefined;\r\n keyJoiner?: string | undefined;\r\n}\r\n\r\nexport interface KeyboardShortcutsHelpProps {\r\n shortcuts?: KeyboardShortcut[] | undefined;\r\n title?: React.ReactNode | undefined;\r\n labels?: KeyboardShortcutsHelpLabels | undefined;\r\n}\r\n\r\nfunction KeyboardShortcutsHelp({\r\n shortcuts = [],\r\n title = \"Raccourcis clavier\",\r\n labels,\r\n}: KeyboardShortcutsHelpProps) {\r\n const [isOpen, setIsOpen] = React.useState(false);\r\n const L = mergeLabels(DEFAULT_LABELS, labels);\r\n\r\n React.useEffect(() => {\r\n const handler = (event: KeyboardEvent) => {\r\n // Only react to \"?\" (Shift+/ on US, AltGr+, on many AZERTY layouts).\r\n // event.key gives us the resolved character regardless of physical key.\r\n if (event.key !== \"?\") return;\r\n\r\n // Modifier keys (Ctrl, Meta, Alt) reserved for browser / OS shortcuts.\r\n if (event.ctrlKey || event.metaKey || event.altKey) return;\r\n\r\n // User is typing in a text field — let \"?\" through.\r\n if (isFocusOnTextEntry()) return;\r\n\r\n event.preventDefault();\r\n setIsOpen((prev) => !prev);\r\n };\r\n\r\n window.addEventListener(\"keydown\", handler);\r\n return () => window.removeEventListener(\"keydown\", handler);\r\n }, []);\r\n\r\n if (!Array.isArray(shortcuts) || shortcuts.length === 0) {\r\n return null;\r\n }\r\n\r\n return (\r\n <Modal open={isOpen} title={title} onClose={() => setIsOpen(false)} size=\"md\">\r\n <dl style={{ margin: 0, padding: 0 }} aria-label={L.listAriaLabel}>\r\n {shortcuts.map((sc, i) => (\r\n <div key={i} style={SHORTCUT_ROW_SX}>\r\n <dt style={SHORTCUT_KEYS_SX}>\r\n {sc.keys.map((k, j) => (\r\n <React.Fragment key={j}>\r\n <ShortcutKey>{k}</ShortcutKey>\r\n {j < sc.keys.length - 1 && (\r\n <span\r\n aria-hidden=\"true\"\r\n style={{\r\n color: \"var(--fg-subtle)\",\r\n fontSize: \"var(--text-xs)\",\r\n }}\r\n >\r\n {L.keyJoiner}\r\n </span>\r\n )}\r\n </React.Fragment>\r\n ))}\r\n </dt>\r\n <dd style={{ margin: 0, fontSize: \"var(--text-body)\" }}>\r\n {sc.description}\r\n </dd>\r\n </div>\r\n ))}\r\n </dl>\r\n <div style={HELP_FOOTNOTE_SX}>\r\n {L.footnoteIntro}{\" \"}\r\n <ShortcutKey>?</ShortcutKey>{\" \"}\r\n {L.footnoteOutro}\r\n </div>\r\n </Modal>\r\n );\r\n}\r\n\r\nexport default KeyboardShortcutsHelp;\r\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"KeyboardShortcutsHelp.js","names":["React","_interopRequireWildcard","require","_Modal","_interopRequireDefault","_mergeLabels","_jsxRuntime","obj","__esModule","_getRequireWildcardCache","nodeInterop","WeakMap","cacheBabelInterop","cacheNodeInterop","_typeof","cache","has","get","newObj","hasPropertyDescriptor","Object","defineProperty","getOwnPropertyDescriptor","key","prototype","hasOwnProperty","call","desc","set","_slicedToArray","arr","i","_arrayWithHoles","_iterableToArrayLimit","_unsupportedIterableToArray","_nonIterableRest","TypeError","o","minLen","_arrayLikeToArray","n","toString","slice","constructor","name","Array","from","test","len","length","arr2","_i","Symbol","iterator","_s","_e","_x","_r","_arr","_n","_d","next","done","push","value","err","isArray","isFocusOnTextEntry","el","document","activeElement","tag","tagName","HTMLElement","isContentEditable","ShortcutKey","_ref","children","jsx","style","display","minWidth","padding","background","border","borderBottomColor","borderRadius","boxShadow","fontFamily","fontSize","textAlign","lineHeight","color","SHORTCUT_ROW_SX","gridTemplateColumns","gap","alignItems","borderBottom","SHORTCUT_KEYS_SX","flexWrap","HELP_FOOTNOTE_SX","marginTop","paddingTop","borderTop","DEFAULT_LABELS","freeze","footnoteIntro","footnoteOutro","listAriaLabel","keyJoiner","KeyboardShortcutsHelp","_ref2","_ref2$shortcuts","shortcuts","_ref2$title","title","labels","open","onOpenChange","_React$useState","useState","_React$useState2","uncontrolledOpen","setUncontrolledOpen","isControlled","undefined","isOpen","L","mergeLabels","isOpenRef","useRef","current","onOpenChangeRef","isControlledRef","requestOpen","useCallback","_onOpenChangeRef$curr","useEffect","handler","event","ctrlKey","metaKey","altKey","preventDefault","window","addEventListener","removeEventListener","jsxs","onClose","size","margin","map","sc","keys","k","j","Fragment","description","_default","exports"],"sources":["../../../src/lib/v2/patterns/KeyboardShortcutsHelp.tsx"],"sourcesContent":["import * as React from \"react\";\r\nimport Modal from \"../components/Modal\";\r\nimport { mergeLabels } from \"../utils/mergeLabels\";\r\n\r\n/* ── Body-only focus guard ────────────────────────────────────────\r\n * The \"?\" key is a printable character. If a user types \"?\" inside an\r\n * Input / Textarea / contentEditable element we must NOT hijack the\r\n * keypress to open the help — they're trying to type a question mark.\r\n *\r\n * BUTTON / A focus is NOT blocking by design: when the user has tabbed\r\n * onto an interactive non-text element, hitting \"?\" makes sense as a\r\n * help affordance (navigation mode, not text-entry mode).\r\n */\r\nfunction isFocusOnTextEntry(): boolean {\r\n const el = typeof document !== \"undefined\" ? document.activeElement : null;\r\n if (!el) return false;\r\n const tag = el.tagName;\r\n if (tag === \"INPUT\" || tag === \"TEXTAREA\" || tag === \"SELECT\") return true;\r\n if (el instanceof HTMLElement && el.isContentEditable) return true;\r\n return false;\r\n}\r\n\r\nfunction ShortcutKey({ children }: { children?: React.ReactNode }) {\r\n return (\r\n <kbd\r\n style={{\r\n display: \"inline-block\",\r\n minWidth: \"1.75em\",\r\n padding: \"0.15em 0.5em\",\r\n background: \"var(--bg-subtle)\",\r\n border: \"1px solid var(--border)\",\r\n borderBottomColor: \"var(--border-strong, var(--border))\",\r\n borderRadius: \"var(--r-sm)\",\r\n boxShadow: \"inset 0 -1px 0 var(--border)\",\r\n fontFamily: \"var(--font-mono, monospace)\",\r\n fontSize: \"var(--text-sm)\",\r\n textAlign: \"center\",\r\n lineHeight: 1.4,\r\n color: \"var(--fg)\",\r\n }}\r\n >\r\n {children}\r\n </kbd>\r\n );\r\n}\r\n\r\nconst SHORTCUT_ROW_SX: React.CSSProperties = {\r\n display: \"grid\",\r\n gridTemplateColumns: \"auto 1fr\",\r\n gap: \"var(--s-4)\",\r\n alignItems: \"center\",\r\n padding: \"var(--s-2) 0\",\r\n borderBottom: \"1px solid var(--border-subtle, var(--border))\",\r\n};\r\n\r\nconst SHORTCUT_KEYS_SX: React.CSSProperties = {\r\n display: \"flex\",\r\n gap: \"var(--s-1)\",\r\n alignItems: \"center\",\r\n flexWrap: \"wrap\",\r\n};\r\n\r\nconst HELP_FOOTNOTE_SX: React.CSSProperties = {\r\n marginTop: \"var(--s-4)\",\r\n paddingTop: \"var(--s-3)\",\r\n borderTop: \"1px solid var(--border)\",\r\n fontSize: \"var(--text-xs)\",\r\n color: \"var(--fg-subtle)\",\r\n lineHeight: 1.5,\r\n};\r\n\r\nconst DEFAULT_LABELS = Object.freeze({\r\n /* Footnote rendered below the shortcut list. Split into two parts so the\r\n * keycap can be embedded in the middle without forcing the i18n string to\r\n * carry HTML tags. */\r\n footnoteIntro: \"Astuce : appuyez sur\",\r\n footnoteOutro:\r\n \"à tout moment pour ouvrir ou fermer cette aide. Les raccourcis s'activent uniquement quand votre curseur n'est pas dans un champ de saisie.\",\r\n /* aria-label on the <dl> listing every shortcut. */\r\n listAriaLabel: \"Liste des raccourcis clavier disponibles sur cette page\",\r\n /* Joiner rendered between alternative keys for the same shortcut. */\r\n keyJoiner: \"ou\",\r\n});\r\n\r\n/**\r\n * KeyboardShortcutsHelp — Portnet UI v2\r\n *\r\n * Charter §5.2 SHOULD — discoverable help overlay for page-level keyboard\r\n * shortcuts. Listens globally for \"?\" and opens a v2.Modal listing every\r\n * shortcut as <kbd> elements (WCAG 1.3.1 semantic).\r\n *\r\n * Self-contained: the host page only declares the shortcuts array and renders\r\n * <KeyboardShortcutsHelp shortcuts={…} /> once.\r\n *\r\n * Localisation (FR / EN / AR):\r\n * <KeyboardShortcutsHelp\r\n * title=\"Keyboard shortcuts\"\r\n * labels={{\r\n * footnoteIntro: \"Tip: press\",\r\n * footnoteOutro: \"anytime to toggle this help…\",\r\n * listAriaLabel: \"List of keyboard shortcuts available on this page\",\r\n * keyJoiner: \"or\",\r\n * }}\r\n * shortcuts={…}\r\n * />\r\n *\r\n * Charter §5.2 SHOULD + WCAG 1.3.1 (semantic <kbd>) + 2.1.1 (keyboard\r\n * reachable) + R-M.* (modal focus trap inherited from v2.Modal).\r\n */\r\n\r\nexport interface KeyboardShortcut {\r\n keys: string[];\r\n description: React.ReactNode;\r\n}\r\n\r\nexport interface KeyboardShortcutsHelpLabels {\r\n footnoteIntro?: string | undefined;\r\n footnoteOutro?: string | undefined;\r\n listAriaLabel?: string | undefined;\r\n keyJoiner?: string | undefined;\r\n}\r\n\r\nexport interface KeyboardShortcutsHelpProps {\r\n shortcuts?: KeyboardShortcut[] | undefined;\r\n title?: React.ReactNode | undefined;\r\n labels?: KeyboardShortcutsHelpLabels | undefined;\r\n /**\r\n * Optional CONTROLLED open state. Omit for the original self-contained\r\n * behaviour (the \"?\" listener owns the state).\r\n *\r\n * Added because the panel had no trigger but the keystroke. Hosts wired it\r\n * correctly and users still reported the shortcuts \"missing\" — they are, in\r\n * every practical sense, if the only affordance is a key you have to already\r\n * know about. Charter §05.2 asks for DISCOVERABLE help, and a host cannot add\r\n * a menu item or button without being able to open this.\r\n */\r\n open?: boolean | undefined;\r\n /** Called with the requested next state, for both \"?\" and the close button. */\r\n onOpenChange?: ((open: boolean) => void) | undefined;\r\n}\r\n\r\nfunction KeyboardShortcutsHelp({\r\n shortcuts = [],\r\n title = \"Raccourcis clavier\",\r\n labels,\r\n open,\r\n onOpenChange,\r\n}: KeyboardShortcutsHelpProps) {\r\n const [uncontrolledOpen, setUncontrolledOpen] = React.useState(false);\r\n const isControlled = open !== undefined;\r\n const isOpen = isControlled ? open : uncontrolledOpen;\r\n const L = mergeLabels(DEFAULT_LABELS, labels);\r\n\r\n /* Refs so the \"?\" listener can stay on a `[]` dependency list — it must not\r\n * be torn down and re-added on every open/close, and in controlled mode there\r\n * is no functional-update form to fall back on. */\r\n const isOpenRef = React.useRef(isOpen);\r\n isOpenRef.current = isOpen;\r\n const onOpenChangeRef = React.useRef(onOpenChange);\r\n onOpenChangeRef.current = onOpenChange;\r\n const isControlledRef = React.useRef(isControlled);\r\n isControlledRef.current = isControlled;\r\n\r\n const requestOpen = React.useCallback((next: boolean) => {\r\n if (!isControlledRef.current) setUncontrolledOpen(next);\r\n onOpenChangeRef.current?.(next);\r\n }, []);\r\n\r\n React.useEffect(() => {\r\n const handler = (event: KeyboardEvent) => {\r\n // Only react to \"?\" (Shift+/ on US, AltGr+, on many AZERTY layouts).\r\n // event.key gives us the resolved character regardless of physical key.\r\n if (event.key !== \"?\") return;\r\n\r\n // Modifier keys (Ctrl, Meta, Alt) reserved for browser / OS shortcuts.\r\n if (event.ctrlKey || event.metaKey || event.altKey) return;\r\n\r\n // User is typing in a text field — let \"?\" through.\r\n if (isFocusOnTextEntry()) return;\r\n\r\n event.preventDefault();\r\n requestOpen(!isOpenRef.current);\r\n };\r\n\r\n window.addEventListener(\"keydown\", handler);\r\n return () => window.removeEventListener(\"keydown\", handler);\r\n }, [requestOpen]);\r\n\r\n if (!Array.isArray(shortcuts) || shortcuts.length === 0) {\r\n return null;\r\n }\r\n\r\n return (\r\n <Modal\r\n open={isOpen}\r\n title={title}\r\n onClose={() => requestOpen(false)}\r\n size=\"md\"\r\n >\r\n <dl style={{ margin: 0, padding: 0 }} aria-label={L.listAriaLabel}>\r\n {shortcuts.map((sc, i) => (\r\n <div key={i} style={SHORTCUT_ROW_SX}>\r\n <dt style={SHORTCUT_KEYS_SX}>\r\n {sc.keys.map((k, j) => (\r\n <React.Fragment key={j}>\r\n <ShortcutKey>{k}</ShortcutKey>\r\n {j < sc.keys.length - 1 && (\r\n <span\r\n aria-hidden=\"true\"\r\n style={{\r\n color: \"var(--fg-subtle)\",\r\n fontSize: \"var(--text-xs)\",\r\n }}\r\n >\r\n {L.keyJoiner}\r\n </span>\r\n )}\r\n </React.Fragment>\r\n ))}\r\n </dt>\r\n <dd style={{ margin: 0, fontSize: \"var(--text-body)\" }}>\r\n {sc.description}\r\n </dd>\r\n </div>\r\n ))}\r\n </dl>\r\n <div style={HELP_FOOTNOTE_SX}>\r\n {L.footnoteIntro}{\" \"}\r\n <ShortcutKey>?</ShortcutKey>{\" \"}\r\n {L.footnoteOutro}\r\n </div>\r\n </Modal>\r\n );\r\n}\r\n\r\nexport default KeyboardShortcutsHelp;\r\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,92 @@
1
+ import * as React from "react";
2
+ import FavoriteToggle from "../components/FavoriteToggle";
3
+ import type { RowId } from "../types/common";
4
+ /**
5
+ * RowFavoriteToggle — Portnet UI v2 (pattern)
6
+ *
7
+ * A store-connected follow star for ONE row. Reads `useIsFavorite`, renders
8
+ * `FavoriteToggle`, and stops its own click/keydown from reaching the row's
9
+ * `onRowClick`.
10
+ *
11
+ * ─────────────────────────────────────────────────────────────────────────────
12
+ * WHY THIS BELONGS IN THE LIBRARY (capability gap G-36)
13
+ *
14
+ * This exact component already existed — as `FavoriteCell`, private inside
15
+ * `makeFavoriteColumn`. So the follow star was reachable in ONE context only:
16
+ * as a DataGrid column. Every other place a row appears had to rebuild it.
17
+ *
18
+ * The place that always appears is the MOBILE CARD. `DataGrid` swaps to
19
+ * `renderMobileCard` below its `mobileBreakpoint`, and `MobileRowCard` has a
20
+ * `leading` slot precisely for a per-row control — but a column definition
21
+ * cannot be rendered into a slot, so the host had to re-derive the star by
22
+ * hand. Observed in `onssa-export-fe` as a local `MobileFavoriteToggle`, and
23
+ * `ms-ti-fe` destructures the identical `MobileRowCard` + `FavoriteToggle` +
24
+ * `useIsFavorite` trio for the same reason.
25
+ *
26
+ * This is the same failure mode G-10 recorded for the card recipe welded
27
+ * inside `FormSection`: the library owned the behaviour but exposed it at only
28
+ * one composition point, so consumers reimplemented it at the others. And it
29
+ * was not a harmless copy — the local twin drifted on the part that matters
30
+ * least visibly and most to a screen-reader user. It labelled itself
31
+ * "Ajouter aux favoris" / "Retirer des favoris" while the grid column on the
32
+ * SAME page said "Suivre" / "Ne plus suivre", and it omitted the status
33
+ * Tooltip entirely. One list, one control, two accessible names, depending on
34
+ * viewport width — exactly what R-2.1 forbids.
35
+ *
36
+ * `makeFavoriteColumn` now renders this component, so the desktop column and
37
+ * the mobile card are guaranteed to agree by construction rather than by
38
+ * review.
39
+ * ─────────────────────────────────────────────────────────────────────────────
40
+ *
41
+ * Usage — mobile card `leading` slot:
42
+ *
43
+ * <MobileRowCard
44
+ * leading={
45
+ * <RowFavoriteToggle
46
+ * resourceKey="ti:list"
47
+ * rowId={row.reference}
48
+ * rowLabel={row.reference}
49
+ * />
50
+ * }
51
+ * title={row.reference}
52
+ * … />
53
+ *
54
+ * a11y. The accessible name is ACTION-oriented ("Suivre" / "Ne plus suivre",
55
+ * optionally enriched with `rowLabel`) because that is the toggle convention;
56
+ * `aria-pressed` — set by `FavoriteToggle` — carries the state. The visible
57
+ * status ("Suivi" / "Non suivi") is shown as a Tooltip on hover/focus. An
58
+ * `aria-label` is therefore ALWAYS supplied, which also stops Tooltip from
59
+ * mirroring its title onto the trigger and producing a doubled name.
60
+ *
61
+ * Requires a <UserPersonalizationProvider> ancestor (`useIsFavorite` throws
62
+ * otherwise). `rowId` MUST be the same id the grid uses, so the follow and the
63
+ * row agree.
64
+ */
65
+ /** `FavoriteToggle`'s own size union, re-derived rather than restated. */
66
+ export type FavoriteToggleSize = NonNullable<React.ComponentProps<typeof FavoriteToggle>["size"]>;
67
+ export interface RowFavoriteToggleLabels {
68
+ addFavorite: string;
69
+ removeFavorite: string;
70
+ statusFollowed: string;
71
+ statusNotFollowed: string;
72
+ }
73
+ export declare const DEFAULT_ROW_FAVORITE_LABELS: Readonly<{
74
+ addFavorite: string;
75
+ removeFavorite: string;
76
+ statusFollowed: string;
77
+ statusNotFollowed: string;
78
+ }>;
79
+ export interface RowFavoriteToggleProps {
80
+ /** Follow namespace — must match the list's other personalization calls. */
81
+ resourceKey: string;
82
+ /** Business row id. MUST match the grid's `getRowId` for this row. */
83
+ rowId: RowId;
84
+ /** Enriches the per-row accessible name ("Suivre : 2025-IM-0042"). */
85
+ rowLabel?: string | undefined;
86
+ /** @default "sm" — fits dense rows and card leading slots. */
87
+ size?: FavoriteToggleSize | undefined;
88
+ labels?: Partial<RowFavoriteToggleLabels> | undefined;
89
+ }
90
+ declare function RowFavoriteToggle(props: RowFavoriteToggleProps): React.JSX.Element;
91
+ export default RowFavoriteToggle;
92
+ //# sourceMappingURL=RowFavoriteToggle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RowFavoriteToggle.d.ts","sourceRoot":"","sources":["../../../src/lib/v2/patterns/RowFavoriteToggle.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,cAAc,MAAM,8BAA8B,CAAC;AAG1D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAE7C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4DG;AAEH,0EAA0E;AAC1E,MAAM,MAAM,kBAAkB,GAAG,WAAW,CAC1C,KAAK,CAAC,cAAc,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CACpD,CAAC;AAEF,MAAM,WAAW,uBAAuB;IACtC,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAED,eAAO,MAAM,2BAA2B;;;;;EAKJ,CAAC;AAErC,MAAM,WAAW,sBAAsB;IACrC,4EAA4E;IAC5E,WAAW,EAAE,MAAM,CAAC;IACpB,sEAAsE;IACtE,KAAK,EAAE,KAAK,CAAC;IACb,sEAAsE;IACtE,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,8DAA8D;IAC9D,IAAI,CAAC,EAAE,kBAAkB,GAAG,SAAS,CAAC;IACtC,MAAM,CAAC,EAAE,OAAO,CAAC,uBAAuB,CAAC,GAAG,SAAS,CAAC;CACvD;AAED,iBAAS,iBAAiB,CAAC,KAAK,EAAE,sBAAsB,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CAuC3E;AAED,eAAe,iBAAiB,CAAC"}
@@ -0,0 +1,127 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports["default"] = exports.DEFAULT_ROW_FAVORITE_LABELS = void 0;
7
+ var React = _interopRequireWildcard(require("react"));
8
+ var _FavoriteToggle = _interopRequireDefault(require("../components/FavoriteToggle"));
9
+ var _Tooltip = _interopRequireDefault(require("../components/Tooltip"));
10
+ var _favorites = require("../personalization/capabilities/favorites");
11
+ var _jsxRuntime = require("react/jsx-runtime");
12
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
13
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
14
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
15
+ function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
16
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
17
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
18
+ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
19
+ function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); }
20
+ function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); } /**
21
+ * RowFavoriteToggle — Portnet UI v2 (pattern)
22
+ *
23
+ * A store-connected follow star for ONE row. Reads `useIsFavorite`, renders
24
+ * `FavoriteToggle`, and stops its own click/keydown from reaching the row's
25
+ * `onRowClick`.
26
+ *
27
+ * ─────────────────────────────────────────────────────────────────────────────
28
+ * WHY THIS BELONGS IN THE LIBRARY (capability gap G-36)
29
+ *
30
+ * This exact component already existed — as `FavoriteCell`, private inside
31
+ * `makeFavoriteColumn`. So the follow star was reachable in ONE context only:
32
+ * as a DataGrid column. Every other place a row appears had to rebuild it.
33
+ *
34
+ * The place that always appears is the MOBILE CARD. `DataGrid` swaps to
35
+ * `renderMobileCard` below its `mobileBreakpoint`, and `MobileRowCard` has a
36
+ * `leading` slot precisely for a per-row control — but a column definition
37
+ * cannot be rendered into a slot, so the host had to re-derive the star by
38
+ * hand. Observed in `onssa-export-fe` as a local `MobileFavoriteToggle`, and
39
+ * `ms-ti-fe` destructures the identical `MobileRowCard` + `FavoriteToggle` +
40
+ * `useIsFavorite` trio for the same reason.
41
+ *
42
+ * This is the same failure mode G-10 recorded for the card recipe welded
43
+ * inside `FormSection`: the library owned the behaviour but exposed it at only
44
+ * one composition point, so consumers reimplemented it at the others. And it
45
+ * was not a harmless copy — the local twin drifted on the part that matters
46
+ * least visibly and most to a screen-reader user. It labelled itself
47
+ * "Ajouter aux favoris" / "Retirer des favoris" while the grid column on the
48
+ * SAME page said "Suivre" / "Ne plus suivre", and it omitted the status
49
+ * Tooltip entirely. One list, one control, two accessible names, depending on
50
+ * viewport width — exactly what R-2.1 forbids.
51
+ *
52
+ * `makeFavoriteColumn` now renders this component, so the desktop column and
53
+ * the mobile card are guaranteed to agree by construction rather than by
54
+ * review.
55
+ * ─────────────────────────────────────────────────────────────────────────────
56
+ *
57
+ * Usage — mobile card `leading` slot:
58
+ *
59
+ * <MobileRowCard
60
+ * leading={
61
+ * <RowFavoriteToggle
62
+ * resourceKey="ti:list"
63
+ * rowId={row.reference}
64
+ * rowLabel={row.reference}
65
+ * />
66
+ * }
67
+ * title={row.reference}
68
+ * … />
69
+ *
70
+ * a11y. The accessible name is ACTION-oriented ("Suivre" / "Ne plus suivre",
71
+ * optionally enriched with `rowLabel`) because that is the toggle convention;
72
+ * `aria-pressed` — set by `FavoriteToggle` — carries the state. The visible
73
+ * status ("Suivi" / "Non suivi") is shown as a Tooltip on hover/focus. An
74
+ * `aria-label` is therefore ALWAYS supplied, which also stops Tooltip from
75
+ * mirroring its title onto the trigger and producing a doubled name.
76
+ *
77
+ * Requires a <UserPersonalizationProvider> ancestor (`useIsFavorite` throws
78
+ * otherwise). `rowId` MUST be the same id the grid uses, so the follow and the
79
+ * row agree.
80
+ */ /** `FavoriteToggle`'s own size union, re-derived rather than restated. */
81
+ var DEFAULT_ROW_FAVORITE_LABELS = exports.DEFAULT_ROW_FAVORITE_LABELS = Object.freeze({
82
+ addFavorite: "Suivre",
83
+ removeFavorite: "Ne plus suivre",
84
+ statusFollowed: "Suivi",
85
+ statusNotFollowed: "Non suivi"
86
+ });
87
+ function RowFavoriteToggle(props) {
88
+ var resourceKey = props.resourceKey,
89
+ rowId = props.rowId,
90
+ rowLabel = props.rowLabel,
91
+ _props$size = props.size,
92
+ size = _props$size === void 0 ? "sm" : _props$size,
93
+ labels = props.labels;
94
+ var L = labels ? _objectSpread(_objectSpread({}, DEFAULT_ROW_FAVORITE_LABELS), labels) : DEFAULT_ROW_FAVORITE_LABELS;
95
+ var _useIsFavorite = (0, _favorites.useIsFavorite)(resourceKey, rowId),
96
+ isFavorite = _useIsFavorite.isFavorite,
97
+ toggle = _useIsFavorite.toggle;
98
+ var action = isFavorite ? L.removeFavorite : L.addFavorite;
99
+ var ariaLabel = rowLabel ? action + " : " + rowLabel : action;
100
+ var statusLabel = isFavorite ? L.statusFollowed : L.statusNotFollowed;
101
+ var handleChange = function handleChange(_next, e) {
102
+ // Don't let the toggle's click bubble to the row's onRowClick.
103
+ if (e && typeof e.stopPropagation === "function") e.stopPropagation();
104
+ toggle();
105
+ };
106
+ var handleKeyDown = function handleKeyDown(e) {
107
+ // Prevent row-level Enter/Space (onRowClick) from also firing; the
108
+ // button's own native activation is unaffected.
109
+ e.stopPropagation();
110
+ };
111
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_Tooltip["default"], {
112
+ title: statusLabel,
113
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_FavoriteToggle["default"], {
114
+ pressed: isFavorite,
115
+ onChange: handleChange,
116
+ onKeyDown: handleKeyDown,
117
+ size: size,
118
+ labels: {
119
+ addFavorite: L.addFavorite,
120
+ removeFavorite: L.removeFavorite
121
+ },
122
+ "aria-label": ariaLabel
123
+ })
124
+ });
125
+ }
126
+ var _default = exports["default"] = RowFavoriteToggle;
127
+ //# sourceMappingURL=RowFavoriteToggle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RowFavoriteToggle.js","names":["React","_interopRequireWildcard","require","_FavoriteToggle","_interopRequireDefault","_Tooltip","_favorites","_jsxRuntime","obj","__esModule","_getRequireWildcardCache","nodeInterop","WeakMap","cacheBabelInterop","cacheNodeInterop","_typeof","cache","has","get","newObj","hasPropertyDescriptor","Object","defineProperty","getOwnPropertyDescriptor","key","prototype","hasOwnProperty","call","desc","set","Symbol","iterator","constructor","ownKeys","object","enumerableOnly","keys","getOwnPropertySymbols","symbols","filter","sym","enumerable","push","apply","_objectSpread","target","i","arguments","length","source","forEach","_defineProperty","getOwnPropertyDescriptors","defineProperties","value","_toPropertyKey","configurable","writable","arg","_toPrimitive","String","input","hint","prim","toPrimitive","undefined","res","TypeError","Number","DEFAULT_ROW_FAVORITE_LABELS","exports","freeze","addFavorite","removeFavorite","statusFollowed","statusNotFollowed","RowFavoriteToggle","props","resourceKey","rowId","rowLabel","_props$size","size","labels","L","_useIsFavorite","useIsFavorite","isFavorite","toggle","action","ariaLabel","statusLabel","handleChange","_next","e","stopPropagation","handleKeyDown","jsx","title","children","pressed","onChange","onKeyDown","_default"],"sources":["../../../src/lib/v2/patterns/RowFavoriteToggle.tsx"],"sourcesContent":["import * as React from \"react\";\r\n\r\nimport FavoriteToggle from \"../components/FavoriteToggle\";\r\nimport Tooltip from \"../components/Tooltip\";\r\nimport { useIsFavorite } from \"../personalization/capabilities/favorites\";\r\nimport type { RowId } from \"../types/common\";\r\n\r\n/**\r\n * RowFavoriteToggle — Portnet UI v2 (pattern)\r\n *\r\n * A store-connected follow star for ONE row. Reads `useIsFavorite`, renders\r\n * `FavoriteToggle`, and stops its own click/keydown from reaching the row's\r\n * `onRowClick`.\r\n *\r\n * ─────────────────────────────────────────────────────────────────────────────\r\n * WHY THIS BELONGS IN THE LIBRARY (capability gap G-36)\r\n *\r\n * This exact component already existed — as `FavoriteCell`, private inside\r\n * `makeFavoriteColumn`. So the follow star was reachable in ONE context only:\r\n * as a DataGrid column. Every other place a row appears had to rebuild it.\r\n *\r\n * The place that always appears is the MOBILE CARD. `DataGrid` swaps to\r\n * `renderMobileCard` below its `mobileBreakpoint`, and `MobileRowCard` has a\r\n * `leading` slot precisely for a per-row control — but a column definition\r\n * cannot be rendered into a slot, so the host had to re-derive the star by\r\n * hand. Observed in `onssa-export-fe` as a local `MobileFavoriteToggle`, and\r\n * `ms-ti-fe` destructures the identical `MobileRowCard` + `FavoriteToggle` +\r\n * `useIsFavorite` trio for the same reason.\r\n *\r\n * This is the same failure mode G-10 recorded for the card recipe welded\r\n * inside `FormSection`: the library owned the behaviour but exposed it at only\r\n * one composition point, so consumers reimplemented it at the others. And it\r\n * was not a harmless copy — the local twin drifted on the part that matters\r\n * least visibly and most to a screen-reader user. It labelled itself\r\n * \"Ajouter aux favoris\" / \"Retirer des favoris\" while the grid column on the\r\n * SAME page said \"Suivre\" / \"Ne plus suivre\", and it omitted the status\r\n * Tooltip entirely. One list, one control, two accessible names, depending on\r\n * viewport width — exactly what R-2.1 forbids.\r\n *\r\n * `makeFavoriteColumn` now renders this component, so the desktop column and\r\n * the mobile card are guaranteed to agree by construction rather than by\r\n * review.\r\n * ─────────────────────────────────────────────────────────────────────────────\r\n *\r\n * Usage — mobile card `leading` slot:\r\n *\r\n * <MobileRowCard\r\n * leading={\r\n * <RowFavoriteToggle\r\n * resourceKey=\"ti:list\"\r\n * rowId={row.reference}\r\n * rowLabel={row.reference}\r\n * />\r\n * }\r\n * title={row.reference}\r\n * … />\r\n *\r\n * a11y. The accessible name is ACTION-oriented (\"Suivre\" / \"Ne plus suivre\",\r\n * optionally enriched with `rowLabel`) because that is the toggle convention;\r\n * `aria-pressed` — set by `FavoriteToggle` — carries the state. The visible\r\n * status (\"Suivi\" / \"Non suivi\") is shown as a Tooltip on hover/focus. An\r\n * `aria-label` is therefore ALWAYS supplied, which also stops Tooltip from\r\n * mirroring its title onto the trigger and producing a doubled name.\r\n *\r\n * Requires a <UserPersonalizationProvider> ancestor (`useIsFavorite` throws\r\n * otherwise). `rowId` MUST be the same id the grid uses, so the follow and the\r\n * row agree.\r\n */\r\n\r\n/** `FavoriteToggle`'s own size union, re-derived rather than restated. */\r\nexport type FavoriteToggleSize = NonNullable<\r\n React.ComponentProps<typeof FavoriteToggle>[\"size\"]\r\n>;\r\n\r\nexport interface RowFavoriteToggleLabels {\r\n addFavorite: string;\r\n removeFavorite: string;\r\n statusFollowed: string;\r\n statusNotFollowed: string;\r\n}\r\n\r\nexport const DEFAULT_ROW_FAVORITE_LABELS = Object.freeze({\r\n addFavorite: \"Suivre\",\r\n removeFavorite: \"Ne plus suivre\",\r\n statusFollowed: \"Suivi\",\r\n statusNotFollowed: \"Non suivi\",\r\n} satisfies RowFavoriteToggleLabels);\r\n\r\nexport interface RowFavoriteToggleProps {\r\n /** Follow namespace — must match the list's other personalization calls. */\r\n resourceKey: string;\r\n /** Business row id. MUST match the grid's `getRowId` for this row. */\r\n rowId: RowId;\r\n /** Enriches the per-row accessible name (\"Suivre : 2025-IM-0042\"). */\r\n rowLabel?: string | undefined;\r\n /** @default \"sm\" — fits dense rows and card leading slots. */\r\n size?: FavoriteToggleSize | undefined;\r\n labels?: Partial<RowFavoriteToggleLabels> | undefined;\r\n}\r\n\r\nfunction RowFavoriteToggle(props: RowFavoriteToggleProps): React.JSX.Element {\r\n const { resourceKey, rowId, rowLabel, size = \"sm\", labels } = props;\r\n const L: RowFavoriteToggleLabels = labels\r\n ? { ...DEFAULT_ROW_FAVORITE_LABELS, ...labels }\r\n : DEFAULT_ROW_FAVORITE_LABELS;\r\n\r\n const { isFavorite, toggle } = useIsFavorite(resourceKey, rowId);\r\n\r\n const action = isFavorite ? L.removeFavorite : L.addFavorite;\r\n const ariaLabel = rowLabel ? action + \" : \" + rowLabel : action;\r\n const statusLabel = isFavorite ? L.statusFollowed : L.statusNotFollowed;\r\n\r\n const handleChange: NonNullable<\r\n React.ComponentProps<typeof FavoriteToggle>[\"onChange\"]\r\n > = function handleChange(_next, e) {\r\n // Don't let the toggle's click bubble to the row's onRowClick.\r\n if (e && typeof e.stopPropagation === \"function\") e.stopPropagation();\r\n toggle();\r\n };\r\n const handleKeyDown: NonNullable<\r\n React.ComponentProps<typeof FavoriteToggle>[\"onKeyDown\"]\r\n > = function handleKeyDown(e) {\r\n // Prevent row-level Enter/Space (onRowClick) from also firing; the\r\n // button's own native activation is unaffected.\r\n e.stopPropagation();\r\n };\r\n\r\n return (\r\n <Tooltip title={statusLabel}>\r\n <FavoriteToggle\r\n pressed={isFavorite}\r\n onChange={handleChange}\r\n onKeyDown={handleKeyDown}\r\n size={size}\r\n labels={{ addFavorite: L.addFavorite, removeFavorite: L.removeFavorite }}\r\n aria-label={ariaLabel}\r\n />\r\n </Tooltip>\r\n );\r\n}\r\n\r\nexport default RowFavoriteToggle;\r\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * _pickerSerialisation — lecture / ecriture partagees des ponts Formik de date.
3
+ *
4
+ * ── POURQUOI CE MODULE EXISTE ────────────────────────────────────────
5
+ *
6
+ * `FormikDatePicker` portait ces deux fonctions en prive. L'arrivee d'un
7
+ * SECOND pont (`FormikDateTimePicker`, gap G-E) posait le choix : les recopier,
8
+ * ou les partager.
9
+ *
10
+ * Les recopier aurait reproduit exactement la situation que la note S-03 de
11
+ * `FormikDatePicker` raconte. Rappel de ce qu'elle dit : ce pont serialisait
12
+ * VERS moment mais relisait DEPUIS `new Date(raw)`, en ignorant
13
+ * `outputFormat`. L'asymetrie corrompait silencieusement tout format non ISO —
14
+ * `new Date("31-12-2026")` donne Invalid Date, `new Date("05-03-2026")` donne
15
+ * le 3 mai au lieu du 5 mars. Le chemin d'ECRITURE fonctionnait, donc un
16
+ * formulaire rempli puis soumis se comportait correctement : le degat
17
+ * n'apparaissait qu'a la RELECTURE, c'est-a-dire en modification. Un module a
18
+ * livre ce defaut pendant sept lots sous un typecheck strict.
19
+ *
20
+ * Une asymetrie de ce genre entre DEUX ponts serait encore moins visible : ils
21
+ * se ressemblent, personne ne les compare, et chacun a l'air correct
22
+ * isolement. La seule garantie est qu'il n'y ait qu'un exemplaire du couple
23
+ * lecture / ecriture.
24
+ *
25
+ * Module INTERNE : non exporte par la surface publique (prefixe `_`).
26
+ */
27
+ /**
28
+ * Relit une valeur stockee par Formik vers un `Date`.
29
+ *
30
+ * `outputFormat` est passe pour que la lecture soit SYMETRIQUE de
31
+ * `serialiseDate` : on parse avec le format qui a servi a ecrire, en mode
32
+ * STRICT. Une valeur stockee qui ne correspond pas rend `null` plutot que la
33
+ * meilleure approximation de moment — une date absente est recuperable, une
34
+ * date fausse de deux mois ne l'est pas.
35
+ */
36
+ export declare const coerceToDate: (raw: unknown, outputFormat?: string) => Date | null;
37
+ /**
38
+ * Serialise un `Date` vers le format demande.
39
+ * undefined -> rend le `Date` tel quel (defaut, compatible)
40
+ * "iso" -> `Date.toISOString()`
41
+ * toute autre chaine -> `moment(date).format(outputFormat)`
42
+ */
43
+ export declare function serialiseDate(date: Date | null, outputFormat: string | undefined): Date | string | null;
44
+ //# sourceMappingURL=_pickerSerialisation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_pickerSerialisation.d.ts","sourceRoot":"","sources":["../../../src/lib/v2/patterns/_pickerSerialisation.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH;;;;;;;;GAQG;AACH,eAAO,MAAM,YAAY,GACvB,KAAK,OAAO,EACZ,eAAe,MAAM,KACpB,IAAI,GAAG,IAwBT,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,IAAI,GAAG,IAAI,EACjB,YAAY,EAAE,MAAM,GAAG,SAAS,GAC/B,IAAI,GAAG,MAAM,GAAG,IAAI,CAOtB"}
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.coerceToDate = void 0;
7
+ exports.serialiseDate = serialiseDate;
8
+ var _moment = _interopRequireDefault(require("moment"));
9
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
10
+ function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
11
+ /**
12
+ * _pickerSerialisation — lecture / ecriture partagees des ponts Formik de date.
13
+ *
14
+ * ── POURQUOI CE MODULE EXISTE ────────────────────────────────────────
15
+ *
16
+ * `FormikDatePicker` portait ces deux fonctions en prive. L'arrivee d'un
17
+ * SECOND pont (`FormikDateTimePicker`, gap G-E) posait le choix : les recopier,
18
+ * ou les partager.
19
+ *
20
+ * Les recopier aurait reproduit exactement la situation que la note S-03 de
21
+ * `FormikDatePicker` raconte. Rappel de ce qu'elle dit : ce pont serialisait
22
+ * VERS moment mais relisait DEPUIS `new Date(raw)`, en ignorant
23
+ * `outputFormat`. L'asymetrie corrompait silencieusement tout format non ISO —
24
+ * `new Date("31-12-2026")` donne Invalid Date, `new Date("05-03-2026")` donne
25
+ * le 3 mai au lieu du 5 mars. Le chemin d'ECRITURE fonctionnait, donc un
26
+ * formulaire rempli puis soumis se comportait correctement : le degat
27
+ * n'apparaissait qu'a la RELECTURE, c'est-a-dire en modification. Un module a
28
+ * livre ce defaut pendant sept lots sous un typecheck strict.
29
+ *
30
+ * Une asymetrie de ce genre entre DEUX ponts serait encore moins visible : ils
31
+ * se ressemblent, personne ne les compare, et chacun a l'air correct
32
+ * isolement. La seule garantie est qu'il n'y ait qu'un exemplaire du couple
33
+ * lecture / ecriture.
34
+ *
35
+ * Module INTERNE : non exporte par la surface publique (prefixe `_`).
36
+ */
37
+
38
+ /**
39
+ * Relit une valeur stockee par Formik vers un `Date`.
40
+ *
41
+ * `outputFormat` est passe pour que la lecture soit SYMETRIQUE de
42
+ * `serialiseDate` : on parse avec le format qui a servi a ecrire, en mode
43
+ * STRICT. Une valeur stockee qui ne correspond pas rend `null` plutot que la
44
+ * meilleure approximation de moment — une date absente est recuperable, une
45
+ * date fausse de deux mois ne l'est pas.
46
+ */
47
+ var coerceToDate = exports.coerceToDate = function coerceToDate(raw, outputFormat) {
48
+ if (raw == null || raw === "") return null;
49
+ if (raw instanceof Date) return raw;
50
+ if (_typeof(raw) === "object" && typeof raw.toDate === "function") {
51
+ var _d$getTime;
52
+ var _d = raw.toDate();
53
+ return isNaN(_d === null || _d === void 0 ? void 0 : (_d$getTime = _d.getTime) === null || _d$getTime === void 0 ? void 0 : _d$getTime.call(_d)) ? null : _d;
54
+ }
55
+ /* Garde sur `typeof raw === "string"` : un horodatage numerique garde le
56
+ * chemin `new Date(number)`, `moment(number, format)` n'ayant pas de sens.
57
+ * "iso" est exclu : ce n'est pas un jeton moment, et `new Date(isoString)`
58
+ * est deja correct. */
59
+ if (typeof raw === "string" && outputFormat !== undefined && outputFormat !== "iso") {
60
+ var parsed = (0, _moment["default"])(raw, outputFormat, true);
61
+ return parsed.isValid() ? parsed.toDate() : null;
62
+ }
63
+ var d = new Date(raw);
64
+ return isNaN(d.getTime()) ? null : d;
65
+ };
66
+
67
+ /**
68
+ * Serialise un `Date` vers le format demande.
69
+ * undefined -> rend le `Date` tel quel (defaut, compatible)
70
+ * "iso" -> `Date.toISOString()`
71
+ * toute autre chaine -> `moment(date).format(outputFormat)`
72
+ */
73
+ function serialiseDate(date, outputFormat) {
74
+ if (!date || !(date instanceof Date) || isNaN(date.getTime())) {
75
+ return outputFormat ? "" : null;
76
+ }
77
+ if (!outputFormat) return date;
78
+ if (outputFormat === "iso") return date.toISOString();
79
+ return (0, _moment["default"])(date).format(outputFormat);
80
+ }
81
+ //# sourceMappingURL=_pickerSerialisation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_pickerSerialisation.js","names":["_moment","_interopRequireDefault","require","obj","__esModule","_typeof","Symbol","iterator","constructor","prototype","coerceToDate","exports","raw","outputFormat","Date","toDate","_d$getTime","d","isNaN","getTime","call","undefined","parsed","moment","isValid","serialiseDate","date","toISOString","format"],"sources":["../../../src/lib/v2/patterns/_pickerSerialisation.ts"],"sourcesContent":["import moment from \"moment\";\r\n\r\n/**\r\n * _pickerSerialisation — lecture / ecriture partagees des ponts Formik de date.\r\n *\r\n * ── POURQUOI CE MODULE EXISTE ────────────────────────────────────────\r\n *\r\n * `FormikDatePicker` portait ces deux fonctions en prive. L'arrivee d'un\r\n * SECOND pont (`FormikDateTimePicker`, gap G-E) posait le choix : les recopier,\r\n * ou les partager.\r\n *\r\n * Les recopier aurait reproduit exactement la situation que la note S-03 de\r\n * `FormikDatePicker` raconte. Rappel de ce qu'elle dit : ce pont serialisait\r\n * VERS moment mais relisait DEPUIS `new Date(raw)`, en ignorant\r\n * `outputFormat`. L'asymetrie corrompait silencieusement tout format non ISO —\r\n * `new Date(\"31-12-2026\")` donne Invalid Date, `new Date(\"05-03-2026\")` donne\r\n * le 3 mai au lieu du 5 mars. Le chemin d'ECRITURE fonctionnait, donc un\r\n * formulaire rempli puis soumis se comportait correctement : le degat\r\n * n'apparaissait qu'a la RELECTURE, c'est-a-dire en modification. Un module a\r\n * livre ce defaut pendant sept lots sous un typecheck strict.\r\n *\r\n * Une asymetrie de ce genre entre DEUX ponts serait encore moins visible : ils\r\n * se ressemblent, personne ne les compare, et chacun a l'air correct\r\n * isolement. La seule garantie est qu'il n'y ait qu'un exemplaire du couple\r\n * lecture / ecriture.\r\n *\r\n * Module INTERNE : non exporte par la surface publique (prefixe `_`).\r\n */\r\n\r\n/**\r\n * Relit une valeur stockee par Formik vers un `Date`.\r\n *\r\n * `outputFormat` est passe pour que la lecture soit SYMETRIQUE de\r\n * `serialiseDate` : on parse avec le format qui a servi a ecrire, en mode\r\n * STRICT. Une valeur stockee qui ne correspond pas rend `null` plutot que la\r\n * meilleure approximation de moment — une date absente est recuperable, une\r\n * date fausse de deux mois ne l'est pas.\r\n */\r\nexport const coerceToDate = (\r\n raw: unknown,\r\n outputFormat?: string\r\n): Date | null => {\r\n if (raw == null || raw === \"\") return null;\r\n if (raw instanceof Date) return raw;\r\n if (\r\n typeof raw === \"object\" &&\r\n typeof (raw as { toDate?: () => Date }).toDate === \"function\"\r\n ) {\r\n const d = (raw as { toDate: () => Date }).toDate();\r\n return isNaN(d?.getTime?.()) ? null : d;\r\n }\r\n /* Garde sur `typeof raw === \"string\"` : un horodatage numerique garde le\r\n * chemin `new Date(number)`, `moment(number, format)` n'ayant pas de sens.\r\n * \"iso\" est exclu : ce n'est pas un jeton moment, et `new Date(isoString)`\r\n * est deja correct. */\r\n if (\r\n typeof raw === \"string\" &&\r\n outputFormat !== undefined &&\r\n outputFormat !== \"iso\"\r\n ) {\r\n const parsed = moment(raw, outputFormat, true);\r\n return parsed.isValid() ? parsed.toDate() : null;\r\n }\r\n const d = new Date(raw as string | number);\r\n return isNaN(d.getTime()) ? null : d;\r\n};\r\n\r\n/**\r\n * Serialise un `Date` vers le format demande.\r\n * undefined -> rend le `Date` tel quel (defaut, compatible)\r\n * \"iso\" -> `Date.toISOString()`\r\n * toute autre chaine -> `moment(date).format(outputFormat)`\r\n */\r\nexport function serialiseDate(\r\n date: Date | null,\r\n outputFormat: string | undefined\r\n): Date | string | null {\r\n if (!date || !(date instanceof Date) || isNaN(date.getTime())) {\r\n return outputFormat ? \"\" : null;\r\n }\r\n if (!outputFormat) return date;\r\n if (outputFormat === \"iso\") return date.toISOString();\r\n return moment(date).format(outputFormat);\r\n}\r\n"],"mappings":";;;;;;;AAAA,IAAAA,OAAA,GAAAC,sBAAA,CAAAC,OAAA;AAA4B,SAAAD,uBAAAE,GAAA,WAAAA,GAAA,IAAAA,GAAA,CAAAC,UAAA,GAAAD,GAAA,gBAAAA,GAAA;AAAA,SAAAE,QAAAF,GAAA,sCAAAE,OAAA,wBAAAC,MAAA,uBAAAA,MAAA,CAAAC,QAAA,aAAAJ,GAAA,kBAAAA,GAAA,gBAAAA,GAAA,WAAAA,GAAA,yBAAAG,MAAA,IAAAH,GAAA,CAAAK,WAAA,KAAAF,MAAA,IAAAH,GAAA,KAAAG,MAAA,CAAAG,SAAA,qBAAAN,GAAA,KAAAE,OAAA,CAAAF,GAAA;AAE5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,IAAMO,YAAY,GAAAC,OAAA,CAAAD,YAAA,GAAG,SAAfA,YAAYA,CACvBE,GAAY,EACZC,YAAqB,EACL;EAChB,IAAID,GAAG,IAAI,IAAI,IAAIA,GAAG,KAAK,EAAE,EAAE,OAAO,IAAI;EAC1C,IAAIA,GAAG,YAAYE,IAAI,EAAE,OAAOF,GAAG;EACnC,IACEP,OAAA,CAAOO,GAAG,MAAK,QAAQ,IACvB,OAAQA,GAAG,CAA6BG,MAAM,KAAK,UAAU,EAC7D;IAAA,IAAAC,UAAA;IACA,IAAMC,EAAC,GAAIL,GAAG,CAA4BG,MAAM,CAAC,CAAC;IAClD,OAAOG,KAAK,CAACD,EAAC,aAADA,EAAC,wBAAAD,UAAA,GAADC,EAAC,CAAEE,OAAO,cAAAH,UAAA,uBAAVA,UAAA,CAAAI,IAAA,CAAAH,EAAa,CAAC,CAAC,GAAG,IAAI,GAAGA,EAAC;EACzC;EACA;AACF;AACA;AACA;EACE,IACE,OAAOL,GAAG,KAAK,QAAQ,IACvBC,YAAY,KAAKQ,SAAS,IAC1BR,YAAY,KAAK,KAAK,EACtB;IACA,IAAMS,MAAM,GAAG,IAAAC,kBAAM,EAACX,GAAG,EAAEC,YAAY,EAAE,IAAI,CAAC;IAC9C,OAAOS,MAAM,CAACE,OAAO,CAAC,CAAC,GAAGF,MAAM,CAACP,MAAM,CAAC,CAAC,GAAG,IAAI;EAClD;EACA,IAAME,CAAC,GAAG,IAAIH,IAAI,CAACF,GAAsB,CAAC;EAC1C,OAAOM,KAAK,CAACD,CAAC,CAACE,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI,GAAGF,CAAC;AACtC,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACO,SAASQ,aAAaA,CAC3BC,IAAiB,EACjBb,YAAgC,EACV;EACtB,IAAI,CAACa,IAAI,IAAI,EAAEA,IAAI,YAAYZ,IAAI,CAAC,IAAII,KAAK,CAACQ,IAAI,CAACP,OAAO,CAAC,CAAC,CAAC,EAAE;IAC7D,OAAON,YAAY,GAAG,EAAE,GAAG,IAAI;EACjC;EACA,IAAI,CAACA,YAAY,EAAE,OAAOa,IAAI;EAC9B,IAAIb,YAAY,KAAK,KAAK,EAAE,OAAOa,IAAI,CAACC,WAAW,CAAC,CAAC;EACrD,OAAO,IAAAJ,kBAAM,EAACG,IAAI,CAAC,CAACE,MAAM,CAACf,YAAY,CAAC;AAC1C","ignoreList":[]}