@flipdish/ui-library 0.32.0 → 0.33.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (196) hide show
  1. package/dist/components/atoms/Avatar/components/AvatarLabelGroup.cjs +6 -4
  2. package/dist/components/atoms/Avatar/components/AvatarLabelGroup.cjs.map +1 -1
  3. package/dist/components/atoms/Avatar/components/AvatarLabelGroup.d.ts +7 -1
  4. package/dist/components/atoms/Avatar/components/AvatarLabelGroup.d.ts.map +1 -1
  5. package/dist/components/atoms/Avatar/components/AvatarLabelGroup.js +6 -4
  6. package/dist/components/atoms/Avatar/components/AvatarLabelGroup.js.map +1 -1
  7. package/dist/components/atoms/Badge/badge.types.cjs.map +1 -1
  8. package/dist/components/atoms/Badge/badge.types.d.ts +2 -1
  9. package/dist/components/atoms/Badge/badge.types.d.ts.map +1 -1
  10. package/dist/components/atoms/Badge/badge.types.js.map +1 -1
  11. package/dist/components/atoms/Badge/index.cjs +2 -1
  12. package/dist/components/atoms/Badge/index.cjs.map +1 -1
  13. package/dist/components/atoms/Badge/index.d.ts.map +1 -1
  14. package/dist/components/atoms/Badge/index.js +2 -1
  15. package/dist/components/atoms/Badge/index.js.map +1 -1
  16. package/dist/components/atoms/Card/index.cjs +28 -0
  17. package/dist/components/atoms/Card/index.cjs.map +1 -0
  18. package/dist/components/atoms/Card/index.d.ts +20 -0
  19. package/dist/components/atoms/Card/index.d.ts.map +1 -0
  20. package/dist/components/atoms/Card/index.js +26 -0
  21. package/dist/components/atoms/Card/index.js.map +1 -0
  22. package/dist/components/atoms/CopyButton/index.cjs +27 -0
  23. package/dist/components/atoms/CopyButton/index.cjs.map +1 -0
  24. package/dist/components/atoms/CopyButton/index.d.ts +28 -0
  25. package/dist/components/atoms/CopyButton/index.d.ts.map +1 -0
  26. package/dist/components/atoms/CopyButton/index.js +25 -0
  27. package/dist/components/atoms/CopyButton/index.js.map +1 -0
  28. package/dist/components/atoms/Flag/flag.types.d.ts +6 -0
  29. package/dist/components/atoms/Flag/flag.types.d.ts.map +1 -0
  30. package/dist/components/atoms/Flag/flag.utils.cjs +45 -0
  31. package/dist/components/atoms/Flag/flag.utils.cjs.map +1 -0
  32. package/dist/components/atoms/Flag/flag.utils.d.ts +15 -0
  33. package/dist/components/atoms/Flag/flag.utils.d.ts.map +1 -0
  34. package/dist/components/atoms/Flag/flag.utils.js +42 -0
  35. package/dist/components/atoms/Flag/flag.utils.js.map +1 -0
  36. package/dist/components/atoms/Flag/index.cjs +47 -0
  37. package/dist/components/atoms/Flag/index.cjs.map +1 -0
  38. package/dist/components/atoms/Flag/index.d.ts +27 -0
  39. package/dist/components/atoms/Flag/index.d.ts.map +1 -0
  40. package/dist/components/atoms/Flag/index.js +45 -0
  41. package/dist/components/atoms/Flag/index.js.map +1 -0
  42. package/dist/components/atoms/SearchInput/index.cjs +32 -0
  43. package/dist/components/atoms/SearchInput/index.cjs.map +1 -0
  44. package/dist/components/atoms/SearchInput/index.d.ts +40 -0
  45. package/dist/components/atoms/SearchInput/index.d.ts.map +1 -0
  46. package/dist/components/atoms/SearchInput/index.js +30 -0
  47. package/dist/components/atoms/SearchInput/index.js.map +1 -0
  48. package/dist/components/molecules/Carousel/hooks/useCarouselScroll.cjs +81 -0
  49. package/dist/components/molecules/Carousel/hooks/useCarouselScroll.cjs.map +1 -0
  50. package/dist/components/molecules/Carousel/hooks/useCarouselScroll.d.ts +46 -0
  51. package/dist/components/molecules/Carousel/hooks/useCarouselScroll.d.ts.map +1 -0
  52. package/dist/components/molecules/Carousel/hooks/useCarouselScroll.js +79 -0
  53. package/dist/components/molecules/Carousel/hooks/useCarouselScroll.js.map +1 -0
  54. package/dist/components/molecules/Carousel/index.cjs +8 -55
  55. package/dist/components/molecules/Carousel/index.cjs.map +1 -1
  56. package/dist/components/molecules/Carousel/index.d.ts +3 -7
  57. package/dist/components/molecules/Carousel/index.d.ts.map +1 -1
  58. package/dist/components/molecules/Carousel/index.js +9 -56
  59. package/dist/components/molecules/Carousel/index.js.map +1 -1
  60. package/dist/components/molecules/CodeSnippet/codeSnippet.utils.cjs +17 -0
  61. package/dist/components/molecules/CodeSnippet/codeSnippet.utils.cjs.map +1 -0
  62. package/dist/components/molecules/CodeSnippet/codeSnippet.utils.d.ts +8 -0
  63. package/dist/components/molecules/CodeSnippet/codeSnippet.utils.d.ts.map +1 -0
  64. package/dist/components/molecules/CodeSnippet/codeSnippet.utils.js +15 -0
  65. package/dist/components/molecules/CodeSnippet/codeSnippet.utils.js.map +1 -0
  66. package/dist/components/molecules/CodeSnippet/hooks/useCodeSnippetCollapse.cjs +29 -0
  67. package/dist/components/molecules/CodeSnippet/hooks/useCodeSnippetCollapse.cjs.map +1 -0
  68. package/dist/components/molecules/CodeSnippet/hooks/useCodeSnippetCollapse.d.ts +29 -0
  69. package/dist/components/molecules/CodeSnippet/hooks/useCodeSnippetCollapse.d.ts.map +1 -0
  70. package/dist/components/molecules/CodeSnippet/hooks/useCodeSnippetCollapse.js +27 -0
  71. package/dist/components/molecules/CodeSnippet/hooks/useCodeSnippetCollapse.js.map +1 -0
  72. package/dist/components/molecules/CodeSnippet/hooks/useCodeSnippetHighlight.cjs +23 -0
  73. package/dist/components/molecules/CodeSnippet/hooks/useCodeSnippetHighlight.cjs.map +1 -0
  74. package/dist/components/molecules/CodeSnippet/hooks/useCodeSnippetHighlight.d.ts +21 -0
  75. package/dist/components/molecules/CodeSnippet/hooks/useCodeSnippetHighlight.d.ts.map +1 -0
  76. package/dist/components/molecules/CodeSnippet/hooks/useCodeSnippetHighlight.js +21 -0
  77. package/dist/components/molecules/CodeSnippet/hooks/useCodeSnippetHighlight.js.map +1 -0
  78. package/dist/components/molecules/CodeSnippet/index.cjs +7 -22
  79. package/dist/components/molecules/CodeSnippet/index.cjs.map +1 -1
  80. package/dist/components/molecules/CodeSnippet/index.d.ts.map +1 -1
  81. package/dist/components/molecules/CodeSnippet/index.js +8 -23
  82. package/dist/components/molecules/CodeSnippet/index.js.map +1 -1
  83. package/dist/components/molecules/DetailList/detailList.types.d.ts +15 -0
  84. package/dist/components/molecules/DetailList/detailList.types.d.ts.map +1 -0
  85. package/dist/components/molecules/DetailList/index.cjs +32 -0
  86. package/dist/components/molecules/DetailList/index.cjs.map +1 -0
  87. package/dist/components/molecules/DetailList/index.d.ts +26 -0
  88. package/dist/components/molecules/DetailList/index.d.ts.map +1 -0
  89. package/dist/components/molecules/DetailList/index.js +30 -0
  90. package/dist/components/molecules/DetailList/index.js.map +1 -0
  91. package/dist/components/molecules/RadioGroup/components/RadioGroupAvatarCard.cjs +43 -0
  92. package/dist/components/molecules/RadioGroup/components/RadioGroupAvatarCard.cjs.map +1 -0
  93. package/dist/components/molecules/RadioGroup/components/RadioGroupAvatarCard.d.ts +24 -0
  94. package/dist/components/molecules/RadioGroup/components/RadioGroupAvatarCard.d.ts.map +1 -0
  95. package/dist/components/molecules/RadioGroup/components/RadioGroupAvatarCard.js +41 -0
  96. package/dist/components/molecules/RadioGroup/components/RadioGroupAvatarCard.js.map +1 -0
  97. package/dist/components/molecules/RadioGroup/index.cjs +2 -0
  98. package/dist/components/molecules/RadioGroup/index.cjs.map +1 -1
  99. package/dist/components/molecules/RadioGroup/index.d.ts +2 -0
  100. package/dist/components/molecules/RadioGroup/index.d.ts.map +1 -1
  101. package/dist/components/molecules/RadioGroup/index.js +1 -0
  102. package/dist/components/molecules/RadioGroup/index.js.map +1 -1
  103. package/dist/components/molecules/RadioGroup/radioGroup.types.d.ts +17 -1
  104. package/dist/components/molecules/RadioGroup/radioGroup.types.d.ts.map +1 -1
  105. package/dist/components/organisms/ApplicationHeader/applicationHeader.types.d.ts +8 -2
  106. package/dist/components/organisms/ApplicationHeader/applicationHeader.types.d.ts.map +1 -1
  107. package/dist/components/organisms/ApplicationHeader/components/AvatarButton.cjs +4 -1
  108. package/dist/components/organisms/ApplicationHeader/components/AvatarButton.cjs.map +1 -1
  109. package/dist/components/organisms/ApplicationHeader/components/AvatarButton.d.ts +2 -1
  110. package/dist/components/organisms/ApplicationHeader/components/AvatarButton.d.ts.map +1 -1
  111. package/dist/components/organisms/ApplicationHeader/components/AvatarButton.js +4 -1
  112. package/dist/components/organisms/ApplicationHeader/components/AvatarButton.js.map +1 -1
  113. package/dist/components/organisms/ApplicationHeader/index.cjs +1 -1
  114. package/dist/components/organisms/ApplicationHeader/index.cjs.map +1 -1
  115. package/dist/components/organisms/ApplicationHeader/index.d.ts.map +1 -1
  116. package/dist/components/organisms/ApplicationHeader/index.js +1 -1
  117. package/dist/components/organisms/ApplicationHeader/index.js.map +1 -1
  118. package/dist/components/organisms/DatePicker/calendarCell.utils.cjs +53 -0
  119. package/dist/components/organisms/DatePicker/calendarCell.utils.cjs.map +1 -0
  120. package/dist/components/organisms/DatePicker/calendarCell.utils.d.ts +70 -0
  121. package/dist/components/organisms/DatePicker/calendarCell.utils.d.ts.map +1 -0
  122. package/dist/components/organisms/DatePicker/calendarCell.utils.js +49 -0
  123. package/dist/components/organisms/DatePicker/calendarCell.utils.js.map +1 -0
  124. package/dist/components/organisms/DatePicker/components/Cell.cjs +24 -30
  125. package/dist/components/organisms/DatePicker/components/Cell.cjs.map +1 -1
  126. package/dist/components/organisms/DatePicker/components/Cell.d.ts.map +1 -1
  127. package/dist/components/organisms/DatePicker/components/Cell.js +25 -31
  128. package/dist/components/organisms/DatePicker/components/Cell.js.map +1 -1
  129. package/dist/components/organisms/FileUpload/fileUpload.utils.cjs +69 -0
  130. package/dist/components/organisms/FileUpload/fileUpload.utils.cjs.map +1 -0
  131. package/dist/components/organisms/FileUpload/fileUpload.utils.d.ts +46 -0
  132. package/dist/components/organisms/FileUpload/fileUpload.utils.d.ts.map +1 -0
  133. package/dist/components/organisms/FileUpload/fileUpload.utils.js +65 -0
  134. package/dist/components/organisms/FileUpload/fileUpload.utils.js.map +1 -0
  135. package/dist/components/organisms/FileUpload/index.cjs +15 -66
  136. package/dist/components/organisms/FileUpload/index.cjs.map +1 -1
  137. package/dist/components/organisms/FileUpload/index.d.ts.map +1 -1
  138. package/dist/components/organisms/FileUpload/index.js +13 -64
  139. package/dist/components/organisms/FileUpload/index.js.map +1 -1
  140. package/dist/components/organisms/HeaderNavigation/index.cjs +2 -3
  141. package/dist/components/organisms/HeaderNavigation/index.cjs.map +1 -1
  142. package/dist/components/organisms/HeaderNavigation/index.d.ts.map +1 -1
  143. package/dist/components/organisms/HeaderNavigation/index.js +2 -3
  144. package/dist/components/organisms/HeaderNavigation/index.js.map +1 -1
  145. package/dist/components/organisms/SidePanel/components/SidePanelContent.cjs +3 -1
  146. package/dist/components/organisms/SidePanel/components/SidePanelContent.cjs.map +1 -1
  147. package/dist/components/organisms/SidePanel/components/SidePanelContent.d.ts.map +1 -1
  148. package/dist/components/organisms/SidePanel/components/SidePanelContent.js +3 -1
  149. package/dist/components/organisms/SidePanel/components/SidePanelContent.js.map +1 -1
  150. package/dist/components/organisms/SidePanel/components/SidePanelFooter.cjs +3 -3
  151. package/dist/components/organisms/SidePanel/components/SidePanelFooter.cjs.map +1 -1
  152. package/dist/components/organisms/SidePanel/components/SidePanelFooter.d.ts +7 -2
  153. package/dist/components/organisms/SidePanel/components/SidePanelFooter.d.ts.map +1 -1
  154. package/dist/components/organisms/SidePanel/components/SidePanelFooter.js +3 -3
  155. package/dist/components/organisms/SidePanel/components/SidePanelFooter.js.map +1 -1
  156. package/dist/components/organisms/SidePanel/components/SidePanelHeader.cjs +7 -3
  157. package/dist/components/organisms/SidePanel/components/SidePanelHeader.cjs.map +1 -1
  158. package/dist/components/organisms/SidePanel/components/SidePanelHeader.d.ts +6 -2
  159. package/dist/components/organisms/SidePanel/components/SidePanelHeader.d.ts.map +1 -1
  160. package/dist/components/organisms/SidePanel/components/SidePanelHeader.js +7 -3
  161. package/dist/components/organisms/SidePanel/components/SidePanelHeader.js.map +1 -1
  162. package/dist/components/organisms/SidePanel/components/SidePanelRegion.cjs +8 -3
  163. package/dist/components/organisms/SidePanel/components/SidePanelRegion.cjs.map +1 -1
  164. package/dist/components/organisms/SidePanel/components/SidePanelRegion.d.ts +2 -1
  165. package/dist/components/organisms/SidePanel/components/SidePanelRegion.d.ts.map +1 -1
  166. package/dist/components/organisms/SidePanel/components/SidePanelRegion.js +8 -3
  167. package/dist/components/organisms/SidePanel/components/SidePanelRegion.js.map +1 -1
  168. package/dist/components/organisms/SidePanel/hooks/usePanelFocus.cjs +12 -1
  169. package/dist/components/organisms/SidePanel/hooks/usePanelFocus.cjs.map +1 -1
  170. package/dist/components/organisms/SidePanel/hooks/usePanelFocus.d.ts +3 -1
  171. package/dist/components/organisms/SidePanel/hooks/usePanelFocus.d.ts.map +1 -1
  172. package/dist/components/organisms/SidePanel/hooks/usePanelFocus.js +13 -2
  173. package/dist/components/organisms/SidePanel/hooks/usePanelFocus.js.map +1 -1
  174. package/dist/components/organisms/SidePanel/index.cjs +2 -2
  175. package/dist/components/organisms/SidePanel/index.cjs.map +1 -1
  176. package/dist/components/organisms/SidePanel/index.d.ts +3 -1
  177. package/dist/components/organisms/SidePanel/index.d.ts.map +1 -1
  178. package/dist/components/organisms/SidePanel/index.js +2 -2
  179. package/dist/components/organisms/SidePanel/index.js.map +1 -1
  180. package/dist/components/organisms/TreeView/index.cjs +11 -26
  181. package/dist/components/organisms/TreeView/index.cjs.map +1 -1
  182. package/dist/components/organisms/TreeView/index.d.ts.map +1 -1
  183. package/dist/components/organisms/TreeView/index.js +12 -27
  184. package/dist/components/organisms/TreeView/index.js.map +1 -1
  185. package/dist/components/organisms/TreeView/treeView.utils.cjs +40 -0
  186. package/dist/components/organisms/TreeView/treeView.utils.cjs.map +1 -1
  187. package/dist/components/organisms/TreeView/treeView.utils.d.ts +37 -0
  188. package/dist/components/organisms/TreeView/treeView.utils.d.ts.map +1 -1
  189. package/dist/components/organisms/TreeView/treeView.utils.js +39 -1
  190. package/dist/components/organisms/TreeView/treeView.utils.js.map +1 -1
  191. package/dist/native/components/atoms/Card/index.d.ts +12 -0
  192. package/dist/native/components/atoms/CopyButton/index.d.ts +12 -0
  193. package/dist/native/components/atoms/Flag/index.d.ts +12 -0
  194. package/dist/native/components/atoms/SearchInput/index.d.ts +12 -0
  195. package/dist/native/components/molecules/DetailList/index.d.ts +12 -0
  196. package/package.json +3 -2
