courthive-components 3.0.1 → 3.2.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 (23) hide show
  1. package/README.md +4 -4
  2. package/dist/components/ladderChart/index.d.ts +2 -0
  3. package/dist/components/ladderChart/ladderChart.d.ts +2 -0
  4. package/dist/components/ladderChart/types.d.ts +72 -0
  5. package/dist/components/policy-catalog/editors/seeding/domain/seedingProjections.d.ts +10 -0
  6. package/dist/components/policy-catalog/editors/seeding/index.d.ts +8 -0
  7. package/dist/components/policy-catalog/editors/seeding/sections/drawTypeOverridesSection.d.ts +6 -0
  8. package/dist/components/policy-catalog/editors/seeding/sections/flagsSection.d.ts +6 -0
  9. package/dist/components/policy-catalog/editors/seeding/sections/profileSection.d.ts +6 -0
  10. package/dist/components/policy-catalog/editors/seeding/sections/thresholdsSection.d.ts +6 -0
  11. package/dist/components/policy-catalog/editors/seeding/seedingEditorControl.d.ts +20 -0
  12. package/dist/components/policy-catalog/editors/seeding/seedingEditorPanel.d.ts +6 -0
  13. package/dist/components/policy-catalog/editors/seeding/seedingEditorStore.d.ts +26 -0
  14. package/dist/components/policy-catalog/editors/seeding/styles.d.ts +24 -0
  15. package/dist/components/policy-catalog/editors/seeding/types.d.ts +41 -0
  16. package/dist/components/policy-catalog/index.d.ts +2 -0
  17. package/dist/components/tournament-card/styles.d.ts +1 -0
  18. package/dist/components/tournament-card/types.d.ts +26 -1
  19. package/dist/courthive-components.css +1 -1
  20. package/dist/courthive-components.es.js +4674 -3125
  21. package/dist/courthive-components.umd.js +15 -15
  22. package/dist/index.d.ts +2 -0
  23. package/package.json +3 -3
package/README.md CHANGED
@@ -18,13 +18,13 @@ This library provides a comprehensive set of UI components for building tourname
18
18
  ## Installation
19
19
 
20
20
  ```bash
21
- npm install courthive-components
22
- # or
23
- yarn add courthive-components
24
- # or
25
21
  pnpm add courthive-components
26
22
  ```
27
23
 
24
+ (External consumers may also use `npm install courthive-components` or
25
+ `yarn add courthive-components`. Inside the CourtHive monorepo,
26
+ pnpm is the only supported manager.)
27
+
28
28
  ## Quick Start
29
29
 
