diff --git a/src/vs/base/browser/dom.ts b/src/vs/base/browser/dom.ts index 2e8651879ef..4db47cd947a 100644 --- a/src/vs/base/browser/dom.ts +++ b/src/vs/base/browser/dom.ts @@ -1734,18 +1734,27 @@ export function computeClippingRect(elementOrRect: HTMLElement | DOMRectReadOnly return { top, right, bottom, left }; } -interface DomNodeAttributes { - role?: string; - ariaHidden?: boolean; - style?: StyleAttributes; -} +type HTMLElementAttributeKeys = Partial<{ [K in keyof T]: T[K] extends Function ? never : T[K] extends object ? HTMLElementAttributeKeys : T[K] }>; +type ElementAttributes = HTMLElementAttributeKeys & Record; +type RemoveHTMLElement = T extends HTMLElement ? never : T; +type UnionToIntersection = (U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never; +type ArrayToObj = UnionToIntersection>; -interface StyleAttributes { - height?: number | string; - width?: number | string; -} - -// +type TagToElement = T extends `.${string}` + ? HTMLDivElement + : T extends `#${string}` + ? HTMLDivElement + : T extends `${infer TStart}#${string}` + ? TStart extends keyof HTMLElementTagNameMap + ? HTMLElementTagNameMap[TStart] + : HTMLElement + : T extends `${infer TStart}.${string}` + ? TStart extends keyof HTMLElementTagNameMap + ? HTMLElementTagNameMap[TStart] + : HTMLElement + : T extends keyof HTMLElementTagNameMap + ? HTMLElementTagNameMap[T] + : HTMLElement; /** * A helper function to create nested dom nodes. @@ -1762,22 +1771,25 @@ interface StyleAttributes { * private readonly editor = createEditor(this.htmlElements.editor); * ``` */ +export function h( + tag: TTag +): (Record<'root', TagToElement>) extends infer Y ? { [TKey in keyof Y]: Y[TKey] } : never; export function h( tag: TTag, - attributes: { $: TId } & DomNodeAttributes + attributes: { $: TId } & Partial>> ): Record>; -export function h(tag: TTag, attributes: DomNodeAttributes): Record<'root', TagToElement>; export function h)[]>( tag: TTag, children: T ): (ArrayToObj & Record<'root', TagToElement>) extends infer Y ? { [TKey in keyof Y]: Y[TKey] } : never; +export function h(tag: TTag, attributes: Partial>>): Record<'root', TagToElement>; export function h)[]>( tag: TTag, - attributes: { $: TId } & DomNodeAttributes, + attributes: { $: TId } & Partial>>, children: T ): (ArrayToObj & Record>) extends infer Y ? { [TKey in keyof Y]: Y[TKey] } : never; -export function h(tag: string, ...args: [] | [attributes: { $: string } & DomNodeAttributes | Record, children?: any[]] | [children: any[]]): Record { - let attributes: { $?: string } & DomNodeAttributes; +export function h(tag: string, ...args: [] | [attributes: { $: string } & Partial> | Record, children?: any[]] | [children: any[]]): Record { + let attributes: { $?: string } & Partial>; let children: (Record | HTMLElement)[] | undefined; if (Array.isArray(args[0])) { @@ -1845,24 +1857,3 @@ export function h(tag: string, ...args: [] | [attributes: { $: string } & DomNod function camelCaseToHyphenCase(str: string) { return str.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase(); } - -type RemoveHTMLElement = T extends HTMLElement ? never : T; - -type ArrayToObj = UnionToIntersection>; - - -type UnionToIntersection = (U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never; - -type HTMLElementsByTagName = { - div: HTMLDivElement; - span: HTMLSpanElement; - a: HTMLAnchorElement; -}; - -type TagToElement = T extends `${infer TStart}.${string}` - ? TStart extends keyof HTMLElementsByTagName - ? HTMLElementsByTagName[TStart] - : HTMLElement - : T extends keyof HTMLElementsByTagName - ? HTMLElementsByTagName[T] - : HTMLElement; diff --git a/src/vs/workbench/contrib/mergeEditor/browser/view/editorGutter.ts b/src/vs/workbench/contrib/mergeEditor/browser/view/editorGutter.ts index 7289cc61637..6b7f4670cb0 100644 --- a/src/vs/workbench/contrib/mergeEditor/browser/view/editorGutter.ts +++ b/src/vs/workbench/contrib/mergeEditor/browser/view/editorGutter.ts @@ -31,7 +31,7 @@ export class EditorGutter extends D super(); this._domNode.className = 'gutter monaco-editor'; const scrollDecoration = this._domNode.appendChild( - h('div.scroll-decoration', { role: 'presentation', ariaHidden: true, style: { width: '100%' } }) + h('div.scroll-decoration', { role: 'presentation', ariaHidden: 'true', style: { width: '100%' } }) .root );