@@ -0,0 +1,42 @@
1
+ import { getEnvironmentVariable } from '@flipdish/ui-library/utilities/renderUtils';
2
+
3
+ const resolvers = new Map();
4
+ const warnedCodes = new Set();
5
+ /**
6
+ * Resolves a country's name from its ISO 3166-1 alpha-2 code, for the flag's default accessible name.
7
+ * @param code The country code, as `Flag` receives it.
8
+ * @param locale BCP 47 tag the name is written in; the app's locale, so server and client agree.
9
+ * @returns The region name in that locale, or the code itself where `Intl.DisplayNames` is missing or rejects the code or locale.
10
+ */
11
+ const getCountryName = (code, locale = 'en') => {
12
+ // Built once per locale; `Intl.DisplayNames` is missing from some older runtimes, where the code stands in.
13
+ let resolver = resolvers.get(locale);
14
+ if (resolver === undefined) {
15
+ try {
16
+ resolver = typeof Intl.DisplayNames === 'function' ? new Intl.DisplayNames([locale], { type: 'region' }) : null;
17
+ }
18
+ catch {
19
+ resolver = null;
20
+ }
21
+ resolvers.set(locale, resolver);
22
+ }
23
+ try {
24
+ return resolver?.of(code) ?? code;
25
+ }
26
+ catch {
27
+ return code;
28
+ }
29
+ };
30
+ /**
31
+ * Warns once per unknown country code outside production, so a bad code is visible in development without flooding the console.
32
+ * @param code The code no flag exists for.
33
+ */
34
+ const warnUnknownCountryOnce = (code) => {
35
+ if (getEnvironmentVariable('NODE_ENV') === 'production' || warnedCodes.has(code))
36
+ return;
37
+ warnedCodes.add(code);
38
+ console.warn(`Flag: no flag for country code "${code}".`);
39
+ };
40
+
41
+ export { getCountryName, warnUnknownCountryOnce };
42
+ //# sourceMappingURL=flag.utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flag.utils.js","sources":["../../../../src/components/atoms/Flag/flag.utils.ts"],"sourcesContent":[null],"names":[],"mappings":";;AAEA,MAAM,SAAS,GAAG,IAAI,GAAG,EAAoC;AAC7D,MAAM,WAAW,GAAG,IAAI,GAAG,EAAU;AAErC;;;;;AAKG;AACI,MAAM,cAAc,GAAG,CAAC,IAAY,EAAE,MAAM,GAAG,IAAI,KAAY;;IAEpE,IAAI,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC;AACpC,IAAA,IAAI,QAAQ,KAAK,SAAS,EAAE;AAC1B,QAAA,IAAI;AACF,YAAA,QAAQ,GAAG,OAAO,IAAI,CAAC,YAAY,KAAK,UAAU,GAAG,IAAI,IAAI,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI;QACjH;AAAE,QAAA,MAAM;YACN,QAAQ,GAAG,IAAI;QACjB;AACA,QAAA,SAAS,CAAC,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC;IACjC;AACA,IAAA,IAAI;QACF,OAAO,QAAQ,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,IAAI;IACnC;AAAE,IAAA,MAAM;AACN,QAAA,OAAO,IAAI;IACb;AACF;AAEA;;;AAGG;AACI,MAAM,sBAAsB,GAAG,CAAC,IAAY,KAAU;AAC3D,IAAA,IAAI,sBAAsB,CAAC,UAAU,CAAC,KAAK,YAAY,IAAI,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC;QAAE;AAClF,IAAA,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC;AACrB,IAAA,OAAO,CAAC,IAAI,CAAC,mCAAmC,IAAI,CAAA,EAAA,CAAI,CAAC;AAC3D;;"}
@@ -0,0 +1,47 @@
1
+ 'use strict';
2
+
3
+ var jsxRuntime = require('react/jsx-runtime');
4
+ var cx = require('@flipdish/ui-library/utilities/cx');
5
+ var testIdUtils = require('@flipdish/ui-library/utilities/testIdUtils');
6
+ var React = require('react');
7
+ var flag_utils = require('./flag.utils.cjs');
8
+
9
+ const toFlagSvg = (set) => {
10
+ const FlagSvg = ({ code, ...props }) => {
11
+ const Svg = set[code];
12
+ if (!Svg) {
13
+ flag_utils.warnUnknownCountryOnce(code);
14
+ return null;
15
+ }
16
+ return jsxRuntime.jsx(Svg, { ...props });
17
+ };
18
+ return { default: FlagSvg };
19
+ };
20
+ // Each set is every country in one ~53 KB gzip module, so it loads on the first flag of that shape rather than with every importer of `Flag`.
21
+ const FLAG_SVGS = {
22
+ round: React.lazy(() => import('country-flag-icons/react/1x1').then((flags) => toFlagSvg(flags))),
23
+ rectangle: React.lazy(() => import('country-flag-icons/react/3x2').then((flags) => toFlagSvg(flags))),
24
+ };
25
+ // A rectangle keeps the art's 3:2 ratio at the same height as the round flag.
26
+ const SIZES = {
27
+ round: { xs: 'size-4', sm: 'size-5', md: 'size-6', lg: 'size-8' },
28
+ rectangle: { xs: 'h-4 w-6', sm: 'h-5 w-7.5', md: 'h-6 w-9', lg: 'h-8 w-12' },
29
+ };
30
+ /**
31
+ * A country's flag from its ISO code, round for inline use beside a label or rectangular where
32
+ * the full flag matters. Each shape is one bundled set from `country-flag-icons` that loads on
33
+ * its first use, so a page costs nothing until it shows a flag and the same after that however
34
+ * many countries it shows.
35
+ *
36
+ * @summary country flag from an ISO country code
37
+ */
38
+ const Flag = ({ code, size = 'sm', shape = 'round', label, locale, className, 'data-testid': dataTestId, ...props }) => {
39
+ const flagTestId = testIdUtils.useResolvedTestId({ testId: dataTestId, segment: 'flag', rootName: 'flag' });
40
+ const name = label ?? flag_utils.getCountryName(code, locale);
41
+ const isDecorative = name === '';
42
+ const FlagSvg = FLAG_SVGS[shape];
43
+ return (jsxRuntime.jsx(React.Suspense, { fallback: null, children: jsxRuntime.jsx(FlagSvg, { ...props, code: code, "data-testid": flagTestId, role: isDecorative ? undefined : 'img', "aria-label": isDecorative ? undefined : name, "aria-hidden": isDecorative || undefined, title: isDecorative ? undefined : name, className: cx.cx('shrink-0 overflow-hidden', shape === 'round' && 'rounded-full', SIZES[shape][size], className) }) }));
44
+ };
45
+
46
+ exports.Flag = Flag;
47
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs","sources":["../../../../src/components/atoms/Flag/index.tsx"],"sourcesContent":[null],"names":["warnUnknownCountryOnce","_jsx","lazy","useResolvedTestId","getCountryName","Suspense","cx"],"mappings":";;;;;;;;AAeA,MAAM,SAAS,GAAG,CAAC,GAAY,KAAI;IACjC,MAAM,OAAO,GAAG,CAAC,EAAE,IAAI,EAAE,GAAG,KAAK,EAAmC,KAAI;AACtE,QAAA,MAAM,GAAG,GAAG,GAAG,CAAC,IAAI,CAAC;QACrB,IAAI,CAAC,GAAG,EAAE;YACRA,iCAAsB,CAAC,IAAI,CAAC;AAC5B,YAAA,OAAO,IAAI;QACb;AACA,QAAA,OAAOC,cAAA,CAAC,GAAG,EAAA,EAAA,GAAK,KAAK,GAAI;AAC3B,IAAA,CAAC;AACD,IAAA,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE;AAC7B,CAAC;AAED;AACA,MAAM,SAAS,GAAG;IAChB,KAAK,EAAEC,UAAI,CAAC,MAAM,OAAO,8BAA8B,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,KAAK,SAAS,CAAC,KAAgB,CAAC,CAAC,CAAC;IACtG,SAAS,EAAEA,UAAI,CAAC,MAAM,OAAO,8BAA8B,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,KAAK,SAAS,CAAC,KAAgB,CAAC,CAAC,CAAC;CAC3G;AAED;AACA,MAAM,KAAK,GAAgD;AACzD,IAAA,KAAK,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,QAAQ,EAAE;AACjE,IAAA,SAAS,EAAE,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE,UAAU,EAAE;CAC7E;AAiBD;;;;;;;AAOG;AACI,MAAM,IAAI,GAAG,CAAC,EAAE,IAAI,EAAE,IAAI,GAAG,IAAI,EAAE,KAAK,GAAG,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,aAAa,EAAE,UAAU,EAAE,GAAG,KAAK,EAAa,KAAI;AACvI,IAAA,MAAM,UAAU,GAAGC,6BAAiB,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;IAC/F,MAAM,IAAI,GAAG,KAAK,IAAIC,yBAAc,CAAC,IAAI,EAAE,MAAM,CAAC;AAClD,IAAA,MAAM,YAAY,GAAG,IAAI,KAAK,EAAE;AAChC,IAAA,MAAM,OAAO,GAAG,SAAS,CAAC,KAAK,CAAC;AAEhC,IAAA,QACEH,cAAA,CAACI,cAAQ,EAAA,EAAC,QAAQ,EAAE,IAAI,EAAA,QAAA,EACtBJ,cAAA,CAAC,OAAO,OACF,KAAK,EACT,IAAI,EAAE,IAAI,iBACG,UAAU,EACvB,IAAI,EAAE,YAAY,GAAG,SAAS,GAAG,KAAK,EAAA,YAAA,EAC1B,YAAY,GAAG,SAAS,GAAG,IAAI,EAAA,aAAA,EAC9B,YAAY,IAAI,SAAS,EACtC,KAAK,EAAE,YAAY,GAAG,SAAS,GAAG,IAAI,EACtC,SAAS,EAAEK,KAAE,CAAC,0BAA0B,EAAE,KAAK,KAAK,OAAO,IAAI,cAAc,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,EAAE,SAAS,CAAC,EAAA,CAC7G,EAAA,CACO;AAEf;;"}
@@ -0,0 +1,27 @@
1
+ import type { SVGProps } from 'react';
2
+ import type { CountryCode, FlagShape, FlagSize } from './flag.types';
3
+ export type { CountryCode, FlagShape, FlagSize } from './flag.types';
4
+ export interface FlagProps extends Omit<SVGProps<SVGSVGElement>, 'children'> {
5
+ /** ISO 3166-1 alpha-2 code of the country to show. */
6
+ code: CountryCode;
7
+ /** Height: `xs` 16px, `sm` 20px, `md` 24px, `lg` 32px. A rectangle is 3:2, so wider than tall. */
8
+ size?: FlagSize;
9
+ /** `round` clips the square art to a circle; `rectangle` shows the 3:2 flag. */
10
+ shape?: FlagShape;
11
+ /** Accessible name. Defaults to the country's name in `locale`; pass `''` to hide the flag from assistive technology when visible text beside it already names the country. */
12
+ label?: string;
13
+ /** BCP 47 tag the default name is written in. Pass the app's locale rather than reading the browser's, so server and client render the same name. */
14
+ locale?: string;
15
+ /** Overrides the `data-testid` (defaults to `fd-flag`). */
16
+ 'data-testid'?: string;
17
+ }
18
+ /**
19
+ * A country's flag from its ISO code, round for inline use beside a label or rectangular where
20
+ * the full flag matters. Each shape is one bundled set from `country-flag-icons` that loads on
21
+ * its first use, so a page costs nothing until it shows a flag and the same after that however
22
+ * many countries it shows.
23
+ *
24
+ * @summary country flag from an ISO country code
25
+ */
26
+ export declare const Flag: ({ code, size, shape, label, locale, className, "data-testid": dataTestId, ...props }: FlagProps) => import("react").JSX.Element;
27
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/atoms/Flag/index.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAgB,QAAQ,EAAE,MAAM,OAAO,CAAC;AAEpD,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAGrE,YAAY,EAAE,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AA8BrE,MAAM,WAAW,SAAU,SAAQ,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,UAAU,CAAC;IAC1E,sDAAsD;IACtD,IAAI,EAAE,WAAW,CAAC;IAClB,kGAAkG;IAClG,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,gFAAgF;IAChF,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,+KAA+K;IAC/K,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qJAAqJ;IACrJ,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,2DAA2D;IAC3D,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,IAAI,GAAI,sFAAuG,SAAS,gCAoBpI,CAAC"}
@@ -0,0 +1,45 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import { cx } from '@flipdish/ui-library/utilities/cx';
3
+ import { useResolvedTestId } from '@flipdish/ui-library/utilities/testIdUtils';
4
+ import { lazy, Suspense } from 'react';
5
+ import { warnUnknownCountryOnce, getCountryName } from './flag.utils.js';
6
+
7
+ const toFlagSvg = (set) => {
8
+ const FlagSvg = ({ code, ...props }) => {
9
+ const Svg = set[code];
10
+ if (!Svg) {
11
+ warnUnknownCountryOnce(code);
12
+ return null;
13
+ }
14
+ return jsx(Svg, { ...props });
15
+ };
16
+ return { default: FlagSvg };
17
+ };
18
+ // Each set is every country in one ~53 KB gzip module, so it loads on the first flag of that shape rather than with every importer of `Flag`.
19
+ const FLAG_SVGS = {
20
+ round: lazy(() => import('country-flag-icons/react/1x1').then((flags) => toFlagSvg(flags))),
21
+ rectangle: lazy(() => import('country-flag-icons/react/3x2').then((flags) => toFlagSvg(flags))),
22
+ };
23
+ // A rectangle keeps the art's 3:2 ratio at the same height as the round flag.
24
+ const SIZES = {
25
+ round: { xs: 'size-4', sm: 'size-5', md: 'size-6', lg: 'size-8' },
26
+ rectangle: { xs: 'h-4 w-6', sm: 'h-5 w-7.5', md: 'h-6 w-9', lg: 'h-8 w-12' },
27
+ };
28
+ /**
29
+ * A country's flag from its ISO code, round for inline use beside a label or rectangular where
30
+ * the full flag matters. Each shape is one bundled set from `country-flag-icons` that loads on
31
+ * its first use, so a page costs nothing until it shows a flag and the same after that however
32
+ * many countries it shows.
33
+ *
34
+ * @summary country flag from an ISO country code
35
+ */
36
+ const Flag = ({ code, size = 'sm', shape = 'round', label, locale, className, 'data-testid': dataTestId, ...props }) => {
37
+ const flagTestId = useResolvedTestId({ testId: dataTestId, segment: 'flag', rootName: 'flag' });
38
+ const name = label ?? getCountryName(code, locale);
39
+ const isDecorative = name === '';
40
+ const FlagSvg = FLAG_SVGS[shape];
41
+ return (jsx(Suspense, { fallback: null, children: jsx(FlagSvg, { ...props, code: code, "data-testid": flagTestId, role: isDecorative ? undefined : 'img', "aria-label": isDecorative ? undefined : name, "aria-hidden": isDecorative || undefined, title: isDecorative ? undefined : name, className: cx('shrink-0 overflow-hidden', shape === 'round' && 'rounded-full', SIZES[shape][size], className) }) }));
42
+ };
43
+
44
+ export { Flag };
45
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../../../../src/components/atoms/Flag/index.tsx"],"sourcesContent":[null],"names":["_jsx"],"mappings":";;;;;;AAeA,MAAM,SAAS,GAAG,CAAC,GAAY,KAAI;IACjC,MAAM,OAAO,GAAG,CAAC,EAAE,IAAI,EAAE,GAAG,KAAK,EAAmC,KAAI;AACtE,QAAA,MAAM,GAAG,GAAG,GAAG,CAAC,IAAI,CAAC;QACrB,IAAI,CAAC,GAAG,EAAE;YACR,sBAAsB,CAAC,IAAI,CAAC;AAC5B,YAAA,OAAO,IAAI;QACb;AACA,QAAA,OAAOA,GAAA,CAAC,GAAG,EAAA,EAAA,GAAK,KAAK,GAAI;AAC3B,IAAA,CAAC;AACD,IAAA,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE;AAC7B,CAAC;AAED;AACA,MAAM,SAAS,GAAG;IAChB,KAAK,EAAE,IAAI,CAAC,MAAM,OAAO,8BAA8B,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,KAAK,SAAS,CAAC,KAAgB,CAAC,CAAC,CAAC;IACtG,SAAS,EAAE,IAAI,CAAC,MAAM,OAAO,8BAA8B,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,KAAK,SAAS,CAAC,KAAgB,CAAC,CAAC,CAAC;CAC3G;AAED;AACA,MAAM,KAAK,GAAgD;AACzD,IAAA,KAAK,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,QAAQ,EAAE;AACjE,IAAA,SAAS,EAAE,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE,UAAU,EAAE;CAC7E;AAiBD;;;;;;;AAOG;AACI,MAAM,IAAI,GAAG,CAAC,EAAE,IAAI,EAAE,IAAI,GAAG,IAAI,EAAE,KAAK,GAAG,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,aAAa,EAAE,UAAU,EAAE,GAAG,KAAK,EAAa,KAAI;AACvI,IAAA,MAAM,UAAU,GAAG,iBAAiB,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;IAC/F,MAAM,IAAI,GAAG,KAAK,IAAI,cAAc,CAAC,IAAI,EAAE,MAAM,CAAC;AAClD,IAAA,MAAM,YAAY,GAAG,IAAI,KAAK,EAAE;AAChC,IAAA,MAAM,OAAO,GAAG,SAAS,CAAC,KAAK,CAAC;AAEhC,IAAA,QACEA,GAAA,CAAC,QAAQ,EAAA,EAAC,QAAQ,EAAE,IAAI,EAAA,QAAA,EACtBA,GAAA,CAAC,OAAO,OACF,KAAK,EACT,IAAI,EAAE,IAAI,iBACG,UAAU,EACvB,IAAI,EAAE,YAAY,GAAG,SAAS,GAAG,KAAK,EAAA,YAAA,EAC1B,YAAY,GAAG,SAAS,GAAG,IAAI,EAAA,aAAA,EAC9B,YAAY,IAAI,SAAS,EACtC,KAAK,EAAE,YAAY,GAAG,SAAS,GAAG,IAAI,EACtC,SAAS,EAAE,EAAE,CAAC,0BAA0B,EAAE,KAAK,KAAK,OAAO,IAAI,cAAc,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,EAAE,SAAS,CAAC,EAAA,CAC7G,EAAA,CACO;AAEf;;"}
@@ -0,0 +1,32 @@
1
+ 'use strict';
2
+
3
+ var jsxRuntime = require('react/jsx-runtime');
4
+ var uiIcons = require('@flipdish/ui-icons');
5
+ var Input = require('@flipdish/ui-library/components/atoms/Input');
6
+ var cx = require('@flipdish/ui-library/utilities/cx');
7
+ var testIdUtils = require('@flipdish/ui-library/utilities/testIdUtils');
8
+ var reactAriaComponents = require('react-aria-components');
9
+ var useHotkeyHint = require('../../../hooks/__internal__/useHotkeyHint/useHotkeyHint.cjs');
10
+
11
+ const sizes = cx.sortCx({
12
+ sm: { input: 'py-2 pr-9 pl-9 text-sm', icon: 'left-3 size-4 stroke-[2.25px]', clear: 'right-2', shortcut: 'pr-1.5' },
13
+ md: { input: 'py-2 pr-9 pl-10 text-md', icon: 'left-3 size-5', clear: 'right-2', shortcut: 'pr-2' },
14
+ lg: { input: 'py-2.5 pr-9.5 pl-10.5 text-md', icon: 'left-3.5 size-5', clear: 'right-2.5', shortcut: 'pr-2.5' },
15
+ });
16
+ /**
17
+ * A search box with a magnifier, a clear button once it holds text, and Escape to clear. Use it
18
+ * wherever typing filters a list or table; for a field that collects a value, use `Input`.
19
+ *
20
+ * @summary search box that filters as you type and clears in one press
21
+ */
22
+ const SearchInput = ({ label, hint, placeholder, size = 'md', clearLabel = 'Clear search', shortcut, className, wrapperClassName, inputClassName, ref, 'data-testid': dataTestId, ...props }) => {
23
+ const inputTestId = testIdUtils.useResolvedTestId({ testId: dataTestId, segment: 'search-input', rootName: 'search-input' });
24
+ const shortcutLabel = useHotkeyHint.useHotkeyHint(shortcut === true ? 'mod+k' : shortcut || null);
25
+ return (jsxRuntime.jsx(reactAriaComponents.SearchField, { "aria-label": label ? undefined : placeholder, ...props, className: cx.cx('group/search flex h-max w-full flex-col items-start gap-1.5', className), children: ({ isInvalid, isDisabled }) => (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [label && jsxRuntime.jsx(Input.Label, { isInvalid: isInvalid, children: label }), jsxRuntime.jsxs(reactAriaComponents.Group, { isDisabled: isDisabled, isInvalid: isInvalid, className: ({ isFocusWithin }) => cx.cx('relative flex w-full items-center rounded-lg bg-primary shadow-xs ring-1 ring-primary transition-shadow duration-100 ease-linear ring-inset', isFocusWithin && !isDisabled && 'ring-2 ring-brand', isDisabled && 'cursor-not-allowed opacity-50', isInvalid && 'ring-error_subtle', isInvalid && isFocusWithin && 'ring-2 ring-error', wrapperClassName), children: [jsxRuntime.jsx(uiIcons.SearchLg, { "aria-hidden": "true", className: cx.cx('pointer-events-none absolute text-fg-quaternary', sizes[size].icon) }), jsxRuntime.jsx(reactAriaComponents.Input, { ref: ref, "data-testid": inputTestId, placeholder: placeholder, className: cx.cx(
26
+ // The browser draws its own cancel control on a search input; the clear button below replaces it.
27
+ 'm-0 w-full bg-transparent text-primary ring-0 outline-hidden placeholder:text-placeholder disabled:cursor-not-allowed [&::-webkit-search-cancel-button]:hidden', sizes[size].input, inputClassName) }), jsxRuntime.jsx(reactAriaComponents.Button, { "aria-label": clearLabel, "data-testid": testIdUtils.joinTestId(inputTestId, 'clear'), className: cx.cx('absolute flex cursor-pointer items-center justify-center rounded-md p-1 text-fg-quaternary outline-focus-ring transition duration-100 ease-linear group-data-empty/search:hidden group-data-disabled/search:hidden group-data-readonly/search:hidden hover:text-fg-quaternary_hover focus-visible:outline-2', sizes[size].clear), children: jsxRuntime.jsx(uiIcons.XClose, { "aria-hidden": "true", className: "size-4 stroke-[2.25px]" }) }), shortcut && (jsxRuntime.jsx("div", { className: cx.cx('pointer-events-none absolute inset-y-0.5 right-0.5 z-10 hidden items-center rounded-r-[inherit] bg-linear-to-r from-transparent to-bg-primary to-40% pl-8 group-data-empty/search:md:flex', sizes[size].shortcut), children: jsxRuntime.jsx("span", { "aria-hidden": "true", className: "rounded px-1 py-px text-xs font-medium text-quaternary ring-1 ring-secondary select-none ring-inset", children: shortcutLabel }) }))] }), hint && jsxRuntime.jsx(Input.HintText, { isInvalid: isInvalid, children: hint })] })) }));
28
+ };
29
+ SearchInput.displayName = 'SearchInput';
30
+
31
+ exports.SearchInput = SearchInput;
32
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs","sources":["../../../../src/components/atoms/SearchInput/index.tsx"],"sourcesContent":[null],"names":["sortCx","useResolvedTestId","useHotkeyHint","_jsx","AriaSearchField","cx","_jsxs","_Fragment","Label","AriaGroup","SearchLg","AriaInput","AriaButton","joinTestId","XClose","HintText"],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ import type { ReactNode, Ref } from 'react';
2
+ import type { SearchFieldProps as AriaSearchFieldProps } from 'react-aria-components';
3
+ export interface SearchInputProps extends Omit<AriaSearchFieldProps, 'children' | 'className' | 'style'> {
4
+ /** Visible label above the field. Without one, pass `aria-label`; the placeholder alone does not name the field once it holds a value. */
5
+ label?: string;
6
+ /** Helper text under the field. */
7
+ hint?: ReactNode;
8
+ /** Placeholder shown while the field is empty. */
9
+ placeholder?: string;
10
+ /** Height, padding and text size. */
11
+ size?: 'sm' | 'md' | 'lg';
12
+ /** Accessible name of the clear button. */
13
+ clearLabel?: string;
14
+ /**
15
+ * Keyboard shortcut hint shown while the field is empty. `true` shows the search shortcut (⌘K on
16
+ * macOS, Ctrl K elsewhere); a shortcut such as `mod+j` is drawn for the user's platform.
17
+ */
18
+ shortcut?: string | boolean;
19
+ /** Extra classes merged onto the outer field. */
20
+ className?: string;
21
+ /** Extra classes merged onto the bordered group around the input. */
22
+ wrapperClassName?: string;
23
+ /** Extra classes merged onto the `<input>`. */
24
+ inputClassName?: string;
25
+ /** Ref forwarded to the `<input>`. */
26
+ ref?: Ref<HTMLInputElement>;
27
+ /** Overrides the `<input>`'s `data-testid` (defaults to `fd-search-input`). The clear button derives `<root>--clear`. */
28
+ 'data-testid'?: string;
29
+ }
30
+ /**
31
+ * A search box with a magnifier, a clear button once it holds text, and Escape to clear. Use it
32
+ * wherever typing filters a list or table; for a field that collects a value, use `Input`.
33
+ *
34
+ * @summary search box that filters as you type and clears in one press
35
+ */
36
+ export declare const SearchInput: {
37
+ ({ label, hint, placeholder, size, clearLabel, shortcut, className, wrapperClassName, inputClassName, ref, "data-testid": dataTestId, ...props }: SearchInputProps): import("react").JSX.Element;
38
+ displayName: string;
39
+ };
40
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/atoms/SearchInput/index.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAC5C,OAAO,KAAK,EAAE,gBAAgB,IAAI,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAUtF,MAAM,WAAW,gBAAiB,SAAQ,IAAI,CAAC,oBAAoB,EAAE,UAAU,GAAG,WAAW,GAAG,OAAO,CAAC;IACtG,0IAA0I;IAC1I,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,mCAAmC;IACnC,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,kDAAkD;IAClD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,qCAAqC;IACrC,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IAC1B,2CAA2C;IAC3C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAC5B,iDAAiD;IACjD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qEAAqE;IACrE,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,+CAA+C;IAC/C,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,sCAAsC;IACtC,GAAG,CAAC,EAAE,GAAG,CAAC,gBAAgB,CAAC,CAAC;IAC5B,yHAAyH;IACzH,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;;;GAKG;AACH,eAAO,MAAM,WAAW;sJAarB,gBAAgB;;CAuElB,CAAC"}
@@ -0,0 +1,30 @@
1
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
+ import { SearchLg, XClose } from '@flipdish/ui-icons';
3
+ import { Label, HintText } from '@flipdish/ui-library/components/atoms/Input';
4
+ import { sortCx, cx } from '@flipdish/ui-library/utilities/cx';
5
+ import { useResolvedTestId, joinTestId } from '@flipdish/ui-library/utilities/testIdUtils';
6
+ import { SearchField, Group, Input, Button } from 'react-aria-components';
7
+ import { useHotkeyHint } from '../../../hooks/__internal__/useHotkeyHint/useHotkeyHint.js';
8
+
9
+ const sizes = sortCx({
10
+ sm: { input: 'py-2 pr-9 pl-9 text-sm', icon: 'left-3 size-4 stroke-[2.25px]', clear: 'right-2', shortcut: 'pr-1.5' },
11
+ md: { input: 'py-2 pr-9 pl-10 text-md', icon: 'left-3 size-5', clear: 'right-2', shortcut: 'pr-2' },
12
+ lg: { input: 'py-2.5 pr-9.5 pl-10.5 text-md', icon: 'left-3.5 size-5', clear: 'right-2.5', shortcut: 'pr-2.5' },
13
+ });
14
+ /**
15
+ * A search box with a magnifier, a clear button once it holds text, and Escape to clear. Use it
16
+ * wherever typing filters a list or table; for a field that collects a value, use `Input`.
17
+ *
18
+ * @summary search box that filters as you type and clears in one press
19
+ */
20
+ const SearchInput = ({ label, hint, placeholder, size = 'md', clearLabel = 'Clear search', shortcut, className, wrapperClassName, inputClassName, ref, 'data-testid': dataTestId, ...props }) => {
21
+ const inputTestId = useResolvedTestId({ testId: dataTestId, segment: 'search-input', rootName: 'search-input' });
22
+ const shortcutLabel = useHotkeyHint(shortcut === true ? 'mod+k' : shortcut || null);
23
+ return (jsx(SearchField, { "aria-label": label ? undefined : placeholder, ...props, className: cx('group/search flex h-max w-full flex-col items-start gap-1.5', className), children: ({ isInvalid, isDisabled }) => (jsxs(Fragment, { children: [label && jsx(Label, { isInvalid: isInvalid, children: label }), jsxs(Group, { isDisabled: isDisabled, isInvalid: isInvalid, className: ({ isFocusWithin }) => cx('relative flex w-full items-center rounded-lg bg-primary shadow-xs ring-1 ring-primary transition-shadow duration-100 ease-linear ring-inset', isFocusWithin && !isDisabled && 'ring-2 ring-brand', isDisabled && 'cursor-not-allowed opacity-50', isInvalid && 'ring-error_subtle', isInvalid && isFocusWithin && 'ring-2 ring-error', wrapperClassName), children: [jsx(SearchLg, { "aria-hidden": "true", className: cx('pointer-events-none absolute text-fg-quaternary', sizes[size].icon) }), jsx(Input, { ref: ref, "data-testid": inputTestId, placeholder: placeholder, className: cx(
24
+ // The browser draws its own cancel control on a search input; the clear button below replaces it.
25
+ 'm-0 w-full bg-transparent text-primary ring-0 outline-hidden placeholder:text-placeholder disabled:cursor-not-allowed [&::-webkit-search-cancel-button]:hidden', sizes[size].input, inputClassName) }), jsx(Button, { "aria-label": clearLabel, "data-testid": joinTestId(inputTestId, 'clear'), className: cx('absolute flex cursor-pointer items-center justify-center rounded-md p-1 text-fg-quaternary outline-focus-ring transition duration-100 ease-linear group-data-empty/search:hidden group-data-disabled/search:hidden group-data-readonly/search:hidden hover:text-fg-quaternary_hover focus-visible:outline-2', sizes[size].clear), children: jsx(XClose, { "aria-hidden": "true", className: "size-4 stroke-[2.25px]" }) }), shortcut && (jsx("div", { className: cx('pointer-events-none absolute inset-y-0.5 right-0.5 z-10 hidden items-center rounded-r-[inherit] bg-linear-to-r from-transparent to-bg-primary to-40% pl-8 group-data-empty/search:md:flex', sizes[size].shortcut), children: jsx("span", { "aria-hidden": "true", className: "rounded px-1 py-px text-xs font-medium text-quaternary ring-1 ring-secondary select-none ring-inset", children: shortcutLabel }) }))] }), hint && jsx(HintText, { isInvalid: isInvalid, children: hint })] })) }));
26
+ };
27
+ SearchInput.displayName = 'SearchInput';
28
+
29
+ export { SearchInput };
30
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../../../../src/components/atoms/SearchInput/index.tsx"],"sourcesContent":[null],"names":["_jsx","AriaSearchField","_jsxs","_Fragment","AriaGroup","AriaInput","AriaButton"],"mappings":"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"}
@@ -0,0 +1,81 @@
1
+ 'use strict';
2
+
3
+ var useEmblaCarousel = require('embla-carousel-react');
4
+ var React = require('react');
5
+
6
+ /**
7
+ * Owns Embla's scroll position for `Carousel`: which snap is selected, whether previous and next
8
+ * are available, and the arrow keys that move between slides.
9
+ *
10
+ * @param options Embla setup for this carousel. The scroll axis comes from `orientation`, not `opts.axis`.
11
+ * @returns The viewport ref, Embla API, scroll actions, derived scroll state, and the keydown handler.
12
+ */
13
+ const useCarouselScroll = ({ orientation, opts, plugins, setApi }) => {
14
+ const [carouselRef, api] = useEmblaCarousel({
15
+ ...opts,
16
+ axis: orientation === 'horizontal' ? 'x' : 'y',
17
+ }, plugins);
18
+ const [canScrollPrev, setCanScrollPrev] = React.useState(false);
19
+ const [canScrollNext, setCanScrollNext] = React.useState(false);
20
+ const [selectedIndex, setSelectedIndex] = React.useState(0);
21
+ const [scrollSnaps, setScrollSnaps] = React.useState([]);
22
+ const onInit = React.useCallback((api) => {
23
+ if (!api)
24
+ return;
25
+ setScrollSnaps(api.scrollSnapList());
26
+ }, []);
27
+ const onSelect = React.useCallback((api) => {
28
+ if (!api)
29
+ return;
30
+ setCanScrollPrev(api.canScrollPrev());
31
+ setCanScrollNext(api.canScrollNext());
32
+ setSelectedIndex(api.selectedScrollSnap());
33
+ }, []);
34
+ const scrollPrev = React.useCallback(() => {
35
+ api?.scrollPrev();
36
+ }, [api]);
37
+ const scrollNext = React.useCallback(() => {
38
+ api?.scrollNext();
39
+ }, [api]);
40
+ const onKeyDownCapture = React.useCallback((event) => {
41
+ if (event.key === 'ArrowLeft') {
42
+ event.preventDefault();
43
+ scrollPrev();
44
+ }
45
+ else if (event.key === 'ArrowRight') {
46
+ event.preventDefault();
47
+ scrollNext();
48
+ }
49
+ }, [scrollPrev, scrollNext]);
50
+ React.useEffect(() => {
51
+ if (!api || !setApi)
52
+ return;
53
+ setApi(api);
54
+ }, [api, setApi]);
55
+ React.useEffect(() => {
56
+ if (!api)
57
+ return;
58
+ onInit(api);
59
+ onSelect(api);
60
+ api.on('reInit', onInit);
61
+ api.on('reInit', onSelect);
62
+ api.on('select', onSelect);
63
+ return () => {
64
+ api?.off('select', onSelect);
65
+ };
66
+ }, [api, onInit, onSelect]);
67
+ return {
68
+ carouselRef,
69
+ api,
70
+ scrollPrev,
71
+ scrollNext,
72
+ canScrollPrev,
73
+ canScrollNext,
74
+ selectedIndex,
75
+ scrollSnaps,
76
+ onKeyDownCapture,
77
+ };
78
+ };
79
+
80
+ exports.useCarouselScroll = useCarouselScroll;
81
+ //# sourceMappingURL=useCarouselScroll.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useCarouselScroll.cjs","sources":["../../../../../src/components/molecules/Carousel/hooks/useCarouselScroll.ts"],"sourcesContent":[null],"names":["useState","useCallback","useEffect"],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ import useEmblaCarousel, { type UseEmblaCarouselType } from 'embla-carousel-react';
2
+ import type { KeyboardEvent } from 'react';
3
+ export type CarouselApi = UseEmblaCarouselType[1];
4
+ type UseCarouselParameters = Parameters<typeof useEmblaCarousel>;
5
+ export type CarouselOptions = UseCarouselParameters[0];
6
+ export type CarouselPlugin = UseCarouselParameters[1];
7
+ export interface UseCarouselScrollOptions {
8
+ /** Scroll axis. `horizontal` maps to Embla's `x`; `vertical` maps to `y` and overrides `opts.axis`. */
9
+ orientation: 'horizontal' | 'vertical';
10
+ /** Embla options, merged under the axis taken from `orientation`. */
11
+ opts?: CarouselOptions;
12
+ /** Embla plugins, forwarded unchanged. */
13
+ plugins?: CarouselPlugin;
14
+ /** Receives the Embla API once it exists, including when this callback's identity changes. */
15
+ setApi?: (api: CarouselApi) => void;
16
+ }
17
+ export interface UseCarouselScrollResult {
18
+ /** Ref for the Embla viewport element. */
19
+ carouselRef: UseEmblaCarouselType[0];
20
+ /** Embla API once the viewport is mounted, otherwise `undefined`. */
21
+ api: CarouselApi;
22
+ /** Scrolls to the previous snap. No-op while `api` is missing. */
23
+ scrollPrev: () => void;
24
+ /** Scrolls to the next snap. No-op while `api` is missing. */
25
+ scrollNext: () => void;
26
+ /** Whether Embla can scroll to a previous snap. */
27
+ canScrollPrev: boolean;
28
+ /** Whether Embla can scroll to a next snap. */
29
+ canScrollNext: boolean;
30
+ /** Index of the selected snap. `0` until Embla reports one. */
31
+ selectedIndex: number;
32
+ /** Snap positions reported by Embla. Empty until init. */
33
+ scrollSnaps: number[];
34
+ /** ArrowLeft and ArrowRight move between snaps; other keys are ignored. */
35
+ onKeyDownCapture: (event: KeyboardEvent<HTMLDivElement>) => void;
36
+ }
37
+ /**
38
+ * Owns Embla's scroll position for `Carousel`: which snap is selected, whether previous and next
39
+ * are available, and the arrow keys that move between slides.
40
+ *
41
+ * @param options Embla setup for this carousel. The scroll axis comes from `orientation`, not `opts.axis`.
42
+ * @returns The viewport ref, Embla API, scroll actions, derived scroll state, and the keydown handler.
43
+ */
44
+ export declare const useCarouselScroll: ({ orientation, opts, plugins, setApi }: UseCarouselScrollOptions) => UseCarouselScrollResult;
45
+ export {};
46
+ //# sourceMappingURL=useCarouselScroll.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useCarouselScroll.d.ts","sourceRoot":"","sources":["../../../../../src/components/molecules/Carousel/hooks/useCarouselScroll.ts"],"names":[],"mappings":"AAEA,OAAO,gBAAgB,EAAE,EAAE,KAAK,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AACnF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAG3C,MAAM,MAAM,WAAW,GAAG,oBAAoB,CAAC,CAAC,CAAC,CAAC;AAClD,KAAK,qBAAqB,GAAG,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC;AACjE,MAAM,MAAM,eAAe,GAAG,qBAAqB,CAAC,CAAC,CAAC,CAAC;AACvD,MAAM,MAAM,cAAc,GAAG,qBAAqB,CAAC,CAAC,CAAC,CAAC;AAEtD,MAAM,WAAW,wBAAwB;IACvC,uGAAuG;IACvG,WAAW,EAAE,YAAY,GAAG,UAAU,CAAC;IACvC,qEAAqE;IACrE,IAAI,CAAC,EAAE,eAAe,CAAC;IACvB,0CAA0C;IAC1C,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,8FAA8F;IAC9F,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,WAAW,KAAK,IAAI,CAAC;CACrC;AAED,MAAM,WAAW,uBAAuB;IACtC,0CAA0C;IAC1C,WAAW,EAAE,oBAAoB,CAAC,CAAC,CAAC,CAAC;IACrC,qEAAqE;IACrE,GAAG,EAAE,WAAW,CAAC;IACjB,kEAAkE;IAClE,UAAU,EAAE,MAAM,IAAI,CAAC;IACvB,8DAA8D;IAC9D,UAAU,EAAE,MAAM,IAAI,CAAC;IACvB,mDAAmD;IACnD,aAAa,EAAE,OAAO,CAAC;IACvB,+CAA+C;IAC/C,aAAa,EAAE,OAAO,CAAC;IACvB,+DAA+D;IAC/D,aAAa,EAAE,MAAM,CAAC;IACtB,0DAA0D;IAC1D,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,2EAA2E;IAC3E,gBAAgB,EAAE,CAAC,KAAK,EAAE,aAAa,CAAC,cAAc,CAAC,KAAK,IAAI,CAAC;CAClE;AAED;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,GAAI,wCAAwC,wBAAwB,KAAG,uBAgFpG,CAAC"}
@@ -0,0 +1,79 @@
1
+ import useEmblaCarousel from 'embla-carousel-react';
2
+ import { useState, useCallback, useEffect } from 'react';
3
+
4
+ /**
5
+ * Owns Embla's scroll position for `Carousel`: which snap is selected, whether previous and next
6
+ * are available, and the arrow keys that move between slides.
7
+ *
8
+ * @param options Embla setup for this carousel. The scroll axis comes from `orientation`, not `opts.axis`.
9
+ * @returns The viewport ref, Embla API, scroll actions, derived scroll state, and the keydown handler.
10
+ */
11
+ const useCarouselScroll = ({ orientation, opts, plugins, setApi }) => {
12
+ const [carouselRef, api] = useEmblaCarousel({
13
+ ...opts,
14
+ axis: orientation === 'horizontal' ? 'x' : 'y',
15
+ }, plugins);
16
+ const [canScrollPrev, setCanScrollPrev] = useState(false);
17
+ const [canScrollNext, setCanScrollNext] = useState(false);
18
+ const [selectedIndex, setSelectedIndex] = useState(0);
19
+ const [scrollSnaps, setScrollSnaps] = useState([]);
20
+ const onInit = useCallback((api) => {
21
+ if (!api)
22
+ return;
23
+ setScrollSnaps(api.scrollSnapList());
24
+ }, []);
25
+ const onSelect = useCallback((api) => {
26
+ if (!api)
27
+ return;
28
+ setCanScrollPrev(api.canScrollPrev());
29
+ setCanScrollNext(api.canScrollNext());
30
+ setSelectedIndex(api.selectedScrollSnap());
31
+ }, []);
32
+ const scrollPrev = useCallback(() => {
33
+ api?.scrollPrev();
34
+ }, [api]);
35
+ const scrollNext = useCallback(() => {
36
+ api?.scrollNext();
37
+ }, [api]);
38
+ const onKeyDownCapture = useCallback((event) => {
39
+ if (event.key === 'ArrowLeft') {
40
+ event.preventDefault();
41
+ scrollPrev();
42
+ }
43
+ else if (event.key === 'ArrowRight') {
44
+ event.preventDefault();
45
+ scrollNext();
46
+ }
47
+ }, [scrollPrev, scrollNext]);
48
+ useEffect(() => {
49
+ if (!api || !setApi)
50
+ return;
51
+ setApi(api);
52
+ }, [api, setApi]);
53
+ useEffect(() => {
54
+ if (!api)
55
+ return;
56
+ onInit(api);
57
+ onSelect(api);
58
+ api.on('reInit', onInit);
59
+ api.on('reInit', onSelect);
60
+ api.on('select', onSelect);
61
+ return () => {
62
+ api?.off('select', onSelect);
63
+ };
64
+ }, [api, onInit, onSelect]);
65
+ return {
66
+ carouselRef,
67
+ api,
68
+ scrollPrev,
69
+ scrollNext,
70
+ canScrollPrev,
71
+ canScrollNext,
72
+ selectedIndex,
73
+ scrollSnaps,
74
+ onKeyDownCapture,
75
+ };
76
+ };
77
+
78
+ export { useCarouselScroll };
79
+ //# sourceMappingURL=useCarouselScroll.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useCarouselScroll.js","sources":["../../../../../src/components/molecules/Carousel/hooks/useCarouselScroll.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
@@ -4,8 +4,8 @@ var jsxRuntime = require('react/jsx-runtime');
4
4
  var Dot = require('@flipdish/ui-library/components/atoms/Dot');
