diff --git a/library/tests/ui/basic-components/number.test.tsx b/library/tests/ui/basic-components/number.test.tsx
new file mode 100644
index 0000000..88a4128
--- /dev/null
+++ b/library/tests/ui/basic-components/number.test.tsx
@@ -0,0 +1,125 @@
+import React from "react";
+import { render, screen } from "@testing-library/react";
+import "@testing-library/jest-dom";
+import { Number } from "../../../ui/src/basic-components/Number";
+
+describe("Number component", () => {
+ it("renders without crashing", () => {
+ render();
+ expect(screen.getByText("1,234")).toBeInTheDocument();
+ });
+
+ it("renders with default props for a decimal value", () => {
+ // default minDecimalDigits = 0, maxDecimalDigits defaults to 20,
+ // so decimals are preserved but not padded
+ render();
+ expect(screen.getByText("3.5")).toBeInTheDocument();
+ });
+
+ it("renders zero correctly", () => {
+ render();
+ expect(screen.getByText("0")).toBeInTheDocument();
+ });
+
+ it("renders negative numbers correctly", () => {
+ render();
+ expect(screen.getByText("-42")).toBeInTheDocument();
+ });
+
+ it("renders very large numbers with grouping separators", () => {
+ render();
+ expect(screen.getByText("1,234,567,890")).toBeInTheDocument();
+ });
+
+ it("respects maxDecimalDigits by truncating/rounding decimals", () => {
+ render();
+ expect(screen.getByText("3.14")).toBeInTheDocument();
+ });
+
+ it("respects minDecimalDigits by padding with trailing zeros", () => {
+ render();
+ expect(screen.getByText("5.00")).toBeInTheDocument();
+ });
+
+ it("applies both minDecimalDigits and maxDecimalDigits together", () => {
+ render();
+ expect(screen.getByText("5.60")).toBeInTheDocument();
+ });
+
+ it("rounds correctly when value exceeds maxDecimalDigits precision", () => {
+ render();
+ expect(screen.getByText("2.6")).toBeInTheDocument();
+ });
+
+ it("fixDecimalDigits overrides both min and max decimal digits", () => {
+ render(
+ ,
+ );
+ expect(screen.getByText("5.7")).toBeInTheDocument();
+ });
+
+ it("fixDecimalDigits pads whole numbers with zeros", () => {
+ render();
+ expect(screen.getByText("7.000")).toBeInTheDocument();
+ });
+
+ it("renders the tooltip prop as the title attribute", () => {
+ render();
+ expect(screen.getByText("10")).toHaveAttribute(
+ "title",
+ "Custom tooltip text",
+ );
+ });
+
+ it("uses the raw value as the tooltip when wholeLengthNumberInTooltip is true", () => {
+ render();
+ expect(screen.getByText("3.14159265358979")).toHaveAttribute(
+ "title",
+ "3.14159265358979",
+ );
+ });
+
+ it("prefers explicit tooltip over wholeLengthNumberInTooltip", () => {
+ render(
+ ,
+ );
+ expect(screen.getByText("3.14159")).toHaveAttribute(
+ "title",
+ "Explicit tooltip",
+ );
+ });
+
+ it("has no title attribute when neither tooltip nor wholeLengthNumberInTooltip is set", () => {
+ render();
+ expect(screen.getByText("10")).not.toHaveAttribute("title");
+ });
+
+ it("merges custom style prop with the computed styles", () => {
+ render();
+ expect(screen.getByText("10")).toHaveStyle({ fontWeight: "bold" });
+ });
+
+ it("renders consistently for darkMode and colorScheme prop combinations", () => {
+ const { rerender } = render(
+ ,
+ );
+ expect(screen.getByText("10")).toBeInTheDocument();
+
+ rerender();
+ expect(screen.getByText("10")).toBeInTheDocument();
+ });
+
+ it("matches snapshot for default rendering", () => {
+ const { asFragment } = render();
+ expect(asFragment()).toMatchSnapshot();
+ });
+});