kopia lustrzana https://github.com/shoelace-style/shoelace
Add event types to react wrapper components (#1419)
* Rename SlSlideChange for consistency with other events * Setup React event types for events used by Shoelace components Means that consumers of Shoelace via the React wrapper will be able to use callback methods with the correct event type, instead of having to rely on casting and friends when using Typescript. * Add docs demonstrating importing event types for React callbackspull/1453/head
rodzic
e1ca7d1f59
commit
8fd01e1eda
|
@ -116,6 +116,7 @@ export default {
|
|||
if (classDoc?.events) {
|
||||
classDoc.events.forEach(event => {
|
||||
event.reactName = `on${pascalCase(event.name)}`;
|
||||
event.eventName = `${pascalCase(event.name)}Event`;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -83,6 +83,25 @@ function MyComponent() {
|
|||
export default MyComponent;
|
||||
```
|
||||
|
||||
You can also import the event type for use in your callbacks, shown below.
|
||||
|
||||
```tsx
|
||||
import { useCallback, useState } from 'react';
|
||||
import { SlInput, SlInputEvent } from '@shoelace-style/shoelace/%NPMDIR%/react';
|
||||
import type SlInputElement from '@shoelace-style/shoelace/%NPMDIR%/components/input/input';
|
||||
|
||||
function MyComponent() {
|
||||
const [value, setValue] = useState('');
|
||||
const onInput = useCallback((event: SlInputEvent) => {
|
||||
setValue(event.detail);
|
||||
}, []);
|
||||
|
||||
return <SlInput value={value} onSlInput={event => setValue((event.target as SlInputElement).value)} />;
|
||||
}
|
||||
|
||||
export default MyComponent;
|
||||
```
|
||||
|
||||
## Testing with Jest
|
||||
|
||||
Testing with web components can be challenging if your test environment runs in a Node environment (i.e. it doesn't run in a real browser). Fortunately, [Jest](https://jestjs.io/) has made a number of strides to support web components and provide additional browser APIs. However, it's still not a complete replication of a browser environment.
|
||||
|
|
|
@ -25,7 +25,14 @@ components.map(component => {
|
|||
const componentDir = path.join(reactDir, tagWithoutPrefix);
|
||||
const componentFile = path.join(componentDir, 'index.ts');
|
||||
const importPath = component.path;
|
||||
const events = (component.events || []).map(event => `${event.reactName}: '${event.name}'`).join(',\n');
|
||||
const eventImports = (component.events || [])
|
||||
.map(event => `import { ${event.eventName} } from '../../../src/events/events';`)
|
||||
.join('\n');
|
||||
const eventNameImport =
|
||||
(component.events || []).length > 0 ? `import { type EventName } from '@lit-labs/react';` : ``;
|
||||
const events = (component.events || [])
|
||||
.map(event => `${event.reactName}: '${event.name}' as EventName<${event.eventName}>`)
|
||||
.join(',\n');
|
||||
|
||||
fs.mkdirSync(componentDir, { recursive: true });
|
||||
|
||||
|
@ -35,6 +42,9 @@ components.map(component => {
|
|||
import { createComponent } from '@lit-labs/react';
|
||||
import Component from '../../${importPath}';
|
||||
|
||||
${eventNameImport}
|
||||
${eventImports}
|
||||
|
||||
export default createComponent({
|
||||
tagName: '${component.tagName}',
|
||||
elementClass: Component,
|
||||
|
|
|
@ -28,7 +28,7 @@ export type { default as SlResizeEvent } from './sl-resize';
|
|||
export type { default as SlSelectEvent } from './sl-select';
|
||||
export type { default as SlSelectionChangeEvent } from './sl-selection-change';
|
||||
export type { default as SlShowEvent } from './sl-show';
|
||||
export type { default as SlSlideChange } from './sl-slide-change';
|
||||
export type { default as SlSlideChangeEvent } from './sl-slide-change';
|
||||
export type { default as SlStartEvent } from './sl-start';
|
||||
export type { default as SlTabHideEvent } from './sl-tab-hide';
|
||||
export type { default as SlTabShowEvent } from './sl-tab-show';
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import type SlCarouselItem from '../components/carousel-item/carousel-item';
|
||||
|
||||
type SlSlideChange = CustomEvent<{ index: number; slide: SlCarouselItem }>;
|
||||
type SlSlideChangeEvent = CustomEvent<{ index: number; slide: SlCarouselItem }>;
|
||||
|
||||
declare global {
|
||||
interface GlobalEventHandlersEventMap {
|
||||
'sl-slide-change': SlSlideChange;
|
||||
'sl-slide-change': SlSlideChangeEvent;
|
||||
}
|
||||
}
|
||||
|
||||
export default SlSlideChange;
|
||||
export default SlSlideChangeEvent;
|
||||
|
|
Ładowanie…
Reference in New Issue