@editframe/react 0.7.0-beta.9 → 0.8.0-beta.10

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 (47) hide show
  1. package/dist/create-component.d.ts +88 -0
  2. package/dist/create-component.js +128 -0
  3. package/dist/elements/Audio.d.ts +2 -0
  4. package/dist/elements/Audio.js +11 -0
  5. package/dist/elements/Captions.d.ts +3 -0
  6. package/dist/elements/Captions.js +17 -0
  7. package/dist/elements/Image.d.ts +2 -0
  8. package/dist/elements/Image.js +11 -0
  9. package/dist/elements/Timegroup.d.ts +2 -0
  10. package/dist/elements/Timegroup.js +11 -0
  11. package/dist/elements/Video.d.ts +2 -0
  12. package/dist/elements/Video.js +11 -0
  13. package/dist/elements/Waveform.d.ts +2 -0
  14. package/dist/elements/Waveform.js +11 -0
  15. package/dist/gui/Filmstrip.d.ts +2 -0
  16. package/dist/gui/Filmstrip.js +11 -0
  17. package/dist/gui/Preview.d.ts +2 -0
  18. package/dist/gui/Preview.js +11 -0
  19. package/dist/gui/ToggleLoop.d.ts +2 -0
  20. package/dist/gui/ToggleLoop.js +11 -0
  21. package/dist/gui/TogglePlay.d.ts +2 -0
  22. package/dist/gui/TogglePlay.js +11 -0
  23. package/dist/gui/Workbench.d.ts +2 -0
  24. package/dist/gui/Workbench.js +11 -0
  25. package/dist/hooks/useTimingInfo.d.ts +7 -0
  26. package/dist/hooks/useTimingInfo.js +35 -0
  27. package/dist/index.d.ts +30 -0
  28. package/dist/index.js +37 -0
  29. package/package.json +7 -9
  30. package/src/elements/{EFAudio.ts → Audio.ts} +1 -1
  31. package/src/elements/{EFCaptions.ts → Captions.ts} +2 -2
  32. package/src/elements/{EFImage.ts → Image.ts} +1 -1
  33. package/src/elements/{EFTimegroup.ts → Timegroup.ts} +2 -2
  34. package/src/elements/{EFVideo.ts → Video.ts} +1 -1
  35. package/src/elements/{EFWaveform.ts → Waveform.ts} +1 -1
  36. package/src/gui/{EFFilmstrip.ts → Filmstrip.ts} +1 -1
  37. package/src/gui/Preview.ts +9 -0
  38. package/src/gui/ToggleLoop.ts +9 -0
  39. package/src/gui/TogglePlay.ts +9 -0
  40. package/src/gui/{EFWorkbench.ts → Workbench.ts} +1 -1
  41. package/CHANGELOG.md +0 -8
  42. package/postcss.config.cjs +0 -6
  43. package/src/create-component.ts +0 -347
  44. package/src/index.ts +0 -11
  45. package/tailwind.config.ts +0 -10
  46. package/tsconfig.json +0 -4
  47. package/vite.config.ts +0 -8
