Integration
Use the scena-video-widget custom element in React, Vue, Angular, and vanilla HTML.
Custom elements work in any framework. Register once at the app entry point, then use <scena-video-widget> in templates.
Vue
main.ts
import { defineScenaElement } from '@retoo/scena';
import '@retoo/scena/styles';
defineScenaElement();
ScenaWidget.vue
<script setup lang="ts">
import { ComponentSize, ComponentShape } from '@retoo/scena';
import { ref, onMounted } from 'vue';
const widgetRef = ref<HTMLElement | null>(null);
onMounted(async () => {
await widgetRef.value?.mount({
video: { src: '/video.mp4' },
size: ComponentSize.MD,
shape: ComponentShape.CIRCLE,
});
});
</script>
<template>
<scena-video-widget ref="widgetRef" />
</template>
Vue recognizes custom elements with hyphens in the tag name automatically. If you get a component resolution warning, add
scena-video-widget to compilerOptions.isCustomElement in your Vue config.React
main.tsx
import { defineScenaElement } from '@retoo/scena';
import '@retoo/scena/styles';
defineScenaElement();
ScenaWidget.tsx
import { ComponentSize, ComponentShape } from '@retoo/scena';
import { useRef, useEffect } from 'react';
export function ScenaWidget() {
const ref = useRef<HTMLElement>(null);
useEffect(() => {
ref.current?.mount({
video: { src: '/video.mp4' },
size: ComponentSize.MD,
shape: ComponentShape.CIRCLE,
});
return () => {
ref.current?.unmount();
};
}, []);
return <scena-video-widget ref={ref} />;
}
TypeScript may not know about the custom element tag. Add a JSX declaration to suppress type errors:
scena.d.ts
declare namespace JSX {
interface IntrinsicElements {
'scena-video-widget': React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>;
}
}
Angular
app.module.ts
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
@NgModule({
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}
app.component.ts
import { Component, ElementRef, ViewChild, AfterViewInit } from '@angular/core';
import { defineScenaElement, ComponentSize, ComponentShape } from '@retoo/scena';
import '@retoo/scena/styles';
defineScenaElement();
@Component({
selector: 'app-root',
template: `<scena-video-widget #widget></scena-video-widget>`,
})
export class AppComponent implements AfterViewInit {
@ViewChild('widget') widgetRef!: ElementRef;
async ngAfterViewInit() {
await this.widgetRef.nativeElement.mount({
video: { src: '/video.mp4' },
size: ComponentSize.MD,
shape: ComponentShape.CIRCLE,
});
}
}
Vanilla JS
index.html
<head>
<link rel="stylesheet" href="https://unpkg.com/@retoo/scena/dist/scena.css" />
</head>
<body>
<scena-video-widget></scena-video-widget>
<script src="https://unpkg.com/@retoo/scena/dist/scena.umd.js"></script>
<script>
window.defineScenaElement();
const el = document.querySelector('scena-video-widget');
el.mount({
video: { src: '/video.mp4' },
size: 'md',
shape: 'circle',
});
</script>
</body>