30
30
  ```javascript
@@ -0,0 +1,2 @@
1
+ export { buildLadderChart } from './ladderChart';
2
+ export type { LadderChartDatum, LadderChartConfig, LadderChartMargins, LadderChartInstance, } from './types';
@@ -0,0 +1,2 @@
1
+ import { LadderChartConfig, LadderChartInstance } from './types';
2
+ export declare function buildLadderChart(container: HTMLElement, initialConfig: LadderChartConfig): LadderChartInstance;
@@ -0,0 +1,72 @@
1
+ /**
2
+ * LadderChart — public types.
3
+ *
4
+ * Visualizes a player's (or any subject's) ordinal progression across a
5
+ * time series. Each datum places a mark at (date, rung), connected
6
+ * chronologically by an optional line.
7
+ *
8
+ * Originally a D3v3 "Ladder chart" in tennisvisuals. Rewritten for
9
+ * D3v7 + TypeScript + the courthive-components vanilla-component
10
+ * pattern (returns SVG element via factory function; no framework).
11
+ */
12
+ export interface LadderChartDatum {
13
+ /** Mark X position. Pass a Date or an ISO-8601 string. */
14
+ date: Date | string;
15
+ /** Mark Y position: 0-based index into `rungs[]`. 0 is the bottom rung. */
16
+ rung: number;
17
+ /** Optional mark color override (CSS color string). Falls back to `markColor`. */
18
+ color?: string;
19
+ /** Optional mark radius override (px). Falls back to `markRadius`. */
20
+ radius?: number;
21
+ /** Optional label for the mark (used in tooltip/aria). Examples: tournament name. */
22
+ label?: string;
23
+ /** Optional secondary label (used in tooltip body). Examples: result string. */
24
+ detail?: string;
25
+ /** Arbitrary attached data, forwarded to onClick/onHover callbacks. */
26
+ meta?: Record<string, unknown>;
27
+ }
28
+ export interface LadderChartMargins {
29
+ top?: number;
30
+ right?: number;
31
+ bottom?: number;
32
+ left?: number;
33
+ }
34
+ export interface LadderChartConfig {
35
+ /** Ordinal rung labels, ordered bottom → top. Example: ['R128','R64','R32','R16','QF','SF','F','W']. */
36
+ rungs: string[];
37
+ /** Mark data. May be unsorted; the renderer sorts by date for the connector. */
38
+ data: LadderChartDatum[];
39
+ /** Chart width in px. Defaults to container's clientWidth (or 600). */
40
+ width?: number;
41
+ /** Chart height in px. Defaults to 240. */
42
+ height?: number;
43
+ margins?: LadderChartMargins;
44
+ /** Optional chart title rendered above the plot. */
45
+ title?: string;
46
+ /** Optional subtitle / source text rendered below the plot. */
47
+ source?: string;
48
+ /** Draw a connector line between marks in chronological order. Default: true. */
49
+ showConnector?: boolean;
50
+ /** Default mark color when datum has no `color` override. Default: `var(--sp-accent)` → `#3366cc`. */
51
+ markColor?: string;
52
+ /** Default mark radius in px when datum has no `radius`. Default: 6. */
53
+ markRadius?: number;
54
+ /** Connector line color. Default: `var(--sp-muted)` → `#94a3b8`. */
55
+ connectorColor?: string;
56
+ /** X-axis date format token (d3-time-format). Auto-selected if absent. */
57
+ xTickFormat?: string;
58
+ /** Maximum number of X-axis ticks. Default: 8. */
59
+ xMaxTicks?: number;
60
+ /** Click handler for a mark. */
61
+ onMarkClick?: (datum: LadderChartDatum, event: MouseEvent) => void;
62
+ /** Hover handler; receives null when the cursor leaves all marks. */
63
+ onMarkHover?: (datum: LadderChartDatum | null, event: MouseEvent | null) => void;
64
+ }
65
+ export interface LadderChartInstance {
66
+ /** The mounted SVG element (already inside the container). */
67
+ element: SVGSVGElement;
68
+ /** Re-render with new partial config (e.g. swap data on player change). */
69
+ update(next: Partial<LadderChartConfig>): void;
70
+ /** Remove the chart from its parent + detach listeners. */
71
+ destroy(): void;
72
+ }
@@ -0,0 +1,10 @@
1
+ import { SeedingPolicyData, SeedingPositioning } from '../types';
2
+ export declare const POSITIONING_OPTIONS: {
3
+ value: SeedingPositioning;
4
+ label: string;
5
+ description: string;
6
+ }[];
7
+ /** Draw types that meaningfully use a positioning override. Mirrors factory drawDefinitionConstants. */
8
+ export declare const DRAW_TYPE_OPTIONS: string[];
9
+ export declare function emptySeedingPolicy(): SeedingPolicyData;
10
+ export declare function positioningLabel(value: SeedingPositioning | undefined): string;
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Seeding Editor — Public API
3
+ */
4
+ export { SeedingEditorControl, createSeedingEditor } from './seedingEditorControl';
5
+ export { SeedingEditorStore } from './seedingEditorStore';
6
+ export { buildSeedingEditorPanel } from './seedingEditorPanel';
7
+ export { emptySeedingPolicy, POSITIONING_OPTIONS, DRAW_TYPE_OPTIONS } from './domain/seedingProjections';
8
+ export type { SeedingPolicyData, SeedingProfile, SeedingPositioning, SeedsCountThreshold, SeedingEditorState, SeedingEditorSection, SeedingEditorChangeListener, SeedingEditorConfig } from './types';
@@ -0,0 +1,6 @@
1
+ import { SeedingEditorConfig, SeedingEditorState } from '../types';
2
+ import { SeedingEditorStore } from '../seedingEditorStore';
3
+ export declare function buildDrawTypeOverridesSection(store: SeedingEditorStore, config: SeedingEditorConfig): {
4
+ element: HTMLElement;
5
+ update(state: SeedingEditorState): void;
6
+ };
@@ -0,0 +1,6 @@
1
+ import { SeedingEditorState } from '../types';
2
+ import { SeedingEditorStore } from '../seedingEditorStore';
3
+ export declare function buildFlagsSection(store: SeedingEditorStore): {
4
+ element: HTMLElement;
5
+ update(state: SeedingEditorState): void;
6
+ };
@@ -0,0 +1,6 @@
1
+ import { SeedingEditorState } from '../types';
2
+ import { SeedingEditorStore } from '../seedingEditorStore';
3
+ export declare function buildProfileSection(store: SeedingEditorStore): {
4
+ element: HTMLElement;
5
+ update(state: SeedingEditorState): void;
6
+ };
@@ -0,0 +1,6 @@
1
+ import { SeedingEditorState } from '../types';
2
+ import { SeedingEditorStore } from '../seedingEditorStore';
3
+ export declare function buildThresholdsSection(store: SeedingEditorStore): {
4
+ element: HTMLElement;
5
+ update(state: SeedingEditorState): void;
6
+ };
@@ -0,0 +1,20 @@
1
+ import { SeedingEditorStore } from './seedingEditorStore';
2
+ import { SeedingPolicyData, SeedingEditorConfig } from './types';
3
+ import { PolicyEditorInstance as CatalogEditorInstance } from '../../types';
4
+ export declare class SeedingEditorControl {
5
+ private readonly store;
6
+ private readonly panel;
7
+ private readonly unsubscribe;
8
+ private container;
9
+ constructor(config: SeedingEditorConfig);
10
+ render(container: HTMLElement): void;
11
+ destroy(): void;
12
+ getData(): SeedingPolicyData;
13
+ setData(data: SeedingPolicyData): void;
14
+ getStore(): SeedingEditorStore;
15
+ static createEditorInstance(config: {
16
+ initialData: Record<string, unknown>;
17
+ onChange: (data: Record<string, unknown>) => void;
18
+ }): CatalogEditorInstance;
19
+ }
20
+ export declare function createSeedingEditor(config: SeedingEditorConfig, container: HTMLElement): SeedingEditorControl;
@@ -0,0 +1,6 @@
1
+ import { SeedingEditorState, SeedingEditorConfig } from './types';
2
+ import { SeedingEditorStore } from './seedingEditorStore';
3
+ export declare function buildSeedingEditorPanel(store: SeedingEditorStore, config: SeedingEditorConfig): {
4
+ element: HTMLElement;
5
+ update(state: SeedingEditorState): void;
6
+ };
@@ -0,0 +1,26 @@
1
+ import { SeedingPolicyData, SeedingEditorState, SeedingEditorSection, SeedingEditorChangeListener, SeedingEditorConfig, SeedsCountThreshold, SeedingPositioning } from './types';
2
+ export declare class SeedingEditorStore {
3
+ private state;
4
+ private readonly listeners;
5
+ private readonly config;
6
+ constructor(config: SeedingEditorConfig);
7
+ getState(): SeedingEditorState;
8
+ getData(): SeedingPolicyData;
9
+ setData(data: SeedingPolicyData): void;
10
+ toggleSection(sectionId: SeedingEditorSection): void;
11
+ setPolicyName(value: string): void;
12
+ setPositioning(value: SeedingPositioning): void;
13
+ setValidSeedPositionsIgnore(value: boolean): void;
14
+ setDuplicateSeedNumbers(value: boolean): void;
15
+ setDrawSizeProgression(value: boolean): void;
16
+ addThreshold(): void;
17
+ removeThreshold(index: number): void;
18
+ setThresholdField(index: number, field: keyof SeedsCountThreshold, value: number): void;
19
+ sortThresholds(): void;
20
+ addDrawTypeOverride(drawType: string, positioning: SeedingPositioning): void;
21
+ removeDrawTypeOverride(drawType: string): void;
22
+ setDrawTypeOverridePositioning(drawType: string, positioning: SeedingPositioning): void;
23
+ subscribe(listener: SeedingEditorChangeListener): () => void;
24
+ private commitDraft;
25
+ private emit;
26
+ }
@@ -0,0 +1,24 @@
1
+ export declare const sdEditorStyle: () => string;
2
+ export declare const sdSectionStyle: () => string;
3
+ export declare const sdSectionHeaderStyle: () => string;
4
+ export declare const sdSectionChevronStyle: () => string;
5
+ export declare const sdSectionBodyStyle: () => string;
6
+ export declare const sdFieldRowStyle: () => string;
7
+ export declare const sdFieldLabelStyle: () => string;
8
+ export declare const sdFieldInputStyle: () => string;
9
+ export declare const sdCheckboxRowStyle: () => string;
10
+ export declare const sdCheckboxDescStyle: () => string;
11
+ export declare const sdRadioGroupStyle: () => string;
12
+ export declare const sdRadioOptionStyle: () => string;
13
+ export declare const sdAddBtnStyle: () => string;
14
+ export declare const sdSortBtnStyle: () => string;
15
+ export declare const sdRemoveBtnStyle: () => string;
16
+ export declare const sdTableWrapStyle: () => string;
17
+ export declare const sdTableStyle: () => string;
18
+ export declare const sdNumberCellInputStyle: () => string;
19
+ export declare const sdEmptyStyle: () => string;
20
+ export declare const sdActionsRowStyle: () => string;
21
+ export declare const sdOverrideRowStyle: () => string;
22
+ export declare const sdOverrideAddRowStyle: () => string;
23
+ export declare const sdOverrideDrawTypeStyle: () => string;
24
+ export declare const sdSelectStyle: () => string;
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Seeding Policy Editor — Type Definitions
3
+ *
4
+ * Mirrors the factory's seeding policy data shape (see
5
+ * factory/src/fixtures/policies/POLICY_SEEDING_*.ts).
6
+ */
7
+ export type SeedingPositioning = 'SEPARATE' | 'WATERFALL' | 'CLUSTER';
8
+ export interface SeedsCountThreshold {
9
+ drawSize: number;
10
+ minimumParticipantCount: number;
11
+ seedsCount: number;
12
+ }
13
+ export interface SeedingProfile {
14
+ positioning?: SeedingPositioning;
15
+ drawTypes?: Record<string, {
16
+ positioning: SeedingPositioning;
17
+ }>;
18
+ }
19
+ export interface SeedingPolicyData {
20
+ policyName?: string;
21
+ seedingProfile?: SeedingProfile;
22
+ validSeedPositions?: {
23
+ ignore: boolean;
24
+ };
25
+ duplicateSeedNumbers?: boolean;
26
+ drawSizeProgression?: boolean;
27
+ seedsCountThresholds?: SeedsCountThreshold[];
28
+ }
29
+ export type SeedingEditorSection = 'profile' | 'flags' | 'thresholds' | 'drawTypeOverrides';
30
+ export interface SeedingEditorState {
31
+ draft: SeedingPolicyData;
32
+ expandedSections: Set<SeedingEditorSection>;
33
+ dirty: boolean;
34
+ }
35
+ export type SeedingEditorChangeListener = (state: SeedingEditorState) => void;
36
+ export interface SeedingEditorConfig {
37
+ initialPolicy?: SeedingPolicyData;
38
+ /** Override the list of drawTypes offered in the overrides picker. */
39
+ drawTypes?: string[];
40
+ onChange?: (policy: SeedingPolicyData) => void;
41
+ }
@@ -16,7 +16,9 @@ export { buildPolicyCatalogLayout } from './ui/policyCatalogLayout';
16
16
  export { buildJsonEditor } from './ui/jsonEditor';
