@weball/ui-kit
Version:
UI Kit library with flexible fixture and tournament components for sports applications
389 lines (377 loc) • 12.7 kB
TypeScript
import * as react_jsx_runtime from 'react/jsx-runtime';
import React from 'react';
/**
* Base entity with minimum required properties
* Users can extend this with any additional properties they need
*/
interface WeballBaseEntity {
id: number;
}
/**
* Minimum required properties for club inscription
* Users can pass objects with additional properties
*/
interface MinClubInscription {
logo: string;
name: string;
color: string;
tableName?: string;
club: Club;
}
/**
* Minimum required properties for fixture vacancy
* Users can pass objects with additional properties
*/
interface MinFixtureVacancy {
name: string;
color: string;
}
/**
* Minimum required properties for category instance
* Users can pass objects with additional properties
*/
interface MinCategoryInstance {
name: string;
}
/**
* Generic club inscription type that accepts any object extending minimum requirements
*/
type ClubInscription<T = {}> = WeballBaseEntity & MinClubInscription & T;
/**
* Generic tournament club type that accepts any object extending minimum requirements
*/
type TournamentClub<T = {}, U = {}> = WeballBaseEntity & {
clubInscription: ClubInscription<U>;
} & T;
/**
* Generic fixture vacancy type that accepts any object extending minimum requirements
*/
type FixtureVacancy<T = {}> = WeballBaseEntity & MinFixtureVacancy & T;
/**
* Generic category instance type that accepts any object extending minimum requirements
*/
type CategoryInstance<T = {}> = WeballBaseEntity & MinCategoryInstance & T;
/**
* Generic tournament match info type that accepts any object extending minimum requirements
*/
type TournamentMatchInfo<T = {}, U = {}, V = {}> = WeballBaseEntity & {
vacancyHome: FixtureVacancy<U> | null;
vacancyAway: FixtureVacancy<V> | null;
} & T;
/**
* Generic tournament category type that accepts any object extending minimum requirements
*/
type TournamentCategory<T = {}, U = {}> = WeballBaseEntity & {
categoryInstance: CategoryInstance<U>;
} & T;
/**
* Generic tournament match type that accepts any object extending minimum requirements
*/
type TournamentMatch<T = {}, U = {}, V = {}, W = {}, X = {}, Y = {}> = WeballBaseEntity & {
scoreHome: number;
scoreAway: number;
scoreHomePenalty?: number;
scoreAwayPenalty?: number;
clubHome: TournamentClub<X> | null;
clubAway: TournamentClub<Y> | null;
category: TournamentCategory<U, V>;
matchInfo: TournamentMatchInfo<W>;
} & T;
/**
* Generic fixture visualizer match type that accepts any object extending minimum requirements
*/
type FixtureVisualizerMatch<T = {}, U = {}, V = {}, W = {}, X = {}, Y = {}> = WeballBaseEntity & {
fixtureVisualizer: FixtureVisualizer<any> | null;
valueScoreAway?: string;
valueScoreHome?: string;
teamWon?: TournamentClub<U> | null;
vacancyHome: FixtureVacancy<V> | null;
vacancyAway: FixtureVacancy<W> | null;
clubHome: TournamentClub<X> | null;
clubAway: TournamentClub<Y> | null;
tournamentMatches?: TournamentMatch<any>[];
} & T;
/**
* Generic fixture visualizer type that accepts any object extending minimum requirements
*/
type FixtureVisualizer<T = {}> = WeballBaseEntity & {
children: FixtureVisualizer<any>[];
matchesPlanning: FixtureVisualizerMatch<any>[];
} & T;
/**
* Helper function to convert an array of fixtures into a FixtureVisualizer object
*
* @param fixtures - Array of fixture data
* @param options - Optional configuration
* @returns FixtureVisualizer object
*
* @example
* ```typescript
* const fixtures = [/* your fixture array *\/];
* const fixtureRoot = createFixtureRoot(fixtures);
*
* // Use in your component:
* // <WbFixture fixtureVisualizerRoot={fixtureRoot} />
* ```
*/
declare function createFixtureRoot<T = any>(fixtures: T[], options?: {
id?: number;
matchesPlanning?: FixtureVisualizerMatch<any>[];
}): FixtureVisualizer<{
fixtures: T[];
}>;
interface Club extends WeballBaseEntity {
name: string;
color: string;
logo: string;
tableName: string;
tableShortName: string;
clubInscription: ClubInscription[];
}
/**
* Minimum required properties for a cup winner
* Users can pass any object that has at least these properties
*/
type MinCupWinner = WeballBaseEntity & MinClubInscription;
/**
* Props interface for WbFixture component with generic type support
* Allows users to pass any data structures that extend the minimum requirements
*
* @template TFixtureData - Type for fixture visualizer data (can contain any additional properties)
* @template TCupWinnerData - Type for cup winner data (can contain any additional properties)
*/
interface WbFixtureProps<TFixtureData = any, TCupWinnerData = any> {
/**
* Cup winner data - can be any object that extends the minimum required properties:
* - id: number
* - logo: string
* - name: string
* - color: string
*
* @example
* ```tsx
* // Basic usage
* cupWinner={{ id: 1, logo: "...", name: "Team A", color: "#fff" }}
*
* // With additional custom data
* cupWinner={{
* id: 1,
* logo: "...",
* name: "Team A",
* color: "#fff",
* customField: "my custom data",
* stats: { wins: 10, losses: 2 }
* }}
* ```
*/
cupWinner?: MinCupWinner & TCupWinnerData;
/**
* URL or path to the cup logo image
*/
cupLogo?: string;
/**
* Callback function triggered when a node is clicked
* @param match - The fixture visualizer match data (with any additional properties)
* @param position - The position clicked: "local", "visit", "resultLocal", or "resultVisit"
*/
onClickNode?: (match: Partial<FixtureVisualizer<TFixtureData>>, position: "local" | "visit" | "resultLocal" | "resultVisit") => void;
/**
* Callback function triggered when a result is saved
* @param fixtureVisualizerId - The ID of the fixture visualizer
* @param scoreHome - Home team score
* @param scoreAway - Away team score
*/
onResultSaved?: (fixtureVisualizerId: number, scoreHome?: number, scoreAway?: number) => void;
/**
* Root fixture visualizer data - can be any object that extends the minimum required properties:
* - id: number
* - children: FixtureVisualizer[]
* - matchesPlanning: FixtureVisualizerMatch[]
*
* @example
* ```tsx
* // Basic usage
* fixtureVisualizerRoot={{
* id: 1,
* children: [],
* matchesPlanning: []
* }}
*
* // With additional custom data
* fixtureVisualizerRoot={{
* id: 1,
* children: [],
* matchesPlanning: [],
* customTournamentData: "...",
* metadata: { created: "2024-01-01", type: "knockout" }
* }}
* ```
*/
fixtureVisualizerRoot?: FixtureVisualizer<TFixtureData>;
/**
* Currently selected fixture visualizer node
*/
nodeSelected?: FixtureVisualizer<TFixtureData>;
/**
* The stage number to start viewing from
*/
viewFromStage?: number;
/**
* Enable or disable edit mode for results
* When true, allows clicking on scores to edit them
* When false, score editing is disabled (view-only mode)
* @default false
*/
editMode?: boolean;
/**
* Enable responsive behavior
* When true, the fixture will scale to fit its container and occupy 100% width
* When false, uses fixed dimensions based on content
* @default true
*/
responsive?: boolean;
}
/**
* WbFixture component - displays tournament bracket/fixture visualization
*
* @template TFixtureData - Type for fixture visualizer data (can contain any additional properties)
* @template TCupWinnerData - Type for cup winner data (can contain any additional properties)
*
* @example
* ```tsx
* // Basic usage with minimum required properties
* <WbFixture
* fixtureVisualizerRoot={{
* id: 1,
* children: [],
* matchesPlanning: [
* {
* id: 1,
* clubHome: { clubInscription: { logo: "...", name: "Team A", color: "#fff" } },
* clubAway: { clubInscription: { logo: "...", name: "Team B", color: "#000" } }
* }
* ]
* }}
* cupWinner={{ id: 1, logo: "...", name: "Winner", color: "#gold" }}
* onClickNode={(match, position) => console.log(match, position)}
* />
*
* // Usage with extended custom data
* <WbFixture
* fixtureVisualizerRoot={{
* id: 1,
* children: [],
* matchesPlanning: [],
* customTournamentName: "World Cup 2024",
* metadata: { season: "2024", region: "Global" }
* }}
* cupWinner={{
* id: 1,
* logo: "...",
* name: "Winner",
* color: "#gold",
* stats: { wins: 15, goals: 45 },
* country: "Argentina"
* }}
* />
* ```
*/
declare const WbFixture: <TFixtureData = any, TCupWinnerData = any>(props: WbFixtureProps<TFixtureData, TCupWinnerData>) => react_jsx_runtime.JSX.Element;
declare const WbFixtureSymmetrical: (props: WbFixtureProps) => react_jsx_runtime.JSX.Element | undefined;
interface BoxProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'color'> {
children?: React.ReactNode;
className?: string;
position?: 'static' | 'relative' | 'absolute' | 'fixed' | 'sticky';
width?: string | number;
height?: string | number;
borderWidth?: number;
borderTopWidth?: number;
borderLeftWidth?: number;
borderRightWidth?: number;
borderBottomWidth?: number;
borderStyle?: 'solid' | 'dashed' | 'dotted' | 'none';
borderTopRightRadius?: number;
borderBottomRightRadius?: number;
borderTopLeftRadius?: number;
borderBottomLeftRadius?: number;
borderColor?: string;
backgroundColor?: string;
px?: number;
py?: number;
gap?: number;
color?: string;
fontSize?: string;
fontWeight?: number;
textAlign?: 'left' | 'center' | 'right' | 'justify';
pointerEvents?: 'auto' | 'none';
}
declare const Box: React.ForwardRefExoticComponent<BoxProps & React.RefAttributes<HTMLDivElement>>;
interface FlexProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'color'> {
children?: React.ReactNode;
className?: string;
direction?: 'row' | 'column' | 'row-reverse' | 'column-reverse';
alignItems?: 'flex-start' | 'flex-end' | 'center' | 'baseline' | 'stretch';
justifyContent?: 'flex-start' | 'flex-end' | 'center' | 'space-between' | 'space-around' | 'space-evenly';
gap?: number;
width?: string | number;
height?: string | number;
maxWidth?: string;
position?: 'static' | 'relative' | 'absolute' | 'fixed' | 'sticky';
px?: number;
py?: number;
mt?: number;
borderRadius?: number;
flexDirection?: 'row' | 'column' | 'row-reverse' | 'column-reverse';
color?: string;
fontWeight?: number;
cursor?: string;
zIndex?: number;
backgroundColor?: string;
}
declare const Flex: React.ForwardRefExoticComponent<FlexProps & React.RefAttributes<HTMLDivElement>>;
interface TextProps {
children?: React.ReactNode;
className?: string;
fontSize?: string;
fontWeight?: string | number;
color?: string;
textAlign?: 'left' | 'center' | 'right' | 'justify';
px?: number;
py?: number;
height?: number | string;
position?: 'static' | 'relative' | 'absolute' | 'fixed' | 'sticky';
pointerEvents?: 'none' | 'auto';
as?: 'p' | 'span' | 'div' | 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';
style?: React.CSSProperties;
onClick?: (event: React.MouseEvent<HTMLElement>) => void;
width?: string;
}
declare const Text: React.ForwardRefExoticComponent<TextProps & React.RefAttributes<HTMLElement>>;
interface ImageProps {
src: string;
alt?: string;
width?: string;
height?: string;
className?: string;
style?: React.CSSProperties;
onError?: (event: React.SyntheticEvent<HTMLImageElement>) => void;
onLoad?: (event: React.SyntheticEvent<HTMLImageElement>) => void;
}
declare const Image: React.FC<ImageProps>;
interface CollapseProps {
children: React.ReactNode;
in: boolean;
animateOpacity?: boolean;
className?: string;
style?: React.CSSProperties;
}
declare const Collapse: React.FC<CollapseProps>;
interface DividerProps {
className?: string;
style?: React.CSSProperties;
orientation?: 'horizontal' | 'vertical';
color?: string;
}
declare const Divider: React.FC<DividerProps>;
export { Box, Collapse, Divider, Flex, Image, Text, WbFixture, WbFixtureSymmetrical, createFixtureRoot };
export type { BoxProps, CollapseProps, DividerProps, FlexProps, ImageProps, TextProps };