@@ -0,0 +1,88 @@
1
+ import { default as React } from 'react';
2
+ type DistributiveOmit<T, K extends string | number | symbol> = T extends any ? K extends keyof T ? Omit<T, K> : T : T;
3
+ type PropsWithoutRef<T> = DistributiveOmit<T, "ref">;
4
+ /**
5
+ * Creates a type to be used for the props of a web component used directly in
6
+ * React JSX.
7
+ *
8
+ * Example:
9
+ *
10
+ * ```ts
11
+ * declare module "react" {
12
+ * namespace JSX {
13
+ * interface IntrinsicElements {
14
+ * 'x-foo': WebComponentProps<XFoo>;
15
+ * }
16
+ * }
17
+ * }
18
+ * ```
19
+ */
20
+ export type WebComponentProps<I extends HTMLElement> = React.DetailedHTMLProps<React.HTMLAttributes<I>, I> & ElementProps<I>;
21
+ /**
22
+ * Type of the React component wrapping the web component. This is the return
23
+ * type of `createComponent`.
24
+ */
25
+ export type ReactWebComponent<I extends HTMLElement, E extends EventNames = {}> = React.ForwardRefExoticComponent<PropsWithoutRef<ComponentProps<I, E>> & React.RefAttributes<I>>;
26
+ type ElementProps<I> = Partial<Omit<I, keyof HTMLElement>>;
27
+ type ComponentProps<I, E extends EventNames = {}> = Omit<React.HTMLAttributes<I>, keyof E | keyof ElementProps<I>> & EventListeners<E> & ElementProps<I>;
28
+ /**
29
+ * Type used to cast an event name with an event type when providing the
30
+ * `events` option to `createComponent` for better typing of the event handler
31
+ * prop.
32
+ *
33
+ * Example:
34
+ *
35
+ * ```ts
36
+ * const FooComponent = createComponent({
37
+ * ...
38
+ * events: {
39
+ * onfoo: 'foo' as EventName<FooEvent>,
40
+ * }
41
+ * });
42
+ * ```
43
+ *
44
+ * `onfoo` prop will have the type `(e: FooEvent) => void`.
45
+ */
46
+ export type EventName<T extends Event = Event> = string & {
47
+ __eventType: T;
48
+ };
49
+ type EventNames = Record<string, EventName | string>;
50
+ type EventListeners<R extends EventNames> = {
51
+ [K in keyof R]?: R[K] extends EventName ? (e: R[K]["__eventType"]) => void : (e: Event) => void;
52
+ };
53
+ export interface Options<I extends HTMLElement, E extends EventNames = {}> {
54
+ react: typeof React;
55
+ tagName: string;
56
+ elementClass: Constructor<I>;
57
+ events?: E;
58
+ displayName?: string;
59
+ }
60
+ type Constructor<T> = {
61
+ new (): T;
62
+ };
63
+ /**
64
+ * Creates a React component for a custom element. Properties are distinguished
65
+ * from attributes automatically, and events can be configured so they are added
66
+ * to the custom element as event listeners.
67
+ *
68
+ * @param options An options bag containing the parameters needed to generate a
69
+ * wrapped web component.
70
+ *
71
+ * @param options.react The React module, typically imported from the `react`
72
+ * npm package.
73
+ * @param options.tagName The custom element tag name registered via
74
+ * `customElements.define`.
75
+ * @param options.elementClass The custom element class registered via
76
+ * `customElements.define`.
77
+ * @param options.events An object listing events to which the component can
78
+ * listen. The object keys are the event property names passed in via React
79
+ * props and the object values are the names of the corresponding events
80
+ * generated by the custom element. For example, given `{onactivate:
81
+ * 'activate'}` an event function may be passed via the component's `onactivate`
82
+ * prop and will be called when the custom element fires its `activate` event.
83
+ * @param options.displayName A React component display name, used in debugging
84
+ * messages. Default value is inferred from the name of custom element class
85
+ * registered via `customElements.define`.
86
+ */
87
+ export declare const createComponent: <I extends HTMLElement, E extends EventNames = {}>({ react: React, tagName, elementClass, events, displayName, }: Options<I, E>) => ReactWebComponent<I, E>;
88
+ export {};
@@ -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
+ };
@@ -0,0 +1,2 @@
1
+ import { EFAudio as EFAudioElement } from '../../../elements/src';
2
+ export declare const Audio: import('@lit/react').ReactWebComponent<EFAudioElement, {}>;
@@ -0,0 +1,11 @@
1
+ import React from "react";
2
+ import { createComponent } from "@lit/react";
3
+ import { EFAudio } from "@editframe/elements";
4
+ const Audio = createComponent({
5
+ tagName: "ef-audio",
6
+ elementClass: EFAudio,
7
+ react: React
8
+ });
9
+ export {
10
+ Audio
11
+ };
@@ -0,0 +1,3 @@
1
+ import { EFCaptions as EFCaptionsElement, EFCaptionsActiveWord as EFCaptionsActiveWordElement } from '../../../elements/src';
2
+ export declare const Captions: import('@lit/react').ReactWebComponent<EFCaptionsElement, {}>;
3
+ export declare const CaptionsActiveWord: import('@lit/react').ReactWebComponent<EFCaptionsActiveWordElement, {}>;
@@ -0,0 +1,17 @@
1
+ import React from "react";
2
+ import { createComponent } from "@lit/react";
3
+ import { EFCaptions, EFCaptionsActiveWord } from "@editframe/elements";
4
+ const Captions = createComponent({
5
+ tagName: "ef-captions",
6
+ elementClass: EFCaptions,
7
+ react: React
8
+ });
9
+ const CaptionsActiveWord = createComponent({
10
+ tagName: "ef-captions-active-word",
11
+ elementClass: EFCaptionsActiveWord,
12
+ react: React
13
+ });
14
+ export {
15
+ Captions,
16
+ CaptionsActiveWord
17
+ };
@@ -0,0 +1,2 @@
1
+ import { EFImage as EFImageElement } from '../../../elements/src';
2
+ export declare const Image: import('@lit/react').ReactWebComponent<EFImageElement, {}>;
@@ -0,0 +1,11 @@
1
+ import React from "react";
2
+ import { createComponent } from "@lit/react";
3
+ import { EFImage } from "@editframe/elements";
4
+ const Image = createComponent({
5
+ tagName: "ef-image",
6
+ elementClass: EFImage,
7
+ react: React
8
+ });
9
+ export {
10
+ Image
11
+ };
@@ -0,0 +1,2 @@
1
+ import { EFTimegroup as EFTimegroupElement } from '../../../elements/src';
2
+ export declare const Timegroup: import('../create-component.ts').ReactWebComponent<EFTimegroupElement, {}>;
@@ -0,0 +1,11 @@
1
+ import React from "react";
2
+ import { createComponent } from "../create-component.js";
3
+ import { EFTimegroup } from "@editframe/elements";
4
+ const Timegroup = createComponent({
5
+ tagName: "ef-timegroup",
6
+ elementClass: EFTimegroup,
7
+ react: React
8
+ });
9
+ export {
10
+ Timegroup
11
+ };
@@ -0,0 +1,2 @@
1
+ import { EFVideo as EFVideoElement } from '../../../elements/src';
2
+ export declare const Video: import('@lit/react').ReactWebComponent<EFVideoElement, {}>;
@@ -0,0 +1,11 @@
1
+ import React from "react";
2
+ import { createComponent } from "@lit/react";
3
+ import { EFVideo } from "@editframe/elements";
4
+ const Video = createComponent({
5
+ tagName: "ef-video",
6
+ elementClass: EFVideo,
7
+ react: React
8
+ });
9
+ export {
10
+ Video
11
+ };
@@ -0,0 +1,2 @@
1
+ import { EFWaveform as EFWaveformElement } from '../../../elements/src';
2
+ export declare const Waveform: import('@lit/react').ReactWebComponent<EFWaveformElement, {}>;
@@ -0,0 +1,11 @@
1
+ import React from "react";
2
+ import { createComponent } from "@lit/react";
3
+ import { EFWaveform } from "@editframe/elements";
4
+ const Waveform = createComponent({
5
+ tagName: "ef-waveform",
6
+ elementClass: EFWaveform,
7
+ react: React
8
+ });
9
+ export {
10
+ Waveform
11
+ };
@@ -0,0 +1,2 @@
1
+ import { EFFilmstrip as EFFilmstripElement } from '../../../elements/src';
2
+ export declare const Filmstrip: import('@lit/react').ReactWebComponent<EFFilmstripElement, {}>;
@@ -0,0 +1,11 @@
1
+ import React from "react";
2
+ import { createComponent } from "@lit/react";
3
+ import { EFFilmstrip } from "@editframe/elements";
4
+ const Filmstrip = createComponent({
5
+ tagName: "ef-filmstrip",
6
+ elementClass: EFFilmstrip,
7
+ react: React
8
+ });
9
+ export {
10
+ Filmstrip
11
+ };
@@ -0,0 +1,2 @@
1
+ import { EFPreview as EFPreviewElement } from '../../../elements/src';
2
+ export declare const EFPreview: import('@lit/react').ReactWebComponent<EFPreviewElement, {}>;
@@ -0,0 +1,11 @@
1
+ import React from "react";
2
+ import { createComponent } from "@lit/react";
3
+ import { EFPreview as EFPreview$1 } from "@editframe/elements";
4
+ const EFPreview = createComponent({
5
+ tagName: "ef-preview",
6
+ elementClass: EFPreview$1,
7
+ react: React
8
+ });
9
+ export {
10
+ EFPreview
11
+ };
@@ -0,0 +1,2 @@
1
+ import { EFToggleLoop as EFToggleLoopElement } from '../../../elements/src';
2
+ export declare const ToggleLoop: import('@lit/react').ReactWebComponent<EFToggleLoopElement, {}>;
@@ -0,0 +1,11 @@
1
+ import React from "react";
2
+ import { createComponent } from "@lit/react";
3
+ import { EFToggleLoop } from "@editframe/elements";
4
+ const ToggleLoop = createComponent({
5
+ tagName: "ef-toggle-loop",
6
+ elementClass: EFToggleLoop,
7
+ react: React
8
+ });
9
+ export {
10
+ ToggleLoop
11
+ };
@@ -0,0 +1,2 @@
1
+ import { EFTogglePlay as EFTogglePlayElement } from '../../../elements/src';
2
+ export declare const TogglePlay: import('@lit/react').ReactWebComponent<EFTogglePlayElement, {}>;
@@ -0,0 +1,11 @@
1
+ import React from "react";
2
+ import { createComponent } from "@lit/react";
3
+ import { EFTogglePlay } from "@editframe/elements";
4
+ const TogglePlay = createComponent({
5
+ tagName: "ef-toggle-play",
6
+ elementClass: EFTogglePlay,
7
+ react: React
8
+ });
9
+ export {
10
+ TogglePlay
11
+ };
@@ -0,0 +1,2 @@
1
+ import { EFWorkbench as EFWorkbenchElement } from '../../../elements/src';
2
+ export declare const Workbench: import('@lit/react').ReactWebComponent<EFWorkbenchElement, {}>;
@@ -0,0 +1,11 @@
1
+ import React from "react";
2
+ import { createComponent } from "@lit/react";
3
+ import { EFWorkbench } from "@editframe/elements";
4
+ const Workbench = createComponent({
5
+ tagName: "ef-workbench",
6
+ elementClass: EFWorkbench,
7
+ react: React
8
+ });
9
+ export {
10
+ Workbench
11
+ };
@@ -0,0 +1,7 @@
1
+ import { EFTimegroup } from '../../../elements/src';
2
+ export declare const useTimingInfo: (timegroupRef?: React.RefObject<EFTimegroup>) => {
3
+ ref: import('react').RefObject<EFTimegroup>;
4
+ ownCurrentTimeMs: number;
5
+ durationMs: number;
6
+ percentComplete: number;
7
+ };
@@ -0,0 +1,35 @@
1
+ import { useState, useEffect, useRef } from "react";
2
+ class CurrentTimeController {
3
+ constructor(host, setCurrentTime) {
4
+ this.host = host;
5
+ this.setCurrentTime = setCurrentTime;
6
+ this.host.addController(this);
7
+ }
8
+ hostDisconnected() {
9
+ this.host.removeController(this);
10
+ }
11
+ hostUpdated() {
12
+ this.setCurrentTime({
13
+ ownCurrentTimeMs: this.host.ownCurrentTimeMs,
14
+ durationMs: this.host.durationMs,
15
+ percentComplete: this.host.ownCurrentTimeMs / this.host.durationMs
16
+ });
17
+ }
18
+ }
19
+ const useTimingInfo = (timegroupRef = useRef(null)) => {
20
+ const [timeInfo, setTimeInfo] = useState({
21
+ ownCurrentTimeMs: 0,
22
+ durationMs: 0,
23
+ percentComplete: 0
24
+ });
25
+ useEffect(() => {
26
+ if (!timegroupRef.current) {
27
+ throw new Error("Timegroup ref not set");
28
+ }
29
+ new CurrentTimeController(timegroupRef.current, setTimeInfo);
30
+ }, [timegroupRef.current]);
31
+ return { ...timeInfo, ref: timegroupRef };
32
+ };
33
+ export {
34
+ useTimingInfo
35
+ };
@@ -0,0 +1,30 @@
1
+ export {
2
+ /** @deprecated Use `Audio` instead of `EFAudio`. Exports starting `EF*` wil be removed in a future release. */
3
+ Audio as EFAudio, Audio, } from './elements/Audio.ts';
4
+ export {
5
+ /** @deprecated Use `Captions` instead of `EFCaptions`. Exports starting `EF*` wil be removed in a future release. */
6
+ Captions as EFCaptions, Captions,
7
+ /** @deprecated Use `CaptionsActiveWord` instead of `EFCaptionsActiveWord`. Exports starting `EF*` wil be removed in a future release. */
8
+ CaptionsActiveWord as EFCaptionsActiveWord, CaptionsActiveWord, } from './elements/Captions.ts';
9
+ export { Image as EFImage, Image, } from './elements/Image.ts';
10
+ export {
11
+ /** @deprecated Use `Timegroup` instead of `EFTimegroup`. Exports starting `EF*` wil be removed in a future release. */
12
+ Timegroup as EFTimegroup, Timegroup, } from './elements/Timegroup.ts';
13
+ export {
14
+ /** @deprecated Use `Video` instead of `EFVideo`. Exports starting `EF*` wil be removed in a future release. */
15
+ Video as EFVideo, Video, } from './elements/Video.ts';
16
+ export {
17
+ /** @deprecated Use `Waveform` instead of `EFWaveform`. Exports starting `EF*` wil be removed in a future release. */
18
+ Waveform as EFWaveform, Waveform, } from './elements/Waveform.ts';
19
+ export {
20
+ /** @deprecated Use `Workbench` instead of `EFWorkbench`. Exports starting `EF*` wil be removed in a future release. */
21
+ Workbench as EFWorkbench, Workbench, } from './gui/Workbench.ts';
22
+ export {
23
+ /** @deprecated Use `Filmstrip` instead of `EFFilmstrip`. Exports starting `EF*` wil be removed in a future release. */
24
+ Filmstrip as EFFilmstrip, Filmstrip, } from './gui/Filmstrip.ts';
25
+ export {
26
+ /** @deprecated Use `Preview` instead of `EFPreview`. Exports starting `EF*` wil be removed in a future release. */
27
+ EFPreview, EFPreview as Preview, } from './gui/Preview.ts';
28
+ export { TogglePlay } from './gui/TogglePlay.ts';
29
+ export { ToggleLoop } from './gui/ToggleLoop.ts';
30
+ export { useTimingInfo } from './hooks/useTimingInfo.ts';
package/dist/index.js ADDED
@@ -0,0 +1,37 @@
1
+ import { Audio, Audio as Audio2 } from "./elements/Audio.js";
2
+ import { Captions, CaptionsActiveWord, Captions as Captions2, CaptionsActiveWord as CaptionsActiveWord2 } from "./elements/Captions.js";
3
+ import { Image, Image as Image2 } from "./elements/Image.js";
4
+ import { Timegroup, Timegroup as Timegroup2 } from "./elements/Timegroup.js";
5
+ import { Video, Video as Video2 } from "./elements/Video.js";
6
+ import { Waveform, Waveform as Waveform2 } from "./elements/Waveform.js";
7
+ import { Workbench, Workbench as Workbench2 } from "./gui/Workbench.js";
8
+ import { Filmstrip, Filmstrip as Filmstrip2 } from "./gui/Filmstrip.js";
9
+ import { EFPreview, EFPreview as EFPreview2 } from "./gui/Preview.js";
10
+ import { TogglePlay } from "./gui/TogglePlay.js";
11
+ import { ToggleLoop } from "./gui/ToggleLoop.js";
12
+ import { useTimingInfo } from "./hooks/useTimingInfo.js";
13
+ export {
14
+ Audio,
15
+ Captions,
16
+ CaptionsActiveWord,
17
+ Audio2 as EFAudio,
18
+ Captions2 as EFCaptions,
19
+ CaptionsActiveWord2 as EFCaptionsActiveWord,
20
+ Filmstrip as EFFilmstrip,
21
+ Image as EFImage,
22
+ EFPreview,
23
+ Timegroup as EFTimegroup,
24
+ Video as EFVideo,
25
+ Waveform as EFWaveform,
26
+ Workbench as EFWorkbench,
27
+ Filmstrip2 as Filmstrip,
28
+ Image2 as Image,
29
+ EFPreview2 as Preview,
30
+ Timegroup2 as Timegroup,
31
+ ToggleLoop,
32
+ TogglePlay,
33
+ Video2 as Video,
34
+ Waveform2 as Waveform,
35
+ Workbench2 as Workbench,
36
+ useTimingInfo
37
+ };
package/package.json CHANGED
@@ -1,16 +1,12 @@
1
1
  {
2
2
  "name": "@editframe/react",
3
- "version": "0.7.0-beta.9",
3
+ "version": "0.8.0-beta.10",
4
4
  "description": "",
5
5
  "exports": {
6
6
  ".": {
7
7
  "import": {
8
- "default": "./dist/index.js",
9
- "types": "./dist/packages/react/src/index.d.ts"
10
- },
11
- "require": {
12
- "default": "./dist/index.cjs",
13
- "types": "./dist/packages/react/src/index.d.ts"
8
+ "types": "./dist/packages/react/src/index.d.ts",
9
+ "default": "./dist/index.js"
14
10
  }
15
11
  }
16
12
  },
@@ -23,17 +19,19 @@
23
19
  "author": "",
24
20
  "license": "UNLICENSED",
25
21
  "dependencies": {
26
- "@editframe/elements": "0.7.0-beta.9",
22
+ "@editframe/elements": "0.8.0-beta.10",
27
23
  "@lit/react": "^1.0.5",
28
24
  "debug": "^4.3.5",
29
25
  "react": "^18.3.0",
30
26
  "react-dom": "^18.3.0"
31
27
  },
32
28
  "devDependencies": {
29
+ "@types/node": "^22.0.0",
33
30
  "@types/react": "^18.3.0",
34
31
  "@types/react-dom": "^18.3.0",
35
32
  "rollup-plugin-tsconfig-paths": "^1.5.2",
36
- "vite-plugin-dts": "^3.9.1",
33
+ "typescript": "^5.5.4",
34
+ "vite-plugin-dts": "^4.0.3",
37
35
  "vite-tsconfig-paths": "^4.3.2"
38
36
  }
39
37
  }
