diff --git a/eslint.config.js b/eslint.config.js index df3672d..74caa80 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -20,6 +20,11 @@ export default tseslint.config( rules: { '@typescript-eslint/no-explicit-any': 'warn', '@typescript-eslint/explicit-module-boundary-types': 'off', + '@typescript-eslint/no-unused-vars': ['error', { + argsIgnorePattern: '^_', + varsIgnorePattern: '^_', + caughtErrorsIgnorePattern: '^_', + }], }, }, { diff --git a/package-lock.json b/package-lock.json index cf9b3a9..3a85eab 100644 --- a/package-lock.json +++ b/package-lock.json @@ -29,13 +29,25 @@ "vue": "^3.5.12" }, "peerDependencies": { - "react": ">=16.8.0", + "@angular/core": ">=18.0.0", + "react": ">=18.0.0", + "solid-js": ">=1.8.0", + "svelte": ">=4.0.0 || >=5.0.0", "vue": ">=3.0.0" }, "peerDependenciesMeta": { + "@angular/core": { + "optional": true + }, "react": { "optional": true }, + "solid-js": { + "optional": true + }, + "svelte": { + "optional": true + }, "vue": { "optional": true } diff --git a/src/adapters/angular.ts b/src/adapters/angular.ts index df431e7..b423aa1 100644 --- a/src/adapters/angular.ts +++ b/src/adapters/angular.ts @@ -1,3 +1,5 @@ +/* eslint-disable @typescript-eslint/triple-slash-reference */ +/// import { Component, Input, @@ -10,8 +12,6 @@ import { ElementRef, ViewChild, ChangeDetectionStrategy, - inject, - effect, signal, } from '@angular/core'; import { Gracket } from '../core/Gracket'; @@ -50,7 +50,6 @@ export class GracketComponent implements OnInit, OnDestroy, OnChanges { // Using signals for reactive state - Angular 18+ best practice protected error = signal(null); private gracketInstance = signal(null); - private elementRef = inject(ElementRef); ngOnInit(): void { // Initialize will happen after view init when container is available diff --git a/src/adapters/module-stubs.d.ts b/src/adapters/module-stubs.d.ts new file mode 100644 index 0000000..f582414 --- /dev/null +++ b/src/adapters/module-stubs.d.ts @@ -0,0 +1,108 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +/* eslint-disable @typescript-eslint/no-unsafe-function-type */ +/* eslint-disable @typescript-eslint/no-empty-object-type */ +/* eslint-disable @typescript-eslint/no-unused-vars */ +// Type stubs for optional peer dependencies during build +// These allow TypeScript to compile without having the actual packages installed +// This file provides minimal type definitions to satisfy TypeScript when peer dependencies are not installed + +// Svelte 5 runes support +declare function $state(initial: T): T; +declare function $effect(fn: () => void | (() => void)): void; +declare function $derived(fn: () => T): T; + +// Solid JSX namespace augmentation +declare namespace JSX { + interface IntrinsicElements { + div: { + ref?: any; + class?: string; + className?: string; + style?: any; + children?: any; + [key: string]: any; + }; + [elemName: string]: any; + } +} + +declare module '@angular/core' { + export interface Type extends Function { + new (...args: any[]): T; + } + export interface SimpleChange { + firstChange: boolean; + previousValue: any; + currentValue: any; + isFirstChange(): boolean; + } + export interface SimpleChanges { + [propName: string]: SimpleChange; + } + export class EventEmitter { + emit(value?: T): void; + subscribe(generatorOrNext?: any, error?: any, complete?: any): any; + } + export class ElementRef { + nativeElement: T; + } + export interface OnInit { + ngOnInit(): void; + } + export interface OnDestroy { + ngOnDestroy(): void; + } + export interface OnChanges { + ngOnChanges(changes: SimpleChanges): void; + } + export const ChangeDetectionStrategy: { + OnPush: number; + Default: number; + }; + export function Component(obj: any): any; + export function Input(obj?: any): any; + export function Output(obj?: any): any; + export function ViewChild(selector: string | Type, opts?: any): any; + export function inject(token: Type | any): T; + export function signal(initialValue: T): any; +} + +declare module 'solid-js' { + export interface Component

{ + (props: P): any; + } + export namespace JSX { + export interface CSSProperties { + [key: string]: string | number | undefined; + } + export interface Element {} + export interface IntrinsicElements { + div: any; + [elemName: string]: any; + } + } + export function createSignal(initialValue: T): [() => T, (v: T) => void]; + export function createEffect(fn: () => void): void; + export function onMount(fn: () => void): void; + export function onCleanup(fn: () => void): void; + export function mergeProps(defaults: Partial, props: U): T & U; + export function mergeProps(a: A, b: B, c: C): A & B & C; + export function mergeProps(...args: any[]): any; +} + +declare module 'svelte' { + export class SvelteComponent { + constructor(options: any); + $on(event: string, handler: (e: any) => any): () => void; + $set(props: Partial): void; + $destroy(): void; + } + export function onMount(fn: () => any): void; + export function onDestroy(fn: () => any): void; + export function createEventDispatcher(): (event: string, detail?: any) => void; +} + +declare module './svelte.svelte' { + const component: any; + export default component; +} diff --git a/src/adapters/solid.tsx b/src/adapters/solid.tsx index 747afc1..f9ebcea 100644 --- a/src/adapters/solid.tsx +++ b/src/adapters/solid.tsx @@ -1,3 +1,5 @@ +/* eslint-disable @typescript-eslint/triple-slash-reference */ +/// import { createSignal, createEffect, @@ -27,8 +29,8 @@ export interface GracketSolidProps extends Omit { * SolidJS component wrapper for Gracket * Uses modern SolidJS best practices with fine-grained reactivity */ -export const GracketSolid: Component = (props) => { - const merged = mergeProps({ class: '', style: {} }, props); +export const GracketSolid: Component = (props: GracketSolidProps) => { + const merged = mergeProps({ class: '', style: {} as JSX.CSSProperties }, props) as Required> & GracketSolidProps; let containerRef: HTMLDivElement | undefined; let gracketInstance: Gracket | null = null; @@ -40,7 +42,7 @@ export const GracketSolid: Component = (props) => { if (!containerRef || !merged.data?.length) return; try { - const { data, onInit, onError, class: _, style: __, ...options } = merged; + const { data, class: _class, style: _style, ...options } = merged; gracketInstance = new Gracket(containerRef, { ...options, diff --git a/src/adapters/svelte.svelte.d.ts b/src/adapters/svelte.svelte.d.ts new file mode 100644 index 0000000..e265bce --- /dev/null +++ b/src/adapters/svelte.svelte.d.ts @@ -0,0 +1,32 @@ +// Type declaration for Svelte component +import type { SvelteComponent } from 'svelte'; +import type { Gracket } from '../core/Gracket'; +import type { GracketOptions, TournamentData } from '../types'; + +export interface GracketSvelteProps { + data: TournamentData; + options?: Omit; + className?: string; + style?: string; +} + +export interface GracketSvelteEvents { + init: CustomEvent; + error: CustomEvent; + update: CustomEvent; +} + +export default class GracketSvelte extends SvelteComponent< + GracketSvelteProps, + GracketSvelteEvents +> { + updateScore( + roundIndex: number, + gameIndex: number, + teamIndex: number, + score: number + ): void; + advanceRound(fromRound?: number): TournamentData | undefined; + getInstance(): Gracket | null; + destroy(): void; +} diff --git a/src/adapters/svelte.ts b/src/adapters/svelte.ts index 2792025..aa24640 100644 --- a/src/adapters/svelte.ts +++ b/src/adapters/svelte.ts @@ -1,3 +1,5 @@ +/* eslint-disable @typescript-eslint/triple-slash-reference */ +/// import { Gracket } from '../core/Gracket'; import type { GracketOptions, TournamentData } from '../types'; diff --git a/src/adapters/webcomponent.ts b/src/adapters/webcomponent.ts index f0c937a..d809776 100644 --- a/src/adapters/webcomponent.ts +++ b/src/adapters/webcomponent.ts @@ -20,7 +20,7 @@ export class GracketElement extends HTMLElement { private container: HTMLDivElement | null = null; private _data: TournamentData = []; private _options: Omit = {}; - private shadowRoot: ShadowRoot; + declare shadowRoot: ShadowRoot; // Observed attributes for reactive updates static get observedAttributes() { diff --git a/tsconfig.json b/tsconfig.json index 5dc8b11..fa2eda0 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -14,8 +14,8 @@ "declarationMap": true, "jsx": "react-jsx", "strict": true, - "noUnusedLocals": true, - "noUnusedParameters": true, + "noUnusedLocals": false, + "noUnusedParameters": false, "noFallthroughCasesInSwitch": true, "esModuleInterop": true, "allowSyntheticDefaultImports": true, @@ -24,5 +24,5 @@ "declarationDir": "./dist" }, "include": ["src"], - "exclude": ["node_modules", "dist", "**/*.test.ts", "**/*.test.tsx"] + "exclude": ["node_modules", "dist", "**/*.test.ts", "**/*.test.tsx", "src/adapters/svelte.svelte"] }