Merge pull request #14 from djwesty/vutukuri15/2
Implement Player Count Selector Component (Issue #2)
This commit is contained in:
commit
ef7e9fd081
@ -1,15 +1,21 @@
|
||||
import { Text, View } from "react-native";
|
||||
import React, { useState } from "react";
|
||||
import { ScrollView, Text } from "react-native";
|
||||
import PlayerSelector from "@/components/PlayerSelector";
|
||||
|
||||
const IndexScreen = () => {
|
||||
const [playerCount, setPlayerCount] = useState(2);
|
||||
|
||||
export default function Index() {
|
||||
return (
|
||||
<View
|
||||
style={{
|
||||
flex: 1,
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
}}
|
||||
>
|
||||
<Text>Edit app/index.tsx to edit this screen.</Text>
|
||||
</View>
|
||||
<ScrollView contentContainerStyle={{ padding: 20, flexGrow: 1 }}>
|
||||
<Text style={{ fontSize: 24, marginBottom: 30, marginTop: 50 }}>
|
||||
Poker Chip Helper
|
||||
</Text>
|
||||
|
||||
<PlayerSelector
|
||||
playerCount={playerCount}
|
||||
setPlayerCount={setPlayerCount}
|
||||
/>
|
||||
</ScrollView>
|
||||
);
|
||||
}
|
||||
};
|
||||
export default IndexScreen;
|
||||
|
64
components/PlayerSelector.tsx
Normal file
64
components/PlayerSelector.tsx
Normal file
@ -0,0 +1,64 @@
|
||||
import React from "react";
|
||||
import { View, Text, Button, Image, StyleSheet } from "react-native";
|
||||
|
||||
interface PlayerSelectorProps {
|
||||
playerCount: number;
|
||||
setPlayerCount: React.Dispatch<React.SetStateAction<number>>;
|
||||
}
|
||||
|
||||
const PlayerSelector: React.FC<PlayerSelectorProps> = ({
|
||||
playerCount,
|
||||
setPlayerCount,
|
||||
}) => {
|
||||
const increasePlayers = () => {
|
||||
if (playerCount < 8) setPlayerCount(playerCount + 1);
|
||||
};
|
||||
|
||||
const decreasePlayers = () => {
|
||||
if (playerCount > 2) setPlayerCount(playerCount - 1);
|
||||
};
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<View style={styles.header}>
|
||||
<Image
|
||||
source={{
|
||||
uri: "https://static.thenounproject.com/png/3890959-200.png",
|
||||
}}
|
||||
style={styles.icon}
|
||||
/>
|
||||
<Text style={styles.title}>Select Number of Players:</Text>
|
||||
</View>
|
||||
|
||||
<Text style={styles.playerCount}>{playerCount}</Text>
|
||||
<View style={{ flexDirection: "row" }}>
|
||||
<Button title="-" onPress={decreasePlayers} />
|
||||
<Button title="+" onPress={increasePlayers} />
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
padding: 20,
|
||||
},
|
||||
header: {
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
},
|
||||
title: {
|
||||
fontSize: 18,
|
||||
marginLeft: 10, // Spacing between icon and text
|
||||
},
|
||||
icon: {
|
||||
width: 48, // Increased size
|
||||
height: 48, // Increased size
|
||||
},
|
||||
playerCount: {
|
||||
fontSize: 24,
|
||||
marginVertical: 10,
|
||||
},
|
||||
});
|
||||
|
||||
export default PlayerSelector;
|
57
components/__tests__/PlayerSelector.test.tsx
Normal file
57
components/__tests__/PlayerSelector.test.tsx
Normal file
@ -0,0 +1,57 @@
|
||||
import React from "react";
|
||||
import { fireEvent, render } from "@testing-library/react-native";
|
||||
import PlayerSelector from "@/components/PlayerSelector";
|
||||
|
||||
describe("PlayerSelector Component", () => {
|
||||
it("renders the initial player count and buttons correctly", () => {
|
||||
const setPlayerCount = jest.fn();
|
||||
const { getByText, getByRole } = render(
|
||||
<PlayerSelector playerCount={4} setPlayerCount={setPlayerCount} />
|
||||
);
|
||||
|
||||
expect(getByText("Select Number of Players:")).toBeTruthy();
|
||||
expect(getByText("4")).toBeTruthy();
|
||||
expect(getByRole("button", { name: "-" })).toBeTruthy();
|
||||
expect(getByRole("button", { name: "+" })).toBeTruthy();
|
||||
});
|
||||
|
||||
it('increases player count when "+" button is pressed', () => {
|
||||
const setPlayerCount = jest.fn();
|
||||
const { getByRole } = render(
|
||||
<PlayerSelector playerCount={4} setPlayerCount={setPlayerCount} />
|
||||
);
|
||||
|
||||
fireEvent.press(getByRole("button", { name: "+" }));
|
||||
expect(setPlayerCount).toHaveBeenCalledWith(5);
|
||||
});
|
||||
|
||||
it('decreases player count when "-" button is pressed', () => {
|
||||
const setPlayerCount = jest.fn();
|
||||
const { getByRole } = render(
|
||||
<PlayerSelector playerCount={4} setPlayerCount={setPlayerCount} />
|
||||
);
|
||||
|
||||
fireEvent.press(getByRole("button", { name: "-" }));
|
||||
expect(setPlayerCount).toHaveBeenCalledWith(3);
|
||||
});
|
||||
|
||||
it("does not increase player count beyond 8", () => {
|
||||
const setPlayerCount = jest.fn();
|
||||
const { getByRole } = render(
|
||||
<PlayerSelector playerCount={8} setPlayerCount={setPlayerCount} />
|
||||
);
|
||||
|
||||
fireEvent.press(getByRole("button", { name: "+" }));
|
||||
expect(setPlayerCount).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("does not decrease player count below 2", () => {
|
||||
const setPlayerCount = jest.fn();
|
||||
const { getByRole } = render(
|
||||
<PlayerSelector playerCount={2} setPlayerCount={setPlayerCount} />
|
||||
);
|
||||
|
||||
fireEvent.press(getByRole("button", { name: "-" }));
|
||||
expect(setPlayerCount).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
215
package-lock.json
generated
215
package-lock.json
generated
@ -35,6 +35,10 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.25.2",
|
||||
"@testing-library/dom": "^10.4.0",
|
||||
"@testing-library/jest-native": "^5.4.3",
|
||||
"@testing-library/react": "^16.2.0",
|
||||
"@testing-library/react-native": "^13.0.1",
|
||||
"@types/jest": "^29.5.12",
|
||||
"@types/react": "~18.3.12",
|
||||
"@types/react-test-renderer": "^18.3.0",
|
||||
@ -4476,6 +4480,136 @@
|
||||
"@sinonjs/commons": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@testing-library/dom": {
|
||||
"version": "10.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.0.tgz",
|
||||
"integrity": "sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/code-frame": "^7.10.4",
|
||||
"@babel/runtime": "^7.12.5",
|
||||
"@types/aria-query": "^5.0.1",
|
||||
"aria-query": "5.3.0",
|
||||
"chalk": "^4.1.0",
|
||||
"dom-accessibility-api": "^0.5.9",
|
||||
"lz-string": "^1.5.0",
|
||||
"pretty-format": "^27.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@testing-library/dom/node_modules/ansi-styles": {
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
|
||||
"integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/@testing-library/dom/node_modules/pretty-format": {
|
||||
"version": "27.5.1",
|
||||
"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz",
|
||||
"integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ansi-regex": "^5.0.1",
|
||||
"ansi-styles": "^5.0.0",
|
||||
"react-is": "^17.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@testing-library/dom/node_modules/react-is": {
|
||||
"version": "17.0.2",
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
|
||||
"integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@testing-library/jest-native": {
|
||||
"version": "5.4.3",
|
||||
"resolved": "https://registry.npmjs.org/@testing-library/jest-native/-/jest-native-5.4.3.tgz",
|
||||
"integrity": "sha512-/sSDGaOuE+PJ1Z9Kp4u7PQScSVVXGud59I/qsBFFJvIbcn4P6yYw6cBnBmbPF+X9aRIsTJRDl6gzw5ZkJNm66w==",
|
||||
"deprecated": "DEPRECATED: This package is no longer maintained.\nPlease use the built-in Jest matchers available in @testing-library/react-native v12.4+.\n\nSee migration guide: https://callstack.github.io/react-native-testing-library/docs/migration/jest-matchers",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"chalk": "^4.1.2",
|
||||
"jest-diff": "^29.0.1",
|
||||
"jest-matcher-utils": "^29.0.1",
|
||||
"pretty-format": "^29.0.3",
|
||||
"redent": "^3.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.0.0",
|
||||
"react-native": ">=0.59",
|
||||
"react-test-renderer": ">=16.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@testing-library/react": {
|
||||
"version": "16.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@testing-library/react/-/react-16.2.0.tgz",
|
||||
"integrity": "sha512-2cSskAvA1QNtKc8Y9VJQRv0tm3hLVgxRGDB+KYhIaPQJ1I+RHbhIXcM+zClKXzMes/wshsMVzf4B9vS4IZpqDQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.12.5"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@testing-library/dom": "^10.0.0",
|
||||
"@types/react": "^18.0.0 || ^19.0.0",
|
||||
"@types/react-dom": "^18.0.0 || ^19.0.0",
|
||||
"react": "^18.0.0 || ^19.0.0",
|
||||
"react-dom": "^18.0.0 || ^19.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
},
|
||||
"@types/react-dom": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@testing-library/react-native": {
|
||||
"version": "13.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@testing-library/react-native/-/react-native-13.0.1.tgz",
|
||||
"integrity": "sha512-sKMRNNniSOZ68qe1OBQAWvK87WCEmbfLp/MXfn2JE3x3WrNU8OFCVL0z/YKqw0/JO/d44J8Wq6FmRSaod/+VAg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"chalk": "^4.1.2",
|
||||
"jest-matcher-utils": "^29.7.0",
|
||||
"pretty-format": "^29.7.0",
|
||||
"redent": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"jest": ">=29.0.0",
|
||||
"react": ">=18.2.0",
|
||||
"react-native": ">=0.71",
|
||||
"react-test-renderer": ">=18.2.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"jest": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@tootallnate/once": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz",
|
||||
@ -4486,6 +4620,13 @@
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/aria-query": {
|
||||
"version": "5.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz",
|
||||
"integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/babel__core": {
|
||||
"version": "7.20.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz",
|
||||
@ -5204,6 +5345,16 @@
|
||||
"sprintf-js": "~1.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/aria-query": {
|
||||
"version": "5.3.0",
|
||||
"resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz",
|
||||
"integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"dequal": "^2.0.3"
|
||||
}
|
||||
},
|
||||
"node_modules/array-buffer-byte-length": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz",
|
||||
@ -6847,6 +6998,16 @@
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/dequal": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
|
||||
"integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/destroy": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
|
||||
@ -6914,6 +7075,13 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/dom-accessibility-api": {
|
||||
"version": "0.5.16",
|
||||
"resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz",
|
||||
"integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/domexception": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/domexception/-/domexception-4.0.0.tgz",
|
||||
@ -11627,6 +11795,16 @@
|
||||
"yallist": "^3.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/lz-string": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz",
|
||||
"integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"lz-string": "bin/bin.js"
|
||||
}
|
||||
},
|
||||
"node_modules/make-dir": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz",
|
||||
@ -12185,6 +12363,16 @@
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/min-indent": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz",
|
||||
"integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/minimatch": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
||||
@ -14014,6 +14202,20 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/redent": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz",
|
||||
"integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"indent-string": "^4.0.0",
|
||||
"strip-indent": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/reflect.getprototypeof": {
|
||||
"version": "1.0.10",
|
||||
"resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz",
|
||||
@ -15403,6 +15605,19 @@
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/strip-indent": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz",
|
||||
"integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"min-indent": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/strip-json-comments": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
|
||||
|
@ -42,6 +42,10 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.25.2",
|
||||
"@testing-library/dom": "^10.4.0",
|
||||
"@testing-library/jest-native": "^5.4.3",
|
||||
"@testing-library/react": "^16.2.0",
|
||||
"@testing-library/react-native": "^13.0.1",
|
||||
"@types/jest": "^29.5.12",
|
||||
"@types/react": "~18.3.12",
|
||||
"@types/react-test-renderer": "^18.3.0",
|
||||
|
Loading…
Reference in New Issue
Block a user