22
33import { Select , Tooltip , useThemeMode } from "flowbite-react" ;
44import type { ComponentProps , PropsWithChildren } from "react" ;
5- import { useEffect , useState } from "react" ;
5+ import { useEffect , useRef , useState } from "react" ;
66import type { IconType } from "react-icons" ;
77import { FaCopy } from "react-icons/fa" ;
88import { HiMoon , HiSun } from "react-icons/hi" ;
@@ -12,10 +12,18 @@ import { TfiMobile } from "react-icons/tfi";
1212import { twMerge } from "tailwind-merge" ;
1313import { CodeHighlight , type Language } from "./code-highlight" ;
1414
15+ type IFrameData = number | IFrameOptions ;
16+
17+ interface IFrameOptions {
18+ height : number ;
19+ noPadding ?: boolean ;
20+ }
21+
1522interface BaseCodeData < T extends "single" | "variant" > {
1623 type : T ;
1724 githubSlug : string ;
1825 component : React . ReactNode ;
26+ iframe ?: IFrameData ;
1927}
2028
2129interface VariantCodeData < V extends Variant > extends BaseCodeData < "variant" > {
@@ -135,8 +143,8 @@ export function CodeDemo({ data }: CodeDemoProps) {
135143 </ div >
136144 </ div >
137145 </ div >
138- < CodePreview view = { view } isRTL = { isRTL } isDarkMode = { isDarkMode } >
139- { data . component }
146+ < CodePreview view = { view } isRTL = { isRTL } isDarkMode = { isDarkMode } iframe = { data . iframe } >
147+ { data . iframe ? < IFrame data = { data } isRTL = { isRTL } isDarkMode = { isDarkMode } /> : data . component }
140148 </ CodePreview >
141149 < div className = "code-syntax-wrapper" >
142150 < div
@@ -173,6 +181,40 @@ export function CodeDemo({ data }: CodeDemoProps) {
173181 ) ;
174182}
175183
184+ function IFrame ( { data, isRTL, isDarkMode } : { data : CodeData ; isRTL : boolean ; isDarkMode : boolean | null } ) {
185+ const ref = useRef < HTMLIFrameElement > ( null ) ;
186+
187+ useEffect ( ( ) => {
188+ const document = ref . current ?. contentDocument ;
189+
190+ if ( ! document ) return ;
191+
192+ document . documentElement . setAttribute ( "dir" , isRTL ? "rtl" : "ltr" ) ;
193+
194+ if ( isDarkMode ) {
195+ document . documentElement . classList . add ( "dark" ) ;
196+ } else {
197+ document . documentElement . classList . remove ( "dark" ) ;
198+ }
199+ } , [ isRTL , isDarkMode ] ) ;
200+
201+ function getSrc ( ) {
202+ const base = "/examples" ;
203+ const target = data . githubSlug . split ( "/" ) [ 1 ] . replace ( ".tsx" , "" ) ;
204+ const noPadding = typeof data . iframe === "object" && data . iframe . noPadding ? `?noPadding` : "" ;
205+
206+ return `${ base } /${ target } ${ noPadding } ` ;
207+ }
208+
209+ function getHeight ( ) : number {
210+ const payload = data . iframe ! ;
211+
212+ return typeof payload === "number" ? payload : payload . height ;
213+ }
214+
215+ return < iframe ref = { ref } src = { getSrc ( ) } height = { getHeight ( ) } className = "w-full" /> ;
216+ }
217+
176218function Tabs ( { tabIndex, items, onSelect } : { tabIndex : number ; items : CodeItem [ ] ; onSelect ( index : number ) : void } ) {
177219 return (
178220 < ul className = "flex flex-1 text-center text-sm font-medium text-gray-500 dark:text-gray-400" >
@@ -198,20 +240,22 @@ function CodePreview({
198240 view,
199241 isRTL,
200242 isDarkMode,
243+ iframe,
201244 children,
202- } : PropsWithChildren < { view : View ; isRTL : boolean ; isDarkMode : boolean | null } > ) {
245+ } : PropsWithChildren < { view : View ; isRTL : boolean ; isDarkMode : boolean | null ; iframe ?: IFrameData } > ) {
203246 return (
204247 < div
205248 { ...( isRTL && { dir : "rtl" } ) }
206249 className = { twMerge ( "code-preview-wrapper" , isDarkMode !== null && ( isDarkMode ? "dark" : "light" ) ) }
207250 >
208- < div className = "code-preview flex border-x border-gray-200 bg-white bg-gradient-to-r p-0 dark:border-gray-600 dark:bg-gray-900" >
251+ < div className = "flex border-x border-gray-200 bg-white bg-gradient-to-r p-0 dark:border-gray-600 dark:bg-gray-900" >
209252 < div className = "code-responsive-wrapper w-full" >
210253 < div
211254 className = { twMerge (
212- "mx-auto w-full bg-white bg-gradient-to-r p-5 dark:bg-gray-900" ,
255+ "mx-auto w-full bg-white bg-gradient-to-r dark:bg-gray-900" ,
213256 view === "tablet" && "max-w-lg" ,
214257 view === "mobile" && "max-w-sm" ,
258+ ! iframe && "p-5" ,
215259 ) }
216260 >
217261 { children }
0 commit comments