diff --git a/src/components/realtimekit/RTKSDKSelector/RTKSDKSelector.tsx b/src/components/realtimekit/RTKSDKSelector/RTKSDKSelector.tsx index 580435af509978..8b6701b8436808 100644 --- a/src/components/realtimekit/RTKSDKSelector/RTKSDKSelector.tsx +++ b/src/components/realtimekit/RTKSDKSelector/RTKSDKSelector.tsx @@ -30,12 +30,12 @@ export default function SDKSelector() { return ( <> -
+
{platforms.map((p) => (
{frameworks.length < 1 && ( -
+
No frameworks available.
)} -
+
{frameworks.map((fw) => { const handleClick = () => { setSelection(platform, fw); @@ -66,7 +66,7 @@ export default function SDKSelector() { +
+ )} + + {isExpanded && ( +
+
+ {name} + +
+ + {component} + +
+ )} + + {!isExpanded && ( + + {component} + + )} +
+ ); +}; + +export default RTKUIComponent; diff --git a/src/components/realtimekit/RTKUIComponentGrid/RTKUIComponentGrid.astro b/src/components/realtimekit/RTKUIComponentGrid/RTKUIComponentGrid.astro new file mode 100644 index 00000000000000..c13135dbaa1099 --- /dev/null +++ b/src/components/realtimekit/RTKUIComponentGrid/RTKUIComponentGrid.astro @@ -0,0 +1,5 @@ +--- +import UIComponentGrid from "./RTKUIComponentGrid.tsx"; +--- + + diff --git a/src/components/realtimekit/RTKUIComponentGrid/RTKUIComponentGrid.tsx b/src/components/realtimekit/RTKUIComponentGrid/RTKUIComponentGrid.tsx new file mode 100644 index 00000000000000..7b7aa39d59278d --- /dev/null +++ b/src/components/realtimekit/RTKUIComponentGrid/RTKUIComponentGrid.tsx @@ -0,0 +1,502 @@ +import { useState, useMemo } from "react"; +import RTKUIComponent from "../RTKUIComponent/RTKUIComponent"; + +const componentGalleryImageModules = import.meta.glob( + "../../../assets/images/realtime/realtimekit/web/components-gallery/*.svg", + { eager: true }, +); + +const componentGalleryImageSrcByFileName = Object.fromEntries( + Object.entries(componentGalleryImageModules).map(([path, mod]) => { + const fileName = path.split("/").pop() as string; + const defaultExport = (mod as any).default; + const src = defaultExport?.src ?? defaultExport; + return [fileName, src]; + }), +) as Record; + +const imageSrc = (fileName: string) => + componentGalleryImageSrcByFileName[fileName]; + +const RTKUIComponentGrid = () => { + const [searchTerm, setSearchTerm] = useState(""); + const basicComponents = [ + { + id: "rtk-avatar", + name: "Avatar", + imagePath: imageSrc("rtk-avatar.svg"), + componentName: "rtk-avatar", + tags: ["participant", "tile", "grid"], + }, + { + id: "rtk-audio-visualizer", + name: "Audio Visualizer", + imagePath: imageSrc("rtk-audio-visualizer.svg"), + componentName: "rtk-audio-visualizer", + tags: ["participant", "audio", "visualizer", "grid"], + }, + { + id: "rtk-button", + name: "Button", + imagePath: imageSrc("rtk-button.svg"), + componentName: "rtk-button", + tags: ["button", "controlbar", "controlbar-button"], + }, + { + id: "rtk-clock", + name: "Clock", + imagePath: imageSrc("rtk-clock.svg"), + componentName: "rtk-clock", + tags: ["clock", "header", "sidebar"], + }, + { + id: "rtk-header", + name: "Header", + imagePath: imageSrc("rtk-header.svg"), + componentName: "rtk-header", + tags: ["header", "sidebar"], + }, + { + id: "rtk-logo", + name: "Logo", + imagePath: imageSrc("rtk-logo.svg"), + componentName: "rtk-logo", + tags: ["logo", "header", "sidebar"], + }, + { + id: "rtk-meeting-title", + name: "Meeting Title", + imagePath: imageSrc("rtk-meeting-title.svg"), + componentName: "rtk-meeting-title", + tags: ["meeting-title", "header", "sidebar"], + }, + { + id: "rtk-recording-indicator", + name: "Recording Indicator", + imagePath: imageSrc("rtk-recording-indicator.svg"), + componentName: "rtk-recording-indicator", + tags: ["recording", "indicator", "header", "sidebar", "controlbar"], + }, + { + id: "rtk-spinner", + name: "Spinner", + imagePath: imageSrc("rtk-spinner.svg"), + componentName: "rtk-spinner", + tags: ["spinner", "controlbar", "controlbar-button"], + }, + { + id: "rtk-switch", + name: "Switch", + imagePath: imageSrc("rtk-switch.svg"), + componentName: "rtk-switch", + tags: ["switch", "controlbar", "button"], + }, + { + id: "rtk-tooltip", + name: "Tooltip", + imagePath: imageSrc("rtk-tooltip.svg"), + componentName: "rtk-tooltip", + tags: ["tooltip", "controlbar", "button"], + }, + ]; + const uiComponents = [ + { + id: "rtk-controlbar", + name: "Control Bar", + imagePath: imageSrc("rtk-controlbar.svg"), + componentName: "rtk-controlbar", + tags: ["controlbar", "button"], + }, + { + id: "rtk-controlbar-button", + name: "Control Bar Button", + imagePath: imageSrc("rtk-controlbar-button.svg"), + componentName: "rtk-controlbar-button", + tags: ["controlbar", "button"], + }, + { + id: "rtk-dialog", + name: "Dialog", + imagePath: imageSrc("rtk-dialog.svg"), + componentName: "rtk-dialog", + tags: ["dialog", "modal", "popup"], + }, + { + id: "rtk-emoji-picker", + name: "Emoji Picker", + imagePath: imageSrc("rtk-emoji-picker.svg"), + componentName: "rtk-emoji-picker", + tags: ["emoji-picker", "sidebar", "chat", "message"], + }, + { + id: "rtk-grid-pagination", + name: "Grid Pagination", + imagePath: imageSrc("rtk-grid-pagination.svg"), + componentName: "rtk-grid-pagination", + tags: ["pagination", "grid", "participant", "tile", "header"], + }, + { + id: "rtk-menu", + name: "Menu", + imagePath: imageSrc("rtk-menu.svg"), + componentName: "rtk-menu", + tags: ["menu", "sidebar", "controlbar", "button"], + }, + { + id: "rtk-name-tag", + name: "Name Tag", + imagePath: imageSrc("rtk-name-tag.svg"), + componentName: "rtk-name-tag", + tags: ["name-tag", "participant", "tile", "grid"], + }, + { + id: "rtk-notification", + name: "Notification", + imagePath: imageSrc("rtk-notification.svg"), + componentName: "rtk-notification", + tags: ["notification", "sidebar", "popup", "chat"], + }, + { + id: "rtk-participant-count", + name: "Participant Count", + imagePath: imageSrc("rtk-participant-count.svg"), + componentName: "rtk-participant-count", + tags: ["participant-count", "header", "sidebar"], + }, + { + id: "rtk-participant-tile", + name: "Participant Tile", + imagePath: imageSrc("rtk-participant-tile.svg"), + componentName: "rtk-participant-tile", + tags: ["participant-tile", "participant", "tile", "grid"], + }, + { + id: "rtk-plugin-main", + name: "Plugin Main View", + imagePath: imageSrc("rtk-plugin-main.svg"), + componentName: "rtk-plugin-main", + tags: ["plugin-main", "plugin", "sidebar", "controlbar", "button"], + }, + ]; + const compositeComponents = [ + { + id: "rtk-chat", + name: "Chat", + imagePath: imageSrc("rtk-chat.svg"), + componentName: "rtk-chat", + tags: ["chat", "message", "sidebar"], + }, + { + id: "rtk-grid", + name: "Grid", + imagePath: imageSrc("rtk-grid.svg"), + componentName: "rtk-grid", + tags: ["grid", "participant", "tile", "layout"], + }, + { + id: "rtk-image-viewer", + name: "Image Viewer", + imagePath: imageSrc("rtk-image-viewer.svg"), + componentName: "rtk-image-viewer", + tags: ["image-viewer", "media", "chat", "sidebar"], + }, + { + id: "rtk-leave-meeting", + name: "Leave Meeting", + imagePath: imageSrc("rtk-leave-meeting.svg"), + componentName: "rtk-leave-meeting", + tags: ["leave", "dialog", "modal", "controlbar", "button", "end"], + }, + { + id: "rtk-mixed-grid", + name: "Mixed Grid", + imagePath: imageSrc("rtk-mixed-grid.svg"), + componentName: "rtk-mixed-grid", + tags: ["mixed", "grid", "participant", "tile", "layout"], + }, + { + id: "rtk-participants", + name: "Participants", + imagePath: imageSrc("rtk-participants.svg"), + componentName: "rtk-participants", + tags: ["participants", "sidebar", "list", "participant", "tile"], + }, + { + id: "rtk-participants-audio", + name: "Participants Audio", + imagePath: imageSrc("rtk-participants-audio.svg"), + componentName: "rtk-participants-audio", + tags: ["participants-audio", "audio", "sidebar", "participant", "list"], + }, + { + id: "rtk-plugins", + name: "Plugins", + imagePath: imageSrc("rtk-plugins.svg"), + componentName: "rtk-plugins", + tags: ["plugins", "sidebar", "list", "plugin"], + }, + { + id: "rtk-polls", + name: "Polls", + imagePath: imageSrc("rtk-polls.svg"), + componentName: "rtk-polls", + tags: ["polls", "sidebar", "voting", "interactive"], + }, + { + id: "rtk-screenshare-view", + name: "Screenshare View", + imagePath: imageSrc("rtk-screenshare-view.svg"), + componentName: "rtk-screenshare-view", + tags: ["screenshare-view", "screenshare", "media", "grid"], + }, + { + id: "rtk-settings", + name: "Settings", + imagePath: imageSrc("rtk-settings.svg"), + componentName: "rtk-settings", + tags: [ + "settings", + "sidebar", + "configuration", + "preferences", + "dialog", + "modal", + ], + }, + { + id: "rtk-settings-audio", + name: "Settings Audio", + imagePath: imageSrc("rtk-settings-audio.svg"), + componentName: "rtk-settings-audio", + tags: [ + "settings-audio", + "audio", + "settings", + "sidebar", + "configuration", + "dialog", + "modal", + ], + }, + { + id: "rtk-settings-video", + name: "Settings Video", + imagePath: imageSrc("rtk-settings-video.svg"), + componentName: "rtk-settings-video", + tags: [ + "settings-video", + "video", + "settings", + "sidebar", + "configuration", + "dialog", + "modal", + ], + }, + { + id: "rtk-sidebar", + name: "Sidebar", + imagePath: imageSrc("rtk-sidebar.svg"), + componentName: "rtk-sidebar", + tags: ["sidebar", "layout", "navigation", "panel"], + }, + { + id: "rtk-simple-grid", + name: "Simple Grid", + imagePath: imageSrc("rtk-simple-grid.svg"), + componentName: "rtk-simple-grid", + tags: ["simple", "grid", "participant", "tile", "layout", "basic"], + }, + { + id: "rtk-spotlight-grid", + name: "Spotlight Grid", + imagePath: imageSrc("rtk-spotlight-grid.svg"), + componentName: "rtk-spotlight-grid", + tags: ["spotlight", "grid", "participant", "tile", "layout", "pinned"], + }, + ]; + const screenComponents = [ + { + id: "rtk-ended-screen", + name: "Ended Screen", + imagePath: imageSrc("rtk-ended-screen.svg"), + componentName: "rtk-ended-screen", + tags: ["ended", "screen", "meeting", "end", "leave"], + }, + { + id: "rtk-idle-screen", + name: "Idle Screen", + imagePath: imageSrc("rtk-idle-screen.svg"), + componentName: "rtk-idle-screen", + tags: ["idle", "screen", "waiting", "lobby", "standby"], + }, + { + id: "rtk-meeting", + name: "Meeting Screen", + imagePath: imageSrc("rtk-meeting.svg"), + componentName: "rtk-meeting", + tags: ["meeting", "screen", "main", "active"], + }, + { + id: "rtk-setup-screen", + name: "Setup Screen", + imagePath: imageSrc("rtk-setup-screen.svg"), + componentName: "rtk-setup-screen", + tags: ["setup", "screen", "configuration", "preview"], + }, + ]; + + // Filter function to search through components + const filterComponents = (components: typeof basicComponents) => { + if (!searchTerm.trim()) return components; + + const lowercaseSearch = searchTerm.toLowerCase(); + return components.filter((component) => { + // Search in name + if (component.name.toLowerCase().includes(lowercaseSearch)) return true; + // Search in component name + if (component.componentName.toLowerCase().includes(lowercaseSearch)) + return true; + // Search in tags + if ( + component.tags.some((tag) => + tag.toLowerCase().includes(lowercaseSearch), + ) + ) + return true; + return false; + }); + }; + + // Filtered component arrays + const filteredBasicComponents = useMemo( + () => filterComponents(basicComponents), + [searchTerm], + ); + const filteredUiComponents = useMemo( + () => filterComponents(uiComponents), + [searchTerm], + ); + const filteredCompositeComponents = useMemo( + () => filterComponents(compositeComponents), + [searchTerm], + ); + const filteredScreenComponents = useMemo( + () => filterComponents(screenComponents), + [searchTerm], + ); + + return ( +
+

Component Gallery

+

+ Search through the comoponent gallery for the component you need. +

+ setSearchTerm(e.target.value)} + /> + + {/* Show no results message if search term exists but no components found */} + {searchTerm.trim() && + filteredBasicComponents.length === 0 && + filteredUiComponents.length === 0 && + filteredCompositeComponents.length === 0 && + filteredScreenComponents.length === 0 && ( +
+

+ No components found for "{searchTerm}" +

+

+ Try searching for terms like "grid", "chat", "button", or + "settings" +

+
+ )} + + {/* Basic Components */} + {filteredBasicComponents.length > 0 && ( + <> +

Basic Components

+

Small, reusable building blocks for your UI.

+
+ {filteredBasicComponents.map((component) => ( + + ))} +
+ + )} + + {/* UI Components */} + {filteredUiComponents.length > 0 && ( + <> +

UI Components

+

Interactive controls and interface elements.

+
+ {filteredUiComponents.map((component) => ( + + ))} +
+ + )} + + {/* Composite Components */} + {filteredCompositeComponents.length > 0 && ( + <> +

Composite Components

+

+ Complete, feature-rich components combining multiple elements. +

+
+ {filteredCompositeComponents.map((component) => ( + + ))} +
+ + )} + + {/* Screen Components */} + {filteredScreenComponents.length > 0 && ( + <> +

Screen Components

+

+ Full-screen views for different meeting states. +

+
+ {filteredScreenComponents.map((component) => ( + + ))} +
+ + )} +
+ ); +}; + +export default RTKUIComponentGrid; diff --git a/src/content/docs/realtime/realtimekit/ui-kit/component-library.mdx b/src/content/docs/realtime/realtimekit/ui-kit/component-library.mdx index 635b145159df3f..4c1a7df2a0cd28 100644 --- a/src/content/docs/realtime/realtimekit/ui-kit/component-library.mdx +++ b/src/content/docs/realtime/realtimekit/ui-kit/component-library.mdx @@ -6,13 +6,14 @@ sidebar: order: 3 --- -import { Tabs, TabItem } from "~/components"; - - - +import RTKSDKSelector from "~/components/realtimekit/RTKSDKSelector/RTKSDKSelector.astro"; +import RTKUIComponent from "~/components/realtimekit/RTKUIComponent/RTKUIComponent.astro"; +import RTKUIComponentGrid from "~/components/realtimekit/RTKUIComponentGrid/RTKUIComponentGrid.astro"; The UI Kit components library provides a comprehensive set of pre-built, customizable components that you can use to build your own custom meeting interface. + + :::note All UI Kit components are built on top of Web Components, regardless of which framework (React/Angular) you use. They render as Web Components in the browser DOM. @@ -24,271 +25,4 @@ All UI Kit components are built on top of Web Components, regardless of which fr React and Angular components are wrappers around the same underlying Web Components, so functionality is identical across all frameworks. ::: -## Basic Components - -Small, reusable building blocks for your UI. - -
- -
- ![Audio - Visualizer](~/assets/images/realtime/realtimekit/web/components-gallery/rtk-audio-visualizer.svg) - `rtk-audio-visualizer` -
- -
- ![Avatar](~/assets/images/realtime/realtimekit/web/components-gallery/rtk-avatar.svg) - `rtk-avatar` -
- -
- ![Button](~/assets/images/realtime/realtimekit/web/components-gallery/rtk-button.svg) - `rtk-button` -
- -
- ![Clock](~/assets/images/realtime/realtimekit/web/components-gallery/rtk-clock.svg) - `rtk-clock` -
- -
- ![Header](~/assets/images/realtime/realtimekit/web/components-gallery/rtk-header.svg) - `rtk-header` -
- - - -
- ![Meeting - Title](~/assets/images/realtime/realtimekit/web/components-gallery/rtk-meeting-title.svg) - `rtk-meeting-title` -
- -
- ![Recording - Indicator](~/assets/images/realtime/realtimekit/web/components-gallery/rtk-recording-indicator.svg) - `rtk-recording-indicator` -
- -
- ![Spinner](~/assets/images/realtime/realtimekit/web/components-gallery/rtk-spinner.svg) - `rtk-spinner` -
- -
- ![Switch](~/assets/images/realtime/realtimekit/web/components-gallery/rtk-switch.svg) - `rtk-switch` -
- -
- ![Tooltip](~/assets/images/realtime/realtimekit/web/components-gallery/rtk-tooltip.svg) - `rtk-tooltip` -
- -
- -## UI Components - -Interactive controls and interface elements. - -
- -
- ![Control - Bar](~/assets/images/realtime/realtimekit/web/components-gallery/rtk-controlbar.svg) - `rtk-controlbar` -
- -
- ![Control Bar - Button](~/assets/images/realtime/realtimekit/web/components-gallery/rtk-controlbar-button.svg) - `rtk-controlbar-button` -
- -
- ![Dialog](~/assets/images/realtime/realtimekit/web/components-gallery/rtk-dialog.svg) - `rtk-dialog` -
- -
- ![Emoji - Picker](~/assets/images/realtime/realtimekit/web/components-gallery/rtk-emoji-picker.svg) - `rtk-emoji-picker` -
- -
- ![Grid - Pagination](~/assets/images/realtime/realtimekit/web/components-gallery/rtk-grid-pagination.svg) - `rtk-grid-pagination` -
- -
- ![Menu](~/assets/images/realtime/realtimekit/web/components-gallery/rtk-menu.svg) - `rtk-menu` -
- -
- ![Name - Tag](~/assets/images/realtime/realtimekit/web/components-gallery/rtk-name-tag.svg) - `rtk-name-tag` -
- -
- ![Notification](~/assets/images/realtime/realtimekit/web/components-gallery/rtk-notification.svg) - `rtk-notification` -
- -
- ![Participant - Count](~/assets/images/realtime/realtimekit/web/components-gallery/rtk-participant-count.svg) - `rtk-participant-count` -
- -
- ![Participant - Tile](~/assets/images/realtime/realtimekit/web/components-gallery/rtk-participant-tile.svg) - `rtk-participant-tile` -
- -
- ![Plugin Main - View](~/assets/images/realtime/realtimekit/web/components-gallery/rtk-plugin-main.svg) - `rtk-plugin-main` -
- -
- -## Composite Components - -Complete, feature-rich components combining multiple elements. - -
- -
- ![Chat](~/assets/images/realtime/realtimekit/web/components-gallery/rtk-chat.svg) - `rtk-chat` -
- -
- ![Grid](~/assets/images/realtime/realtimekit/web/components-gallery/rtk-grid.svg) - `rtk-grid` -
- -
- ![Image - Viewer](~/assets/images/realtime/realtimekit/web/components-gallery/rtk-image-viewer.svg) - `rtk-image-viewer` -
- -
- ![Leave - Meeting](~/assets/images/realtime/realtimekit/web/components-gallery/rtk-leave-meeting.svg) - `rtk-leave-meeting` -
- -
- ![Mixed - Grid](~/assets/images/realtime/realtimekit/web/components-gallery/rtk-mixed-grid.svg) - `rtk-mixed-grid` -
- -
- ![Participants](~/assets/images/realtime/realtimekit/web/components-gallery/rtk-participants.svg) - `rtk-participants` -
- -
- ![Participants - Audio](~/assets/images/realtime/realtimekit/web/components-gallery/rtk-participants-audio.svg) - `rtk-participants-audio` -
- -
- ![Plugins](~/assets/images/realtime/realtimekit/web/components-gallery/rtk-plugins.svg) - `rtk-plugins` -
- -
- ![Polls](~/assets/images/realtime/realtimekit/web/components-gallery/rtk-polls.svg) - `rtk-polls` -
- -
- ![Screenshare - View](~/assets/images/realtime/realtimekit/web/components-gallery/rtk-screenshare-view.svg) - `rtk-screenshare-view` -
- -
- ![Settings](~/assets/images/realtime/realtimekit/web/components-gallery/rtk-settings.svg) - `rtk-settings` -
- -
- ![Settings - Audio](~/assets/images/realtime/realtimekit/web/components-gallery/rtk-settings-audio.svg) - `rtk-settings-audio` -
- -
- ![Settings - Video](~/assets/images/realtime/realtimekit/web/components-gallery/rtk-settings-video.svg) - `rtk-settings-video` -
- -
- ![Sidebar](~/assets/images/realtime/realtimekit/web/components-gallery/rtk-sidebar.svg) - `rtk-sidebar` -
- -
- ![Simple - Grid](~/assets/images/realtime/realtimekit/web/components-gallery/rtk-simple-grid.svg) - `rtk-simple-grid` -
- -
- ![Spotlight - Grid](~/assets/images/realtime/realtimekit/web/components-gallery/rtk-spotlight-grid.svg) - `rtk-spotlight-grid` -
- -
- -## Screen Components - -Full-screen views for different meeting states. - -
- -
- ![Ended - Screen](~/assets/images/realtime/realtimekit/web/components-gallery/rtk-ended-screen.svg) - `rtk-ended-screen` -
- -
- ![Idle - Screen](~/assets/images/realtime/realtimekit/web/components-gallery/rtk-idle-screen.svg) - `rtk-idle-screen` -
- -
- ![Meeting - Screen](~/assets/images/realtime/realtimekit/web/components-gallery/rtk-meeting.svg) - `rtk-meeting` -
- -
- ![Setup - Screen](~/assets/images/realtime/realtimekit/web/components-gallery/rtk-setup-screen.svg) - `rtk-setup-screen` -
- -
- -
-
+