@editframe/react 0.21.0-beta.0 → 0.23.6-beta.0

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.
Files changed (78) hide show
  1. package/dist/components/TimeDisplay.js +7 -5
  2. package/dist/elements/Audio.d.ts +1 -1
  3. package/dist/elements/Audio.js +7 -5
  4. package/dist/elements/Captions.d.ts +5 -5
  5. package/dist/elements/Captions.js +24 -18
  6. package/dist/elements/Image.d.ts +1 -1
  7. package/dist/elements/Image.js +7 -5
  8. package/dist/elements/Surface.d.ts +1 -1
  9. package/dist/elements/Surface.js +9 -7
  10. package/dist/elements/ThumbnailStrip.d.ts +1 -1
  11. package/dist/elements/ThumbnailStrip.js +9 -7
  12. package/dist/elements/Timegroup.d.ts +1 -1
  13. package/dist/elements/Timegroup.js +7 -5
  14. package/dist/elements/Video.d.ts +1 -1
  15. package/dist/elements/Video.js +7 -5
  16. package/dist/elements/Waveform.d.ts +1 -1
  17. package/dist/elements/Waveform.js +7 -5
  18. package/dist/gui/Configuration.d.ts +1 -1
  19. package/dist/gui/Configuration.js +7 -5
  20. package/dist/gui/Controls.d.ts +1 -1
  21. package/dist/gui/Controls.js +7 -5
  22. package/dist/gui/EFDial.d.ts +4 -0
  23. package/dist/gui/EFDial.js +14 -0
  24. package/dist/gui/EFResizableBox.d.ts +4 -0
  25. package/dist/gui/EFResizableBox.js +14 -0
  26. package/dist/gui/Filmstrip.d.ts +1 -1
  27. package/dist/gui/Filmstrip.js +7 -5
  28. package/dist/gui/FitScale.d.ts +1 -1
  29. package/dist/gui/FitScale.js +7 -5
  30. package/dist/gui/FocusOverlay.d.ts +1 -1
  31. package/dist/gui/FocusOverlay.js +7 -5
  32. package/dist/gui/Pause.d.ts +2 -0
  33. package/dist/gui/Pause.js +11 -0
  34. package/dist/gui/Play.d.ts +2 -0
  35. package/dist/gui/Play.js +11 -0
  36. package/dist/gui/Preview.d.ts +1 -1
  37. package/dist/gui/Preview.js +7 -5
  38. package/dist/gui/Scrubber.d.ts +1 -1
  39. package/dist/gui/Scrubber.js +7 -5
  40. package/dist/gui/ToggleLoop.d.ts +1 -1
  41. package/dist/gui/ToggleLoop.js +7 -5
  42. package/dist/gui/TogglePlay.d.ts +1 -1
  43. package/dist/gui/TogglePlay.js +7 -5
  44. package/dist/gui/Workbench.d.ts +1 -1
  45. package/dist/gui/Workbench.js +7 -5
  46. package/dist/hooks/create-element.d.ts +21 -0
  47. package/dist/hooks/create-element.js +103 -0
  48. package/dist/hooks/useTimingInfo.js +33 -32
  49. package/dist/index.d.ts +4 -0
  50. package/dist/index.js +34 -1
  51. package/package.json +6 -5
  52. package/src/components/TimeDisplay.tsx +1 -1
  53. package/src/elements/Audio.ts +1 -1
  54. package/src/elements/Captions.ts +1 -1
  55. package/src/elements/Image.ts +1 -1
  56. package/src/elements/Surface.ts +1 -1
  57. package/src/elements/ThumbnailStrip.ts +1 -1
  58. package/src/elements/Timegroup.ts +1 -1
  59. package/src/elements/Video.ts +1 -1
  60. package/src/elements/Waveform.ts +1 -1
  61. package/src/gui/Configuration.ts +1 -1
  62. package/src/gui/Controls.browsertest.tsx +112 -0
  63. package/src/gui/Controls.ts +1 -1
  64. package/src/gui/EFDial.ts +12 -0
  65. package/src/gui/EFResizableBox.ts +12 -0
  66. package/src/gui/Filmstrip.ts +1 -1
  67. package/src/gui/FitScale.ts +1 -1
  68. package/src/gui/FocusOverlay.ts +1 -1
  69. package/src/gui/Pause.ts +9 -0
  70. package/src/gui/Play.ts +9 -0
  71. package/src/gui/Preview.ts +1 -1
  72. package/src/gui/Scrubber.ts +1 -1
  73. package/src/gui/ToggleLoop.ts +1 -1
  74. package/src/gui/TogglePlay.ts +1 -1
  75. package/src/gui/Workbench.ts +1 -1
  76. package/src/hooks/create-element.ts +167 -0
  77. package/types.json +1 -1
  78. package/dist/create-component.d.ts +0 -88
