diff --git a/package.json b/package.json index 6e3d2ff..79c93b9 100644 --- a/package.json +++ b/package.json @@ -6,12 +6,13 @@ "main": "dist/vhtml.js", "minified:main": "dist/vhtml.min.js", "jsnext:main": "src/vhtml.js", + "types": "src/vhtml.d.ts", "scripts": { "build": "npm-run-all transpile minify size", "transpile": "rollup -c rollup.config.js", "minify": "uglifyjs $npm_package_main -cm -o $npm_package_minified_main -p relative --in-source-map ${npm_package_main}.map --source-map ${npm_package_minified_main}.map", "size": "echo \"gzip size: $(gzip-size $npm_package_minified_main | pretty-bytes)\"", - "test": "eslint {src,test} && mocha --compilers js:babel-register test/**/*.js", + "test": "tsd && eslint {src,test} && mocha --compilers js:babel-register test/**/*.js", "prepublish": "npm-run-all build test", "release": "npm run -s build && git commit -am $npm_package_version && git tag $npm_package_version && git push && git push --tags && npm publish" }, @@ -31,7 +32,10 @@ ] }, "files": [ - "src", + "src/vhtml.js", + "src/empty-tags.js", + "src/jsx.d.ts", + "src/vhtml.d.ts", "dist" ], "keywords": [ @@ -68,6 +72,8 @@ "rollup": "^0.36.3", "rollup-plugin-babel": "^2.4.0", "rollup-plugin-es3": "^1.0.3", + "tsd": "^0.11.0", + "typescript": "^3.9.5", "uglify-js": "^2.6.2" } } diff --git a/rollup.config.js b/rollup.config.js index 3a7799d..124b6a7 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -10,7 +10,7 @@ export default { dest: pkg.main, sourceMap: path.resolve(pkg.main), moduleName: pkg.amdName, - exports: 'default', + exports: ['Fragmant', 'default'], format: 'umd', plugins: [ babel({ diff --git a/src/jsx.d.ts b/src/jsx.d.ts new file mode 100644 index 0000000..8d2055a --- /dev/null +++ b/src/jsx.d.ts @@ -0,0 +1,926 @@ +type Defaultize = + // Distribute over unions + Props extends any // Make any properties included in Default optional + ? Partial>> & + // Include the remaining properties from Props + Pick> + : never; + +export namespace JSXInternal { + type LibraryManagedAttributes = Component extends { + defaultProps: infer Defaults; + } + ? Defaultize + : Props; + + interface IntrinsicAttributes { + key?: any; + } + + type Element = string + + interface ElementAttributesProperty { + props: any; + } + + interface ElementChildrenAttribute { + children: any; + } + + interface SVGAttributes + extends HTMLAttributes { + accentHeight?: number | string; + accumulate?: 'none' | 'sum'; + additive?: 'replace' | 'sum'; + alignmentBaseline?: + | 'auto' + | 'baseline' + | 'before-edge' + | 'text-before-edge' + | 'middle' + | 'central' + | 'after-edge' + | 'text-after-edge' + | 'ideographic' + | 'alphabetic' + | 'hanging' + | 'mathematical' + | 'inherit'; + allowReorder?: 'no' | 'yes'; + alphabetic?: number | string; + amplitude?: number | string; + arabicForm?: 'initial' | 'medial' | 'terminal' | 'isolated'; + ascent?: number | string; + attributeName?: string; + attributeType?: string; + autoReverse?: number | string; + azimuth?: number | string; + baseFrequency?: number | string; + baselineShift?: number | string; + baseProfile?: number | string; + bbox?: number | string; + begin?: number | string; + bias?: number | string; + by?: number | string; + calcMode?: number | string; + capHeight?: number | string; + clip?: number | string; + clipPath?: string; + clipPathUnits?: number | string; + clipRule?: number | string; + colorInterpolation?: number | string; + colorInterpolationFilters?: 'auto' | 'sRGB' | 'linearRGB' | 'inherit'; + colorProfile?: number | string; + colorRendering?: number | string; + contentScriptType?: number | string; + contentStyleType?: number | string; + cursor?: number | string; + cx?: number | string; + cy?: number | string; + d?: string; + decelerate?: number | string; + descent?: number | string; + diffuseConstant?: number | string; + direction?: number | string; + display?: number | string; + divisor?: number | string; + dominantBaseline?: number | string; + dur?: number | string; + dx?: number | string; + dy?: number | string; + edgeMode?: number | string; + elevation?: number | string; + enableBackground?: number | string; + end?: number | string; + exponent?: number | string; + externalResourcesRequired?: number | string; + fill?: string; + fillOpacity?: number | string; + fillRule?: 'nonzero' | 'evenodd' | 'inherit'; + filter?: string; + filterRes?: number | string; + filterUnits?: number | string; + floodColor?: number | string; + floodOpacity?: number | string; + focusable?: number | string; + fontFamily?: string; + fontSize?: number | string; + fontSizeAdjust?: number | string; + fontStretch?: number | string; + fontStyle?: number | string; + fontVariant?: number | string; + fontWeight?: number | string; + format?: number | string; + from?: number | string; + fx?: number | string; + fy?: number | string; + g1?: number | string; + g2?: number | string; + glyphName?: number | string; + glyphOrientationHorizontal?: number | string; + glyphOrientationVertical?: number | string; + glyphRef?: number | string; + gradientTransform?: string; + gradientUnits?: string; + hanging?: number | string; + horizAdvX?: number | string; + horizOriginX?: number | string; + ideographic?: number | string; + imageRendering?: number | string; + in2?: number | string; + in?: string; + intercept?: number | string; + k1?: number | string; + k2?: number | string; + k3?: number | string; + k4?: number | string; + k?: number | string; + kernelMatrix?: number | string; + kernelUnitLength?: number | string; + kerning?: number | string; + keyPoints?: number | string; + keySplines?: number | string; + keyTimes?: number | string; + lengthAdjust?: number | string; + letterSpacing?: number | string; + lightingColor?: number | string; + limitingConeAngle?: number | string; + local?: number | string; + markerEnd?: string; + markerHeight?: number | string; + markerMid?: string; + markerStart?: string; + markerUnits?: number | string; + markerWidth?: number | string; + mask?: string; + maskContentUnits?: number | string; + maskUnits?: number | string; + mathematical?: number | string; + mode?: number | string; + numOctaves?: number | string; + offset?: number | string; + opacity?: number | string; + operator?: number | string; + order?: number | string; + orient?: number | string; + orientation?: number | string; + origin?: number | string; + overflow?: number | string; + overlinePosition?: number | string; + overlineThickness?: number | string; + paintOrder?: number | string; + panose1?: number | string; + pathLength?: number | string; + patternContentUnits?: string; + patternTransform?: number | string; + patternUnits?: string; + pointerEvents?: number | string; + points?: string; + pointsAtX?: number | string; + pointsAtY?: number | string; + pointsAtZ?: number | string; + preserveAlpha?: number | string; + preserveAspectRatio?: string; + primitiveUnits?: number | string; + r?: number | string; + radius?: number | string; + refX?: number | string; + refY?: number | string; + renderingIntent?: number | string; + repeatCount?: number | string; + repeatDur?: number | string; + requiredExtensions?: number | string; + requiredFeatures?: number | string; + restart?: number | string; + result?: string; + rotate?: number | string; + rx?: number | string; + ry?: number | string; + scale?: number | string; + seed?: number | string; + shapeRendering?: number | string; + slope?: number | string; + spacing?: number | string; + specularConstant?: number | string; + specularExponent?: number | string; + speed?: number | string; + spreadMethod?: string; + startOffset?: number | string; + stdDeviation?: number | string; + stemh?: number | string; + stemv?: number | string; + stitchTiles?: number | string; + stopColor?: string; + stopOpacity?: number | string; + strikethroughPosition?: number | string; + strikethroughThickness?: number | string; + string?: number | string; + stroke?: string; + strokeDasharray?: string | number; + strokeDashoffset?: string | number; + strokeLinecap?: 'butt' | 'round' | 'square' | 'inherit'; + strokeLinejoin?: 'miter' | 'round' | 'bevel' | 'inherit'; + strokeMiterlimit?: string; + strokeOpacity?: number | string; + strokeWidth?: number | string; + surfaceScale?: number | string; + systemLanguage?: number | string; + tableValues?: number | string; + targetX?: number | string; + targetY?: number | string; + textAnchor?: string; + textDecoration?: number | string; + textLength?: number | string; + textRendering?: number | string; + to?: number | string; + transform?: string; + u1?: number | string; + u2?: number | string; + underlinePosition?: number | string; + underlineThickness?: number | string; + unicode?: number | string; + unicodeBidi?: number | string; + unicodeRange?: number | string; + unitsPerEm?: number | string; + vAlphabetic?: number | string; + values?: string; + vectorEffect?: number | string; + version?: string; + vertAdvY?: number | string; + vertOriginX?: number | string; + vertOriginY?: number | string; + vHanging?: number | string; + vIdeographic?: number | string; + viewBox?: string; + viewTarget?: number | string; + visibility?: number | string; + vMathematical?: number | string; + widths?: number | string; + wordSpacing?: number | string; + writingMode?: number | string; + x1?: number | string; + x2?: number | string; + x?: number | string; + xChannelSelector?: string; + xHeight?: number | string; + xlinkActuate?: string; + xlinkArcrole?: string; + xlinkHref?: string; + xlinkRole?: string; + xlinkShow?: string; + xlinkTitle?: string; + xlinkType?: string; + xmlBase?: string; + xmlLang?: string; + xmlns?: string; + xmlnsXlink?: string; + xmlSpace?: string; + y1?: number | string; + y2?: number | string; + y?: number | string; + yChannelSelector?: string; + z?: number | string; + zoomAndPan?: string; + } + + interface PathAttributes { + d: string; + } + + type TargetedEvent< + Target extends EventTarget = EventTarget, + TypedEvent extends Event = Event + > = Omit & { + readonly currentTarget: Target; + }; + + type TargetedAnimationEvent = TargetedEvent< + Target, + AnimationEvent + >; + type TargetedClipboardEvent = TargetedEvent< + Target, + ClipboardEvent + >; + type TargetedCompositionEvent = TargetedEvent< + Target, + CompositionEvent + >; + type TargetedDragEvent = TargetedEvent< + Target, + DragEvent + >; + type TargetedFocusEvent = TargetedEvent< + Target, + FocusEvent + >; + type TargetedKeyboardEvent = TargetedEvent< + Target, + KeyboardEvent + >; + type TargetedMouseEvent = TargetedEvent< + Target, + MouseEvent + >; + type TargetedPointerEvent = TargetedEvent< + Target, + PointerEvent + >; + type TargetedTouchEvent = TargetedEvent< + Target, + TouchEvent + >; + type TargetedTransitionEvent = TargetedEvent< + Target, + TransitionEvent + >; + type TargetedUIEvent = TargetedEvent< + Target, + UIEvent + >; + type TargetedWheelEvent = TargetedEvent< + Target, + WheelEvent + >; + + interface EventHandler { + + /** + * The `this` keyword always points to the DOM element the event handler + * was invoked on. See: https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Event_handlers#Event_handlers_parameters_this_binding_and_the_return_value + */ + (this: E['currentTarget'], event: E): void; + } + + type AnimationEventHandler = EventHandler< + TargetedAnimationEvent + >; + type ClipboardEventHandler = EventHandler< + TargetedClipboardEvent + >; + type CompositionEventHandler = EventHandler< + TargetedCompositionEvent + >; + type DragEventHandler = EventHandler< + TargetedDragEvent + >; + type FocusEventHandler = EventHandler< + TargetedFocusEvent + >; + type GenericEventHandler = EventHandler< + TargetedEvent + >; + type KeyboardEventHandler = EventHandler< + TargetedKeyboardEvent + >; + type MouseEventHandler = EventHandler< + TargetedMouseEvent + >; + type PointerEventHandler = EventHandler< + TargetedPointerEvent + >; + type TouchEventHandler = EventHandler< + TargetedTouchEvent + >; + type TransitionEventHandler = EventHandler< + TargetedTransitionEvent + >; + type UIEventHandler = EventHandler< + TargetedUIEvent + >; + type WheelEventHandler = EventHandler< + TargetedWheelEvent + >; + + interface DOMAttributes + extends h.VHTMLDOMAttributes { + // Image Events + onLoad?: GenericEventHandler; + onLoadCapture?: GenericEventHandler; + onError?: GenericEventHandler; + onErrorCapture?: GenericEventHandler; + + // Clipboard Events + onCopy?: ClipboardEventHandler; + onCopyCapture?: ClipboardEventHandler; + onCut?: ClipboardEventHandler; + onCutCapture?: ClipboardEventHandler; + onPaste?: ClipboardEventHandler; + onPasteCapture?: ClipboardEventHandler; + + // Composition Events + onCompositionEnd?: CompositionEventHandler; + onCompositionEndCapture?: CompositionEventHandler; + onCompositionStart?: CompositionEventHandler; + onCompositionStartCapture?: CompositionEventHandler; + onCompositionUpdate?: CompositionEventHandler; + onCompositionUpdateCapture?: CompositionEventHandler; + + // Details Events + onToggle?: GenericEventHandler; + + // Focus Events + onFocus?: FocusEventHandler; + onFocusCapture?: FocusEventHandler; + onBlur?: FocusEventHandler; + onBlurCapture?: FocusEventHandler; + + // Form Events + onChange?: GenericEventHandler; + onChangeCapture?: GenericEventHandler; + onInput?: GenericEventHandler; + onInputCapture?: GenericEventHandler; + onSearch?: GenericEventHandler; + onSearchCapture?: GenericEventHandler; + onSubmit?: GenericEventHandler; + onSubmitCapture?: GenericEventHandler; + onInvalid?: GenericEventHandler; + onInvalidCapture?: GenericEventHandler; + onReset?: GenericEventHandler; + onResetCapture?: GenericEventHandler; + onFormData?: GenericEventHandler; + onFormDataCapture?: GenericEventHandler; + + + // Keyboard Events + onKeyDown?: KeyboardEventHandler; + onKeyDownCapture?: KeyboardEventHandler; + onKeyPress?: KeyboardEventHandler; + onKeyPressCapture?: KeyboardEventHandler; + onKeyUp?: KeyboardEventHandler; + onKeyUpCapture?: KeyboardEventHandler; + + // Media Events + onAbort?: GenericEventHandler; + onAbortCapture?: GenericEventHandler; + onCanPlay?: GenericEventHandler; + onCanPlayCapture?: GenericEventHandler; + onCanPlayThrough?: GenericEventHandler; + onCanPlayThroughCapture?: GenericEventHandler; + onDurationChange?: GenericEventHandler; + onDurationChangeCapture?: GenericEventHandler; + onEmptied?: GenericEventHandler; + onEmptiedCapture?: GenericEventHandler; + onEncrypted?: GenericEventHandler; + onEncryptedCapture?: GenericEventHandler; + onEnded?: GenericEventHandler; + onEndedCapture?: GenericEventHandler; + onLoadedData?: GenericEventHandler; + onLoadedDataCapture?: GenericEventHandler; + onLoadedMetadata?: GenericEventHandler; + onLoadedMetadataCapture?: GenericEventHandler; + onLoadStart?: GenericEventHandler; + onLoadStartCapture?: GenericEventHandler; + onPause?: GenericEventHandler; + onPauseCapture?: GenericEventHandler; + onPlay?: GenericEventHandler; + onPlayCapture?: GenericEventHandler; + onPlaying?: GenericEventHandler; + onPlayingCapture?: GenericEventHandler; + onProgress?: GenericEventHandler; + onProgressCapture?: GenericEventHandler; + onRateChange?: GenericEventHandler; + onRateChangeCapture?: GenericEventHandler; + onSeeked?: GenericEventHandler; + onSeekedCapture?: GenericEventHandler; + onSeeking?: GenericEventHandler; + onSeekingCapture?: GenericEventHandler; + onStalled?: GenericEventHandler; + onStalledCapture?: GenericEventHandler; + onSuspend?: GenericEventHandler; + onSuspendCapture?: GenericEventHandler; + onTimeUpdate?: GenericEventHandler; + onTimeUpdateCapture?: GenericEventHandler; + onVolumeChange?: GenericEventHandler; + onVolumeChangeCapture?: GenericEventHandler; + onWaiting?: GenericEventHandler; + onWaitingCapture?: GenericEventHandler; + + // MouseEvents + onClick?: MouseEventHandler; + onClickCapture?: MouseEventHandler; + onContextMenu?: MouseEventHandler; + onContextMenuCapture?: MouseEventHandler; + onDblClick?: MouseEventHandler; + onDblClickCapture?: MouseEventHandler; + onDrag?: DragEventHandler; + onDragCapture?: DragEventHandler; + onDragEnd?: DragEventHandler; + onDragEndCapture?: DragEventHandler; + onDragEnter?: DragEventHandler; + onDragEnterCapture?: DragEventHandler; + onDragExit?: DragEventHandler; + onDragExitCapture?: DragEventHandler; + onDragLeave?: DragEventHandler; + onDragLeaveCapture?: DragEventHandler; + onDragOver?: DragEventHandler; + onDragOverCapture?: DragEventHandler; + onDragStart?: DragEventHandler; + onDragStartCapture?: DragEventHandler; + onDrop?: DragEventHandler; + onDropCapture?: DragEventHandler; + onMouseDown?: MouseEventHandler; + onMouseDownCapture?: MouseEventHandler; + onMouseEnter?: MouseEventHandler; + onMouseEnterCapture?: MouseEventHandler; + onMouseLeave?: MouseEventHandler; + onMouseLeaveCapture?: MouseEventHandler; + onMouseMove?: MouseEventHandler; + onMouseMoveCapture?: MouseEventHandler; + onMouseOut?: MouseEventHandler; + onMouseOutCapture?: MouseEventHandler; + onMouseOver?: MouseEventHandler; + onMouseOverCapture?: MouseEventHandler; + onMouseUp?: MouseEventHandler; + onMouseUpCapture?: MouseEventHandler; + + // Selection Events + onSelect?: GenericEventHandler; + onSelectCapture?: GenericEventHandler; + + // Touch Events + onTouchCancel?: TouchEventHandler; + onTouchCancelCapture?: TouchEventHandler; + onTouchEnd?: TouchEventHandler; + onTouchEndCapture?: TouchEventHandler; + onTouchMove?: TouchEventHandler; + onTouchMoveCapture?: TouchEventHandler; + onTouchStart?: TouchEventHandler; + onTouchStartCapture?: TouchEventHandler; + + // Pointer Events + onPointerOver?: PointerEventHandler; + onPointerOverCapture?: PointerEventHandler; + onPointerEnter?: PointerEventHandler; + onPointerEnterCapture?: PointerEventHandler; + onPointerDown?: PointerEventHandler; + onPointerDownCapture?: PointerEventHandler; + onPointerMove?: PointerEventHandler; + onPointerMoveCapture?: PointerEventHandler; + onPointerUp?: PointerEventHandler; + onPointerUpCapture?: PointerEventHandler; + onPointerCancel?: PointerEventHandler; + onPointerCancelCapture?: PointerEventHandler; + onPointerOut?: PointerEventHandler; + onPointerOutCapture?: PointerEventHandler; + onPointerLeave?: PointerEventHandler; + onPointerLeaveCapture?: PointerEventHandler; + onGotPointerCapture?: PointerEventHandler; + onGotPointerCaptureCapture?: PointerEventHandler; + onLostPointerCapture?: PointerEventHandler; + onLostPointerCaptureCapture?: PointerEventHandler; + + // UI Events + onScroll?: UIEventHandler; + onScrollCapture?: UIEventHandler; + + // Wheel Events + onWheel?: WheelEventHandler; + onWheelCapture?: WheelEventHandler; + + // Animation Events + onAnimationStart?: AnimationEventHandler; + onAnimationStartCapture?: AnimationEventHandler; + onAnimationEnd?: AnimationEventHandler; + onAnimationEndCapture?: AnimationEventHandler; + onAnimationIteration?: AnimationEventHandler; + onAnimationIterationCapture?: AnimationEventHandler; + + // Transition Events + onTransitionEnd?: TransitionEventHandler; + onTransitionEndCapture?: TransitionEventHandler; + } + + interface HTMLAttributes + extends DOMAttributes { + // Standard HTML Attributes + accept?: string; + acceptCharset?: string; + accessKey?: string; + action?: string; + allowFullScreen?: boolean; + allowTransparency?: boolean; + alt?: string; + as?: string; + async?: boolean; + autocomplete?: string; + autoComplete?: string; + autocorrect?: string; + autoCorrect?: string; + autofocus?: boolean; + autoFocus?: boolean; + autoPlay?: boolean; + capture?: boolean; + cellPadding?: number | string; + cellSpacing?: number | string; + charSet?: string; + challenge?: string; + checked?: boolean; + class?: string; + className?: string; + cols?: number; + colSpan?: number; + content?: string; + contentEditable?: boolean; + contextMenu?: string; + controls?: boolean; + controlsList?: string; + coords?: string; + crossOrigin?: string; + data?: string; + dateTime?: string; + default?: boolean; + defer?: boolean; + dir?: 'auto' | 'rtl' | 'ltr'; + disabled?: boolean; + disableRemotePlayback?: boolean; + download?: any; + draggable?: boolean; + encType?: string; + form?: string; + formAction?: string; + formEncType?: string; + formMethod?: string; + formNoValidate?: boolean; + formTarget?: string; + frameBorder?: number | string; + headers?: string; + height?: number | string; + hidden?: boolean; + high?: number; + href?: string; + hrefLang?: string; + for?: string; + htmlFor?: string; + httpEquiv?: string; + icon?: string; + id?: string; + inputMode?: string; + integrity?: string; + is?: string; + keyParams?: string; + keyType?: string; + kind?: string; + label?: string; + lang?: string; + list?: string; + loading?: 'eager' | 'lazy'; + loop?: boolean; + low?: number; + manifest?: string; + marginHeight?: number; + marginWidth?: number; + max?: number | string; + maxLength?: number; + media?: string; + mediaGroup?: string; + method?: string; + min?: number | string; + minLength?: number; + multiple?: boolean; + muted?: boolean; + name?: string; + nonce?: string; + noValidate?: boolean; + open?: boolean; + optimum?: number; + pattern?: string; + placeholder?: string; + playsInline?: boolean; + poster?: string; + preload?: string; + radioGroup?: string; + readOnly?: boolean; + rel?: string; + required?: boolean; + role?: string; + rows?: number; + rowSpan?: number; + sandbox?: string; + scope?: string; + scoped?: boolean; + scrolling?: string; + seamless?: boolean; + selected?: boolean; + shape?: string; + size?: number; + sizes?: string; + slot?: string; + span?: number; + spellcheck?: boolean; + src?: string; + srcset?: string; + srcDoc?: string; + srcLang?: string; + srcSet?: string; + start?: number; + step?: number | string; + style?: string | { [key: string]: string | number }; + summary?: string; + tabIndex?: number; + target?: string; + title?: string; + type?: string; + useMap?: string; + value?: string | string[] | number; + volume?: string | number; + width?: number | string; + wmode?: string; + wrap?: string; + + // RDFa Attributes + about?: string; + datatype?: string; + inlist?: any; + prefix?: string; + property?: string; + resource?: string; + typeof?: string; + vocab?: string; + + // Microdata Attributes + itemProp?: string; + itemScope?: boolean; + itemType?: string; + itemID?: string; + itemRef?: string; + } + + interface HTMLMarqueeElement extends HTMLElement { + behavior?: 'scroll' | 'slide' | 'alternate'; + bgColor?: string; + direction?: 'left' | 'right' | 'up' | 'down'; + height?: number | string; + hspace?: number | string; + loop?: number | string; + scrollAmount?: number | string; + scrollDelay?: number | string; + trueSpeed?: boolean; + vspace?: number | string; + width?: number | string; + } + + interface IntrinsicElements { + // HTML + a: HTMLAttributes; + abbr: HTMLAttributes; + address: HTMLAttributes; + area: HTMLAttributes; + article: HTMLAttributes; + aside: HTMLAttributes; + audio: HTMLAttributes; + b: HTMLAttributes; + base: HTMLAttributes; + bdi: HTMLAttributes; + bdo: HTMLAttributes; + big: HTMLAttributes; + blockquote: HTMLAttributes; + body: HTMLAttributes; + br: HTMLAttributes; + button: HTMLAttributes; + canvas: HTMLAttributes; + caption: HTMLAttributes; + cite: HTMLAttributes; + code: HTMLAttributes; + col: HTMLAttributes; + colgroup: HTMLAttributes; + data: HTMLAttributes; + datalist: HTMLAttributes; + dd: HTMLAttributes; + del: HTMLAttributes; + details: HTMLAttributes; + dfn: HTMLAttributes; + dialog: HTMLAttributes; + div: HTMLAttributes; + dl: HTMLAttributes; + dt: HTMLAttributes; + em: HTMLAttributes; + embed: HTMLAttributes; + fieldset: HTMLAttributes; + figcaption: HTMLAttributes; + figure: HTMLAttributes; + footer: HTMLAttributes; + form: HTMLAttributes; + h1: HTMLAttributes; + h2: HTMLAttributes; + h3: HTMLAttributes; + h4: HTMLAttributes; + h5: HTMLAttributes; + h6: HTMLAttributes; + head: HTMLAttributes; + header: HTMLAttributes; + hgroup: HTMLAttributes; + hr: HTMLAttributes; + html: HTMLAttributes; + i: HTMLAttributes; + iframe: HTMLAttributes; + img: HTMLAttributes; + input: HTMLAttributes; + ins: HTMLAttributes; + kbd: HTMLAttributes; + keygen: HTMLAttributes; + label: HTMLAttributes; + legend: HTMLAttributes; + li: HTMLAttributes; + link: HTMLAttributes; + main: HTMLAttributes; + map: HTMLAttributes; + mark: HTMLAttributes; + marquee: HTMLAttributes; + menu: HTMLAttributes; + menuitem: HTMLAttributes; + meta: HTMLAttributes; + meter: HTMLAttributes; + nav: HTMLAttributes; + noscript: HTMLAttributes; + object: HTMLAttributes; + ol: HTMLAttributes; + optgroup: HTMLAttributes; + option: HTMLAttributes; + output: HTMLAttributes; + p: HTMLAttributes; + param: HTMLAttributes; + picture: HTMLAttributes; + pre: HTMLAttributes; + progress: HTMLAttributes; + q: HTMLAttributes; + rp: HTMLAttributes; + rt: HTMLAttributes; + ruby: HTMLAttributes; + s: HTMLAttributes; + samp: HTMLAttributes; + script: HTMLAttributes; + section: HTMLAttributes; + select: HTMLAttributes; + slot: HTMLAttributes; + small: HTMLAttributes; + source: HTMLAttributes; + span: HTMLAttributes; + strong: HTMLAttributes; + style: HTMLAttributes; + sub: HTMLAttributes; + summary: HTMLAttributes; + sup: HTMLAttributes; + table: HTMLAttributes; + tbody: HTMLAttributes; + td: HTMLAttributes; + textarea: HTMLAttributes; + tfoot: HTMLAttributes; + th: HTMLAttributes; + thead: HTMLAttributes; + time: HTMLAttributes; + title: HTMLAttributes; + tr: HTMLAttributes; + track: HTMLAttributes; + u: HTMLAttributes; + ul: HTMLAttributes; + var: HTMLAttributes; + video: HTMLAttributes; + wbr: HTMLAttributes; + + //SVG + svg: SVGAttributes; + animate: SVGAttributes; + circle: SVGAttributes; + clipPath: SVGAttributes; + defs: SVGAttributes; + desc: SVGAttributes; + ellipse: SVGAttributes; + feBlend: SVGAttributes; + feColorMatrix: SVGAttributes; + feComponentTransfer: SVGAttributes; + feComposite: SVGAttributes; + feConvolveMatrix: SVGAttributes; + feDiffuseLighting: SVGAttributes; + feDisplacementMap: SVGAttributes; + feFlood: SVGAttributes; + feGaussianBlur: SVGAttributes; + feImage: SVGAttributes; + feMerge: SVGAttributes; + feMergeNode: SVGAttributes; + feMorphology: SVGAttributes; + feOffset: SVGAttributes; + feSpecularLighting: SVGAttributes; + feTile: SVGAttributes; + feTurbulence: SVGAttributes; + filter: SVGAttributes; + foreignObject: SVGAttributes; + g: SVGAttributes; + image: SVGAttributes; + line: SVGAttributes; + linearGradient: SVGAttributes; + marker: SVGAttributes; + mask: SVGAttributes; + path: SVGAttributes; + pattern: SVGAttributes; + polygon: SVGAttributes; + polyline: SVGAttributes; + radialGradient: SVGAttributes; + rect: SVGAttributes; + stop: SVGAttributes; + symbol: SVGAttributes; + text: SVGAttributes; + tspan: SVGAttributes; + use: SVGAttributes; + } +} diff --git a/src/vhtml.d.ts b/src/vhtml.d.ts new file mode 100644 index 0000000..6164c82 --- /dev/null +++ b/src/vhtml.d.ts @@ -0,0 +1,74 @@ +export = h; +export as namespace h; + +import { JSXInternal } from './jsx'; + +declare namespace h { + export import JSX = JSXInternal; + + type Key = string | number | any; + + type ComponentChild = Record | string | number | boolean | null | undefined; + + type ComponentChildren = ComponentChild[] | ComponentChild; + + interface Attributes { + key?: Key; + jsx?: boolean; + } + + interface VHTMLDOMAttributes { + children?: ComponentChildren; + dangerouslySetInnerHTML?: { + __html: string; + }; + } + + type RenderableProps

= P & + Readonly; + + type ComponentType

> = FunctionComponent

; + + interface FunctionComponent

> { + (props: RenderableProps

, context?: any): string | null; + displayName?: string; + defaultProps?: Partial

; + } + + interface FunctionalComponent

> + extends FunctionComponent

{} + + const Fragmant: FunctionComponent; +} + +/** + * Hyperscript reviver that constructs a sanitized HTML string. + * + * @param type - DOM node type to create. + * @param props - Property data object. + * @param children - Children components. + * @returns Sanitized HTML string. + */ +declare function h( + type: string, + props: + | (JSXInternal.HTMLAttributes & + JSXInternal.SVGAttributes & + Record) + | null, + ...children: h.ComponentChildren[] +): string; + +/** + * Hyperscript reviver that constructs a sanitized HTML string. + * + * @param type - DOM node type to create. + * @param props - Property data object. + * @param children - Children components. + * @returns Sanitized HTML string. + */ +declare function h

( + type: h.ComponentType

, + props: (h.Attributes & P) | null, + ...children: h.ComponentChildren[] +): string; diff --git a/src/vhtml.js b/src/vhtml.js index 0e03f69..b524acb 100644 --- a/src/vhtml.js +++ b/src/vhtml.js @@ -11,6 +11,10 @@ let DOMAttributeNames = { let sanitized = {}; +export function Fragment(attrs) { + return attrs.children; +} + /** Hyperscript reviver that constructs a sanitized HTML string. */ export default function h(name, attrs) { let stack=[], s = ''; diff --git a/src/vhtml.test-d.tsx b/src/vhtml.test-d.tsx new file mode 100644 index 0000000..8ee640f --- /dev/null +++ b/src/vhtml.test-d.tsx @@ -0,0 +1,40 @@ +import h, { JSX } from './vhtml'; +import { expectType } from 'tsd'; + +// Empty div +expectType(

); + +// className prop +expectType(); + +// Other props +expectType(); + +// Children, spreading etc. +let items = ['one', 'two']; + +interface Props { + children?: JSX.Element[]; + item: string, + index: number, +} + +const Item = ({ item, index, children }: Props) => ( +
  • +

    {item}

    + {children} +
  • +); +expectType(
    +

    Hi!

    +
      + { items.map( (item, index) => ( + + This is item {item}! + + )) } +
    +
    ); + +// Fragments +expectType(); diff --git a/test/vhtml.js b/test/vhtml.js index f88ddf2..1ac2056 100644 --- a/test/vhtml.js +++ b/test/vhtml.js @@ -174,6 +174,23 @@ describe('vhtml', () => { ); }); + it('should support fragments', () => { + expect( + + ).to.equal( + '' + ); + }); + it('should support fragments children', () => { + expect( + +

    foo

    +
    + ).to.equal( + '

    foo

    ' + ); + }); + it('should support string fragments', () => { expect( h(null, null, "foo", "bar", "baz") diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..bc9ad73 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "noEmit": true, + "moduleResolution": "node", + "esModuleInterop": true, + "jsx": "react", + "jsxFactory": "h", + "baseUrl": ".", + "lib": ["DOM"] + }, + "include": ["src"] +}