courthive-components 6.13.0 → 7.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 (29) hide show
  1. package/README.md +27 -39
  2. package/dist/components/schedule-page/domain/activeStrip.d.ts +5 -0
  3. package/dist/components/scoring/logic/irregularEnding.d.ts +1 -1
  4. package/dist/components/scoring/logic/scoreEntrySelectors.d.ts +2 -0
  5. package/dist/components/scoring/logic/scoreEntryText.d.ts +93 -0
  6. package/dist/components/scoring/regions/dialPadRegion.d.ts +2 -0
  7. package/dist/components/scoring/regions/dynamicSetsRegion.d.ts +3 -0
  8. package/dist/components/scoring/regions/freeScoreRegion.d.ts +3 -1
  9. package/dist/components/scoring/regions/scoreReadout.d.ts +1 -1
  10. package/dist/components/scoring/scoreEntryCard.d.ts +4 -1
  11. package/dist/courthive-components.css +1 -1
  12. package/dist/courthive-components.es.js +10159 -11706
  13. package/dist/courthive-components.umd.js +73 -109
  14. package/dist/features.css +1 -1
  15. package/dist/index.d.ts +5 -3
  16. package/dist/theme/palettes.d.ts +30 -0
  17. package/package.json +2 -2
  18. package/dist/components/scoring/approaches/dialPadApproach.d.ts +0 -2
  19. package/dist/components/scoring/approaches/dialPadLogic.d.ts +0 -17
  20. package/dist/components/scoring/approaches/dynamicSetsApproach.d.ts +0 -2
  21. package/dist/components/scoring/approaches/freeScoreApproach.d.ts +0 -2
  22. package/dist/components/scoring/approaches/inlineScoringApproach.d.ts +0 -2
  23. package/dist/components/scoring/config.d.ts +0 -28
  24. package/dist/components/scoring/index.d.ts +0 -6
  25. package/dist/components/scoring/logic/outcomeProjection.d.ts +0 -25
  26. package/dist/components/scoring/scoringModal.d.ts +0 -2
  27. package/dist/components/scoring/statusCodePicker.d.ts +0 -15
  28. package/dist/components/scoring/utils/scoreFormatters.d.ts +0 -12
  29. package/dist/components/scoring/utils/scoreValidator.d.ts +0 -16