5
5
  var cx = require('@flipdish/ui-library/utilities/cx');
6
6
  var testIdUtils = require('@flipdish/ui-library/utilities/testIdUtils');
7
- var useEmblaCarousel = require('embla-carousel-react');
8
7
  var React = require('react');
8
+ var useCarouselScroll = require('./hooks/useCarouselScroll.cjs');
9
9
 
10
10
  const CarouselContext = React.createContext(null);
11
11
  const useCarousel = () => {
@@ -17,59 +17,12 @@ const useCarousel = () => {
17
17
  };
18
18
  const CarouselRoot = ({ orientation = 'horizontal', opts, setApi, plugins, className, children, 'data-testid': dataTestId, ...props }) => {
19
19
  const rootTestId = testIdUtils.useResolvedTestId({ testId: dataTestId, segment: 'carousel', rootName: 'carousel' });
20
- const [carouselRef, api] = useEmblaCarousel({
21
- ...opts,
22
- axis: orientation === 'horizontal' ? 'x' : 'y',
23
- }, plugins);
24
- const [canScrollPrev, setCanScrollPrev] = React.useState(false);
25
- const [canScrollNext, setCanScrollNext] = React.useState(false);
26
- const [selectedIndex, setSelectedIndex] = React.useState(0);
27
- const [scrollSnaps, setScrollSnaps] = React.useState([]);
28
- const onInit = React.useCallback((api) => {
29
- if (!api)
30
- return;
31
- setScrollSnaps(api.scrollSnapList());
32
- }, []);
33
- const onSelect = React.useCallback((api) => {
34
- if (!api)
35
- return;
36
- setCanScrollPrev(api.canScrollPrev());
37
- setCanScrollNext(api.canScrollNext());
38
- setSelectedIndex(api.selectedScrollSnap());
39
- }, []);
40
- const scrollPrev = React.useCallback(() => {
41
- api?.scrollPrev();
42
- }, [api]);
43
- const scrollNext = React.useCallback(() => {
44
- api?.scrollNext();
45
- }, [api]);
46
- const handleKeyDown = React.useCallback((event) => {
47
- if (event.key === 'ArrowLeft') {
48
- event.preventDefault();
49
- scrollPrev();
50
- }
51
- else if (event.key === 'ArrowRight') {
52
- event.preventDefault();
53
- scrollNext();
54
- }
55
- }, [scrollPrev, scrollNext]);
56
- React.useEffect(() => {
57
- if (!api || !setApi)
58
- return;
59
- setApi(api);
60
- }, [api, setApi]);
61
- React.useEffect(() => {
62
- if (!api)
63
- return;
64
- onInit(api);
65
- onSelect(api);
66
- api.on('reInit', onInit);
67
- api.on('reInit', onSelect);
68
- api.on('select', onSelect);
69
- return () => {
70
- api?.off('select', onSelect);
71
- };
72
- }, [api, onInit, onSelect]);
20
+ const { carouselRef, api, scrollPrev, scrollNext, canScrollPrev, canScrollNext, selectedIndex, scrollSnaps, onKeyDownCapture } = useCarouselScroll.useCarouselScroll({
21
+ orientation,
22
+ opts,
23
+ plugins,
24
+ setApi,
25
+ });
73
26
  return (jsxRuntime.jsx(testIdUtils.TestIdProvider, { value: rootTestId, children: jsxRuntime.jsx(CarouselContext.Provider, { value: {
74
27
  carouselRef,
75
28
  api: api,
@@ -81,7 +34,7 @@ const CarouselRoot = ({ orientation = 'horizontal', opts, setApi, plugins, class
81
34
  canScrollNext,
82
35
  selectedIndex,
83
36
  scrollSnaps,
84
- }, children: jsxRuntime.jsx("div", { onKeyDownCapture: handleKeyDown, className: cx.cx('relative', className), role: "region", "aria-roledescription": "carousel", ...props, "data-testid": rootTestId, children: children }) }) }));
37
+ }, children: jsxRuntime.jsx("div", { onKeyDownCapture: onKeyDownCapture, className: cx.cx('relative', className), role: "region", "aria-roledescription": "carousel", ...props, "data-testid": rootTestId, children: children }) }) }));
85
38
  };
86
39
  const CarouselContent = ({ className, overflowHidden = true, ...props }) => {
87
40
  const { carouselRef, orientation } = useCarousel();