17
17
  export { SchedulingEditorControl, createSchedulingEditor, SchedulingEditorStore, validateSchedulingPolicy, formatCodeLabel, emptySchedulingPolicy, buildSchedulingEditorPanel } from './editors/scheduling';
18
18
  export { RankingPointsEditorControl, createRankingPointsEditor, RankingPointsEditorStore, buildRankingPointsEditorPanel, emptyRankingPolicy } from './editors/ranking';
19
+ export { SeedingEditorControl, createSeedingEditor, SeedingEditorStore, buildSeedingEditorPanel, emptySeedingPolicy, POSITIONING_OPTIONS, DRAW_TYPE_OPTIONS } from './editors/seeding';
19
20
  export type { PolicyCatalogItem, PolicyCatalogState, PolicyCatalogChangeListener, PolicyCatalogConfig, PolicyEditorInstance, PolicyEditorPlugin, PolicySource, PolicyTypeGroup, PolicyTypeMeta, CatalogGroupBy, UIPanel } from './types';
20
21
  export type { SchedulingPolicyData, SchedulingEditorState, SchedulingEditorSection, SchedulingEditorChangeListener, SchedulingEditorConfig, SchedulingValidationResult, ValidationSeverity, MinutesEntry, AverageTimeEntry, RecoveryTimeEntry, MatchUpAverageTime, MatchUpRecoveryTime } from './editors/scheduling';