@@ -2,7 +2,7 @@ import React from "react";
2
2
  import { createComponent } from "@lit/react";
3
3
  import { EFAudio as EFAudioElement } from "@editframe/elements";
4
4
 
5
- export const EFAudio = createComponent({
5
+ export const Audio = createComponent({
6
6
  tagName: "ef-audio",
7
7
  elementClass: EFAudioElement,
8
8
  react: React,
@@ -5,13 +5,13 @@ import {
5
5
  EFCaptionsActiveWord as EFCaptionsActiveWordElement,
6
6
  } from "@editframe/elements";
7
7
 
8
- export const EFCaptions = createComponent({
8
+ export const Captions = createComponent({
9
9
  tagName: "ef-captions",
10
10
  elementClass: EFCaptionsElement,
11
11
  react: React,
12
12
  });
13
13
 
14
- export const EFCaptionsActiveWord = createComponent({
14
+ export const CaptionsActiveWord = createComponent({
15
15
  tagName: "ef-captions-active-word",
16
16
  elementClass: EFCaptionsActiveWordElement,
17
17
  react: React,
@@ -2,7 +2,7 @@ import React from "react";
2
2
  import { createComponent } from "@lit/react";
3
3
  import { EFImage as EFImageElement } from "@editframe/elements";
4
4
 
5
- export const EFImage = createComponent({
5
+ export const Image = createComponent({
6
6
  tagName: "ef-image",
7
7
  elementClass: EFImageElement,
8
8
  react: React,
@@ -1,8 +1,8 @@
1
1
  import React from "react";
2
- import { createComponent } from "../create-component";
2
+ import { createComponent } from "../create-component.ts";
3
3
  import { EFTimegroup as EFTimegroupElement } from "@editframe/elements";
4
4
 
5
- export const EFTimegroup = createComponent({
5
+ export const Timegroup = createComponent({
6
6
  tagName: "ef-timegroup",
7
7
  elementClass: EFTimegroupElement,
8
8
  react: React,
@@ -2,7 +2,7 @@ import React from "react";
2
2
  import { createComponent } from "@lit/react";
3
3
  import { EFVideo as EFVideoElement } from "@editframe/elements";
4
4
 
5
- export const EFVideo = createComponent({
5
+ export const Video = createComponent({
6
6
  tagName: "ef-video",
7
7
  elementClass: EFVideoElement,
8
8
  react: React,
@@ -2,7 +2,7 @@ import React from "react";
2
2
  import { createComponent } from "@lit/react";
3
3
  import { EFWaveform as EFWaveformElement } from "@editframe/elements";
4
4
 
5
- export const EFWaveform = createComponent({
5
+ export const Waveform = createComponent({
6
6
  tagName: "ef-waveform",
7
7
  elementClass: EFWaveformElement,
8
8
  react: React,
@@ -2,7 +2,7 @@ import React from "react";
2
2
  import { createComponent } from "@lit/react";
3
3
  import { EFFilmstrip as EFFilmstripElement } from "@editframe/elements";
4
4
 
5
- export const EFFilmstrip = createComponent({
5
+ export const Filmstrip = createComponent({
6
6
  tagName: "ef-filmstrip",
7
7
  elementClass: EFFilmstripElement,
8
8
  react: React,
@@ -0,0 +1,9 @@
1
+ import React from "react";
2
+ import { createComponent } from "@lit/react";
3
+ import { EFPreview as EFPreviewElement } from "@editframe/elements";
4
+
5
+ export const EFPreview = createComponent({
6
+ tagName: "ef-preview",
7
+ elementClass: EFPreviewElement,
8
+ react: React,
9
+ });
@@ -0,0 +1,9 @@
1
+ import React from "react";
2
+ import { createComponent } from "@lit/react";
3
+ import { EFToggleLoop as EFToggleLoopElement } from "@editframe/elements";
4
+
5
+ export const ToggleLoop = createComponent({
6
+ tagName: "ef-toggle-loop",
7
+ elementClass: EFToggleLoopElement,
8
+ react: React,
9
+ });
@@ -0,0 +1,9 @@
1
+ import React from "react";
2
+ import { createComponent } from "@lit/react";
3
+ import { EFTogglePlay as EFTogglePlayElement } from "@editframe/elements";
4
+
5
+ export const TogglePlay = createComponent({
6
+ tagName: "ef-toggle-play",
7
+ elementClass: EFTogglePlayElement,
8
+ react: React,
9
+ });
@@ -2,7 +2,7 @@ import React from "react";
2
2
  import { createComponent } from "@lit/react";
3
3
  import { EFWorkbench as EFWorkbenchElement } from "@editframe/elements";
4
4
 
5
- export const EFWorkbench = createComponent({
5
+ export const Workbench = createComponent({
6
6
  tagName: "ef-workbench",
7
7
  elementClass: EFWorkbenchElement,
8
8
  react: React,
package/CHANGELOG.md DELETED
@@ -1,8 +0,0 @@
1
- # @editframe/react
2
-
3
- ## 0.7.0-beta.9
4
-
5
- ### Patch Changes
6
-
7
- - Updated dependencies [[`17c4452`](https://github.com/editframe/elements/commit/17c4452f679b042ac0accd9bf520728455e8cc2c)]:
8
- - @editframe/elements@0.7.0-beta.9
@@ -1,6 +0,0 @@
1
- const path = require("node:path");
2
- module.exports = {
3
- plugins: {
4
- tailwindcss: {},
5
- },
6
- };
@@ -1,347 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright 2018 Google LLC
4
- * SPDX-License-Identifier: BSD-3-Clause
5
- */
6
-
7
- import type React from "react";
8
-
9
- const NODE_MODE = false;
10
- const DEV_MODE = true;
11
-
12
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
13
- type DistributiveOmit<T, K extends string | number | symbol> = T extends any
14
- ? K extends keyof T
15
- ? Omit<T, K>
16
- : T
17
- : T;
18
- type PropsWithoutRef<T> = DistributiveOmit<T, "ref">;
19
-
20
- /**
21
- * Creates a type to be used for the props of a web component used directly in
22
- * React JSX.
23
- *
24
- * Example:
25
- *
26
- * ```ts
27
- * declare module "react" {
28
- * namespace JSX {
29
- * interface IntrinsicElements {
30
- * 'x-foo': WebComponentProps<XFoo>;
31
- * }
32
- * }
33
- * }
34
- * ```
35
- */
36
- export type WebComponentProps<I extends HTMLElement> = React.DetailedHTMLProps<
37
- React.HTMLAttributes<I>,
38
- I
39
- > &
40
- ElementProps<I>;
41
-
42
- /**
43
- * Type of the React component wrapping the web component. This is the return
44
- * type of `createComponent`.
45
- */
46
- export type ReactWebComponent<
47
- I extends HTMLElement,
48
- E extends EventNames = {},
49
- > = React.ForwardRefExoticComponent<
50
- // TODO(augustjk): Remove and use `React.PropsWithoutRef` when
51
- // https://github.com/preactjs/preact/issues/4124 is fixed.
52
- PropsWithoutRef<ComponentProps<I, E>> & React.RefAttributes<I>
53
- >;
54
-
55
- // Props derived from custom element class. Currently has limitations of making
56
- // all properties optional and also surfaces life cycle methods in autocomplete.
57
- // TODO(augustjk) Consider omitting keyof LitElement to remove "internal"
58
- // lifecycle methods or allow user to explicitly provide props.
59
- type ElementProps<I> = Partial<Omit<I, keyof HTMLElement>>;
60
-
61
- // Acceptable props to the React component.
62
- type ComponentProps<I, E extends EventNames = {}> = Omit<
63
- React.HTMLAttributes<I>,
64
- // Prefer type of provided event handler props or those on element over
65
- // built-in HTMLAttributes
66
- keyof E | keyof ElementProps<I>
67
- > &
68
- EventListeners<E> &
69
- ElementProps<I>;
70
-
71
- /**
72
- * Type used to cast an event name with an event type when providing the
73
- * `events` option to `createComponent` for better typing of the event handler
74
- * prop.
75
- *
76
- * Example:
77
- *
78
- * ```ts
79
- * const FooComponent = createComponent({
80
- * ...
81
- * events: {
82
- * onfoo: 'foo' as EventName<FooEvent>,
83
- * }
84
- * });
85
- * ```
86
- *
87
- * `onfoo` prop will have the type `(e: FooEvent) => void`.
88
- */
89
- export type EventName<T extends Event = Event> = string & {
90
- __eventType: T;
91
- };
92
-
93
- // A key value map matching React prop names to event names.
94
- type EventNames = Record<string, EventName | string>;
95
-
96
- // A map of expected event listener types based on EventNames.
97
- type EventListeners<R extends EventNames> = {
98
- [K in keyof R]?: R[K] extends EventName
99
- ? (e: R[K]["__eventType"]) => void
100
- : (e: Event) => void;
101
- };
102
-
103
- export interface Options<I extends HTMLElement, E extends EventNames = {}> {
104
- react: typeof React;
105
- tagName: string;
106
- elementClass: Constructor<I>;
107
- events?: E;
108
- displayName?: string;
109
- }
110
-
111
- type Constructor<T> = { new (): T };
112
-
113
- const reservedReactProperties = new Set([
114
- "id",
115
- "children",
116
- "localName",
117
- "ref",
118
- "style",
119
- "className",
120
- ]);
121
-
122
- const listenedEvents = new WeakMap<Element, Map<string, EventListenerObject>>();
123
-
124
- /**
125
- * Adds an event listener for the specified event to the given node. In the
126
- * React setup, there should only ever be one event listener. Thus, for
127
- * efficiency only one listener is added and the handler for that listener is
128
- * updated to point to the given listener function.
129
- */
130
- const addOrUpdateEventListener = (
131
- node: Element,
132
- event: string,
133
- listener: (event?: Event) => void,
134
- ) => {
135
- let events = listenedEvents.get(node);
136
- if (events === undefined) {
137
- // biome-ignore lint/suspicious/noAssignInExpressions: copied from @lit
138
- listenedEvents.set(node, (events = new Map()));
139
- }
140
- let handler = events.get(event);
141
- if (listener !== undefined) {
142
- // If necessary, add listener and track handler
143
- if (handler === undefined) {
144
- // biome-ignore lint/suspicious/noAssignInExpressions: copied from @lit
145
- events.set(event, (handler = { handleEvent: listener }));
146
- node.addEventListener(event, handler);
147
- // Otherwise just update the listener with new value
148
- } else {
149
- handler.handleEvent = listener;
150
- }
151
- // Remove listener if one exists and value is undefined
152
- } else if (handler !== undefined) {
153
- events.delete(event);
154
- node.removeEventListener(event, handler);
155
- }
156
- };
157
-
158
- /**
159
- * Sets properties and events on custom elements. These properties and events
160
- * have been pre-filtered so we know they should apply to the custom element.
161
- */
162
- const setProperty = <E extends Element>(
163
- node: E,
164
- name: string,
165
- value: unknown,
166
- old: unknown,
167
- events?: EventNames,
168
- ) => {
169
- const event = events?.[name];
170
- // Dirty check event value.
171
- if (event !== undefined) {
172
- if (value !== old) {
173
- addOrUpdateEventListener(node, event, value as (e?: Event) => void);
174
- }
175
- return;
176
- }
177
- // But don't dirty check properties; elements are assumed to do this.
178
- node[name as keyof E] = value as E[keyof E];
179
-
180
- // This block is to replicate React's behavior for attributes of native
181
- // elements where `undefined` or `null` values result in attributes being
182
- // removed.
183
- // https://github.com/facebook/react/blob/899cb95f52cc83ab5ca1eb1e268c909d3f0961e7/packages/react-dom-bindings/src/client/DOMPropertyOperations.js#L107-L141
184
- //
185
- // It's only needed here for native HTMLElement properties that reflect
186
- // attributes of the same name but don't have that behavior like "id" or
187
- // "draggable".
188
- if (
189
- (value === undefined || value === null) &&
190
- name in HTMLElement.prototype
191
- ) {
192
- node.removeAttribute(name);
193
- }
194
- };
195
-
196
- /**
197
- * Creates a React component for a custom element. Properties are distinguished
198
- * from attributes automatically, and events can be configured so they are added
199
- * to the custom element as event listeners.
200
- *
201
- * @param options An options bag containing the parameters needed to generate a
202
- * wrapped web component.
203
- *
204
- * @param options.react The React module, typically imported from the `react`
205
- * npm package.
206
- * @param options.tagName The custom element tag name registered via
207
- * `customElements.define`.
208
- * @param options.elementClass The custom element class registered via
209
- * `customElements.define`.
210
- * @param options.events An object listing events to which the component can
211
- * listen. The object keys are the event property names passed in via React
212
- * props and the object values are the names of the corresponding events
213
- * generated by the custom element. For example, given `{onactivate:
214
- * 'activate'}` an event function may be passed via the component's `onactivate`
215
- * prop and will be called when the custom element fires its `activate` event.
216
- * @param options.displayName A React component display name, used in debugging
217
- * messages. Default value is inferred from the name of custom element class
218
- * registered via `customElements.define`.
219
- */
220
- export const createComponent = <
221
- I extends HTMLElement,
222
- E extends EventNames = {},
223
- >({
224
- react: React,
225
- tagName,
226
- elementClass,
227
- events,
228
- displayName,
229
- }: Options<I, E>): ReactWebComponent<I, E> => {
230
- const eventProps = new Set(Object.keys(events ?? {}));
231
-
232
- if (DEV_MODE) {
233
- for (const p of reservedReactProperties) {
234
- if (p in elementClass.prototype && !(p in HTMLElement.prototype)) {
235
- // Note, this effectively warns only for `ref` since the other
236
- // reserved props are on HTMLElement.prototype. To address this
237
- // would require crawling down the prototype, which doesn't feel worth
238
- // it since implementing these properties on an element is extremely
239
- // rare.
240
- console.warn(
241
- `${tagName} contains property ${p} which is a React reserved property. It will be used by React and not set on the element.`,
242
- );
243
- }
244
- }
245
- }
246
-
247
- type Props = ComponentProps<I, E>;
248
-
249
- const ReactComponent = React.forwardRef<I, Props>((props, ref) => {
250
- const prevElemPropsRef = React.useRef(new Map());
251
- const elementRef = React.useRef<I | null>(null);
252
-
253
- // Props to be passed to React.createElement
254
- const reactProps: Record<string, unknown> = {};
255
- // Props to be set on element with setProperty
256
- const elementProps: Record<string, unknown> = {};
257
-
258
- for (const [k, v] of Object.entries(props)) {
259
- if (reservedReactProperties.has(k)) {
260
- // React does *not* handle `className` for custom elements so
261
- // coerce it to `class` so it's handled correctly.
262
- reactProps[k === "className" ? "class" : k] = v;
263
- continue;
264
- }
265
-
266
- if (eventProps.has(k) || k in elementClass.prototype) {
267
- elementProps[k] = v;
268
- continue;
269
- }
270
-
271
- reactProps[k] = v;
272
- }
273
-
274
- // useLayoutEffect produces warnings during server rendering.
275
- if (!NODE_MODE) {
276
- // This one has no dependency array so it'll run on every re-render.
277
- React.useLayoutEffect(() => {
278
- if (elementRef.current === null) {
279
- return;
280
- }
281
- const newElemProps = new Map();
282
- for (const key in elementProps) {
283
- setProperty(
284
- elementRef.current,
285
- key,
286
- props[key],
287
- prevElemPropsRef.current.get(key),
288
- events,
289
- );
290
- prevElemPropsRef.current.delete(key);
291
- newElemProps.set(key, props[key]);
292
- }
293
- // "Unset" any props from previous render that no longer exist.
294
- // Setting to `undefined` seems like the correct thing to "unset"
295
- // but currently React will set it as `null`.
296
- // See https://github.com/facebook/react/issues/28203
297
- for (const [key, value] of prevElemPropsRef.current) {
298
- setProperty(elementRef.current, key, undefined, value, events);
299
- }
300
- prevElemPropsRef.current = newElemProps;
301
- });
302
-
303
- // Empty dependency array so this will only run once after first render.
304
- React.useLayoutEffect(() => {
305
- elementRef.current?.removeAttribute("defer-hydration");
306
- }, []);
307
- }
308
-
309
- if (NODE_MODE) {
310
- // If component is to be server rendered with `@lit/ssr-react`, pass
311
- // element properties in a special bag to be set by the server-side
312
- // element renderer.
313
- if (
314
- (React.createElement.name === "litPatchedCreateElement" ||
315
- // @ts-expect-error globalThis is any
316
- globalThis.litSsrReactEnabled) &&
317
- Object.keys(elementProps).length
318
- ) {
319
- // This property needs to remain unminified.
320
- reactProps._$litProps$ = elementProps;
321
- }
322
- } else {
323
- // Suppress hydration warning for server-rendered attributes.
324
- // This property needs to remain unminified.
325
- reactProps.suppressHydrationWarning = true;
326
- }
327
-
328
- return React.createElement(tagName, {
329
- ...reactProps,
330
- ref: React.useCallback(
331
- (node: I) => {
332
- elementRef.current = node;
333
- if (typeof ref === "function") {
334
- ref(node);
335
- } else if (ref !== null) {
336
- ref.current = node;
337
- }
338
- },
339
- [ref],
340
- ),
341
- });
342
- });
343
-
344
- ReactComponent.displayName = displayName ?? elementClass.name;
345
-
346
- return ReactComponent;
347
- };
package/src/index.ts DELETED
@@ -1,11 +0,0 @@
1
- export { EFAudio } from "./elements/EFAudio";
2
- export { EFCaptions, EFCaptionsActiveWord } from "./elements/EFCaptions";
3
- export { EFImage } from "./elements/EFImage";
4
- export { EFTimegroup } from "./elements/EFTimegroup";
5
- export { EFVideo } from "./elements/EFVideo";
6
- export { EFWaveform } from "./elements/EFWaveform";
7
-
8
- export { EFWorkbench } from "./gui/EFWorkbench";
9
- export { EFFilmstrip } from "./gui/EFFilmstrip";
10
-
11
- export { useTimingInfo } from "./hooks/useTimingInfo";
@@ -1,10 +0,0 @@
1
- import type { Config } from "tailwindcss";
2
-
3
- module.exports = {
4
- content: ["./src/**/*.ts"],
5
-
6
- theme: {
7
- extend: {},
8
- },
9
- plugins: [],
10
- } satisfies Config;
package/tsconfig.json DELETED
@@ -1,4 +0,0 @@
1
- {
2
- "include": ["src/**/*.ts"],
3
- "extends": "../../tsconfig.json"
4
- }
package/vite.config.ts DELETED
@@ -1,8 +0,0 @@
1
- import path from "node:path";
2
-
3
- import { defineViteBuildConfig } from "../defineViteBuildConfig";
4
-
5
- export default defineViteBuildConfig({
6
- root: path.dirname(new URL(import.meta.url).pathname),
7
- name: "editframe-react",
8
- });