package/dist/features.css CHANGED
@@ -1,2 +1,2 @@
1
- .court-line{stroke:#505ab4b3;stroke-width:1.5px;fill:none;vector-effect:non-scaling-stroke}.court--tennis .court-line{stroke:#3c50c8cc}.court--basketball .court-line{stroke:#b450c8b3}.court--baseball .court-line{stroke:#c83246b3}.court--hockey .court-line{stroke:#1e78d2bf}.court--pickleball .court-line{stroke:#14a046b3}.court--badminton .court-line{stroke:#00b4a0b3}.court--padel .court-line{stroke:#c88214bf}@media (prefers-color-scheme:dark){:root:not([data-theme]) .court-line{stroke:#7882ff80}:root:not([data-theme]) .court--tennis .court-line{stroke:#667eea99}:root:not([data-theme]) .court--basketball .court-line{stroke:#f093fb80}:root:not([data-theme]) .court--baseball .court-line{stroke:#f5576c80}:root:not([data-theme]) .court--hockey .court-line{stroke:#4facfe8c}:root:not([data-theme]) .court--pickleball .court-line{stroke:#43e97b80}:root:not([data-theme]) .court--badminton .court-line{stroke:#38f9d780}:root:not([data-theme]) .court--padel .court-line{stroke:#ffb74d8c}}[data-theme=dark] .court-line{stroke:#7882ff80}[data-theme=dark] .court--tennis .court-line{stroke:#667eea99}[data-theme=dark] .court--basketball .court-line{stroke:#f093fb80}[data-theme=dark] .court--baseball .court-line{stroke:#f5576c80}[data-theme=dark] .court--hockey .court-line{stroke:#4facfe8c}[data-theme=dark] .court--pickleball .court-line{stroke:#43e97b80}[data-theme=dark] .court--badminton .court-line{stroke:#38f9d780}[data-theme=dark] .court--padel .court-line{stroke:#ffb74d8c}.chc-sb{flex-direction:row;align-items:stretch;gap:2px;min-width:0;height:1.5em;display:none;overflow:hidden}.chc-sb__seg{background:var(--seg-bg,var(--chc-text-muted,#6b7280));color:#fff;border-radius:2px;flex:0 0 0;justify-content:center;align-items:center;min-width:0;padding:0;font-size:.85em;font-weight:600;line-height:1;transition:opacity .15s;display:flex;overflow:hidden}.chc-sb__seg.is-clickable{cursor:pointer}.chc-sb__seg.is-clickable:hover{filter:brightness(1.1)}.chc-sb.has-active .chc-sb__seg:not(.is-active){opacity:.35}
1
+ .court-line{stroke:color-mix(in srgb, var(--chc-accent-indigo) 70%, transparent);stroke-width:1.5px;fill:none;vector-effect:non-scaling-stroke}.court--tennis .court-line{stroke:color-mix(in srgb, var(--chc-accent-indigo) 80%, transparent)}.court--basketball .court-line{stroke:color-mix(in srgb, var(--chc-accent-purple) 70%, transparent)}.court--baseball .court-line{stroke:color-mix(in srgb, var(--chc-accent-red) 70%, transparent)}.court--hockey .court-line{stroke:color-mix(in srgb, var(--chc-accent-blue) 75%, transparent)}.court--pickleball .court-line{stroke:color-mix(in srgb, var(--chc-accent-green) 70%, transparent)}.court--badminton .court-line{stroke:color-mix(in srgb, var(--chc-accent-teal) 70%, transparent)}.court--padel .court-line{stroke:color-mix(in srgb, var(--chc-accent-orange) 75%, transparent)}.chc-sb{flex-direction:row;align-items:stretch;gap:2px;min-width:0;height:1.5em;display:none;overflow:hidden}.chc-sb__seg{background:var(--seg-bg,var(--chc-text-muted));color:#fff;border-radius:2px;flex:0 0 0;justify-content:center;align-items:center;min-width:0;padding:0;font-size:.85em;font-weight:600;line-height:1;transition:opacity .15s;display:flex;overflow:hidden}.chc-sb__seg.is-clickable{cursor:pointer}.chc-sb__seg.is-clickable:hover{filter:brightness(1.1)}.chc-sb.has-active .chc-sb__seg:not(.is-active){opacity:.35}
2
2
  /*$vite$:1*/
package/dist/index.d.ts CHANGED
@@ -28,14 +28,14 @@ export { getCategoryModal } from './components/categories/category/category';
28
28
  export type { CategoryConfig, Category } from './components/categories/category/category';
29
29
  export { getFlightProfileModal } from './components/flightProfile/flightProfileNew';
30
30
  export type { FlightProfileConfig } from './components/flightProfile/flightProfileNew';
31
- export { scoringModal } from './components/scoring/scoringModal';
32
- export { setScoringConfig, getScoringConfig, resetScoringConfig } from './components/scoring/config';
33
- export type { ScoringModalParams, ScoringModalLabels, ScoreOutcome, SetScore } from './components/scoring/types';
34
31
  export type { StatusCodeGroups, StatusCodeEntry } from './components/scoring/logic/statusCodes';
32
+ export type { SetScore } from './components/scoring/types';
35
33
  export { openScoreEntryDialog } from './components/scoring/scoreEntryDialog';
36
34
  export type { ScoreEntryDialogParams, ScoreEntryApproach, ScoreEntryDialog } from './components/scoring/scoreEntryDialog';
37
35
  export type { ScoreEntryOutcome, ScoreEntryCard } from './components/scoring/scoreEntryCard';
38
36
  export { toEngineOutcome } from './components/scoring/logic/engineOutcome';
37
+ export { SCORE_ENTRY_TEXT, scoreEntryText } from './components/scoring/logic/scoreEntryText';
38
+ export type { ScoreEntryTextKey, ScoreEntryLabels } from './components/scoring/logic/scoreEntryText';
39
39
  export type { EngineOutcome as ScoreEntryEngineOutcome } from './components/scoring/logic/engineOutcome';
40
40
  export { getSetFormatForIndex, isSetTiebreakOnly, isSetTimed, getMaxAllowedScore, isSetComplete, getSetWinner, isMatchComplete, getMatchWinner, calculateComplement, shouldApplySmartComplement, shouldShowTiebreak, shouldCreateNextSet, buildSetScore } from './components/scoring/logic/dynamicSetsLogic';
41
41
  export type { SetFormat, MatchUpConfig, SmartComplementResult } from './components/scoring/logic/dynamicSetsLogic';
@@ -127,3 +127,5 @@ export { buildInteractiveScoringShell } from './components/interactive-scoring';
127
127
  export type { InteractiveScoringShell, InteractiveScoringShellConfig, StateChangedDetail } from './components/interactive-scoring';
128
128
  export { PolicyCatalogControl, PolicyCatalogStore, createPolicyCatalog, filterPolicyCatalog, groupPolicyCatalog, POLICY_TYPE_METADATA, POLICY_TYPE_GROUPS, getPolicyTypeMeta, buildPolicyCatalogPanel, buildEditorShell, buildPolicyCatalogLayout, buildJsonEditor, SchedulingEditorControl, createSchedulingEditor, SchedulingEditorStore, validateSchedulingPolicy, formatCodeLabel, emptySchedulingPolicy, buildSchedulingEditorPanel } from './components/policy-catalog';
129
129
  export type { PolicyCatalogItem, PolicyCatalogState, PolicyCatalogChangeListener, PolicyCatalogConfig, PolicyEditorInstance, PolicyEditorPlugin, PolicySource, PolicyTypeGroup, PolicyTypeMeta, CatalogGroupBy as PolicyCatalogGroupBy, SchedulingPolicyData, SchedulingEditorState, SchedulingEditorSection, SchedulingEditorChangeListener, SchedulingEditorConfig, SchedulingValidationResult, ValidationSeverity as SchedulingValidationSeverity, MinutesEntry, AverageTimeEntry, RecoveryTimeEntry, MatchUpAverageTime, MatchUpRecoveryTime } from './components/policy-catalog';
130
+ export { THEME_PALETTES, DEFAULT_DARK_PALETTE, DEFAULT_LIGHT_PALETTE, applyThemePalette, getThemePalettes, defaultThemePalette, resolveThemePalette } from './theme/palettes';
131
+ export type { ThemeMode, ThemePalette } from './theme/palettes';
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Color palette catalog.
3
+ *
4
+ * A palette is chosen per mode: a user picks one light palette and one dark palette, and `data-theme`
5
+ * (owned by the host app: light | dark, resolved from light/dark/system) decides which of the two shows.
6
+ * The host sets `data-palette` on <html> with `applyThemePalette`; the token values live in
7
+ * styles/theme.css (the defaults) and styles/palettes.css (the alternatives).
8
+ *
9
+ * Names are proper names, like font names, so they are not translated.
10
+ */
11
+ export type ThemeMode = 'light' | 'dark';
12
+ export type ThemePalette = {
13
+ id: string;
14
+ mode: ThemeMode;
15
+ name: string;
16
+ /** Representative colors for a picker: canvas, surface, chrome, text, accent, success. */
17
+ swatches: string[];
18
+ };
19
+ export declare const DEFAULT_LIGHT_PALETTE = "courtside";
20
+ export declare const DEFAULT_DARK_PALETTE = "midnight";
21
+ export declare const THEME_PALETTES: readonly ThemePalette[];
22
+ export declare function getThemePalettes(mode: ThemeMode): ThemePalette[];
23
+ export declare function defaultThemePalette(mode: ThemeMode): string;
24
+ /**
25
+ * The palette id to use for `mode`. A missing, unknown or wrong-mode id (a retired palette, a stored
26
+ * light id offered for dark) resolves to the mode's default rather than to no palette at all.
27
+ */
28
+ export declare function resolveThemePalette(mode: ThemeMode, paletteId?: string | null): string;
29
+ /** Sets `data-palette` on the root element and returns the id it applied. */
30
+ export declare function applyThemePalette(mode: ThemeMode, paletteId?: string | null, root?: HTMLElement): string;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "courthive-components",
3
3
  "packageManager": "pnpm@12.14.0",
4
- "version": "6.13.0",
4
+ "version": "7.0.0",
5
5
  "engines": {
6
6
  "node": ">=24"
7
7
  },
@@ -111,7 +111,7 @@
111
111
  "semver": "7.8.5",
112
112
  "storybook": "^10.2.17",
113
113
  "tabulator-tables": "6.6.1",
114
- "tods-competition-factory": "7.21.0",
114
+ "tods-competition-factory": "7.22.0",
115
115
  "typescript": "^6.0.2",
116
116
  "vite": "8.3.4",
117
117
  "vite-plugin-dts": "^5.0.0",
@@ -1,2 +0,0 @@
1
- import { RenderScoreEntryParams } from '../types';
2
- export declare function renderDialPadScoreEntry(params: RenderScoreEntryParams): void;
@@ -1,17 +0,0 @@
1
- /**
2
- * Shared dial pad logic - formats raw digits into score string
3
- * Parses matchUpFormat to determine boundaries
4
- */
5
- export type FormatOptions = {
6
- matchUpFormat: string;
7
- };
8
- /**
9
- * Convert raw digits to formatted score string
10
- * Example: "6464" with matchUpFormat 'SET3-S:6/TB7' becomes "6-4 6-4"
11
- */
12
- export declare function formatScoreString(digits: string, options: FormatOptions): string;
13
- /**
14
- * The number of sets a format names. `matchUpFormatCode.parse` puts `bestOf` and `exactly` at the top level
15
- * of the parsed format, never inside `setFormat`.
16
- */
17
- export declare function setCountOf(parsedFormat: any): number;
@@ -1,2 +0,0 @@
1
- import { RenderScoreEntryParams } from '../types';
2
- export declare function renderDynamicSetsScoreEntry(params: RenderScoreEntryParams): void;
@@ -1,2 +0,0 @@
1
- import { RenderScoreEntryParams } from '../types';
2
- export declare function renderFreeScoreEntry(params: RenderScoreEntryParams): void;
@@ -1,2 +0,0 @@
1
- import { RenderScoreEntryParams } from '../types';
2
- export declare function renderInlineScoringEntry(params: RenderScoreEntryParams): void;
@@ -1,28 +0,0 @@
1
- /**
2
- * Scoring configuration for courthive-components
3
- * This provides a simple configuration object that can be modified by consumers
4
- */
5
- export interface ScoringConfig {
6
- scoringApproach?: 'freeScore' | 'dynamicSets' | 'dialPad' | 'inlineScoring';
7
- smartComplements?: boolean;
8
- composition?: string;
9
- idiom?: string;
10
- dateFormat?: string;
11
- timeFormat?: string;
12
- }
13
- /**
14
- * Get current scoring configuration
15
- */
16
- export declare function getScoringConfig(): ScoringConfig;
17
- /**
18
- * Set scoring configuration (can be partial)
19
- */
20
- export declare function setScoringConfig(config: Partial<ScoringConfig>): void;
21
- /**
22
- * Reset configuration to defaults
23
- */
24
- export declare function resetScoringConfig(): void;
25
- /**
26
- * Stub for loadSettings (for compatibility with TMX code)
27
- */
28
- export declare function loadSettings(): any;
@@ -1,6 +0,0 @@
1
- /**
2
- * Scoring Modal - Modern TypeScript implementation
3
- * Entry point for the scoring system
4
- */
5
- export { scoringModal } from './scoringModal';
6
- export * from './types';
@@ -1,25 +0,0 @@
1
- import { ScoreOutcome } from '../types';
2
- /** The fields a projection may replace. Everything else on the matchUp is carried through as-is. */
3
- type ProjectableMatchUp = {
4
- score?: any;
5
- matchUpStatus?: string;
6
- winningSide?: number;
7
- [key: string]: any;
8
- };
9
- /**
10
- * The matchUp the next approach should hydrate from.
11
- *
12
- * Returns the original when there is nothing in progress to carry — the ordinary case on first open,
13
- * where the saved matchUp IS the truth.
14
- *
15
- * ── `winningSide` takes no fallback, and that is the whole care of this function ──
16
- *
17
- * It is read from the outcome and never from the saved matchUp. If the operator has cleared the
18
- * score, the outcome carries no winner, and falling back to the stored one would put back a winner
19
- * they had just removed — an unanswered question read as a particular answer, which is the fail-open
20
- * shape (Mentat architectural standard A3) that `irregularEnding.ts` exists to prevent, one field
21
- * over. `score` and `matchUpStatus` DO fall back, because an outcome that asserts neither is not
22
- * claiming the match has no score or no status; it is simply not speaking about them.
23
- */
24
- export declare function projectOutcomeOntoMatchUp<T extends ProjectableMatchUp>(matchUp: T, outcome?: ScoreOutcome | null): T;
25
- export {};
@@ -1,2 +0,0 @@
1
- import { ScoringModalParams } from './types';
2
- export declare function scoringModal(params: ScoringModalParams): void;
@@ -1,15 +0,0 @@
1
- import { StatusCodeGroups } from './logic/statusCodes';
2
- import { ScoringModalLabels } from './types';
3
- export type StatusCodePickerHandle = {
4
- element: HTMLElement;
5
- /** Re-render for a new status. Returns the code still selected, if any. */
6
- update: (matchUpStatus: string | undefined) => string | undefined;
7
- /** The chosen code, or undefined when none is chosen or none is offered. */
8
- getSelectedCode: () => string | undefined;
9
- };
10
- export declare function buildStatusCodePicker(params: {
11
- groups?: StatusCodeGroups;
12
- labels?: ScoringModalLabels;
13
- /** The code already recorded on the matchUp, so re-opening the dialog shows what was saved. */
14
- initialCode?: string;
15
- }): StatusCodePickerHandle;
@@ -1,12 +0,0 @@
1
- /**
2
- * Shared utilities for formatting scores for display in scoring modals
3
- */
4
- /**
5
- * Format existing score object into string for input field
6
- */
7
- export declare function formatExistingScore(scoreObject: any, matchUpStatus?: string): string;
8
- /**
9
- * Get short abbreviation for matchUpStatus
10
- * Returns empty string for unknown or unhandled statuses
11
- */
12
- export declare function getStatusAbbreviation(status: string): string;
@@ -1,16 +0,0 @@
1
- import { ScoreOutcome } from '../types';
2
- /**
3
- * Validate a score string using generateOutcomeFromScoreString with preserveSideOrder
4
- */
5
- export declare function validateScore(scoreString: string, matchUpFormat?: string, matchUpStatus?: string): ScoreOutcome;
6
- /**
7
- * Validate individual set scores (for Dynamic Sets approach)
8
- * Builds a scoreString from the sets and uses validateScore for consistent validation
9
- */
10
- export declare function validateSetScores(sets: Array<{
11
- side1?: number;
12
- side2?: number;
13
- side1TiebreakScore?: number;
14
- side2TiebreakScore?: number;
15
- winningSide?: number;
16
- }>, matchUpFormat?: string, allowIncomplete?: boolean): ScoreOutcome;