165 lines
4.3 KiB
TypeScript
165 lines
4.3 KiB
TypeScript
// TypeScript React
|
|
|
|
/** @author Willy <willy@wmail.com>
|
|
* @url https://reactjs.org/ **/
|
|
|
|
import React from 'react';
|
|
import { PhotoStory, VideoStory } from './stories';
|
|
|
|
function Story(props) {
|
|
const SpecificStory = components[props.storyType];
|
|
return <SpecificStory story={ props.story } attr2="&ref;" attr3="Hello\n" />;
|
|
}
|
|
|
|
function
|
|
<Tag attr1={ <tag/> function <noTag/> return class var 0x123 { } &noRef; hello() React.Component() } attr2="&ref;">
|
|
/* no comment*/ function <tag/> return class var 0x123 &ref; hello() React.Component()
|
|
.<tag/> anyWord <tag/>
|
|
{ function <tag> return class var 0x123 hello() React.Component() }
|
|
</Tag>
|
|
|
|
<tag1> </tag1>
|
|
<tag1> </Tag$>
|
|
<Tag$> </tag>
|
|
|
|
<tag/*comment*/attr1/*comment*/= /*comment*/"value"/*comment*/attr2 /*comment*/attr3='a' key/*comment*/key2 />
|
|
|
|
// Detect Valid tags
|
|
|
|
/* comment */ <tag></tag>
|
|
{ /* comment
|
|
*/ <Tag />
|
|
word <noTag/> . <noTag/> } <noTag/>
|
|
return /* comment
|
|
multiline */ <tag/> /* comment */ <Tag/>
|
|
&& /*comment*/ <Tag/>
|
|
& /*comment*/ <noTag/>
|
|
|
|
<tag/>
|
|
{ <hello>Hello</hello> }
|
|
?<Tag />;
|
|
[ <tag /> ( <tag />
|
|
,<Tag/> =<Tag/>
|
|
&&<tag/> ||<tag/>
|
|
return <tag/> ;
|
|
default<tag/> ;
|
|
<Tag> <tag> <tag$/> </tag> return </Tag>
|
|
|
|
anyWord<noTag>
|
|
anyWord/*comment*/ <noTag/>
|
|
.<noTag>
|
|
&<notag> | <noTag/>
|
|
% /* comment*/ <noTag/>
|
|
|
|
// TODO: Fix this (comment before the tag name):
|
|
var x = </**/div></div>;
|
|
|
|
// Tag after ":"
|
|
annotation: <tag/>
|
|
annotation: text [ <tag/> ]
|
|
console.log("hello")
|
|
|
|
// Type assertion in tag
|
|
<C<number>/>
|
|
<C<number>> </C>
|
|
<C
|
|
<error />
|
|
|
|
// Non-ASCII tag name & attribute
|
|
<日本語></日本語>;
|
|
<Component 本本:本-本 aa本:本 aa:aa />
|
|
<aaaa:ñ />
|
|
|
|
<Namespace.DeepNamespace.Component />;
|
|
<Component { ... x } y
|
|
={2 } z />;
|
|
|
|
let k1 =
|
|
<Comp a={10} b="hi" {...o} >
|
|
hi hi hi!
|
|
</Comp>;
|
|
|
|
let k2 =
|
|
<Comp a={10} b="hi">
|
|
<div> My Div </div>
|
|
{(name: string) => <div> My name {name} </div>}
|
|
</Comp>;
|
|
|
|
let k3 = <GenericComponent initialValues={{ x: "y" }} nextValues={a => ({ x: a.x })} />; // No Error
|
|
|
|
// OK
|
|
let k1 = <Comp a={10} b="hi"><></><Button /><AnotherButton /></Comp>;
|
|
let k2 = <Comp a={10} b="hi"><><Button /></><AnotherButton /></Comp>;
|
|
let k3 = <Comp a={10} b="hi"><><Button /><AnotherButton /></></Comp>;
|
|
let k4 = <SingleChildComp a={10} b="hi"><><Button /><AnotherButton /></></SingleChildComp>;
|
|
// OK
|
|
let k1 = <div> <h2> Hello </h2> <h1> world </h1></div>;
|
|
let k2 = <div> <h2> Hello </h2> {(user: any) => <h2>{user.name}</h2>}</div>;
|
|
let k3 = <div> {1} {"That is a number"} </div>;
|
|
let k4 = <Button> <h2> Hello </h2> </Button>;
|
|
|
|
// Empty tags
|
|
hello<>
|
|
hello<string>
|
|
|
|
<></>; // no whitespace
|
|
< ></ >; // lots of whitespace
|
|
< /*starting wrap*/ ></ /*ending wrap*/>; // comments in the tags
|
|
<>hi</>; // text inside
|
|
<><span>hi</span><div>bye</div></>; // children
|
|
<><span>1</span><><span>2.1</span><span>2.2</span></><span>3</span></>; // nested fragments
|
|
<>#</>; // # would cause scanning error if not in jsxtext
|
|
|
|
// Tags after substitutions in templates
|
|
`aaa${<tag></tag>//comment
|
|
/*comment*/<A/>}`
|
|
|
|
// Don't highlight tags within type declaration
|
|
type T12 = ReturnType<(<T>() => T)>;
|
|
type T13 = ReturnType<(<T extends U, U extends number[]>() => T)>;
|
|
type T14 = ReturnType<typeof f1>;
|
|
type T15 = ReturnType<(s: string) => void>;
|
|
|
|
// Don't highlight tags within variable declaration
|
|
let myIdentity: <T>(arg: T) => T <noTag/> = <Tag />;
|
|
var myIdentity: <U>(arg: U) => U = identity;
|
|
const myIdentity: {<T>(arg: T): T} = identity;
|
|
|
|
// Don't highlight tags within interfaces and classes
|
|
interface GenericIdentityFn {
|
|
<T>(arg: T): T;
|
|
<noTag />
|
|
}
|
|
class Handler {
|
|
info: <T>(arg: T): T <noTag />;
|
|
<tag> </tag>
|
|
}
|
|
|
|
// Highlight "<T extends" as a type assertion, not as a tag
|
|
// (the "cast" expression works and isn't supported in the TSX file)
|
|
const goodHighlighting = <T extends I>(
|
|
arg: T
|
|
) => {
|
|
const a = arg
|
|
return a
|
|
}
|
|
<tag> text <T extends I/> </tag> // Here "<T extends I/>" is a tag
|
|
|
|
// Check character after tag name, do not highlight invalid tags
|
|
<noTag ?
|
|
<noTag ,
|
|
<noTag /* comment */ ?
|
|
<noTag#
|
|
<noTag/*comment*/#
|
|
|
|
// Conditionals expressions
|
|
let y = foo == null ? null : <Tag/>;
|
|
let x = (foo === null || foo === undefined) ?
|
|
undefined :<tag>hello</tag>;
|
|
|
|
// Tagged template literals
|
|
tagFunc`
|
|
Hello world!
|
|
${ <Tag />; 22 + "11" }`;
|
|
obj.something.tagFunc`Setting ${setting} is ${value}!`;
|