-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
25 changed files
with
546 additions
and
431 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
67 changes: 54 additions & 13 deletions
67
packages/error-overlay/overlay/src/components/button/Button.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,27 +1,68 @@ | ||
import { FunctionComponent, SyntheticEvent } from 'react'; | ||
import clsx from 'clsx'; | ||
import { FunctionComponent } from 'react'; | ||
|
||
type ButtonProps = { | ||
type?: 'submit' | 'reset' | 'button'; | ||
export type ButtonProps = { | ||
btn?: 'primary' | 'secondary'; | ||
color?: 'orange' | 'gray' | 'green' | 'light'; | ||
size?: 'sm' | 'xs'; | ||
linkStyle?: boolean; | ||
bordered?: boolean; | ||
onClick?(event: SyntheticEvent): void; | ||
}; | ||
|
||
const Button: FunctionComponent<ButtonProps> = ({ | ||
type = 'button', | ||
const Button: FunctionComponent< | ||
ButtonProps & | ||
React.DetailedHTMLProps< | ||
React.ButtonHTMLAttributes<HTMLButtonElement>, | ||
HTMLButtonElement | ||
> | ||
> = ({ | ||
children, | ||
className, | ||
color = 'gray', | ||
size = 'sm', | ||
bordered = false, | ||
onClick, | ||
children | ||
linkStyle = false, | ||
type = 'button', | ||
...restProps | ||
}) => { | ||
return ( | ||
<button | ||
type={type} | ||
onClick={event => onClick && onClick(event)} | ||
className={`flex items-center py-2 px-3 font-mono text-sm text-gray-600 hover:text-blue-500 active:text-blue-600 transition-all duration-100 ease-in-out active:scale-95 ${ | ||
bordered ? 'border border-gray-600 hover:border-blue-500' : '' | ||
}`}> | ||
className={clsx( | ||
'tracking-tighter border-2 transition-all', | ||
{ | ||
'p-2 text-xs': size === 'xs', | ||
'py-2 px-3 text-sm': size === 'sm', | ||
'border-transparent': linkStyle, | ||
'active:scale-90': linkStyle || size === 'xs', | ||
'active:scale-95': !linkStyle, | ||
'text-slate-600 hover:text-slate-800': color === 'gray', | ||
[bordered | ||
? 'border-slate-500 hover:border-slate-700 hover:bg-slate-100' | ||
: 'border-slate-200 bg-slate-200 hover:border-slate-300 hover:bg-slate-300']: | ||
!linkStyle && color === 'gray', | ||
'text-slate-500 hover:text-slate-300': color === 'light', | ||
[bordered | ||
? 'border-slate-500 hover:border-slate-700 hover:bg-slate-100' | ||
: 'border-slate-200 bg-slate-200 hover:border-slate-300 hover:bg-slate-300']: | ||
!linkStyle && color === 'gray', | ||
'text-emerald-600 hover:text-emerald-700': color === 'green', | ||
[bordered | ||
? 'border-emerald-500 hover:border-emerald-600 hover:bg-emerald-50' | ||
: 'border-emerald-100 bg-emerald-100 hover:border-emerald-200 hover:bg-emerald-200']: | ||
!linkStyle && color === 'green', | ||
'text-orange-600 hover:text-orange-700': color === 'orange', | ||
[bordered | ||
? 'border-orange-500 hover:border-orange-600 hover:bg-orange-50' | ||
: 'border-orange-100 bg-orange-100 hover:border-orange-200 hover:bg-orange-200']: | ||
!linkStyle && color === 'orange' | ||
}, | ||
className | ||
)} | ||
{...restProps}> | ||
{children} | ||
</button> | ||
); | ||
}; | ||
|
||
export { Button }; | ||
export default Button; |
129 changes: 77 additions & 52 deletions
129
packages/error-overlay/overlay/src/components/frame/Frame.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,72 +1,97 @@ | ||
import hljs from 'highlight.js/lib/core'; | ||
import hljsJS from 'highlight.js/lib/languages/javascript'; | ||
import { FunctionComponent, memo } from 'react'; | ||
import PrismJS from 'prismjs'; | ||
import { FunctionComponent, memo, useCallback, useState } from 'react'; | ||
import { FrameWrapper } from 'types'; | ||
|
||
import { ChevronIcon } from '#/components'; | ||
import { ErrorWrapper } from '#/reducers'; | ||
|
||
import { FrameHeader } from './FrameHeader'; | ||
import FrameHeader from './FrameHeader'; | ||
|
||
import 'highlight.js/styles/github-dark-dimmed.css'; | ||
import 'prismjs/components/prism-jsx'; | ||
import 'prismjs/components/prism-javascript'; | ||
import './prismjs.css'; | ||
|
||
hljs.registerLanguage('javascript', hljsJS); | ||
|
||
type FrameProps = { | ||
export type FrameProps = { | ||
errorId: ErrorWrapper['id']; | ||
frameWrapper: FrameWrapper; | ||
}; | ||
|
||
const FrameBase: FunctionComponent<FrameProps> = ({ | ||
frameWrapper, | ||
errorId | ||
}) => { | ||
if (!frameWrapper) { | ||
return null; | ||
function getPrismLanguage( | ||
fileUri: string | ||
): { | ||
grammar: PrismJS.Grammar; | ||
language: PrismJS.Language; | ||
} { | ||
let language: PrismJS.Language = 'javascript'; | ||
|
||
if (fileUri.endsWith('.jsx')) { | ||
language = 'jsx'; | ||
} | ||
|
||
return { grammar: PrismJS.languages[language], language }; | ||
} | ||
|
||
const Frame: FunctionComponent<FrameProps> = ({ frameWrapper, errorId }) => { | ||
const { frame } = frameWrapper; | ||
const sourceFragment = frameWrapper.showOriginal | ||
? frame.originalSourceFragment | ||
: frame.sourceFragment; | ||
const hasFragment = | ||
Array.isArray(sourceFragment) && sourceFragment.length > 0; | ||
|
||
const [isFragmentVisible, setIsFragmentVisible] = useState<boolean>( | ||
hasFragment | ||
); | ||
|
||
const handleHeaderClick = useCallback(() => { | ||
setIsFragmentVisible(visible => !visible); | ||
}, []); | ||
|
||
const { grammar, language } = getPrismLanguage( | ||
frame.originalFileName || frame.fileName | ||
); | ||
|
||
return ( | ||
<div className="group mb-4"> | ||
<FrameHeader frameWrapper={frameWrapper} errorId={errorId} /> | ||
<div className="overflow-hidden mb-4 rounded-md shadow-lg text-slate-50 bg-slate-700 shadow-slate-700/50"> | ||
<FrameHeader | ||
onHeaderClick={handleHeaderClick} | ||
frameWrapper={frameWrapper} | ||
isFragmentVisible={isFragmentVisible} | ||
hasFragment={hasFragment} | ||
errorId={errorId} | ||
/> | ||
|
||
<div className="overflow-y-auto p-3 font-mono text-xs leading-5 bg-gray-100 rounded language-javascript hljs"> | ||
<pre> | ||
{(frameWrapper.showOriginal | ||
? frameWrapper.frame.originalSourceFragment | ||
: frameWrapper.frame.sourceFragment | ||
)?.map(line => ( | ||
<div | ||
key={line.line} | ||
className={`flex items-center ${ | ||
line.highlight ? 'bg-red-500 bg-opacity-25' : '' | ||
}`}> | ||
{line.highlight && ( | ||
<span className="text-red-500"> | ||
<ChevronIcon | ||
className="w-4 h-4" | ||
style={{ | ||
marginLeft: '-1px' | ||
{isFragmentVisible && ( | ||
<div className="overflow-y-auto py-3 text-sm leading-6 rounded-b-xl text-slate-50 bg-slate-700"> | ||
<pre> | ||
<code> | ||
{(frameWrapper.showOriginal | ||
? frame.originalSourceFragment | ||
: frame.sourceFragment | ||
)?.map(line => ( | ||
<div | ||
key={line.line} | ||
className={`flex items-center border-l-4 ${ | ||
line.highlight | ||
? 'bg-rose-500/20 border-rose-500' | ||
: 'border-transparent' | ||
}`}> | ||
<div className="pr-3 pl-3 mr-3 border-r-2 text-slate-400 border-slate-600/75"> | ||
{line.line} | ||
</div> | ||
<div | ||
dangerouslySetInnerHTML={{ | ||
__html: PrismJS.highlight(line.source, grammar, language) | ||
}} | ||
/> | ||
</span> | ||
)} | ||
<span className="pr-2 border-r border-gray-500"> | ||
{line.highlight ? line.line : ` ${line.line}`} | ||
</span> | ||
<div | ||
className="pl-2" | ||
dangerouslySetInnerHTML={{ | ||
__html: hljs.highlight(line.source, { | ||
language: 'javascript' | ||
}).value | ||
}}></div> | ||
</div> | ||
))} | ||
</pre> | ||
</div> | ||
</div> | ||
))} | ||
</code> | ||
</pre> | ||
</div> | ||
)} | ||
</div> | ||
); | ||
}; | ||
|
||
const Frame = memo(FrameBase); | ||
export { Frame, FrameBase }; | ||
export { Frame, getPrismLanguage }; | ||
export default memo(Frame); |
Oops, something went wrong.