21
22
  export type { RankingPolicyData, RankingPointsEditorState, RankingEditorSection, RankingPointsEditorChangeListener, RankingPointsEditorConfig, AwardProfileData, QualityWinProfileData, AggregationRulesData, TableLayout } from './editors/ranking';
23
+ export type { SeedingPolicyData, SeedingProfile, SeedingPositioning, SeedsCountThreshold, SeedingEditorState, SeedingEditorSection, SeedingEditorChangeListener, SeedingEditorConfig } from './editors/seeding';
22
24
  export declare function createPolicyCatalog(config: PolicyCatalogConfig, container: HTMLElement): PolicyCatalogControl;
@@ -18,6 +18,7 @@ export declare const tcFooterStyle: () => string;
18
18
  export declare const tcFeeBadgeStyle: () => string;
19
19
  export declare const tcPlayerCountStyle: () => string;
20
20
  export declare const tcEventCountStyle: () => string;
21
+ export declare const tcTierBadgeStyle: () => string;
21
22
  export declare const tcSkeletonStyle: () => string;
22
23
  export declare const tcSkeletonLineStyle: () => string;
23
24
  export declare const tcSkeletonBlockStyle: () => string;
@@ -4,6 +4,23 @@ export interface TournamentStatusPill {
4
4
  kind: TournamentStatusKind;
5
5
  label: string;
6
6
  }
