// TypeScript React

/** @author Willy
* @url https://reactjs.org/ **/

import React from 'react';
import { PhotoStory, VideoStory } from './stories';

function Story(props) {
const SpecificStory = components[props.storyType];
return story={ props.story } attr2="&ref;" attr3="Hello\n" />;
}

function
attr1={ function <noTag/> return class var 0x123 { } &noRef; hello() React.Component() } attr2="&ref;">
/* no comment*/ function return class var 0x123 &ref; hello() React.Component()
. anyWord
{ function <tag> return class var 0x123 hello() React.Component() }



Tag$>


/*comment*/attr1/*comment*/= /*comment*/"value"/*comment*/attr2 /*comment*/attr3='a' key/*comment*/key2 />

// Detect Valid tags

/* comment */
{ /* comment
*/ />
word <noTag/> . <noTag/> } <noTag/>
return /* comment
multiline */ /* comment */
&& /*comment*/
& /*comment*/ <noTag/>


{ Hello }
? />;
[ /> ( />
, =
&& ||
return ;
default ;
return

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:
annotation: text [ ]
console.log("hello")

// Type assertion in tag
<number>/>
<number>>

/>

// Non-ASCII tag name & attribute
<日本語>;
本本:本-本 aa本:本 aa:aa />
/>

/>;
{ ... x } y
={2 } z />;

let k1 =
a={10} b="hi" {...o} >
hi hi hi!
;

let k2 =
a={10} b="hi">
My Div

{(name: string) =>
My name {name}
}
;

let k3 = initialValues={{ x: "y" }} nextValues={a => ({ x: a.x })} />; // No Error

// OK
let k1 = a={10} b="hi"><> /> />;
let k2 = a={10} b="hi"><> /> />;
let k3 = a={10} b="hi"><> /> />;
let k4 = a={10} b="hi"><> /> />;
// OK
let k1 =

Hello

world

;
let k2 =

Hello

{(user: any) =>

{user.name}

}
;
let k3 =
{1} {"That is a number"}
;
let k4 = ;

// Empty tags
hello<>
hello<string>

<>; // no whitespace
< >; // lots of whitespace
< /*starting wrap*/ > /*ending wrap*/>; // comments in the tags
<>hi; // text inside
<>hi
bye
; // children
<>1<>2.12.23; // nested fragments
<>#; // # would cause scanning error if not in jsxtext

// Tags after substitutions in templates
${//comment
/*comment*/}

// 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/> = />;
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 />;

}

// Highlight "
// (the "cast" expression works and isn't supported in the TSX file)
const goodHighlighting = <T extends I>(
arg: T
) => {
const a = arg
return a
}
text extends I/> // Here "" 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 : ;
let x = (foo === null || foo === undefined) ?
undefined :hello;

// Tagged template literals
tagFunc

${ />; 22 + "11" };
obj.something.tagFunc${setting}${value};