@@ -398,18 +398,44 @@ function kebabToCamelCase(str: string): string {
398398 return str . replace ( / - ( [ a - z ] ) / g, ( _ , letter ) => letter . toUpperCase ( ) ) ;
399399}
400400
401+ /**
402+ * Properties that can be either HTML attributes or CSS properties depending on context
403+ */
404+ const DUAL_PURPOSE_PROPERTIES = new Set ( [ 'border' , 'width' , 'height' ] ) ;
405+
406+ /**
407+ * Element types that should treat dual-purpose properties as HTML attributes
408+ */
409+ const HTML_ATTRIBUTE_ELEMENTS = new Set ( [ 'table' , 'img' , 'input' , 'canvas' ] ) ;
410+
401411/**
402412 * Converts framework-agnostic attributes to React props
403413 * Handles HTML attribute to React JSX attribute conversion and CSS properties
404414 */
405- function toReactProps (
406- attributes : Record < string , unknown >
415+ export function toReactProps (
416+ attributes : Record < string , unknown > ,
417+ elementType ?: string
407418) : Record < string , unknown > {
408419 const reactProps : Record < string , unknown > = { } ;
409420 const styleProps : Record < string , string > = { } ;
410421
411422 for ( const [ key , value ] of Object . entries ( attributes ) ) {
412- // Handle CSS properties - move them to style object
423+ // Handle dual-purpose properties based on element context
424+ if ( DUAL_PURPOSE_PROPERTIES . has ( key . toLowerCase ( ) ) ) {
425+ if ( elementType && HTML_ATTRIBUTE_ELEMENTS . has ( elementType ) ) {
426+ // Treat as HTML attribute for specific elements
427+ const reactKey = HTML_TO_REACT_ATTRS [ key . toLowerCase ( ) ] || key ;
428+ reactProps [ reactKey ] = value ;
429+ continue ;
430+ } else {
431+ // Treat as CSS property for other elements
432+ const camelKey = kebabToCamelCase ( key ) ;
433+ styleProps [ camelKey ] = String ( value ) ;
434+ continue ;
435+ }
436+ }
437+
438+ // Handle other CSS properties - move them to style object
413439 if ( CSS_PROPERTIES . has ( key . toLowerCase ( ) ) ) {
414440 const camelKey = kebabToCamelCase ( key ) ;
415441 styleProps [ camelKey ] = String ( value ) ;
@@ -480,8 +506,8 @@ export function createHtmlComponent<T extends keyof JSX.IntrinsicElements>(
480506 config : HtmlComponentConfig = { }
481507) : ElementRenderer {
482508 const Component : ElementRenderer = ( { children, attributes, element } ) => {
483- // Convert to React props and merge with config
484- const reactProps = toReactProps ( attributes || { } ) ;
509+ // Convert to React props and merge with config, passing element type for context
510+ const reactProps = toReactProps ( attributes || { } , tag as string ) ;
485511 const mergedProps = {
486512 ...reactProps ,
487513 ...config . attributes ,
@@ -515,7 +541,7 @@ export function createLinkComponent<T extends keyof JSX.IntrinsicElements>(
515541 element,
516542 } ) => {
517543 // Convert to React props and merge with config
518- const reactProps = toReactProps ( attributes || { } ) ;
544+ const reactProps = toReactProps ( attributes || { } , tag as string ) ;
519545
520546 // Type-safe access to link properties
521547 const linkProps = {
@@ -554,7 +580,7 @@ export function createImageComponent<T extends keyof JSX.IntrinsicElements>(
554580 element,
555581 } ) => {
556582 // Convert to React props and merge with config
557- const reactProps = toReactProps ( attributes || { } ) ;
583+ const reactProps = toReactProps ( attributes || { } , tag as string ) ;
558584
559585 // Type-safe access to image properties
560586 const imageProps = {
@@ -596,7 +622,7 @@ export function createTableComponent<T extends keyof JSX.IntrinsicElements>(
596622 element,
597623 } ) => {
598624 // Convert to React props and merge with config
599- const reactProps = toReactProps ( attributes || { } ) ;
625+ const reactProps = toReactProps ( attributes || { } , tag as string ) ;
600626
601627 const mergedProps = {
602628 ...reactProps ,
0 commit comments