refactor: remove type assertions in component props
- create proper UncapStarProps and TranscendenceStarProps interfaces - use discriminated union for StarRender type - add function overloads for createStarProps with type safety - remove 'as any' casts from star component spreading - remove optionalProps workaround in SegmentedControl - stop spreading HTMLAttributes to RadioGroupPrimitive (not supported)
This commit is contained in:
parent
654eabbeba
commit
ca16ca145b
2 changed files with 50 additions and 16 deletions
|
|
@ -7,7 +7,6 @@
|
||||||
import type { Snippet } from 'svelte'
|
import type { Snippet } from 'svelte'
|
||||||
import styles from './segmented-control.module.scss'
|
import styles from './segmented-control.module.scss'
|
||||||
import type { HTMLAttributes } from 'svelte/elements'
|
import type { HTMLAttributes } from 'svelte/elements'
|
||||||
import { optionalProps } from '$lib/utils/typeShims'
|
|
||||||
|
|
||||||
export type SegmentedControlVariant = 'default' | 'blended' | 'background'
|
export type SegmentedControlVariant = 'default' | 'blended' | 'background'
|
||||||
|
|
||||||
|
|
@ -32,8 +31,7 @@
|
||||||
gap = false,
|
gap = false,
|
||||||
class: className,
|
class: className,
|
||||||
wrapperClass,
|
wrapperClass,
|
||||||
children,
|
children
|
||||||
...restProps
|
|
||||||
}: Props = $props()
|
}: Props = $props()
|
||||||
|
|
||||||
// Provide variant to child segments via context
|
// Provide variant to child segments via context
|
||||||
|
|
@ -85,7 +83,7 @@
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class={wrapperClassList}>
|
<div class={wrapperClassList}>
|
||||||
<RadioGroupPrimitive.Root bind:value class={classList} {...(optionalProps(restProps) as any)}>
|
<RadioGroupPrimitive.Root bind:value class={classList}>
|
||||||
{@render children?.()}
|
{@render children?.()}
|
||||||
</RadioGroupPrimitive.Root>
|
</RadioGroupPrimitive.Root>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -19,15 +19,34 @@
|
||||||
updateTranscendence?: ((index: number) => void) | undefined
|
updateTranscendence?: ((index: number) => void) | undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
interface StarRender {
|
// Props for UncapStar component
|
||||||
type: 'uncap' | 'transcendence'
|
interface UncapStarProps {
|
||||||
props: {
|
empty?: boolean
|
||||||
index?: number
|
special?: boolean
|
||||||
onStarClick?: (index: number, empty: boolean) => void
|
flb?: boolean
|
||||||
[key: string]: any
|
ulb?: boolean
|
||||||
}
|
index: number
|
||||||
|
tabindex?: number
|
||||||
|
onStarClick: (index: number, empty: boolean) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Props for TranscendenceStar component
|
||||||
|
interface TranscendenceStarProps {
|
||||||
|
className?: string
|
||||||
|
stage?: number
|
||||||
|
type?: 'character' | 'weapon' | 'summon'
|
||||||
|
editable?: boolean
|
||||||
|
interactive?: boolean
|
||||||
|
tabindex?: number
|
||||||
|
onStarClick?: () => void
|
||||||
|
onFragmentClick?: (newStage: number) => void
|
||||||
|
onFragmentHover?: (newStage: number) => void
|
||||||
|
}
|
||||||
|
|
||||||
|
type StarRender =
|
||||||
|
| { type: 'uncap'; props: UncapStarProps }
|
||||||
|
| { type: 'transcendence'; props: TranscendenceStarProps }
|
||||||
|
|
||||||
let {
|
let {
|
||||||
type,
|
type,
|
||||||
rarity,
|
rarity,
|
||||||
|
|
@ -77,13 +96,26 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Options for creating uncap star props
|
||||||
|
interface UncapStarOptions {
|
||||||
|
index: number
|
||||||
|
flb?: boolean
|
||||||
|
ulb?: boolean
|
||||||
|
special?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
// Helper function to create star props
|
// Helper function to create star props
|
||||||
const createStarProps = (starType: 'uncap' | 'transcendence', options: any = {}): StarRender => {
|
function createStarProps(starType: 'transcendence'): StarRender
|
||||||
|
function createStarProps(starType: 'uncap', options: UncapStarOptions): StarRender
|
||||||
|
function createStarProps(
|
||||||
|
starType: 'uncap' | 'transcendence',
|
||||||
|
options?: UncapStarOptions
|
||||||
|
): StarRender {
|
||||||
if (starType === 'transcendence') {
|
if (starType === 'transcendence') {
|
||||||
return {
|
return {
|
||||||
type: 'transcendence',
|
type: 'transcendence',
|
||||||
props: {
|
props: {
|
||||||
stage: transcendenceStage,
|
stage: transcendenceStage ?? 0,
|
||||||
type,
|
type,
|
||||||
editable,
|
editable,
|
||||||
interactive: editable,
|
interactive: editable,
|
||||||
|
|
@ -92,6 +124,10 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!options) {
|
||||||
|
throw new Error('Options required for uncap star')
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
type: 'uncap',
|
type: 'uncap',
|
||||||
props: {
|
props: {
|
||||||
|
|
@ -100,7 +136,7 @@
|
||||||
flb: options.flb,
|
flb: options.flb,
|
||||||
ulb: options.ulb,
|
ulb: options.ulb,
|
||||||
special: options.special,
|
special: options.special,
|
||||||
tabIndex: editable ? 0 : undefined,
|
tabindex: editable ? 0 : undefined,
|
||||||
onStarClick: editable ? toggleStar : () => {}
|
onStarClick: editable ? toggleStar : () => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -164,9 +200,9 @@
|
||||||
{@const star = renderStar(i)}
|
{@const star = renderStar(i)}
|
||||||
{#if star}
|
{#if star}
|
||||||
{#if star.type === 'transcendence'}
|
{#if star.type === 'transcendence'}
|
||||||
<TranscendenceStar {...(star.props as any)} />
|
<TranscendenceStar {...star.props} />
|
||||||
{:else}
|
{:else}
|
||||||
<UncapStar {...(star.props as any)} />
|
<UncapStar {...star.props} />
|
||||||
{/if}
|
{/if}
|
||||||
{/if}
|
{/if}
|
||||||
{/each}
|
{/each}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue