@editframe/react 0.6.0-beta.22 → 0.7.0-beta.4
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/create-component.cjs +128 -0
- package/dist/create-component.js +128 -0
- package/dist/elements/EFTimegroup.cjs +2 -2
- package/dist/elements/EFTimegroup.js +1 -1
- package/dist/packages/react/src/create-component.d.ts +89 -0
- package/dist/packages/react/src/elements/EFTimegroup.d.ts +1 -1
- package/package.json +3 -2
- package/src/elements/EFTimegroup.ts +1 -1
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
/**
|
|
4
|
+
* @license
|
|
5
|
+
* Copyright 2018 Google LLC
|
|
6
|
+
* SPDX-License-Identifier: BSD-3-Clause
|
|
7
|
+
*/
|
|
8
|
+
const reservedReactProperties = /* @__PURE__ */ new Set([
|
|
9
|
+
"id",
|
|
10
|
+
"children",
|
|
11
|
+
"localName",
|
|
12
|
+
"ref",
|
|
13
|
+
"style",
|
|
14
|
+
"className"
|
|
15
|
+
]);
|
|
16
|
+
const listenedEvents = /* @__PURE__ */ new WeakMap();
|
|
17
|
+
const addOrUpdateEventListener = (node, event, listener) => {
|
|
18
|
+
let events = listenedEvents.get(node);
|
|
19
|
+
if (events === void 0) {
|
|
20
|
+
listenedEvents.set(node, events = /* @__PURE__ */ new Map());
|
|
21
|
+
}
|
|
22
|
+
let handler = events.get(event);
|
|
23
|
+
if (listener !== void 0) {
|
|
24
|
+
if (handler === void 0) {
|
|
25
|
+
events.set(event, handler = { handleEvent: listener });
|
|
26
|
+
node.addEventListener(event, handler);
|
|
27
|
+
} else {
|
|
28
|
+
handler.handleEvent = listener;
|
|
29
|
+
}
|
|
30
|
+
} else if (handler !== void 0) {
|
|
31
|
+
events.delete(event);
|
|
32
|
+
node.removeEventListener(event, handler);
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
const setProperty = (node, name, value, old, events) => {
|
|
36
|
+
const event = events?.[name];
|
|
37
|
+
if (event !== void 0) {
|
|
38
|
+
if (value !== old) {
|
|
39
|
+
addOrUpdateEventListener(node, event, value);
|
|
40
|
+
}
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
node[name] = value;
|
|
44
|
+
if ((value === void 0 || value === null) && name in HTMLElement.prototype) {
|
|
45
|
+
node.removeAttribute(name);
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
const createComponent = ({
|
|
49
|
+
react: React,
|
|
50
|
+
tagName,
|
|
51
|
+
elementClass,
|
|
52
|
+
events,
|
|
53
|
+
displayName
|
|
54
|
+
}) => {
|
|
55
|
+
const eventProps = new Set(Object.keys(events ?? {}));
|
|
56
|
+
{
|
|
57
|
+
for (const p of reservedReactProperties) {
|
|
58
|
+
if (p in elementClass.prototype && !(p in HTMLElement.prototype)) {
|
|
59
|
+
console.warn(
|
|
60
|
+
`${tagName} contains property ${p} which is a React reserved property. It will be used by React and not set on the element.`
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
const ReactComponent = React.forwardRef((props, ref) => {
|
|
66
|
+
const prevElemPropsRef = React.useRef(/* @__PURE__ */ new Map());
|
|
67
|
+
const elementRef = React.useRef(null);
|
|
68
|
+
const reactProps = {};
|
|
69
|
+
const elementProps = {};
|
|
70
|
+
for (const [k, v] of Object.entries(props)) {
|
|
71
|
+
if (reservedReactProperties.has(k)) {
|
|
72
|
+
reactProps[k === "className" ? "class" : k] = v;
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
if (eventProps.has(k) || k in elementClass.prototype) {
|
|
76
|
+
elementProps[k] = v;
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
reactProps[k] = v;
|
|
80
|
+
}
|
|
81
|
+
{
|
|
82
|
+
React.useLayoutEffect(() => {
|
|
83
|
+
if (elementRef.current === null) {
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
const newElemProps = /* @__PURE__ */ new Map();
|
|
87
|
+
for (const key in elementProps) {
|
|
88
|
+
setProperty(
|
|
89
|
+
elementRef.current,
|
|
90
|
+
key,
|
|
91
|
+
props[key],
|
|
92
|
+
prevElemPropsRef.current.get(key),
|
|
93
|
+
events
|
|
94
|
+
);
|
|
95
|
+
prevElemPropsRef.current.delete(key);
|
|
96
|
+
newElemProps.set(key, props[key]);
|
|
97
|
+
}
|
|
98
|
+
for (const [key, value] of prevElemPropsRef.current) {
|
|
99
|
+
setProperty(elementRef.current, key, void 0, value, events);
|
|
100
|
+
}
|
|
101
|
+
prevElemPropsRef.current = newElemProps;
|
|
102
|
+
});
|
|
103
|
+
React.useLayoutEffect(() => {
|
|
104
|
+
elementRef.current?.removeAttribute("defer-hydration");
|
|
105
|
+
}, []);
|
|
106
|
+
}
|
|
107
|
+
{
|
|
108
|
+
reactProps.suppressHydrationWarning = true;
|
|
109
|
+
}
|
|
110
|
+
return React.createElement(tagName, {
|
|
111
|
+
...reactProps,
|
|
112
|
+
ref: React.useCallback(
|
|
113
|
+
(node) => {
|
|
114
|
+
elementRef.current = node;
|
|
115
|
+
if (typeof ref === "function") {
|
|
116
|
+
ref(node);
|
|
117
|
+
} else if (ref !== null) {
|
|
118
|
+
ref.current = node;
|
|
119
|
+
}
|
|
120
|
+
},
|
|
121
|
+
[ref]
|
|
122
|
+
)
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
ReactComponent.displayName = displayName ?? elementClass.name;
|
|
126
|
+
return ReactComponent;
|
|
127
|
+
};
|
|
128
|
+
exports.createComponent = createComponent;
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2018 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: BSD-3-Clause
|
|
5
|
+
*/
|
|
6
|
+
const reservedReactProperties = /* @__PURE__ */ new Set([
|
|
7
|
+
"id",
|
|
8
|
+
"children",
|
|
9
|
+
"localName",
|
|
10
|
+
"ref",
|
|
11
|
+
"style",
|
|
12
|
+
"className"
|
|
13
|
+
]);
|
|
14
|
+
const listenedEvents = /* @__PURE__ */ new WeakMap();
|
|
15
|
+
const addOrUpdateEventListener = (node, event, listener) => {
|
|
16
|
+
let events = listenedEvents.get(node);
|
|
17
|
+
if (events === void 0) {
|
|
18
|
+
listenedEvents.set(node, events = /* @__PURE__ */ new Map());
|
|
19
|
+
}
|
|
20
|
+
let handler = events.get(event);
|
|
21
|
+
if (listener !== void 0) {
|
|
22
|
+
if (handler === void 0) {
|
|
23
|
+
events.set(event, handler = { handleEvent: listener });
|
|
24
|
+
node.addEventListener(event, handler);
|
|
25
|
+
} else {
|
|
26
|
+
handler.handleEvent = listener;
|
|
27
|
+
}
|
|
28
|
+
} else if (handler !== void 0) {
|
|
29
|
+
events.delete(event);
|
|
30
|
+
node.removeEventListener(event, handler);
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
const setProperty = (node, name, value, old, events) => {
|
|
34
|
+
const event = events?.[name];
|
|
35
|
+
if (event !== void 0) {
|
|
36
|
+
if (value !== old) {
|
|
37
|
+
addOrUpdateEventListener(node, event, value);
|
|
38
|
+
}
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
node[name] = value;
|
|
42
|
+
if ((value === void 0 || value === null) && name in HTMLElement.prototype) {
|
|
43
|
+
node.removeAttribute(name);
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
const createComponent = ({
|
|
47
|
+
react: React,
|
|
48
|
+
tagName,
|
|
49
|
+
elementClass,
|
|
50
|
+
events,
|
|
51
|
+
displayName
|
|
52
|
+
}) => {
|
|
53
|
+
const eventProps = new Set(Object.keys(events ?? {}));
|
|
54
|
+
{
|
|
55
|
+
for (const p of reservedReactProperties) {
|
|
56
|
+
if (p in elementClass.prototype && !(p in HTMLElement.prototype)) {
|
|
57
|
+
console.warn(
|
|
58
|
+
`${tagName} contains property ${p} which is a React reserved property. It will be used by React and not set on the element.`
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
const ReactComponent = React.forwardRef((props, ref) => {
|
|
64
|
+
const prevElemPropsRef = React.useRef(/* @__PURE__ */ new Map());
|
|
65
|
+
const elementRef = React.useRef(null);
|
|
66
|
+
const reactProps = {};
|
|
67
|
+
const elementProps = {};
|
|
68
|
+
for (const [k, v] of Object.entries(props)) {
|
|
69
|
+
if (reservedReactProperties.has(k)) {
|
|
70
|
+
reactProps[k === "className" ? "class" : k] = v;
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
if (eventProps.has(k) || k in elementClass.prototype) {
|
|
74
|
+
elementProps[k] = v;
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
reactProps[k] = v;
|
|
78
|
+
}
|
|
79
|
+
{
|
|
80
|
+
React.useLayoutEffect(() => {
|
|
81
|
+
if (elementRef.current === null) {
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
const newElemProps = /* @__PURE__ */ new Map();
|
|
85
|
+
for (const key in elementProps) {
|
|
86
|
+
setProperty(
|
|
87
|
+
elementRef.current,
|
|
88
|
+
key,
|
|
89
|
+
props[key],
|
|
90
|
+
prevElemPropsRef.current.get(key),
|
|
91
|
+
events
|
|
92
|
+
);
|
|
93
|
+
prevElemPropsRef.current.delete(key);
|
|
94
|
+
newElemProps.set(key, props[key]);
|
|
95
|
+
}
|
|
96
|
+
for (const [key, value] of prevElemPropsRef.current) {
|
|
97
|
+
setProperty(elementRef.current, key, void 0, value, events);
|
|
98
|
+
}
|
|
99
|
+
prevElemPropsRef.current = newElemProps;
|
|
100
|
+
});
|
|
101
|
+
React.useLayoutEffect(() => {
|
|
102
|
+
elementRef.current?.removeAttribute("defer-hydration");
|
|
103
|
+
}, []);
|
|
104
|
+
}
|
|
105
|
+
{
|
|
106
|
+
reactProps.suppressHydrationWarning = true;
|
|
107
|
+
}
|
|
108
|
+
return React.createElement(tagName, {
|
|
109
|
+
...reactProps,
|
|
110
|
+
ref: React.useCallback(
|
|
111
|
+
(node) => {
|
|
112
|
+
elementRef.current = node;
|
|
113
|
+
if (typeof ref === "function") {
|
|
114
|
+
ref(node);
|
|
115
|
+
} else if (ref !== null) {
|
|
116
|
+
ref.current = node;
|
|
117
|
+
}
|
|
118
|
+
},
|
|
119
|
+
[ref]
|
|
120
|
+
)
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
ReactComponent.displayName = displayName ?? elementClass.name;
|
|
124
|
+
return ReactComponent;
|
|
125
|
+
};
|
|
126
|
+
export {
|
|
127
|
+
createComponent
|
|
128
|
+
};
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
3
|
const React = require("react");
|
|
4
|
-
const
|
|
4
|
+
const createComponent = require("../create-component.cjs");
|
|
5
5
|
const elements = require("@editframe/elements");
|
|
6
|
-
const EFTimegroup =
|
|
6
|
+
const EFTimegroup = createComponent.createComponent({
|
|
7
7
|
tagName: "ef-timegroup",
|
|
8
8
|
elementClass: elements.EFTimegroup,
|
|
9
9
|
react: React
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import { createComponent } from "
|
|
2
|
+
import { createComponent } from "../create-component.js";
|
|
3
3
|
import { EFTimegroup as EFTimegroup$1 } from "@editframe/elements";
|
|
4
4
|
const EFTimegroup = createComponent({
|
|
5
5
|
tagName: "ef-timegroup",
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
|
|
3
|
+
type DistributiveOmit<T, K extends string | number | symbol> = T extends any ? K extends keyof T ? Omit<T, K> : T : T;
|
|
4
|
+
type PropsWithoutRef<T> = DistributiveOmit<T, "ref">;
|
|
5
|
+
/**
|
|
6
|
+
* Creates a type to be used for the props of a web component used directly in
|
|
7
|
+
* React JSX.
|
|
8
|
+
*
|
|
9
|
+
* Example:
|
|
10
|
+
*
|
|
11
|
+
* ```ts
|
|
12
|
+
* declare module "react" {
|
|
13
|
+
* namespace JSX {
|
|
14
|
+
* interface IntrinsicElements {
|
|
15
|
+
* 'x-foo': WebComponentProps<XFoo>;
|
|
16
|
+
* }
|
|
17
|
+
* }
|
|
18
|
+
* }
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export type WebComponentProps<I extends HTMLElement> = React.DetailedHTMLProps<React.HTMLAttributes<I>, I> & ElementProps<I>;
|
|
22
|
+
/**
|
|
23
|
+
* Type of the React component wrapping the web component. This is the return
|
|
24
|
+
* type of `createComponent`.
|
|
25
|
+
*/
|
|
26
|
+
export type ReactWebComponent<I extends HTMLElement, E extends EventNames = {}> = React.ForwardRefExoticComponent<PropsWithoutRef<ComponentProps<I, E>> & React.RefAttributes<I>>;
|
|
27
|
+
type ElementProps<I> = Partial<Omit<I, keyof HTMLElement>>;
|
|
28
|
+
type ComponentProps<I, E extends EventNames = {}> = Omit<React.HTMLAttributes<I>, keyof E | keyof ElementProps<I>> & EventListeners<E> & ElementProps<I>;
|
|
29
|
+
/**
|
|
30
|
+
* Type used to cast an event name with an event type when providing the
|
|
31
|
+
* `events` option to `createComponent` for better typing of the event handler
|
|
32
|
+
* prop.
|
|
33
|
+
*
|
|
34
|
+
* Example:
|
|
35
|
+
*
|
|
36
|
+
* ```ts
|
|
37
|
+
* const FooComponent = createComponent({
|
|
38
|
+
* ...
|
|
39
|
+
* events: {
|
|
40
|
+
* onfoo: 'foo' as EventName<FooEvent>,
|
|
41
|
+
* }
|
|
42
|
+
* });
|
|
43
|
+
* ```
|
|
44
|
+
*
|
|
45
|
+
* `onfoo` prop will have the type `(e: FooEvent) => void`.
|
|
46
|
+
*/
|
|
47
|
+
export type EventName<T extends Event = Event> = string & {
|
|
48
|
+
__eventType: T;
|
|
49
|
+
};
|
|
50
|
+
type EventNames = Record<string, EventName | string>;
|
|
51
|
+
type EventListeners<R extends EventNames> = {
|
|
52
|
+
[K in keyof R]?: R[K] extends EventName ? (e: R[K]["__eventType"]) => void : (e: Event) => void;
|
|
53
|
+
};
|
|
54
|
+
export interface Options<I extends HTMLElement, E extends EventNames = {}> {
|
|
55
|
+
react: typeof React;
|
|
56
|
+
tagName: string;
|
|
57
|
+
elementClass: Constructor<I>;
|
|
58
|
+
events?: E;
|
|
59
|
+
displayName?: string;
|
|
60
|
+
}
|
|
61
|
+
type Constructor<T> = {
|
|
62
|
+
new (): T;
|
|
63
|
+
};
|
|
64
|
+
/**
|
|
65
|
+
* Creates a React component for a custom element. Properties are distinguished
|
|
66
|
+
* from attributes automatically, and events can be configured so they are added
|
|
67
|
+
* to the custom element as event listeners.
|
|
68
|
+
*
|
|
69
|
+
* @param options An options bag containing the parameters needed to generate a
|
|
70
|
+
* wrapped web component.
|
|
71
|
+
*
|
|
72
|
+
* @param options.react The React module, typically imported from the `react`
|
|
73
|
+
* npm package.
|
|
74
|
+
* @param options.tagName The custom element tag name registered via
|
|
75
|
+
* `customElements.define`.
|
|
76
|
+
* @param options.elementClass The custom element class registered via
|
|
77
|
+
* `customElements.define`.
|
|
78
|
+
* @param options.events An object listing events to which the component can
|
|
79
|
+
* listen. The object keys are the event property names passed in via React
|
|
80
|
+
* props and the object values are the names of the corresponding events
|
|
81
|
+
* generated by the custom element. For example, given `{onactivate:
|
|
82
|
+
* 'activate'}` an event function may be passed via the component's `onactivate`
|
|
83
|
+
* prop and will be called when the custom element fires its `activate` event.
|
|
84
|
+
* @param options.displayName A React component display name, used in debugging
|
|
85
|
+
* messages. Default value is inferred from the name of custom element class
|
|
86
|
+
* registered via `customElements.define`.
|
|
87
|
+
*/
|
|
88
|
+
export declare const createComponent: <I extends HTMLElement, E extends EventNames = {}>({ react: React, tagName, elementClass, events, displayName, }: Options<I, E>) => ReactWebComponent<I, E>;
|
|
89
|
+
export {};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { EFTimegroup as EFTimegroupElement } from '../../../elements/src';
|
|
2
2
|
|
|
3
|
-
export declare const EFTimegroup: import('
|
|
3
|
+
export declare const EFTimegroup: import('../create-component').ReactWebComponent<EFTimegroupElement, {}>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@editframe/react",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0-beta.4",
|
|
4
4
|
"description": "",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": {
|
|
@@ -23,8 +23,9 @@
|
|
|
23
23
|
"author": "",
|
|
24
24
|
"license": "UNLICENSED",
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"@editframe/elements": "0.
|
|
26
|
+
"@editframe/elements": "0.7.0-beta.4",
|
|
27
27
|
"@lit/react": "^1.0.5",
|
|
28
|
+
"debug": "^4.3.5",
|
|
28
29
|
"react": "^18.3.0",
|
|
29
30
|
"react-dom": "^18.3.0"
|
|
30
31
|
},
|