7
+ /**
8
+ * Federation-specific competitive tier. Mirrors the factory's
9
+ * `TierClassification` shape (kept in lockstep but duplicated here to
10
+ * avoid pulling tods-competition-factory into the component's runtime
11
+ * dependency graph).
12
+ *
13
+ * - `system`: federation namespace, e.g. `'ITF_JUNIOR'`, `'ATP'`, `'PPA'`.
14
+ * - `value`: the tier within that system, e.g. `'J500'`, `'Masters 1000'`, `'Gold'`.
15
+ * - `numericRank`: optional sort key — lower = more prestigious. Used by
16
+ * the card / table column to sort tournaments without round-tripping
17
+ * through a ranking policy.
18
+ */
19
+ export interface TierClassification {
20
+ system: string;
21
+ value: string;
22
+ numericRank?: number;
23
+ }
7
24
  export interface TournamentEntryFee {
8
25
  amount: number;
9
26
  currencyCode?: string;
@@ -39,8 +56,16 @@ export interface TournamentCardData {
39
56
  updatedAt?: string;
40
57
  /** When true, render an offline/local indicator */
41
58
  offline?: boolean;
59
+ /**
60
+ * Competitive tier classification (federation-specific). When present
61
+ * and the `'tier'` field is in `TournamentCardConfig.body` (default), the
62
+ * card renders a small chip displaying `tournamentTier.value`. The
63
+ * Tabulator list view sorts on `numericRank` ascending with `value`
64
+ * lex fallback.
65
+ */
66
+ tournamentTier?: TierClassification;
42
67
  }
43
- export type TournamentCardField = 'title' | 'location' | 'dateRange' | 'feeBadge' | 'playerCount' | 'eventCount' | 'organizerName' | 'updatedAt';
68
+ export type TournamentCardField = 'title' | 'tier' | 'location' | 'dateRange' | 'feeBadge' | 'playerCount' | 'eventCount' | 'organizerName' | 'updatedAt';
44
69
  export type TournamentCardCornerField = 'status' | 'offline';
45
70
  export interface TournamentCardConfig {
46
71
  /** Whether to render the image zone. Defaults to true. */