@wise/art 0.0.0-experimental-6054253 → 0.0.0-experimental-324afbb

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wise/art",
3
- "version": "0.0.0-experimental-6054253",
3
+ "version": "0.0.0-experimental-324afbb",
4
4
  "license": "MIT",
5
5
  "description": "React library for art elements in UI",
6
6
  "homepage": "https://github.com/transferwise/web-art#readme",
@@ -11,43 +11,69 @@ export default meta;
11
11
 
12
12
  type Story = StoryObj<typeof Flag>;
13
13
 
14
- type GroupedFlag = { country: string[]; currencies: string[][] };
15
-
16
- const groupFlags = (flags: { country: string[]; currency: string[] }[]): GroupedFlag[] =>
17
- flags.reduce<GroupedFlag[]>((acc, flag) => {
18
- const existing = acc.find(
19
- (currentFlag) => currentFlag.country[0] && currentFlag.country[0] === flag.country[0],
20
- );
21
- if (existing) {
22
- existing.currencies.push(flag.currency);
23
- } else {
24
- acc.push({ country: flag.country, currencies: [flag.currency] });
14
+ interface GroupedFlag { name: string; countryCode?: string; currencyCodes: string[] }
15
+
16
+ const toTitleCase = (str: string) =>
17
+ str.replace(/\b\w/gu, (char) => char.toUpperCase());
18
+
19
+ const deriveName = (slug: string): string => {
20
+ if (!slug.includes('-')) return toTitleCase(slug);
21
+ const nameSlug = slug.slice(slug.indexOf('-') + 1);
22
+ return toTitleCase(nameSlug.replace(/-/gu, ' '));
23
+ };
24
+
25
+ const groupByCountry = (
26
+ entries: [string, (typeof flagRawMetaData)[keyof typeof flagRawMetaData]][],
27
+ ): GroupedFlag[] => {
28
+ const countryMap = new Map<string, GroupedFlag>();
29
+ const standaloneFlags: GroupedFlag[] = [];
30
+
31
+ for (const [slug, data] of entries) {
32
+ const isDetailed = 'detailed' in data && data.detailed;
33
+ if (!isDetailed) {
34
+ const iso2 = 'iso2' in data ? data.iso2 : undefined;
35
+ const currencyCode = 'currencyCode' in data ? data.currencyCode : undefined;
36
+
37
+ if (iso2) {
38
+ const existing = countryMap.get(iso2);
39
+ if (existing) {
40
+ if (currencyCode) existing.currencyCodes.push(currencyCode);
41
+ } else {
42
+ countryMap.set(iso2, {
43
+ name: deriveName(slug),
44
+ countryCode: iso2,
45
+ currencyCodes: currencyCode ? [currencyCode] : [],
46
+ });
47
+ }
48
+ } else {
49
+ // Use slug as fallback code for entries without iso2 or currencyCode (e.g. "wise")
50
+ const code = currencyCode ?? slug;
51
+ standaloneFlags.push({
52
+ name: deriveName(slug),
53
+ countryCode: code,
54
+ currencyCodes: currencyCode ? [currencyCode] : [],
55
+ });
56
+ }
25
57
  }
26
- return acc;
27
- }, []);
28
-
29
- const allFlagsSorted = groupFlags(
30
- Object.values(flagRawMetaData)
31
- .flat()
32
- .sort((a, b) => {
33
- const nameA = (a.country.at(-1) ?? a.currency?.at(-1) ?? '').toLowerCase();
34
- const nameB = (b.country.at(-1) ?? b.currency?.at(-1) ?? '').toLowerCase();
35
- return nameA.localeCompare(nameB);
36
- }),
58
+ }
59
+
60
+ return [...countryMap.values(), ...standaloneFlags];
61
+ };
62
+
63
+ const allEntries = Object.entries(flagRawMetaData);
64
+ const allFlagsSorted = groupByCountry(allEntries).sort((a, b) =>
65
+ a.name.localeCompare(b.name),
37
66
  );
38
67
 
68
+ const getFlagsByRegion = (region: string): GroupedFlag[] =>
69
+ groupByCountry(allEntries.filter(([, data]) => data.group === region));
70
+
39
71
  // Helper function to render all flags and sizes for a given region
40
72
  const AllFlagsAndSizes = (
41
73
  region: string,
42
74
  flagsOverride?: GroupedFlag[],
43
75
  ) => {
44
- const regionFlags =
45
- flagsOverride ??
46
- groupFlags(
47
- Object.entries(flagRawMetaData)
48
- .filter(([currentRegion]) => currentRegion === region)
49
- .flatMap(([, flags]) => flags),
50
- );
76
+ const regionFlags = flagsOverride ?? getFlagsByRegion(region);
51
77
 
52
78
  return (
53
79
  <>
@@ -71,19 +97,11 @@ const AllFlagsAndSizes = (
71
97
  }}
72
98
  >
73
99
  {regionFlags.map((flag) => {
74
- const countryCode = flag.country[0]?.toUpperCase();
75
- const primaryCurrencyCode = flag.currencies[0]?.[0]?.toUpperCase();
76
- const flagCode = countryCode ?? primaryCurrencyCode;
77
- const currencyCodes = flag.currencies.map((currency) => currency[0]).filter(Boolean).map((code) => code.toUpperCase());
78
-
79
- // Covers cases where there's just a currency code and no country (e.g. Euro)
80
- const flagName = countryCode
81
- ? flag.country.at(-1)
82
- : flag.currencies[0]?.at(-1);
100
+ const flagCode = flag.countryCode ?? flag.currencyCodes[0];
83
101
 
84
102
  return (
85
103
  <div
86
- key={flagName}
104
+ key={flag.name}
87
105
  style={{
88
106
  display: 'flex',
89
107
  flexDirection: 'column',
@@ -111,19 +129,19 @@ const AllFlagsAndSizes = (
111
129
  alignItems: 'flex-start',
112
130
  }}
113
131
  >
114
- <strong>{flagName}</strong>
132
+ <strong>{flag.name}</strong>
115
133
  <span>
116
- {countryCode && (
134
+ {flag.countryCode && (
117
135
  <>
118
- Country: <code>{countryCode}</code>
136
+ Country: <code>{flag.countryCode}</code>
119
137
  </>
120
138
  )}
121
- {currencyCodes.length > 0 && (
139
+ {flag.currencyCodes.length > 0 && (
122
140
  <>
123
141
  <br />
124
142
  <span>
125
- {`${currencyCodes.length === 1 ? 'Currency' : 'Currencies'}: `}
126
- {currencyCodes.map((currencyCode) => (
143
+ {`${flag.currencyCodes.length === 1 ? 'Currency' : 'Currencies'}: `}
144
+ {flag.currencyCodes.map((currencyCode) => (
127
145
  <code key={currencyCode}>{currencyCode}</code>
128
146
  ))}
129
147
  </span>
@@ -182,7 +200,3 @@ export const SouthAmerica: Story = {
182
200
  export const Misc: Story = {
183
201
  render: () => AllFlagsAndSizes('Misc'),
184
202
  };
185
-
186
- export const Fallback: Story = {
187
- render: () => AllFlagsAndSizes('Fallback'),
188
- };