@@ -0,0 +1,167 @@
1
+ import React from "react";
2
+
3
+ let isomorphicEffect =
4
+ typeof window !== "undefined" ? React.useLayoutEffect : React.useEffect;
5
+
6
+ export function setIsomorphicEffect(
7
+ effect: typeof React.useLayoutEffect | typeof React.useEffect,
8
+ ) {
9
+ isomorphicEffect = effect;
10
+ }
11
+
12
+ const reservedReactProperties = new Set([
13
+ "children",
14
+ "localName",
15
+ "ref",
16
+ "style",
17
+ "className",
18
+ ]);
19
+ const listenedEvents = new WeakMap<Element, Map<string, EventListenerObject>>();
20
+
21
+ type Constructor<T> = { new (): T };
22
+ type EventNames = Record<string, string>;
23
+
24
+ type EventListeners<E extends EventNames> = {
25
+ [K in keyof E]?: (e: Event) => void;
26
+ };
27
+
28
+ type ElementProps<I> = Partial<Omit<I, keyof HTMLElement>>;
29
+ type ComponentProps<I, E extends EventNames = {}> = Omit<
30
+ React.HTMLAttributes<I>,
31
+ keyof E | keyof ElementProps<I>
32
+ > &
33
+ EventListeners<E> &
34
+ ElementProps<I>;
35
+
36
+ export type ReactWebComponent<
37
+ I extends HTMLElement,
38
+ E extends EventNames = {},
39
+ > = React.ForwardRefExoticComponent<
40
+ ComponentProps<I, E> & React.RefAttributes<I>
41
+ >;
42
+
43
+ export interface Options<I extends HTMLElement, E extends EventNames = {}> {
44
+ react: typeof React;
45
+ tagName: string;
46
+ elementClass: Constructor<I>;
47
+ events?: E;
48
+ displayName?: string;
49
+ }
50
+
51
+ function addOrUpdateEventListener(
52
+ node: Element,
53
+ event: string,
54
+ listener?: (e?: Event) => void,
55
+ ) {
56
+ let events = listenedEvents.get(node);
57
+ if (!events) {
58
+ events = new Map();
59
+ listenedEvents.set(node, events);
60
+ }
61
+ let handler = events.get(event);
62
+
63
+ if (listener) {
64
+ if (!handler) {
65
+ handler = { handleEvent: listener };
66
+ events.set(event, handler);
67
+ node.addEventListener(event, handler);
68
+ } else {
69
+ handler.handleEvent = listener;
70
+ }
71
+ } else if (handler) {
72
+ events.delete(event);
73
+ node.removeEventListener(event, handler);
74
+ }
75
+ }
76
+
77
+ function setProperty<E extends Element>(
78
+ node: E,
79
+ name: string,
80
+ value: unknown,
81
+ old: unknown,
82
+ events?: EventNames,
83
+ ) {
84
+ const event = events?.[name];
85
+ if (event) {
86
+ if (value !== old)
87
+ addOrUpdateEventListener(node, event, value as (e?: Event) => void);
88
+ return;
89
+ }
90
+ node[name as keyof E] = value as E[keyof E];
91
+ if (
92
+ (value === undefined || value === null) &&
93
+ name in HTMLElement.prototype
94
+ ) {
95
+ node.removeAttribute(name);
96
+ }
97
+ }
98
+
99
+ export function createComponent<
100
+ I extends HTMLElement,
101
+ E extends EventNames = {},
102
+ >({
103
+ react: React,
104
+ tagName,
105
+ elementClass,
106
+ events,
107
+ displayName,
108
+ }: Options<I, E>): ReactWebComponent<I, E> {
109
+ const eventProps = new Set(Object.keys(events ?? {}));
110
+
111
+ const ReactComponent = React.forwardRef<I, ComponentProps<I, E>>(
112
+ (props, ref) => {
113
+ const elementRef = React.useRef<I | null>(null);
114
+ const prevPropsRef = React.useRef(new Map<string, unknown>());
115
+
116
+ const reactProps: Record<string, unknown> = {
117
+ suppressHydrationWarning: true,
118
+ };
119
+ const elementProps: Record<string, unknown> = {};
120
+
121
+ for (const [k, v] of Object.entries(props)) {
122
+ if (reservedReactProperties.has(k)) {
123
+ reactProps[k === "className" ? "class" : k] = v;
124
+ continue;
125
+ }
126
+ if (eventProps.has(k) || k in elementClass.prototype)
127
+ elementProps[k] = v;
128
+ reactProps[k] = v;
129
+ }
130
+
131
+ isomorphicEffect(() => {
132
+ if (!elementRef.current) return;
133
+ const newProps = new Map<string, unknown>();
134
+ for (const key in elementProps) {
135
+ setProperty(
136
+ elementRef.current,
137
+ key,
138
+ props[key as keyof typeof props],
139
+ prevPropsRef.current.get(key),
140
+ events,
141
+ );
142
+ prevPropsRef.current.delete(key);
143
+ newProps.set(key, props[key as keyof typeof props]);
144
+ }
145
+ for (const [key, value] of prevPropsRef.current) {
146
+ setProperty(elementRef.current, key, undefined, value, events);
147
+ }
148
+ prevPropsRef.current = newProps;
149
+
150
+ // Remove defer-hydration if present
151
+ elementRef.current.removeAttribute("defer-hydration");
152
+ }, [props]);
153
+
154
+ return React.createElement(tagName, {
155
+ ...reactProps,
156
+ ref: (node: I) => {
157
+ elementRef.current = node;
158
+ if (typeof ref === "function") ref(node);
159
+ else if (ref) ref.current = node;
160
+ },
161
+ });
162
+ },
163
+ );
164
+
165
+ ReactComponent.displayName = displayName ?? elementClass.name;
166
+ return ReactComponent as ReactWebComponent<I, E>;
167
+ }