Skip to content

Commit

Permalink
feat: dynamic JSX interface inheritance (#71)
Browse files Browse the repository at this point in the history
- Added `ReactHTMLProps` utility type to dynamically handle React HTML element type definitions.
- Fixed incorrect type generation for some elements (e.g., `input`), ensuring appropriate attribute types are used.
  • Loading branch information
honeymaro authored Dec 5, 2024
1 parent 2d1036f commit 1072bc6
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 127 deletions.
115 changes: 0 additions & 115 deletions src/html.ts

This file was deleted.

14 changes: 6 additions & 8 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { type PluginCreator } from 'postcss'
import selectorParser = require('postcss-selector-parser')
import atImport = require('postcss-import')
import path = require('node:path')
const html = require('./html')
const key = require('./key')

declare module 'postcss-selector-parser' {
Expand All @@ -27,7 +26,11 @@ type Parsed = Record<
>

function render(parsed: Parsed): string {
let interfaceDefinitions = ''
let interfaceDefinitions = `type ReactHTMLProps<
Tag extends keyof React.ReactHTML
> = React.ReactHTML[Tag] extends React.DetailedHTMLFactory<infer Attributes, infer Element>
? React.DetailedHTMLProps<Attributes, Element>
: React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>\n\n`
const jsxElements: Record<string, string[]> = {}

// Normalize
Expand Down Expand Up @@ -101,12 +104,7 @@ function render(parsed: Parsed): string {

const attributeEntries = Object.entries(attributes)

let htmlElement = 'HTMLElement'
if (tag in html) {
htmlElement = html[tag as keyof typeof html]
}

let interfaceDefinition = `interface ${interfaceName} extends React.DetailedHTMLProps<React.HTMLAttributes<${htmlElement}>, ${htmlElement}> {\n`
let interfaceDefinition = `interface ${interfaceName} extends ReactHTMLProps<'${tag}'> {\n`

discriminatorAttributes.forEach((attr) => {
interfaceDefinition += ` '${attr}'?: never\n`
Expand Down
14 changes: 10 additions & 4 deletions test/mist.d.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,24 @@
interface Mist_button extends React.DetailedHTMLProps<React.HTMLAttributes<HTMLButtonElement>, HTMLButtonElement> {
type ReactHTMLProps<
Tag extends keyof React.ReactHTML
> = React.ReactHTML[Tag] extends React.DetailedHTMLFactory<infer Attributes, infer Element>
? React.DetailedHTMLProps<Attributes, Element>
: React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>

interface Mist_button extends ReactHTMLProps<'button'> {
'data-variant'?: 'primary' | 'secondary'
style?: { '--highlightColor'?: string } & React.CSSProperties
}

interface Mist_div extends React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement> {
interface Mist_div extends ReactHTMLProps<'div'> {
'data-component'?: never
}

interface Mist_div_data_component_card extends React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement> {
interface Mist_div_data_component_card extends ReactHTMLProps<'div'> {
'data-component': 'card'
'data-size'?: 'sm' | 'xl'
}

interface Mist_div_data_component_card_title extends React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement> {
interface Mist_div_data_component_card_title extends ReactHTMLProps<'div'> {
'data-component': 'card-title'
}

Expand Down

0 comments on commit 1072bc6

Please sign in to comment.