shoelace-style/shoelace

[React] Insufficient type for onSlChange event listeners

Open

#2,440 opened on May 12, 2025

View on GitHub
 (0 comments) (0 reactions) (0 assignees)TypeScript (922 forks)github user discovery
bughelp wanted

Repository metrics

Stars
 (13,867 stars)
PR merge metrics
 (No merged PRs in 30d)

Description

Describe the bug

The onSlChange event listener properties take an event listener for a SlChangeEvent event. That's defined as

export type SlChangeEvent = CustomEvent<Record<PropertyKey, never>>;
declare global {
    interface GlobalEventHandlersEventMap {
        'sl-change': SlChangeEvent;
    }
}

The event.target isn't specified. It should be the custom element type, e.g. <sl-input> or <sl-select>.

To Reproduce

Create a React form element with an onSlChange event handler:

<!-- this doesn't work, per TypeScript: -->
import SlInput from '@shoelace-style/shoelace/dist/react/input/index.js';
<SlInput
  label="From"
  type="date"
  defaultValue={from?.toISOString()?.slice(0, 10)}
  onSlChange={(e) => updateFilters({ from: e.target.valueAsDate })}
/>

<!-- this does: -->
import SlInput from '@shoelace-style/shoelace/dist/react/input/index.js';
import type SlInputElement from '@shoelace-style/shoelace/dist/components/input/input.component.js';
<SlInput
  label="From"
  type="date"
  defaultValue={from?.toISOString()?.slice(0, 10)}
  onSlChange={(e) => updateFilters({ from: (e.target as SlInputElement).valueAsDate })}
/>

It's a little bit worse for <SlSelect> since target.value is string | string[], but should really be determined by multiple.

Contributor guide