react-native-football-formation 1.0.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 (65) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +447 -0
  3. package/dist/assets/index.d.ts +13 -0
  4. package/dist/assets/index.d.ts.map +1 -0
  5. package/dist/assets/index.js +15 -0
  6. package/dist/components/FormationField.d.ts +5 -0
  7. package/dist/components/FormationField.d.ts.map +1 -0
  8. package/dist/components/FormationField.js +147 -0
  9. package/dist/components/PlayerCard.d.ts +5 -0
  10. package/dist/components/PlayerCard.d.ts.map +1 -0
  11. package/dist/components/PlayerCard.js +365 -0
  12. package/dist/components/index.d.ts +3 -0
  13. package/dist/components/index.d.ts.map +1 -0
  14. package/dist/components/index.js +10 -0
  15. package/dist/index.d.ts +11 -0
  16. package/dist/index.d.ts.map +1 -0
  17. package/dist/index.js +35 -0
  18. package/dist/theme/defaultTheme.d.ts +12 -0
  19. package/dist/theme/defaultTheme.d.ts.map +1 -0
  20. package/dist/theme/defaultTheme.js +70 -0
  21. package/dist/theme/index.d.ts +2 -0
  22. package/dist/theme/index.d.ts.map +1 -0
  23. package/dist/theme/index.js +17 -0
  24. package/dist/types/component.types.d.ts +48 -0
  25. package/dist/types/component.types.d.ts.map +1 -0
  26. package/dist/types/component.types.js +2 -0
  27. package/dist/types/formation.types.d.ts +59 -0
  28. package/dist/types/formation.types.d.ts.map +1 -0
  29. package/dist/types/formation.types.js +5 -0
  30. package/dist/types/index.d.ts +4 -0
  31. package/dist/types/index.d.ts.map +1 -0
  32. package/dist/types/index.js +19 -0
  33. package/dist/types/theme.types.d.ts +44 -0
  34. package/dist/types/theme.types.d.ts.map +1 -0
  35. package/dist/types/theme.types.js +5 -0
  36. package/dist/utils/formationCoordinates.d.ts +10 -0
  37. package/dist/utils/formationCoordinates.d.ts.map +1 -0
  38. package/dist/utils/formationCoordinates.js +311 -0
  39. package/dist/utils/index.d.ts +3 -0
  40. package/dist/utils/index.d.ts.map +1 -0
  41. package/dist/utils/index.js +18 -0
  42. package/dist/utils/transformLineup.d.ts +21 -0
  43. package/dist/utils/transformLineup.d.ts.map +1 -0
  44. package/dist/utils/transformLineup.js +126 -0
  45. package/package.json +60 -0
  46. package/src/assets/images/field.png +0 -0
  47. package/src/assets/images/football.png +0 -0
  48. package/src/assets/images/kicker.png +0 -0
  49. package/src/assets/images/ownGoals.png +0 -0
  50. package/src/assets/images/playerPlaceholder.png +0 -0
  51. package/src/assets/images/renewal.png +0 -0
  52. package/src/assets/index.ts +12 -0
  53. package/src/components/FormationField.tsx +182 -0
  54. package/src/components/PlayerCard.tsx +452 -0
  55. package/src/components/index.ts +2 -0
  56. package/src/index.ts +20 -0
  57. package/src/theme/defaultTheme.ts +74 -0
  58. package/src/theme/index.ts +1 -0
  59. package/src/types/component.types.ts +72 -0
  60. package/src/types/formation.types.ts +88 -0
  61. package/src/types/index.ts +3 -0
  62. package/src/types/theme.types.ts +48 -0
  63. package/src/utils/formationCoordinates.ts +335 -0
  64. package/src/utils/index.ts +2 -0
  65. package/src/utils/transformLineup.ts +158 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,447 @@
1
+ # React Native Football Formation
2
+
3
+ A highly customizable React Native component for displaying football/soccer team formations with player positions, stats, and match information.
4
+
5
+ ![React Native](https://img.shields.io/badge/React%20Native-%3E%3D0.74.0-blue)
6
+ ![TypeScript](https://img.shields.io/badge/TypeScript-5.0-blue)
7
+ ![License](https://img.shields.io/badge/license-MIT-green)
8
+
9
+ ## Features
10
+
11
+ ✅ **24 Supported Formations** - All major tactical formations (4-3-3, 4-2-3-1, 3-5-2, etc.)
12
+ ✅ **Player Statistics** - Goals, assists, cards, substitutions, own goals
13
+ ✅ **Highly Customizable** - Theme system for colors, fonts, spacing
14
+ ✅ **RTL Support** - Built-in support for right-to-left languages
15
+ ✅ **TypeScript** - Full type safety and IntelliSense
16
+ ✅ **Expo & Bare RN** - Compatible with both Expo and bare React Native projects
17
+ ✅ **Asset Override** - Use your own field backgrounds and icons
18
+ ✅ **Component Override** - Custom rendering for player cards and footer
19
+ ✅ **Responsive** - Adapts to different screen sizes
20
+
21
+ ## Installation
22
+
23
+ ```bash
24
+ npm install react-native-football-formation
25
+ ```
26
+
27
+ or
28
+
29
+ ```bash
30
+ yarn add react-native-football-formation
31
+ ```
32
+
33
+ ## Quick Start
34
+
35
+ ```tsx
36
+ import { FormationField } from 'react-native-football-formation';
37
+
38
+ function App() {
39
+ const lineup = {
40
+ players: [/* player data */],
41
+ formationUsed: '433',
42
+ };
43
+
44
+ return <FormationField lineup={lineup} />;
45
+ }
46
+ ```
47
+
48
+ ## Basic Usage
49
+
50
+ ### Simple Example
51
+
52
+ ```tsx
53
+ import React from 'react';
54
+ import { FormationField } from 'react-native-football-formation';
55
+
56
+ export default function FormationScreen() {
57
+ const teamLineup = {
58
+ players: [
59
+ {
60
+ playerId: '1',
61
+ matchName: 'De Gea',
62
+ shirtNumber: 1,
63
+ rating: '7.5',
64
+ position: 'Goalkeeper',
65
+ formationPlace: '1',
66
+ stats: [],
67
+ },
68
+ // ... 10 more players
69
+ ],
70
+ formationUsed: '433',
71
+ };
72
+
73
+ return (
74
+ <FormationField
75
+ lineup={teamLineup}
76
+ getPlayerPhotoUrl={(playerId) =>
77
+ `https://example.com/players/${playerId}.png`
78
+ }
79
+ />
80
+ );
81
+ }
82
+ ```
83
+
84
+ ### With Custom Theme
85
+
86
+ ```tsx
87
+ <FormationField
88
+ lineup={teamLineup}
89
+ theme={{
90
+ colors: {
91
+ primary: '#FF0000',
92
+ success: '#00FF00',
93
+ warning: '#FFAA00',
94
+ },
95
+ typography: {
96
+ fontFamily: 'MyCustomFont-Regular',
97
+ fontFamilyBold: 'MyCustomFont-Bold',
98
+ },
99
+ }}
100
+ />
101
+ ```
102
+
103
+ ### With Player Interaction
104
+
105
+ ```tsx
106
+ <FormationField
107
+ lineup={teamLineup}
108
+ onPlayerPress={(player) => {
109
+ console.log('Player tapped:', player.matchName);
110
+ // Navigate to player details or show modal
111
+ }}
112
+ />
113
+ ```
114
+
115
+ ### With Custom Assets
116
+
117
+ ```tsx
118
+ <FormationField
119
+ lineup={teamLineup}
120
+ fieldImage={require('./assets/custom-field.png')}
121
+ footballIcon={require('./assets/custom-goal-icon.png')}
122
+ playerPlaceholder={require('./assets/custom-placeholder.png')}
123
+ />
124
+ ```
125
+
126
+ ## API Reference
127
+
128
+ ### FormationField Props
129
+
130
+ | Prop | Type | Default | Description |
131
+ |------|------|---------|-------------|
132
+ | `lineup` | `TeamLineup` | **required** | Team lineup data with players and formation |
133
+ | `width` | `number` | `screenWidth + 10` | Field width |
134
+ | `height` | `number` | `395` | Field height |
135
+ | `theme` | `Partial<FormationTheme>` | `defaultTheme` | Theme customization |
136
+ | `fieldImage` | `ImageSourcePropType` | default field | Background field image |
137
+ | `playerPlaceholder` | `ImageSourcePropType` | default avatar | Placeholder for missing player photos |
138
+ | `footballIcon` | `ImageSourcePropType` | default icon | Icon for goals |
139
+ | `kickerIcon` | `ImageSourcePropType` | default icon | Icon for assists |
140
+ | `renewalIcon` | `ImageSourcePropType` | default icon | Icon for substitutions |
141
+ | `ownGoalIcon` | `ImageSourcePropType` | default icon | Icon for own goals |
142
+ | `logoImage` | `ImageSourcePropType` | `undefined` | Optional logo to display |
143
+ | `renderPlayerCard` | `(player, width, height) => ReactNode` | `undefined` | Custom player card renderer |
144
+ | `renderFooter` | `(formation) => ReactNode` | `undefined` | Custom footer renderer |
145
+ | `onPlayerPress` | `(player) => void` | `undefined` | Player tap callback |
146
+ | `showLogo` | `boolean` | `false` | Show/hide logo |
147
+ | `showFormation` | `boolean` | `true` | Show/hide formation badge |
148
+ | `showRating` | `boolean` | `false` | Show/hide player ratings |
149
+ | `containerStyle` | `ViewStyle` | `undefined` | Container style override |
150
+ | `playerCardStyle` | `ViewStyle` | `undefined` | Player card style override |
151
+ | `playerNameStyle` | `TextStyle` | `undefined` | Player name text style override |
152
+ | `getPlayerPhotoUrl` | `(playerId: string) => string` | `undefined` | Function to generate player photo URLs |
153
+
154
+ ### TeamLineup Type
155
+
156
+ ```typescript
157
+ interface TeamLineup {
158
+ players: Player[];
159
+ formationUsed: string; // e.g., "433", "4231", "352"
160
+ }
161
+
162
+ interface Player {
163
+ rating: string;
164
+ playerId: string;
165
+ position: string;
166
+ matchName: string;
167
+ shirtNumber: number;
168
+ formationPlace?: string; // "1" to "11"
169
+ stats: PlayerStats[] | null[];
170
+ }
171
+
172
+ interface PlayerStats {
173
+ type: string; // "goals", "yellowCard", "redCard", "goalAssist", etc.
174
+ value: string | number;
175
+ }
176
+ ```
177
+
178
+ ### FormationTheme Type
179
+
180
+ ```typescript
181
+ interface FormationTheme {
182
+ colors: {
183
+ primary: string;
184
+ blue: string;
185
+ white: string;
186
+ text: string;
187
+ border: string;
188
+ warning: string;
189
+ success: string;
190
+ error: string;
191
+ newError: string;
192
+ formationBadge: string;
193
+ };
194
+ spacing: {
195
+ playerCardWidth: number;
196
+ playerCardHeight: number;
197
+ playerImageSize: number;
198
+ jerseyNumberSize: number;
199
+ iconSize: number;
200
+ badgeMinWidth: number;
201
+ badgeHeight: number;
202
+ };
203
+ typography: {
204
+ playerNameSize: number;
205
+ formationSize: number;
206
+ jerseyNumberSize: number;
207
+ goalCountSize: number;
208
+ fontFamily?: string;
209
+ fontFamilyBold?: string;
210
+ };
211
+ borderRadius: {
212
+ playerImage: number;
213
+ badge: number;
214
+ card: number;
215
+ };
216
+ }
217
+ ```
218
+
219
+ ## Supported Formations
220
+
221
+ The component supports 24 different tactical formations:
222
+
223
+ ### 4-Back Formations
224
+ - `4-4-2` - Classic 4-4-2
225
+ - `4-3-3` - 4-3-3
226
+ - `4-2-3-1` - 4-2-3-1 (most common modern formation)
227
+ - `4-1-2-1-2` - 4-1-2-1-2 Diamond
228
+ - `4-5-1` - 4-5-1
229
+ - `4-4-1-1` - 4-4-1-1
230
+ - `4-1-4-1` - 4-1-4-1
231
+ - `4-3-2-1` - 4-3-2-1 Christmas Tree
232
+ - `4-2-2-2` - 4-2-2-2
233
+ - `4-1-3-2` - 4-1-3-2
234
+ - `4-2-4-0` - 4-2-4-0 False 9
235
+ - `4-3-1-2` - 4-3-1-2
236
+
237
+ ### 5-Back Formations
238
+ - `5-3-2` - 5-3-2
239
+ - `5-4-1` - 5-4-1
240
+
241
+ ### 3-Back Formations
242
+ - `3-5-2` - 3-5-2
243
+ - `3-4-3` - 3-4-3
244
+ - `3-5-1-1` - 3-5-1-1
245
+ - `3-4-2-1` - 3-4-2-1
246
+ - `3-4-1-2` - 3-4-1-2
247
+ - `3-1-4-2` - 3-1-4-2
248
+ - `3-4-3d` - 3-4-3 Diamond
249
+ - `3-2-4-1` - 3-2-4-1
250
+ - `3-3-3-1` - 3-3-3-1
251
+
252
+ ## Advanced Usage
253
+
254
+ ### Custom Player Card Renderer
255
+
256
+ ```tsx
257
+ <FormationField
258
+ lineup={teamLineup}
259
+ renderPlayerCard={(player, fieldWidth, fieldHeight) => (
260
+ <CustomPlayerCard
261
+ player={player}
262
+ width={fieldWidth}
263
+ height={fieldHeight}
264
+ onPress={() => navigateToPlayerDetails(player)}
265
+ />
266
+ )}
267
+ />
268
+ ```
269
+
270
+ ### Custom Footer
271
+
272
+ ```tsx
273
+ <FormationField
274
+ lineup={teamLineup}
275
+ renderFooter={(formation) => (
276
+ <View style={styles.customFooter}>
277
+ <Text>Formation: {formation}</Text>
278
+ <Text>Tactical Analysis</Text>
279
+ </View>
280
+ )}
281
+ />
282
+ ```
283
+
284
+ ### Full Customization Example
285
+
286
+ ```tsx
287
+ <FormationField
288
+ lineup={teamLineup}
289
+ width={400}
290
+ height={500}
291
+ theme={{
292
+ colors: {
293
+ primary: '#0066CC',
294
+ success: '#28A745',
295
+ warning: '#FFC107',
296
+ error: '#DC3545',
297
+ text: '#000000',
298
+ white: '#FFFFFF',
299
+ formationBadge: '#2C3E50',
300
+ },
301
+ typography: {
302
+ fontFamily: 'Roboto-Regular',
303
+ fontFamilyBold: 'Roboto-Bold',
304
+ playerNameSize: 14,
305
+ formationSize: 16,
306
+ },
307
+ spacing: {
308
+ playerCardWidth: 80,
309
+ playerCardHeight: 60,
310
+ playerImageSize: 50,
311
+ },
312
+ }}
313
+ fieldImage={require('./assets/grass-field.png')}
314
+ onPlayerPress={(player) => console.log(player)}
315
+ showFormation={true}
316
+ showLogo={false}
317
+ getPlayerPhotoUrl={(playerId) =>
318
+ `https://cdn.example.com/players/${playerId}.png`
319
+ }
320
+ />
321
+ ```
322
+
323
+ ## Player Statistics
324
+
325
+ The component automatically displays player statistics when available:
326
+
327
+ - ⚽ **Goals** - Football icon with count
328
+ - 👟 **Assists** - Kicker icon
329
+ - 🟨 **Yellow Card** - Yellow card indicator
330
+ - 🟥 **Red Card** - Red card indicator
331
+ - 🔄 **Substitution** - Substitution icon
332
+ - ⚽🔴 **Own Goals** - Own goal icon with count
333
+
334
+ Statistics are extracted from the `stats` array in the player data:
335
+
336
+ ```typescript
337
+ {
338
+ stats: [
339
+ { type: 'goals', value: '2' },
340
+ { type: 'yellowCard', value: '1' },
341
+ { type: 'goalAssist', value: '1' },
342
+ ]
343
+ }
344
+ ```
345
+
346
+ ## Utilities
347
+
348
+ The package exports utility functions for advanced use cases:
349
+
350
+ ```typescript
351
+ import {
352
+ transformLineupByFormationPlace,
353
+ hasStat,
354
+ getStatValue,
355
+ FORMATION_COORDINATES_BY_PLACE,
356
+ } from 'react-native-football-formation';
357
+
358
+ // Transform raw lineup data
359
+ const positionedPlayers = transformLineupByFormationPlace(
360
+ teamLineup,
361
+ '4-3-3',
362
+ (playerId) => `https://example.com/${playerId}.png`
363
+ );
364
+
365
+ // Check if player has a stat
366
+ const hasGoals = hasStat(player.stats, 'goals');
367
+
368
+ // Get stat value
369
+ const goalCount = getStatValue(player.stats, 'goals');
370
+
371
+ // Access formation coordinates
372
+ const coords = FORMATION_COORDINATES_BY_PLACE['4-3-3']['1']; // GK position
373
+ ```
374
+
375
+ ## TypeScript Support
376
+
377
+ The package is written in TypeScript and includes full type definitions. Import types for better development experience:
378
+
379
+ ```typescript
380
+ import type {
381
+ TeamLineup,
382
+ Player,
383
+ LineupFormationPlayer,
384
+ FormationTheme,
385
+ FormationFieldProps,
386
+ } from 'react-native-football-formation';
387
+ ```
388
+
389
+ ## Troubleshooting
390
+
391
+ ### Images not loading
392
+
393
+ Make sure you've provided either:
394
+ 1. Player photo URLs via the `photo` field in player data, OR
395
+ 2. A `getPlayerPhotoUrl` function prop
396
+
397
+ ```tsx
398
+ <FormationField
399
+ lineup={teamLineup}
400
+ getPlayerPhotoUrl={(playerId) =>
401
+ `https://your-cdn.com/players/${playerId}.png`
402
+ }
403
+ />
404
+ ```
405
+
406
+ ### Formation not displaying correctly
407
+
408
+ Ensure the `formationUsed` field matches one of the supported formations (without dashes):
409
+ - ✅ `"433"` or `"4-3-3"`
410
+ - ❌ `"4-3-3-1"` (not supported)
411
+
412
+ The component automatically handles both formats ("433" and "4-3-3").
413
+
414
+ ### Players in wrong positions
415
+
416
+ Check that each player has a valid `formationPlace` field from "1" to "11":
417
+ - Position 1 is always the goalkeeper
418
+ - Positions 2-11 depend on the formation
419
+
420
+ ## Examples
421
+
422
+ See the `/examples` directory for complete working examples:
423
+
424
+ - **basic/** - Simple formation display
425
+ - **custom-styling/** - Custom theme and styling
426
+ - **custom-assets/** - Custom images and icons
427
+
428
+ ## Contributing
429
+
430
+ Contributions are welcome! Please feel free to submit a Pull Request.
431
+
432
+ ## License
433
+
434
+ MIT © Arbab Rafiq
435
+
436
+ ## Author
437
+
438
+ **Arbab Rafiq**
439
+
440
+ ## Acknowledgments
441
+
442
+ - Inspired by modern football tactical analysis tools
443
+ - Built for the React Native community
444
+
445
+ ---
446
+
447
+ Made with ⚽ for football fans and developers
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Default image assets for the Formation Field component
3
+ * Users can override these by passing custom ImageSourcePropType to the component
4
+ */
5
+ export declare const defaultAssets: {
6
+ field: any;
7
+ football: any;
8
+ kicker: any;
9
+ renewal: any;
10
+ ownGoals: any;
11
+ playerPlaceholder: any;
12
+ };
13
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/assets/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,eAAO,MAAM,aAAa;;;;;;;CAOzB,CAAC"}
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.defaultAssets = void 0;
4
+ /**
5
+ * Default image assets for the Formation Field component
6
+ * Users can override these by passing custom ImageSourcePropType to the component
7
+ */
8
+ exports.defaultAssets = {
9
+ field: require('./images/field.png'),
10
+ football: require('./images/football.png'),
11
+ kicker: require('./images/kicker.png'),
12
+ renewal: require('./images/renewal.png'),
13
+ ownGoals: require('./images/ownGoals.png'),
14
+ playerPlaceholder: require('./images/playerPlaceholder.png'),
15
+ };
@@ -0,0 +1,5 @@
1
+ import React from 'react';
2
+ import { FormationFieldProps } from '../types';
3
+ declare const _default: React.NamedExoticComponent<FormationFieldProps>;
4
+ export default _default;
5
+ //# sourceMappingURL=FormationField.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FormationField.d.ts","sourceRoot":"","sources":["../../src/components/FormationField.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAkB,MAAM,OAAO,CAAC;AAUvC,OAAO,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;;AA2K/C,wBAA0C"}
@@ -0,0 +1,147 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ const react_1 = __importStar(require("react"));
40
+ const react_native_1 = require("react-native");
41
+ const utils_1 = require("../utils");
42
+ const theme_1 = require("../theme");
43
+ const assets_1 = require("../assets");
44
+ const PlayerCard_1 = __importDefault(require("./PlayerCard"));
45
+ const { width: screenWidth } = react_native_1.Dimensions.get('window');
46
+ const FormationField = ({ lineup, width = screenWidth + 10, height = 395, theme: customTheme, fieldImage = assets_1.defaultAssets.field, playerPlaceholder, footballIcon, kickerIcon, renewalIcon, ownGoalIcon, logoImage, renderPlayerCard, renderFooter, onPlayerPress, showLogo = false, showFormation = true, showRating = false, containerStyle, playerCardStyle, playerNameStyle, getPlayerPhotoUrl, }) => {
47
+ const theme = (0, theme_1.mergeTheme)(customTheme);
48
+ const lineupTransformed = (0, react_1.useMemo)(() => {
49
+ if (!lineup)
50
+ return [];
51
+ const formation = lineup?.formationUsed?.split('').join('-') || '4-3-3';
52
+ return (0, utils_1.transformLineupByFormationPlace)(lineup, formation, getPlayerPhotoUrl);
53
+ }, [lineup, getPlayerPhotoUrl]);
54
+ const formationDisplay = lineup?.formationUsed?.split('').join('-') || '4-3-3';
55
+ return (<react_native_1.ImageBackground source={fieldImage} style={[
56
+ styles.footballField,
57
+ {
58
+ width,
59
+ height,
60
+ },
61
+ containerStyle,
62
+ ]} resizeMode="cover">
63
+ {/* Players */}
64
+ {!!lineupTransformed?.length &&
65
+ lineupTransformed?.map(player => {
66
+ if (renderPlayerCard) {
67
+ return (<react_native_1.View key={player.playerId}>
68
+ {renderPlayerCard(player, width, height)}
69
+ </react_native_1.View>);
70
+ }
71
+ return (<PlayerCard_1.default key={player.playerId} player={player} fieldWidth={width} fieldHeight={height} theme={theme} onPress={onPlayerPress} style={playerCardStyle} nameStyle={playerNameStyle} playerPlaceholder={playerPlaceholder} footballIcon={footballIcon} kickerIcon={kickerIcon} renewalIcon={renewalIcon} ownGoalIcon={ownGoalIcon}/>);
72
+ })}
73
+
74
+ {/* Footer Section */}
75
+ {renderFooter ? (<react_native_1.View style={styles.fieldBottomWrapper}>
76
+ {renderFooter(formationDisplay)}
77
+ </react_native_1.View>) : (<react_native_1.View style={styles.fieldBottomWrapper}>
78
+ <react_native_1.View style={[
79
+ styles.fieldBottomContainer,
80
+ {
81
+ flexDirection: react_native_1.I18nManager.isRTL ? 'row-reverse' : 'row',
82
+ },
83
+ ]}>
84
+ {/* Formation Display */}
85
+ {showFormation && (<react_native_1.View style={{ justifyContent: 'center' }}>
86
+ <react_native_1.View style={[
87
+ styles.formationUsedContainer,
88
+ { backgroundColor: theme.colors.formationBadge },
89
+ ]}>
90
+ <react_native_1.Text style={[
91
+ styles.formationText,
92
+ {
93
+ fontSize: theme.typography.formationSize,
94
+ fontFamily: theme.typography.fontFamilyBold,
95
+ color: theme.colors.white,
96
+ },
97
+ ]}>
98
+ {formationDisplay}
99
+ </react_native_1.Text>
100
+ </react_native_1.View>
101
+ </react_native_1.View>)}
102
+
103
+ {/* Optional Logo */}
104
+ {showLogo && logoImage && (<react_native_1.View style={styles.logoImageContainer}>
105
+ <react_native_1.ImageBackground source={logoImage} style={styles.logoImage}/>
106
+ </react_native_1.View>)}
107
+ </react_native_1.View>
108
+ </react_native_1.View>)}
109
+ </react_native_1.ImageBackground>);
110
+ };
111
+ const styles = react_native_1.StyleSheet.create({
112
+ footballField: {
113
+ position: 'relative',
114
+ marginTop: 20,
115
+ },
116
+ fieldBottomWrapper: {
117
+ height: 40,
118
+ position: 'absolute',
119
+ bottom: react_native_1.Platform.OS === 'ios' ? 4 : 5,
120
+ },
121
+ fieldBottomContainer: {
122
+ paddingHorizontal: 10,
123
+ width: '100%',
124
+ justifyContent: 'space-between',
125
+ alignItems: 'center',
126
+ },
127
+ formationUsedContainer: {
128
+ minWidth: 60,
129
+ minHeight: 20,
130
+ borderRadius: 99,
131
+ justifyContent: 'center',
132
+ alignItems: 'center',
133
+ paddingHorizontal: 12,
134
+ paddingVertical: 4,
135
+ },
136
+ formationText: {
137
+ includeFontPadding: false,
138
+ },
139
+ logoImageContainer: {
140
+ justifyContent: 'center',
141
+ },
142
+ logoImage: {
143
+ width: 64,
144
+ height: 60,
145
+ },
146
+ });
147
+ exports.default = react_1.default.memo(FormationField);
@@ -0,0 +1,5 @@
1
+ import React from 'react';
2
+ import { PlayerCardProps } from '../types';
3
+ declare const _default: React.NamedExoticComponent<PlayerCardProps>;
4
+ export default _default;
5
+ //# sourceMappingURL=PlayerCard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PlayerCard.d.ts","sourceRoot":"","sources":["../../src/components/PlayerCard.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAU1B,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;;AAyb3C,wBAAsC"}