@desynth/web-components-react 6.7.25-alpha.1 → 13.9.26-alpha.1
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.
- package/dist/components.d.ts +466 -32
- package/dist/components.js +877 -64
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/package.json +40 -39
- package/readme.md +225 -11
- package/dist/react-component-lib/createComponent.d.ts +0 -10
- package/dist/react-component-lib/createComponent.js +0 -74
- package/dist/react-component-lib/createOverlayComponent.d.ts +0 -21
- package/dist/react-component-lib/createOverlayComponent.js +0 -95
- package/dist/react-component-lib/index.d.ts +0 -2
- package/dist/react-component-lib/index.js +0 -2
- package/dist/react-component-lib/interfaces.d.ts +0 -29
- package/dist/react-component-lib/interfaces.js +0 -1
- package/dist/react-component-lib/utils/attachProps.d.ts +0 -16
- package/dist/react-component-lib/utils/attachProps.js +0 -107
- package/dist/react-component-lib/utils/case.d.ts +0 -2
- package/dist/react-component-lib/utils/case.js +0 -6
- package/dist/react-component-lib/utils/dev.d.ts +0 -2
- package/dist/react-component-lib/utils/dev.js +0 -12
- package/dist/react-component-lib/utils/index.d.ts +0 -10
- package/dist/react-component-lib/utils/index.js +0 -31
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './components.js';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './components.js';
|
package/package.json
CHANGED
|
@@ -1,41 +1,42 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
2
|
+
"name": "@desynth/web-components-react",
|
|
3
|
+
"sideEffects": false,
|
|
4
|
+
"version": "13.09.26-alpha.01",
|
|
5
|
+
"description": "React proxy for @desynth/web-components",
|
|
6
|
+
"license": "MPL-2.0",
|
|
7
|
+
"homepage": "https://github.com/desynth/desynth-web-components#readme",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/desynth/desynth-web-components.git"
|
|
11
|
+
},
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/desynth/desynth-web-components/issues"
|
|
14
|
+
},
|
|
15
|
+
"publishConfig": {
|
|
16
|
+
"access": "public"
|
|
17
|
+
},
|
|
18
|
+
"scripts": {
|
|
19
|
+
"build": "npm run tsc",
|
|
20
|
+
"tsc": "tsc -p ."
|
|
21
|
+
},
|
|
22
|
+
"main": "./dist/index.js",
|
|
23
|
+
"module": "./dist/index.js",
|
|
24
|
+
"types": "./dist/index.d.ts",
|
|
25
|
+
"files": [
|
|
26
|
+
"dist/"
|
|
27
|
+
],
|
|
28
|
+
"type": "module",
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"@types/react": "19.2.4",
|
|
31
|
+
"@types/react-dom": "19.2.3"
|
|
32
|
+
},
|
|
33
|
+
"dependencies": {
|
|
34
|
+
"react": ">=19.2.0",
|
|
35
|
+
"react-dom": ">=19.2.0",
|
|
36
|
+
"typescript": "5.2.2"
|
|
37
|
+
},
|
|
38
|
+
"peerDependencies": {
|
|
39
|
+
"react": ">=19.2.0",
|
|
40
|
+
"react-dom": ">=19.2.0"
|
|
41
|
+
}
|
|
41
42
|
}
|
package/readme.md
CHANGED
|
@@ -1,15 +1,229 @@
|
|
|
1
|
-
# desynth
|
|
2
|
-
|
|
1
|
+
# `@desynth/web-components-react`
|
|
2
|
+
|
|
3
|
+
Wrappers React tipados para los Custom Elements de `@desynth/web-components`, generados por `@stencil/react-output-target`.
|
|
4
|
+
|
|
5
|
+
## Requisitos e instalación
|
|
6
|
+
|
|
7
|
+
El paquete declara `react >= 19.2.0` y `react-dom >= 19.2.0` como peer dependencies. Los wrappers importan las clases y tipos del paquete core, por lo que debe instalarse también:
|
|
3
8
|
|
|
4
9
|
```bash
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
npm install @desynth/web-components-react @desynth/web-components react react-dom
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Conviene mantener `@desynth/web-components-react` y `@desynth/web-components` en versiones compatibles, especialmente en versiones alpha.
|
|
14
|
+
|
|
15
|
+
## Uso
|
|
16
|
+
|
|
17
|
+
Todos los wrappers se exportan desde la entrada principal:
|
|
18
|
+
|
|
19
|
+
```tsx
|
|
20
|
+
import {
|
|
21
|
+
DesynthButton,
|
|
22
|
+
DesynthDataTable,
|
|
23
|
+
} from '@desynth/web-components-react';
|
|
24
|
+
|
|
25
|
+
export function Example() {
|
|
26
|
+
return (
|
|
27
|
+
<>
|
|
28
|
+
<DesynthButton buttonText="Guardar" variant="solid" />
|
|
29
|
+
<DesynthDataTable
|
|
30
|
+
columns={JSON.stringify([{ key: 'name', label: 'Nombre' }])}
|
|
31
|
+
rows={JSON.stringify([{ id: '1', name: 'Ada' }])}
|
|
32
|
+
emptyText="Sin resultados"
|
|
33
|
+
/>
|
|
34
|
+
</>
|
|
35
|
+
);
|
|
36
|
+
}
|
|
12
37
|
```
|
|
13
|
-
## General Solution's Architecture Design
|
|
14
|
-

|
|
15
38
|
|
|
39
|
+
Las exportaciones usan nombres PascalCase derivados de las clases generadas: `DesynthButton`, `DesynthTextInput`, `HorizontalCards` y `HtmlEditor`, entre otras.
|
|
40
|
+
|
|
41
|
+
## Registro de Custom Elements
|
|
42
|
+
|
|
43
|
+
No llames a `defineCustomElements()` para usar estos wrappers. Cada wrapper generado recibe su propia función `defineCustomElement` desde `@desynth/web-components/dist/<tag>.js` y registra ese elemento al cargarse.
|
|
44
|
+
|
|
45
|
+
El loader global solo es necesario si, además de los wrappers React, la aplicación renderiza etiquetas Custom Element directamente y quiere registrarlas en bloque:
|
|
46
|
+
|
|
47
|
+
```ts
|
|
48
|
+
import { defineCustomElements } from '@desynth/web-components/loader';
|
|
49
|
+
|
|
50
|
+
defineCustomElements();
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
No mezcles ambos mecanismos por rutina: los registros individuales ya comprueban si el elemento existe y el loader global añade trabajo innecesario cuando toda la UI usa wrappers.
|
|
54
|
+
|
|
55
|
+
## Propiedades y nombres
|
|
56
|
+
|
|
57
|
+
En JSX se usan los nombres de propiedad de Stencil en camelCase, no los atributos HTML en kebab-case:
|
|
58
|
+
|
|
59
|
+
| Web Component | React |
|
|
60
|
+
| --- | --- |
|
|
61
|
+
| `button-text` | `buttonText` |
|
|
62
|
+
| `empty-text` | `emptyText` |
|
|
63
|
+
| `preview-url` | `previewUrl` |
|
|
64
|
+
| `button-id` | `buttonId` |
|
|
65
|
+
|
|
66
|
+
Las propiedades booleanas reciben booleanos reales:
|
|
67
|
+
|
|
68
|
+
```tsx
|
|
69
|
+
<DesynthButton disabled={isSaving} full buttonText="Guardar" />
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Los tipos de cada wrapper proceden del paquete core y están incluidos en `dist/components.d.ts`.
|
|
73
|
+
|
|
74
|
+
## Datos JSON
|
|
75
|
+
|
|
76
|
+
Varias propiedades complejas del core están declaradas como `string` y el componente ejecuta `JSON.parse` internamente. En esos casos hay que serializar arrays y objetos también desde React; pasar el objeto directamente contradice la API generada.
|
|
77
|
+
|
|
78
|
+
```tsx
|
|
79
|
+
import { DesynthDataTable } from '@desynth/web-components-react';
|
|
80
|
+
|
|
81
|
+
type Row = {
|
|
82
|
+
id: string;
|
|
83
|
+
name: string;
|
|
84
|
+
status: 'active' | 'paused';
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
const columns = [
|
|
88
|
+
{ key: 'name', label: 'Nombre' },
|
|
89
|
+
{ key: 'status', label: 'Estado' },
|
|
90
|
+
];
|
|
91
|
+
|
|
92
|
+
const rows: Row[] = [
|
|
93
|
+
{ id: 'usr-1', name: 'Ada', status: 'active' },
|
|
94
|
+
];
|
|
95
|
+
|
|
96
|
+
export function UsersTable() {
|
|
97
|
+
return (
|
|
98
|
+
<DesynthDataTable
|
|
99
|
+
columns={JSON.stringify(columns)}
|
|
100
|
+
rows={JSON.stringify(rows)}
|
|
101
|
+
badges={JSON.stringify({
|
|
102
|
+
status: { active: '#18864b', paused: '#8a6400' },
|
|
103
|
+
})}
|
|
104
|
+
actions={JSON.stringify([
|
|
105
|
+
{ key: 'open', label: 'Abrir' },
|
|
106
|
+
])}
|
|
107
|
+
onHandleAction={(event) => {
|
|
108
|
+
const { rowId, action } = event.detail;
|
|
109
|
+
console.log(rowId, action);
|
|
110
|
+
}}
|
|
111
|
+
/>
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
No todas las propiedades con datos son JSON. Revisa el tipo exportado o la referencia del componente core antes de serializar.
|
|
117
|
+
|
|
118
|
+
## Eventos
|
|
119
|
+
|
|
120
|
+
Los eventos de Stencil se convierten en props React con prefijo `on` y PascalCase:
|
|
121
|
+
|
|
122
|
+
| Evento DOM | Prop React |
|
|
123
|
+
| --- | --- |
|
|
124
|
+
| `handleClick` | `onHandleClick` |
|
|
125
|
+
| `handleChange` | `onHandleChange` |
|
|
126
|
+
| `handleAction` | `onHandleAction` |
|
|
127
|
+
| `htmlChanged` | `onHtmlChanged` |
|
|
128
|
+
|
|
129
|
+
El callback recibe un `CustomEvent` tipado; la carga útil está en `event.detail`.
|
|
130
|
+
|
|
131
|
+
```tsx
|
|
132
|
+
import { DesynthTextInput } from '@desynth/web-components-react';
|
|
133
|
+
|
|
134
|
+
export function Search() {
|
|
135
|
+
return (
|
|
136
|
+
<DesynthTextInput
|
|
137
|
+
inputId="search"
|
|
138
|
+
inputName="Buscar"
|
|
139
|
+
onHandleInput={(event) => {
|
|
140
|
+
console.log(event.detail.value);
|
|
141
|
+
}}
|
|
142
|
+
/>
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
Usa el nombre exacto expuesto por el wrapper. No lo sustituyas por `onClick` o `onChange` salvo que la API tipada del componente lo declare.
|
|
148
|
+
|
|
149
|
+
## Slots y `children`
|
|
150
|
+
|
|
151
|
+
El contenido hijo se proyecta al slot por defecto. Para un slot con nombre, añade `slot` al nodo hijo:
|
|
152
|
+
|
|
153
|
+
```tsx
|
|
154
|
+
import {
|
|
155
|
+
DesynthBookCard,
|
|
156
|
+
DesynthButton,
|
|
157
|
+
} from '@desynth/web-components-react';
|
|
158
|
+
|
|
159
|
+
export function Book() {
|
|
160
|
+
return (
|
|
161
|
+
<DesynthBookCard
|
|
162
|
+
title="Diseño de sistemas"
|
|
163
|
+
chapters={JSON.stringify(['Introducción', 'Arquitectura'])}
|
|
164
|
+
>
|
|
165
|
+
<div slot="actions">
|
|
166
|
+
<DesynthButton buttonText="Leer" size="xs" />
|
|
167
|
+
</div>
|
|
168
|
+
</DesynthBookCard>
|
|
169
|
+
);
|
|
170
|
+
}
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
Los nombres de slot disponibles dependen del componente core; no existe una lista universal.
|
|
174
|
+
|
|
175
|
+
## SSR y React Server Components
|
|
176
|
+
|
|
177
|
+
El archivo generado comienza con `'use client'`. Los wrappers registran Custom Elements y están destinados al navegador:
|
|
178
|
+
|
|
179
|
+
- impórtalos y renderízalos desde componentes cliente;
|
|
180
|
+
- en Next.js App Router, coloca el uso detrás de un archivo con `'use client'`;
|
|
181
|
+
- no dependas de que el Shadow DOM esté renderizado en el HTML del servidor;
|
|
182
|
+
- si el bundler evalúa módulos DOM durante SSR, carga el componente cliente de forma dinámica con SSR desactivado.
|
|
183
|
+
|
|
184
|
+
Ejemplo para Next.js:
|
|
185
|
+
|
|
186
|
+
```tsx
|
|
187
|
+
'use client';
|
|
188
|
+
|
|
189
|
+
import { DesynthButton } from '@desynth/web-components-react';
|
|
190
|
+
|
|
191
|
+
export function SaveButton() {
|
|
192
|
+
return <DesynthButton buttonText="Guardar" />;
|
|
193
|
+
}
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
El paquete core genera una salida `dist/hydrate`, pero este paquete React no configura por sí mismo una integración SSR o de hidratación para el framework.
|
|
197
|
+
|
|
198
|
+
## Tokens
|
|
199
|
+
|
|
200
|
+
Carga el tema CSS una sola vez desde la hoja global de la aplicación:
|
|
201
|
+
|
|
202
|
+
```css
|
|
203
|
+
@import '@desynth/style-tokens/dist/assets/css/variables-all.css';
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
El CSS de tokens llega como dependencia transitiva del core, pero su importación es explícita. Consulta el README de `@desynth/web-components` para las variantes de tema publicadas.
|
|
207
|
+
|
|
208
|
+
## Desarrollo local y sincronización
|
|
209
|
+
|
|
210
|
+
`src/components.ts` es generado: no debe editarse a mano. El flujo local correcto, desde la raíz del monorepo, es:
|
|
211
|
+
|
|
212
|
+
```bash
|
|
213
|
+
npm run build --workspace=@desynth/web-components
|
|
214
|
+
npm run build --workspace=@desynth/web-components-react
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
El build de Stencil ejecuta el React output target y vuelve a generar `packages/components-react/src`; después, el script del wrapper ejecuta TypeScript y sincroniza `dist/`. Si solo se compila este paquete sin regenerar primero el core, los proxies pueden quedar desalineados con el catálogo actual.
|
|
218
|
+
|
|
219
|
+
El paquete React publica únicamente `dist/` y su script disponible es:
|
|
220
|
+
|
|
221
|
+
```bash
|
|
222
|
+
npm run build # equivalente a: npm run tsc
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
No hay script de tests definido en este paquete.
|
|
226
|
+
|
|
227
|
+
## Licencia
|
|
228
|
+
|
|
229
|
+
MPL-2.0 según el manifiesto del paquete.
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
export interface HTMLStencilElement extends HTMLElement {
|
|
3
|
-
componentOnReady(): Promise<this>;
|
|
4
|
-
}
|
|
5
|
-
interface StencilReactInternalProps<ElementType> extends React.HTMLAttributes<ElementType> {
|
|
6
|
-
forwardedRef: React.RefObject<ElementType>;
|
|
7
|
-
ref?: React.Ref<any>;
|
|
8
|
-
}
|
|
9
|
-
export declare const createReactComponent: <PropType, ElementType extends HTMLStencilElement, ContextStateType = {}, ExpandedPropsTypes = {}>(tagName: string, ReactComponentContext?: React.Context<ContextStateType> | undefined, manipulatePropsFunction?: ((originalProps: StencilReactInternalProps<ElementType>, propsToPass: any) => ExpandedPropsTypes) | undefined, defineCustomElement?: () => void) => React.ForwardRefExoticComponent<React.PropsWithoutRef<import("./utils").StencilReactExternalProps<PropType, ElementType>> & React.RefAttributes<ElementType>>;
|
|
10
|
-
export {};
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
var __rest = (this && this.__rest) || function (s, e) {
|
|
2
|
-
var t = {};
|
|
3
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
4
|
-
t[p] = s[p];
|
|
5
|
-
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
6
|
-
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
7
|
-
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
8
|
-
t[p[i]] = s[p[i]];
|
|
9
|
-
}
|
|
10
|
-
return t;
|
|
11
|
-
};
|
|
12
|
-
import React, { createElement } from 'react';
|
|
13
|
-
import { attachProps, camelToDashCase, createForwardRef, dashToPascalCase, isCoveredByReact, mergeRefs } from './utils';
|
|
14
|
-
export const createReactComponent = (tagName, ReactComponentContext, manipulatePropsFunction, defineCustomElement) => {
|
|
15
|
-
if (defineCustomElement !== undefined) {
|
|
16
|
-
defineCustomElement();
|
|
17
|
-
}
|
|
18
|
-
const displayName = dashToPascalCase(tagName);
|
|
19
|
-
const ReactComponent = class extends React.Component {
|
|
20
|
-
constructor(props) {
|
|
21
|
-
super(props);
|
|
22
|
-
this.setComponentElRef = (element) => {
|
|
23
|
-
this.componentEl = element;
|
|
24
|
-
};
|
|
25
|
-
}
|
|
26
|
-
componentDidMount() {
|
|
27
|
-
this.componentDidUpdate(this.props);
|
|
28
|
-
}
|
|
29
|
-
componentDidUpdate(prevProps) {
|
|
30
|
-
attachProps(this.componentEl, this.props, prevProps);
|
|
31
|
-
}
|
|
32
|
-
render() {
|
|
33
|
-
const _a = this.props, { children, forwardedRef, style, className, ref } = _a, cProps = __rest(_a, ["children", "forwardedRef", "style", "className", "ref"]);
|
|
34
|
-
let propsToPass = Object.keys(cProps).reduce((acc, name) => {
|
|
35
|
-
const value = cProps[name];
|
|
36
|
-
if (name.indexOf('on') === 0 && name[2] === name[2].toUpperCase()) {
|
|
37
|
-
const eventName = name.substring(2).toLowerCase();
|
|
38
|
-
if (typeof document !== 'undefined' && isCoveredByReact(eventName)) {
|
|
39
|
-
acc[name] = value;
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
else {
|
|
43
|
-
// we should only render strings, booleans, and numbers as attrs in html.
|
|
44
|
-
// objects, functions, arrays etc get synced via properties on mount.
|
|
45
|
-
const type = typeof value;
|
|
46
|
-
if (type === 'string' || type === 'boolean' || type === 'number') {
|
|
47
|
-
acc[camelToDashCase(name)] = value;
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
return acc;
|
|
51
|
-
}, {});
|
|
52
|
-
if (manipulatePropsFunction) {
|
|
53
|
-
propsToPass = manipulatePropsFunction(this.props, propsToPass);
|
|
54
|
-
}
|
|
55
|
-
const newProps = Object.assign(Object.assign({}, propsToPass), { ref: mergeRefs(forwardedRef, this.setComponentElRef), style });
|
|
56
|
-
/**
|
|
57
|
-
* We use createElement here instead of
|
|
58
|
-
* React.createElement to work around a
|
|
59
|
-
* bug in Vite (https://github.com/vitejs/vite/issues/6104).
|
|
60
|
-
* React.createElement causes all elements to be rendered
|
|
61
|
-
* as <tagname> instead of the actual Web Component.
|
|
62
|
-
*/
|
|
63
|
-
return createElement(tagName, newProps, children);
|
|
64
|
-
}
|
|
65
|
-
static get displayName() {
|
|
66
|
-
return displayName;
|
|
67
|
-
}
|
|
68
|
-
};
|
|
69
|
-
// If context was passed to createReactComponent then conditionally add it to the Component Class
|
|
70
|
-
if (ReactComponentContext) {
|
|
71
|
-
ReactComponent.contextType = ReactComponentContext;
|
|
72
|
-
}
|
|
73
|
-
return createForwardRef(ReactComponent, displayName);
|
|
74
|
-
};
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { OverlayEventDetail } from './interfaces';
|
|
3
|
-
import { StencilReactForwardedRef } from './utils';
|
|
4
|
-
interface OverlayElement extends HTMLElement {
|
|
5
|
-
present: () => Promise<void>;
|
|
6
|
-
dismiss: (data?: any, role?: string | undefined) => Promise<boolean>;
|
|
7
|
-
}
|
|
8
|
-
export interface ReactOverlayProps {
|
|
9
|
-
children?: React.ReactNode;
|
|
10
|
-
isOpen: boolean;
|
|
11
|
-
onDidDismiss?: (event: CustomEvent<OverlayEventDetail>) => void;
|
|
12
|
-
onDidPresent?: (event: CustomEvent<OverlayEventDetail>) => void;
|
|
13
|
-
onWillDismiss?: (event: CustomEvent<OverlayEventDetail>) => void;
|
|
14
|
-
onWillPresent?: (event: CustomEvent<OverlayEventDetail>) => void;
|
|
15
|
-
}
|
|
16
|
-
export declare const createOverlayComponent: <OverlayComponent extends object, OverlayType extends OverlayElement>(tagName: string, controller: {
|
|
17
|
-
create: (options: any) => Promise<OverlayType>;
|
|
18
|
-
}, customElement?: any) => React.ForwardRefExoticComponent<React.PropsWithoutRef<OverlayComponent & ReactOverlayProps & {
|
|
19
|
-
forwardedRef?: StencilReactForwardedRef<OverlayType> | undefined;
|
|
20
|
-
}> & React.RefAttributes<OverlayType>>;
|
|
21
|
-
export {};
|
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
var __rest = (this && this.__rest) || function (s, e) {
|
|
2
|
-
var t = {};
|
|
3
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
4
|
-
t[p] = s[p];
|
|
5
|
-
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
6
|
-
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
7
|
-
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
8
|
-
t[p[i]] = s[p[i]];
|
|
9
|
-
}
|
|
10
|
-
return t;
|
|
11
|
-
};
|
|
12
|
-
import React from 'react';
|
|
13
|
-
import ReactDOM from 'react-dom';
|
|
14
|
-
import { attachProps, dashToPascalCase, defineCustomElement, setRef } from './utils';
|
|
15
|
-
export const createOverlayComponent = (tagName, controller, customElement) => {
|
|
16
|
-
defineCustomElement(tagName, customElement);
|
|
17
|
-
const displayName = dashToPascalCase(tagName);
|
|
18
|
-
const didDismissEventName = `on${displayName}DidDismiss`;
|
|
19
|
-
const didPresentEventName = `on${displayName}DidPresent`;
|
|
20
|
-
const willDismissEventName = `on${displayName}WillDismiss`;
|
|
21
|
-
const willPresentEventName = `on${displayName}WillPresent`;
|
|
22
|
-
let isDismissing = false;
|
|
23
|
-
class Overlay extends React.Component {
|
|
24
|
-
constructor(props) {
|
|
25
|
-
super(props);
|
|
26
|
-
if (typeof document !== 'undefined') {
|
|
27
|
-
this.el = document.createElement('div');
|
|
28
|
-
}
|
|
29
|
-
this.handleDismiss = this.handleDismiss.bind(this);
|
|
30
|
-
}
|
|
31
|
-
static get displayName() {
|
|
32
|
-
return displayName;
|
|
33
|
-
}
|
|
34
|
-
componentDidMount() {
|
|
35
|
-
if (this.props.isOpen) {
|
|
36
|
-
this.present();
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
componentWillUnmount() {
|
|
40
|
-
if (this.overlay) {
|
|
41
|
-
this.overlay.dismiss();
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
handleDismiss(event) {
|
|
45
|
-
if (this.props.onDidDismiss) {
|
|
46
|
-
this.props.onDidDismiss(event);
|
|
47
|
-
}
|
|
48
|
-
setRef(this.props.forwardedRef, null);
|
|
49
|
-
}
|
|
50
|
-
shouldComponentUpdate(nextProps) {
|
|
51
|
-
// Check if the overlay component is about to dismiss
|
|
52
|
-
if (this.overlay && nextProps.isOpen !== this.props.isOpen && nextProps.isOpen === false) {
|
|
53
|
-
isDismissing = true;
|
|
54
|
-
}
|
|
55
|
-
return true;
|
|
56
|
-
}
|
|
57
|
-
async componentDidUpdate(prevProps) {
|
|
58
|
-
if (this.overlay) {
|
|
59
|
-
attachProps(this.overlay, this.props, prevProps);
|
|
60
|
-
}
|
|
61
|
-
if (prevProps.isOpen !== this.props.isOpen && this.props.isOpen === true) {
|
|
62
|
-
this.present(prevProps);
|
|
63
|
-
}
|
|
64
|
-
if (this.overlay && prevProps.isOpen !== this.props.isOpen && this.props.isOpen === false) {
|
|
65
|
-
await this.overlay.dismiss();
|
|
66
|
-
isDismissing = false;
|
|
67
|
-
/**
|
|
68
|
-
* Now that the overlay is dismissed
|
|
69
|
-
* we need to render again so that any
|
|
70
|
-
* inner components will be unmounted
|
|
71
|
-
*/
|
|
72
|
-
this.forceUpdate();
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
async present(prevProps) {
|
|
76
|
-
const _a = this.props, { children, isOpen, onDidDismiss, onDidPresent, onWillDismiss, onWillPresent } = _a, cProps = __rest(_a, ["children", "isOpen", "onDidDismiss", "onDidPresent", "onWillDismiss", "onWillPresent"]);
|
|
77
|
-
const elementProps = Object.assign(Object.assign({}, cProps), { ref: this.props.forwardedRef, [didDismissEventName]: this.handleDismiss, [didPresentEventName]: (e) => this.props.onDidPresent && this.props.onDidPresent(e), [willDismissEventName]: (e) => this.props.onWillDismiss && this.props.onWillDismiss(e), [willPresentEventName]: (e) => this.props.onWillPresent && this.props.onWillPresent(e) });
|
|
78
|
-
this.overlay = await controller.create(Object.assign(Object.assign({}, elementProps), { component: this.el, componentProps: {} }));
|
|
79
|
-
setRef(this.props.forwardedRef, this.overlay);
|
|
80
|
-
attachProps(this.overlay, elementProps, prevProps);
|
|
81
|
-
await this.overlay.present();
|
|
82
|
-
}
|
|
83
|
-
render() {
|
|
84
|
-
/**
|
|
85
|
-
* Continue to render the component even when
|
|
86
|
-
* overlay is dismissing otherwise component
|
|
87
|
-
* will be hidden before animation is done.
|
|
88
|
-
*/
|
|
89
|
-
return ReactDOM.createPortal(this.props.isOpen || isDismissing ? this.props.children : null, this.el);
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
return React.forwardRef((props, ref) => {
|
|
93
|
-
return React.createElement(Overlay, Object.assign({}, props, { forwardedRef: ref }));
|
|
94
|
-
});
|
|
95
|
-
};
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
export interface EventEmitter<T = any> {
|
|
2
|
-
emit: (data?: T) => CustomEvent<T>;
|
|
3
|
-
}
|
|
4
|
-
export interface StyleReactProps {
|
|
5
|
-
class?: string;
|
|
6
|
-
className?: string;
|
|
7
|
-
style?: {
|
|
8
|
-
[key: string]: any;
|
|
9
|
-
};
|
|
10
|
-
}
|
|
11
|
-
export interface OverlayEventDetail<T = any> {
|
|
12
|
-
data?: T;
|
|
13
|
-
role?: string;
|
|
14
|
-
}
|
|
15
|
-
export interface OverlayInterface {
|
|
16
|
-
el: HTMLElement;
|
|
17
|
-
animated: boolean;
|
|
18
|
-
keyboardClose: boolean;
|
|
19
|
-
overlayIndex: number;
|
|
20
|
-
presented: boolean;
|
|
21
|
-
enterAnimation?: any;
|
|
22
|
-
leaveAnimation?: any;
|
|
23
|
-
didPresent: EventEmitter<void>;
|
|
24
|
-
willPresent: EventEmitter<void>;
|
|
25
|
-
willDismiss: EventEmitter<OverlayEventDetail>;
|
|
26
|
-
didDismiss: EventEmitter<OverlayEventDetail>;
|
|
27
|
-
present(): Promise<void>;
|
|
28
|
-
dismiss(data?: any, role?: string): Promise<boolean>;
|
|
29
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
export declare const attachProps: (node: HTMLElement, newProps: any, oldProps?: any) => void;
|
|
2
|
-
export declare const getClassName: (classList: DOMTokenList, newProps: any, oldProps: any) => string;
|
|
3
|
-
/**
|
|
4
|
-
* Transforms a React event name to a browser event name.
|
|
5
|
-
*/
|
|
6
|
-
export declare const transformReactEventName: (eventNameSuffix: string) => string;
|
|
7
|
-
/**
|
|
8
|
-
* Checks if an event is supported in the current execution environment.
|
|
9
|
-
* @license Modernizr 3.0.0pre (Custom Build) | MIT
|
|
10
|
-
*/
|
|
11
|
-
export declare const isCoveredByReact: (eventNameSuffix: string) => boolean;
|
|
12
|
-
export declare const syncEvent: (node: Element & {
|
|
13
|
-
__events?: {
|
|
14
|
-
[key: string]: ((e: Event) => any) | undefined;
|
|
15
|
-
} | undefined;
|
|
16
|
-
}, eventName: string, newEventHandler?: ((e: Event) => any) | undefined) => void;
|