mirror of
https://github.com/zoriya/v10.git
synced 2026-08-16 02:45:09 +00:00
feat(monorepo): migrate prototype code to organized package structure
Migrate all prototype code from vjs10-prototype repository into the monorepo structure following established dependency hierarchy and package organization patterns. Core packages migrated: - @vjs-10/media-store: Complete media store with nanostores integration - @vjs-10/playback-engine: HLS.js playback engine implementation - @vjs-10/media: Core media state owner and interfaces HTML packages migrated: - @vjs-10/html-icons: Web component icons with proper base classes - @vjs-10/html-media-elements: Context provider integration - @vjs-10/html: Main HTML UI components, skins, and utilities React packages migrated: - @vjs-10/react-icons: React icon components - @vjs-10/react-media-elements: Video component with state integration - @vjs-10/react-media-store: MediaProvider and React hooks - @vjs-10/react: Main React UI components and skins Changes made: - Updated all imports to use monorepo package names (@vjs-10/*) - Distributed dependencies to specific packages that use them - Preserved all prototype functionality and component structure - Created proper index files for all packages - Fixed workspace protocol usage for npm compatibility 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude
parent
fc5a0e46fd
commit
4b472ec49c
@@ -1,134 +1,5 @@
|
||||
import { getIcon, createSVGString, IconDefinition } from '@vjs-10/icons';
|
||||
|
||||
export interface IconElementOptions {
|
||||
className?: string;
|
||||
size?: number;
|
||||
color?: string;
|
||||
}
|
||||
|
||||
export function createIconElement(iconName: string, options: IconElementOptions = {}): HTMLElement {
|
||||
const icon = getIcon(iconName);
|
||||
if (!icon) {
|
||||
throw new Error(`Icon "${iconName}" not found`);
|
||||
}
|
||||
|
||||
const container = document.createElement('span');
|
||||
container.className = `vjs-icon vjs-icon-${iconName} ${options.className || ''}`.trim();
|
||||
|
||||
const svgString = createSVGString(icon);
|
||||
container.innerHTML = svgString;
|
||||
|
||||
const svg = container.querySelector('svg');
|
||||
if (svg && options.size) {
|
||||
svg.style.width = `${options.size}px`;
|
||||
svg.style.height = `${options.size}px`;
|
||||
}
|
||||
|
||||
if (svg && options.color) {
|
||||
svg.style.fill = options.color;
|
||||
}
|
||||
|
||||
return container;
|
||||
}
|
||||
|
||||
export class VjsIcon extends HTMLElement {
|
||||
private _name: string = '';
|
||||
private _size?: number;
|
||||
private _color?: string;
|
||||
|
||||
static get observedAttributes() {
|
||||
return ['name', 'size', 'color'];
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.attachShadow({ mode: 'open' });
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
this.render();
|
||||
}
|
||||
|
||||
attributeChangedCallback(name: string, oldValue: string, newValue: string) {
|
||||
if (oldValue !== newValue) {
|
||||
switch (name) {
|
||||
case 'name':
|
||||
this._name = newValue;
|
||||
break;
|
||||
case 'size':
|
||||
this._size = newValue ? parseInt(newValue, 10) : undefined;
|
||||
break;
|
||||
case 'color':
|
||||
this._color = newValue;
|
||||
break;
|
||||
}
|
||||
this.render();
|
||||
}
|
||||
}
|
||||
|
||||
private render() {
|
||||
if (!this.shadowRoot || !this._name) return;
|
||||
|
||||
const icon = getIcon(this._name);
|
||||
if (!icon) {
|
||||
this.shadowRoot.innerHTML = `<span>Icon "${this._name}" not found</span>`;
|
||||
return;
|
||||
}
|
||||
|
||||
const svgString = createSVGString(icon);
|
||||
const styles = `
|
||||
<style>
|
||||
:host {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
svg {
|
||||
width: ${this._size ? `${this._size}px` : '1em'};
|
||||
height: ${this._size ? `${this._size}px` : '1em'};
|
||||
fill: ${this._color || 'currentColor'};
|
||||
}
|
||||
</style>
|
||||
`;
|
||||
|
||||
this.shadowRoot.innerHTML = styles + svgString;
|
||||
}
|
||||
|
||||
get name() {
|
||||
return this._name;
|
||||
}
|
||||
|
||||
set name(value: string) {
|
||||
this.setAttribute('name', value);
|
||||
}
|
||||
|
||||
get size() {
|
||||
return this._size;
|
||||
}
|
||||
|
||||
set size(value: number | undefined) {
|
||||
if (value !== undefined) {
|
||||
this.setAttribute('size', value.toString());
|
||||
} else {
|
||||
this.removeAttribute('size');
|
||||
}
|
||||
}
|
||||
|
||||
get color() {
|
||||
return this._color;
|
||||
}
|
||||
|
||||
set color(value: string | undefined) {
|
||||
if (value !== undefined) {
|
||||
this.setAttribute('color', value);
|
||||
} else {
|
||||
this.removeAttribute('color');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!customElements.get('vjs-icon')) {
|
||||
customElements.define('vjs-icon', VjsIcon);
|
||||
}
|
||||
|
||||
export { getIcon, createSVGString } from '@vjs-10/icons';
|
||||
export * as MediaPlayIcon from './media-play-icon.js';
|
||||
export * as MediaPauseIcon from './media-pause-icon.js';
|
||||
export * as MediaVolumeHighIcon from './media-volume-high-icon.js';
|
||||
export * as MediaVolumeLowIcon from './media-volume-low-icon.js';
|
||||
export * as MediaVolumeOffIcon from './media-volume-off-icon.js';
|
||||
@@ -0,0 +1,26 @@
|
||||
export function getTemplateHTML() {
|
||||
return /* html */ `
|
||||
<style>
|
||||
:host {
|
||||
display: inline-block;
|
||||
}
|
||||
svg {
|
||||
fill: currentColor;
|
||||
}
|
||||
</style>
|
||||
`;
|
||||
}
|
||||
|
||||
export class MediaChromeIcon extends HTMLElement {
|
||||
static shadowRootOptions = { mode: 'open' as ShadowRootMode };
|
||||
static getTemplateHTML = getTemplateHTML;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
if (!this.shadowRoot) {
|
||||
this.attachShadow((this.constructor as typeof MediaChromeIcon).shadowRootOptions);
|
||||
this.shadowRoot!.innerHTML = (this.constructor as typeof MediaChromeIcon).getTemplateHTML();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import { MediaChromeIcon } from './media-chrome-icon.js';
|
||||
|
||||
export function getTemplateHTML() {
|
||||
return /* html */ `
|
||||
${MediaChromeIcon.getTemplateHTML()}
|
||||
<svg viewBox="0 0 24 24">
|
||||
<path d="M6 19h4V5H6v14zm8-14v14h4V5h-4z"/>
|
||||
</svg>
|
||||
`;
|
||||
}
|
||||
|
||||
export class MediaPauseIcon extends MediaChromeIcon {
|
||||
static getTemplateHTML = getTemplateHTML;
|
||||
}
|
||||
|
||||
customElements.define('media-pause-icon', MediaPauseIcon);
|
||||
@@ -0,0 +1,21 @@
|
||||
import { MediaChromeIcon } from './media-chrome-icon.js';
|
||||
|
||||
export function getTemplateHTML() {
|
||||
return /* html */ `
|
||||
${MediaChromeIcon.getTemplateHTML()}
|
||||
<style>
|
||||
:host {
|
||||
display: var(--media-play-icon-display, inline-flex);
|
||||
}
|
||||
</style>
|
||||
<svg viewBox="0 0 24 24">
|
||||
<path d="M8 5v14l11-7z"/>
|
||||
</svg>
|
||||
`;
|
||||
}
|
||||
|
||||
export class MediaPlayIcon extends MediaChromeIcon {
|
||||
static getTemplateHTML = getTemplateHTML;
|
||||
}
|
||||
|
||||
customElements.define('media-play-icon', MediaPlayIcon);
|
||||
@@ -0,0 +1,23 @@
|
||||
import { MediaChromeIcon } from './media-chrome-icon.js';
|
||||
|
||||
const highIcon = `<svg aria-hidden="true" viewBox="0 0 24 24">
|
||||
<path d="M3 9v6h4l5 5V4L7 9H3Zm13.5 3A4.5 4.5 0 0 0 14 8v8a4.47 4.47 0 0 0 2.5-4ZM14 3.23v2.06a7 7 0 0 1 0 13.42v2.06a9 9 0 0 0 0-17.54Z"/>
|
||||
</svg>`;
|
||||
|
||||
export function getTemplateHTML() {
|
||||
return /* html */ `
|
||||
${MediaChromeIcon.getTemplateHTML()}
|
||||
<style>
|
||||
:host {
|
||||
display: var(--media-play-icon-display, inline-flex);
|
||||
}
|
||||
</style>
|
||||
${highIcon}
|
||||
`;
|
||||
}
|
||||
|
||||
export class MediaVolumeHighIcon extends MediaChromeIcon {
|
||||
static getTemplateHTML = getTemplateHTML;
|
||||
}
|
||||
|
||||
customElements.define('media-volume-high-icon', MediaVolumeHighIcon);
|
||||
@@ -0,0 +1,23 @@
|
||||
import { MediaChromeIcon } from './media-chrome-icon.js';
|
||||
|
||||
const lowIcon = `<svg aria-hidden="true" viewBox="0 0 24 24">
|
||||
<path d="M3 9v6h4l5 5V4L7 9H3Zm13.5 3A4.5 4.5 0 0 0 14 8v8a4.47 4.47 0 0 0 2.5-4Z"/>
|
||||
</svg>`;
|
||||
|
||||
export function getTemplateHTML() {
|
||||
return /* html */ `
|
||||
${MediaChromeIcon.getTemplateHTML()}
|
||||
<style>
|
||||
:host {
|
||||
display: var(--media-play-icon-display, inline-flex);
|
||||
}
|
||||
</style>
|
||||
${lowIcon}
|
||||
`;
|
||||
}
|
||||
|
||||
export class MediaVolumeLowIcon extends MediaChromeIcon {
|
||||
static getTemplateHTML = getTemplateHTML;
|
||||
}
|
||||
|
||||
customElements.define('media-volume-low-icon', MediaVolumeLowIcon);
|
||||
@@ -0,0 +1,23 @@
|
||||
import { MediaChromeIcon } from './media-chrome-icon.js';
|
||||
|
||||
const offIcon = `<svg aria-hidden="true" viewBox="0 0 24 24">
|
||||
<path d="M16.5 12A4.5 4.5 0 0 0 14 8v2.18l2.45 2.45a4.22 4.22 0 0 0 .05-.63Zm2.5 0a6.84 6.84 0 0 1-.54 2.64L20 16.15A8.8 8.8 0 0 0 21 12a9 9 0 0 0-7-8.77v2.06A7 7 0 0 1 19 12ZM4.27 3 3 4.27 7.73 9H3v6h4l5 5v-6.73l4.25 4.25A6.92 6.92 0 0 1 14 18.7v2.06A9 9 0 0 0 17.69 19l2 2.05L21 19.73l-9-9L4.27 3ZM12 4 9.91 6.09 12 8.18V4Z"/>
|
||||
</svg>`;
|
||||
|
||||
export function getTemplateHTML() {
|
||||
return /* html */ `
|
||||
${MediaChromeIcon.getTemplateHTML()}
|
||||
<style>
|
||||
:host {
|
||||
display: var(--media-play-icon-display, inline-flex);
|
||||
}
|
||||
</style>
|
||||
${offIcon}
|
||||
`;
|
||||
}
|
||||
|
||||
export class MediaVolumeOffIcon extends MediaChromeIcon {
|
||||
static getTemplateHTML = getTemplateHTML;
|
||||
}
|
||||
|
||||
customElements.define('media-volume-off-icon', MediaVolumeOffIcon);
|
||||
Reference in New Issue
Block a user