mirror of
https://github.com/EnixCoda/Gitako.git
synced 2026-03-11 08:54:44 +00:00
refactor: use primer
This commit is contained in:
parent
83335a061e
commit
f430c7bc26
12 changed files with 290 additions and 281 deletions
|
|
@ -1,3 +1,4 @@
|
|||
import { Text } from '@primer/components'
|
||||
import { LoadingIndicator } from 'components/LoadingIndicator'
|
||||
import { Node } from 'components/Node'
|
||||
import { SearchBar } from 'components/SearchBar'
|
||||
|
|
@ -69,7 +70,11 @@ const RawFileExplorer: React.FC<Props & ConnectorState> = function RawFileExplor
|
|||
({ nodes, focusedNode }: VisibleNodes) => {
|
||||
const inSearch = searchKey !== ''
|
||||
if (inSearch && nodes.length === 0) {
|
||||
return <label className={'no-results'}>No results found.</label>
|
||||
return (
|
||||
<Text marginTop={6} textAlign="center" color="text.gray">
|
||||
No results found.
|
||||
</Text>
|
||||
)
|
||||
}
|
||||
return (
|
||||
<SizeObserver className={'files'}>
|
||||
|
|
@ -210,7 +215,7 @@ function ListView({
|
|||
}}
|
||||
itemData={{ nodes }}
|
||||
itemCount={nodes.length}
|
||||
itemSize={35}
|
||||
itemSize={36}
|
||||
height={height}
|
||||
width={width}
|
||||
>
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import { Breadcrumb } from '@primer/components'
|
||||
import * as React from 'react'
|
||||
import { MetaData } from 'utils/GitHubHelper'
|
||||
|
||||
|
|
@ -10,15 +11,13 @@ export function MetaBar({ metaData }: Props) {
|
|||
const repoUrl = metaData?.api?.html_url
|
||||
return (
|
||||
<div className={'meta-bar'}>
|
||||
<a className={'username'} href={userUrl}>
|
||||
{metaData.userName}
|
||||
</a>
|
||||
/
|
||||
<a className={'repo-name'} href={repoUrl}>
|
||||
{metaData.repoName}
|
||||
</a>
|
||||
/
|
||||
{metaData.branchName}
|
||||
<Breadcrumb>
|
||||
<Breadcrumb.Item href={userUrl}>{metaData.userName}</Breadcrumb.Item>
|
||||
<Breadcrumb.Item className={'repo-name'} href={repoUrl}>
|
||||
{metaData.repoName}
|
||||
</Breadcrumb.Item>
|
||||
<Breadcrumb.Item selected>{metaData.branchName}</Breadcrumb.Item>
|
||||
</Breadcrumb>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import { Text } from '@primer/components'
|
||||
import { useConfigs } from 'containers/ConfigsContext'
|
||||
import * as React from 'react'
|
||||
import { cx } from 'utils/cx'
|
||||
|
|
@ -45,24 +46,19 @@ export function Node({ node, depth, expanded, focused, renderActions, style, onC
|
|||
|
||||
const { name, path } = node
|
||||
return (
|
||||
<div
|
||||
className={cx(`node-item-row`, { focused, disabled: node.accessDenied })}
|
||||
style={style}
|
||||
<a
|
||||
href={node.url}
|
||||
onClick={onClickNode}
|
||||
className={cx(`node-item`, { focused, disabled: node.accessDenied, expanded })}
|
||||
style={{ ...style, paddingLeft: `${10 + 20 * depth}px` }}
|
||||
title={path}
|
||||
>
|
||||
<a href={node.url} onClick={onClickNode}>
|
||||
<div
|
||||
className={cx('node-item', { expanded })}
|
||||
style={{ paddingLeft: `${10 + 20 * depth}px` }}
|
||||
>
|
||||
<div className={'node-item-label'}>
|
||||
<NodeItemIcon node={node} open={expanded} />
|
||||
<span className={'node-item-name'}>{name}</span>
|
||||
</div>
|
||||
{renderActions && <div>{renderActions(node)}</div>}
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
<div className={'node-item-label'}>
|
||||
<NodeItemIcon node={node} open={expanded} />
|
||||
<Text fontSize={14}>{name}</Text>
|
||||
</div>
|
||||
{renderActions && <div>{renderActions(node)}</div>}
|
||||
</a>
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
import { TextInput } from '@primer/components'
|
||||
import { Search } from '@primer/octicons-react'
|
||||
import * as React from 'react'
|
||||
import { cx } from 'utils/cx'
|
||||
|
||||
|
|
@ -10,10 +12,12 @@ type Props = {
|
|||
export function SearchBar({ onSearch, onFocus, searchKey }: Props) {
|
||||
return (
|
||||
<div className={'search-input-wrapper'}>
|
||||
<input
|
||||
<TextInput
|
||||
backgroundColor="white"
|
||||
icon={Search as any}
|
||||
onFocus={onFocus}
|
||||
tabIndex={0}
|
||||
className={cx('form-control', 'search-input', {
|
||||
className={cx('search-input', {
|
||||
error: !isValidRegexpSource(searchKey),
|
||||
})}
|
||||
aria-label="search files"
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import { Link } from '@primer/components'
|
||||
import { Icon } from 'components/Icon'
|
||||
import { VERSION } from 'env'
|
||||
import * as React from 'react'
|
||||
|
|
@ -5,6 +6,7 @@ import { Config } from 'utils/configHelper'
|
|||
import { useStates } from 'utils/hooks/useStates'
|
||||
import { AccessTokenSettings } from './settings/AccessTokenSettings'
|
||||
import { FileTreeSettings } from './settings/FileTreeSettings'
|
||||
import { SettingsSection } from './settings/SettingsSection'
|
||||
import { SidebarSettings } from './settings/SidebarSettings'
|
||||
import { SimpleToggleField } from './SimpleToggleField'
|
||||
|
||||
|
|
@ -58,8 +60,7 @@ function SettingsBarContent() {
|
|||
<AccessTokenSettings />
|
||||
<SidebarSettings />
|
||||
<FileTreeSettings />
|
||||
<div className={'gitako-settings-bar-content-section others'}>
|
||||
<h4>More</h4>
|
||||
<SettingsSection title={'More'}>
|
||||
{moreFields.map(field => (
|
||||
<React.Fragment key={field.key}>
|
||||
<SimpleToggleField field={field} />
|
||||
|
|
@ -67,13 +68,12 @@ function SettingsBarContent() {
|
|||
))}
|
||||
|
||||
{reloadHint && <div className={'hint'}>{reloadHint}</div>}
|
||||
</div>
|
||||
<div className={'gitako-settings-bar-content-section issue'}>
|
||||
<h4>Contact</h4>
|
||||
</SettingsSection>
|
||||
<SettingsSection title={'Contact'}>
|
||||
<a href="https://github.com/EnixCoda/Gitako/issues" target="_blank">
|
||||
Report bug / Request feature.
|
||||
</a>
|
||||
</div>
|
||||
</SettingsSection>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
|
|
@ -85,14 +85,15 @@ export function SettingsBar(props: Props) {
|
|||
<div className={'gitako-settings-bar'}>
|
||||
{activated && <SettingsBarContent />}
|
||||
<div className={'header-row'}>
|
||||
<a
|
||||
className={'version'}
|
||||
<Link
|
||||
color="gray.4"
|
||||
fontSize={14}
|
||||
href={wikiLinks.changeLog}
|
||||
target={'_blank'}
|
||||
title={'Check out new features!'}
|
||||
>
|
||||
{VERSION}
|
||||
</a>
|
||||
</Link>
|
||||
{activated ? (
|
||||
<Icon
|
||||
type={'chevron-down'}
|
||||
|
|
|
|||
|
|
@ -162,11 +162,11 @@ function renderAccessDeniedError(hasToken: boolean) {
|
|||
) : (
|
||||
<p>
|
||||
Gitako needs access token to read this project due to{' '}
|
||||
<a target="_blank" href="https://developer.github.com/v3/#rate-limiting">
|
||||
<a href="https://developer.github.com/v3/#rate-limiting" target="_blank">
|
||||
GitHub rate limiting
|
||||
</a>{' '}
|
||||
and{' '}
|
||||
<a target="_blank" href="https://developer.github.com/v3/#authentication">
|
||||
<a href="https://developer.github.com/v3/#authentication" target="_blank">
|
||||
auth needs
|
||||
</a>
|
||||
. Please setup access token in the settings panel below.
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import { useConfigs } from 'containers/ConfigsContext'
|
||||
import * as React from 'react'
|
||||
import { cx } from 'utils/cx'
|
||||
import { SimpleField } from './SettingsBar'
|
||||
|
||||
type Props = {
|
||||
|
|
@ -12,9 +13,8 @@ export function SimpleToggleField({ field, onChange }: Props) {
|
|||
const configContext = useConfigs()
|
||||
const value = configContext.val[field.key]
|
||||
return (
|
||||
<div className={'form-checkbox'}>
|
||||
<div className={cx('field', 'field-checkbox')}>
|
||||
<input
|
||||
className={'form-control'}
|
||||
id={field.key}
|
||||
name={field.key}
|
||||
type={'checkbox'}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
import { Button, TextInput } from '@primer/components'
|
||||
import { wikiLinks } from 'components/SettingsBar'
|
||||
import { useConfigs } from 'containers/ConfigsContext'
|
||||
import { oauth } from 'env'
|
||||
import * as React from 'react'
|
||||
import { useStates } from 'utils/hooks/useStates'
|
||||
import { SettingsSection } from './SettingsSection'
|
||||
|
||||
const ACCESS_TOKEN_REGEXP = /^[0-9a-f]{40}$/
|
||||
|
||||
|
|
@ -13,6 +15,7 @@ export function AccessTokenSettings(props: React.PropsWithChildren<Props>) {
|
|||
const hasAccessToken = Boolean(configContext.val.access_token)
|
||||
const useAccessToken = useStates('')
|
||||
const useAccessTokenHint = useStates<React.ReactNode>('')
|
||||
const focusInput = useStates(false)
|
||||
|
||||
const { val: accessTokenHint } = useAccessTokenHint
|
||||
const { val: accessToken } = useAccessToken
|
||||
|
|
@ -26,7 +29,7 @@ export function AccessTokenSettings(props: React.PropsWithChildren<Props>) {
|
|||
({ currentTarget: { value } }: React.FormEvent<HTMLInputElement>) => {
|
||||
useAccessToken.set(value)
|
||||
useAccessTokenHint.set(
|
||||
ACCESS_TOKEN_REGEXP.test(value) ? '' : 'This token is in unknown format.',
|
||||
ACCESS_TOKEN_REGEXP.test(value) ? '' : 'Gitako does not recognize the token.',
|
||||
)
|
||||
},
|
||||
[],
|
||||
|
|
@ -57,13 +60,17 @@ export function AccessTokenSettings(props: React.PropsWithChildren<Props>) {
|
|||
)
|
||||
|
||||
return (
|
||||
<div className={'gitako-settings-bar-content-section access-token'}>
|
||||
<h4>
|
||||
Access Token{' '}
|
||||
<a href={wikiLinks.createAccessToken} target="_blank">
|
||||
(?)
|
||||
</a>
|
||||
</h4>
|
||||
<SettingsSection
|
||||
title={
|
||||
<span>
|
||||
Access Token
|
||||
<a href={wikiLinks.createAccessToken} target="_blank">
|
||||
{' '}
|
||||
(?)
|
||||
</a>
|
||||
</span>
|
||||
}
|
||||
>
|
||||
{!hasAccessToken && (
|
||||
<a
|
||||
className={'link-button'}
|
||||
|
|
@ -79,25 +86,27 @@ export function AccessTokenSettings(props: React.PropsWithChildren<Props>) {
|
|||
</a>
|
||||
)}
|
||||
<div className={'access-token-input-control'}>
|
||||
<input
|
||||
className={'access-token-input form-control'}
|
||||
<TextInput
|
||||
backgroundColor="#fff"
|
||||
marginRight={1}
|
||||
className={'access-token-input'}
|
||||
disabled={hasAccessToken}
|
||||
placeholder={hasAccessToken ? 'Your token is saved' : 'Or input here manually'}
|
||||
value={accessToken}
|
||||
onFocus={() => focusInput.set(true)}
|
||||
onBlur={() => focusInput.set(false)}
|
||||
onChange={onInputAccessToken}
|
||||
onKeyPress={onPressAccessToken}
|
||||
/>
|
||||
{hasAccessToken && !accessToken ? (
|
||||
<button className={'btn'} onClick={() => configContext.set({ access_token: '' })}>
|
||||
Clear
|
||||
</button>
|
||||
<Button onClick={() => configContext.set({ access_token: '' })}>Clear</Button>
|
||||
) : (
|
||||
<button className={'btn'} onClick={() => saveToken()} disabled={!accessToken}>
|
||||
<Button onClick={() => saveToken()} disabled={!accessToken}>
|
||||
Save
|
||||
</button>
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
{accessTokenHint && <span className={'hint'}>{accessTokenHint}</span>}
|
||||
</div>
|
||||
{accessTokenHint && !focusInput.val && <span className={'hint'}>{accessTokenHint}</span>}
|
||||
</SettingsSection>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import { SimpleToggleField } from 'components/SimpleToggleField'
|
|||
import { useConfigs } from 'containers/ConfigsContext'
|
||||
import * as React from 'react'
|
||||
import { Config } from 'utils/configHelper'
|
||||
import { SettingsSection } from './SettingsSection'
|
||||
|
||||
const options: {
|
||||
key: Config['icons']
|
||||
|
|
@ -31,29 +32,27 @@ type Props = {}
|
|||
export function FileTreeSettings(props: React.PropsWithChildren<Props>) {
|
||||
const configContext = useConfigs()
|
||||
return (
|
||||
<div className={'gitako-settings-bar-content-section'}>
|
||||
<h4>File Tree</h4>
|
||||
<label className="form-label" htmlFor="file-tree-icons">
|
||||
Icons
|
||||
</label>
|
||||
<div>
|
||||
<select
|
||||
id="file-tree-icons"
|
||||
onChange={e => {
|
||||
configContext.set({
|
||||
icons: e.target.value as Config['icons'],
|
||||
})
|
||||
}}
|
||||
className={'file-tree-input form-control'}
|
||||
placeholder={'focus here and press the shortcut keys'}
|
||||
value={configContext.val.icons}
|
||||
>
|
||||
{options.map(option => (
|
||||
<option key={option.key} value={option.value}>
|
||||
{option.label}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
<SettingsSection title={'File Tree'}>
|
||||
<div className={'field'}>
|
||||
<label htmlFor="file-tree-icons">Icons</label>
|
||||
<div>
|
||||
<select
|
||||
id="file-tree-icons"
|
||||
onChange={e => {
|
||||
configContext.set({
|
||||
icons: e.target.value as Config['icons'],
|
||||
})
|
||||
}}
|
||||
className={'file-tree-input form-control'}
|
||||
value={configContext.val.icons}
|
||||
>
|
||||
{options.map(option => (
|
||||
<option key={option.key} value={option.value}>
|
||||
{option.label}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<SimpleToggleField
|
||||
field={{
|
||||
|
|
@ -62,6 +61,6 @@ export function FileTreeSettings(props: React.PropsWithChildren<Props>) {
|
|||
wikiLink: wikiLinks.compressSingletonFolder,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</SettingsSection>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
13
src/components/settings/SettingsSection.tsx
Normal file
13
src/components/settings/SettingsSection.tsx
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
import * as React from 'react'
|
||||
type Props = {
|
||||
title: React.ReactNode
|
||||
}
|
||||
|
||||
export function SettingsSection({ title, children }: React.PropsWithChildren<Props>) {
|
||||
return (
|
||||
<div className={'settings-section'}>
|
||||
<h4>{title}</h4>
|
||||
{children}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
@ -1,9 +1,11 @@
|
|||
import { Button, TextInput } from '@primer/components'
|
||||
import { SimpleToggleField } from 'components/SimpleToggleField'
|
||||
import { useConfigs } from 'containers/ConfigsContext'
|
||||
import * as React from 'react'
|
||||
import { friendlyFormatShortcut } from 'utils/general'
|
||||
import { useStates } from 'utils/hooks/useStates'
|
||||
import * as keyHelper from 'utils/keyHelper'
|
||||
import { SettingsSection } from './SettingsSection'
|
||||
|
||||
type Props = {}
|
||||
|
||||
|
|
@ -11,43 +13,46 @@ export function SidebarSettings(props: React.PropsWithChildren<Props>) {
|
|||
const configContext = useConfigs()
|
||||
const useToggleShowSideBarShortcut = useStates(configContext.val.shortcut)
|
||||
const { val: toggleShowSideBarShortcut } = useToggleShowSideBarShortcut
|
||||
const focused = useStates(false)
|
||||
|
||||
React.useEffect(() => {
|
||||
useToggleShowSideBarShortcut.set(configContext.val.shortcut)
|
||||
}, [configContext.val.shortcut])
|
||||
|
||||
return (
|
||||
<div className={'gitako-settings-bar-content-section toggle-shortcut'}>
|
||||
<h4>Toggle Sidebar</h4>
|
||||
<label className="form-label" htmlFor="toggle-sidebar-shortcut">
|
||||
Keyboard Shortcut
|
||||
</label>
|
||||
<div className={'toggle-shortcut-input-control'}>
|
||||
<input
|
||||
id="toggle-sidebar-shortcut"
|
||||
className={'toggle-shortcut-input form-control'}
|
||||
placeholder={'focus here and press the shortcut keys'}
|
||||
value={friendlyFormatShortcut(toggleShowSideBarShortcut)}
|
||||
onKeyDown={React.useCallback((e: React.KeyboardEvent<HTMLInputElement>) => {
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
// Clear shortcut with backspace
|
||||
const shortcut = e.key === 'Backspace' ? '' : keyHelper.parseEvent(e)
|
||||
useToggleShowSideBarShortcut.set(shortcut)
|
||||
}, [])}
|
||||
readOnly
|
||||
/>
|
||||
<button
|
||||
className={'btn'}
|
||||
disabled={toggleShowSideBarShortcut === configContext.val.shortcut}
|
||||
onClick={() => {
|
||||
const { val: toggleShowSideBarShortcut } = useToggleShowSideBarShortcut
|
||||
if (typeof toggleShowSideBarShortcut !== 'string') return
|
||||
configContext.set({ shortcut: toggleShowSideBarShortcut })
|
||||
}}
|
||||
>
|
||||
Save
|
||||
</button>
|
||||
<SettingsSection title={'Toggle Sidebar'}>
|
||||
<div className={'field'}>
|
||||
<label htmlFor="toggle-sidebar-shortcut">Keyboard Shortcut</label>
|
||||
<div className={'toggle-shortcut-input-control'}>
|
||||
<TextInput
|
||||
id="toggle-sidebar-shortcut"
|
||||
backgroundColor="#fff"
|
||||
marginRight={1}
|
||||
className={'toggle-shortcut-input'}
|
||||
onFocus={() => focused.set(true)}
|
||||
onBlur={() => focused.set(false)}
|
||||
placeholder={focused.val ? 'Press key combination' : 'Click here to set'}
|
||||
value={friendlyFormatShortcut(toggleShowSideBarShortcut)}
|
||||
onKeyDown={React.useCallback((e: React.KeyboardEvent<HTMLInputElement>) => {
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
// Clear shortcut with backspace
|
||||
const shortcut = e.key === 'Backspace' ? '' : keyHelper.parseEvent(e)
|
||||
useToggleShowSideBarShortcut.set(shortcut)
|
||||
}, [])}
|
||||
readOnly
|
||||
/>
|
||||
<Button
|
||||
disabled={toggleShowSideBarShortcut === configContext.val.shortcut}
|
||||
onClick={() => {
|
||||
const { val: toggleShowSideBarShortcut } = useToggleShowSideBarShortcut
|
||||
if (typeof toggleShowSideBarShortcut !== 'string') return
|
||||
configContext.set({ shortcut: toggleShowSideBarShortcut })
|
||||
}}
|
||||
>
|
||||
Save
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
<SimpleToggleField
|
||||
field={{
|
||||
|
|
@ -59,6 +64,6 @@ export function SidebarSettings(props: React.PropsWithChildren<Props>) {
|
|||
},
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</SettingsSection>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
310
src/content.scss
310
src/content.scss
|
|
@ -1,5 +1,14 @@
|
|||
@import '~nprogress/nprogress.css';
|
||||
|
||||
@import '~@primer/css/base/index.scss';
|
||||
|
||||
@import '~@primer/css/support/variables/colors.scss';
|
||||
@import '~@primer/css/support/variables/color-system.scss';
|
||||
@import '~@primer/css/support/variables/typography.scss';
|
||||
@import '~@primer/css/support/variables/misc.scss';
|
||||
@import '~@primer/css/support/variables/layout.scss';
|
||||
@import '~@primer/css/marketing/support/variables.scss';
|
||||
|
||||
$name: gitako;
|
||||
|
||||
$min-screen-width: 1280px;
|
||||
|
|
@ -17,7 +26,7 @@ $minimal-z-index: max($github-header-z-index, $github-pull-request-float-header-
|
|||
|
||||
.#{$name}-ready {
|
||||
.js-header-wrapper {
|
||||
background: #24292e;
|
||||
background: $gray-dark;
|
||||
}
|
||||
.Header {
|
||||
max-width: 1012px;
|
||||
|
|
@ -43,14 +52,14 @@ $minimal-z-index: max($github-header-z-index, $github-pull-request-float-header-
|
|||
.clippy {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border: 1px solid #ddd;
|
||||
border: 1px solid $border-gray-dark;
|
||||
border-radius: 4px;
|
||||
background: #f9f9f9;
|
||||
background: $bg-gray-light;
|
||||
&:hover {
|
||||
background: #fff;
|
||||
background: $bg-white;
|
||||
}
|
||||
&:active {
|
||||
background: #f0f0f0;
|
||||
background: $bg-gray-light;
|
||||
}
|
||||
.icon {
|
||||
width: 100%;
|
||||
|
|
@ -107,15 +116,15 @@ $minimal-z-index: max($github-header-z-index, $github-pull-request-float-header-
|
|||
animation: toggle-show-button-wrapper-expand $animation-duration;
|
||||
|
||||
&.collapsed {
|
||||
border-color: #999999;
|
||||
border-color: $border-gray;
|
||||
border-radius: 3px;
|
||||
background: #f5f5f5;
|
||||
background: $bg-gray;
|
||||
|
||||
@include transform-collapsed();
|
||||
animation: toggle-show-button-wrapper-collapse $animation-duration;
|
||||
|
||||
.action-icon {
|
||||
color: #0366d6d0;
|
||||
color: $blue;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -138,7 +147,7 @@ $minimal-z-index: max($github-header-z-index, $github-pull-request-float-header-
|
|||
}
|
||||
|
||||
.action-icon {
|
||||
color: #666666;
|
||||
color: $gray;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
text-align: center;
|
||||
|
|
@ -151,7 +160,7 @@ $minimal-z-index: max($github-header-z-index, $github-pull-request-float-header-
|
|||
|
||||
&.error {
|
||||
.action-icon {
|
||||
color: #d73a49;
|
||||
color: $red;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -191,13 +200,13 @@ $minimal-z-index: max($github-header-z-index, $github-pull-request-float-header-
|
|||
cursor: ew-resize;
|
||||
user-select: none;
|
||||
width: 0;
|
||||
background: #e1e4e8;
|
||||
border-left: 1px solid #e1e4e8;
|
||||
background: $bg-gray;
|
||||
border-right: 1px solid $border-gray;
|
||||
overflow: hidden;
|
||||
&:hover {
|
||||
&:hover,
|
||||
&:active {
|
||||
width: 16px;
|
||||
background: #fafbfc;
|
||||
border-right: 1px solid #e1e4e8;
|
||||
background: $bg-gray-light;
|
||||
}
|
||||
|
||||
.octicon {
|
||||
|
|
@ -212,9 +221,9 @@ $minimal-z-index: max($github-header-z-index, $github-pull-request-float-header-
|
|||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background: #fafbfc;
|
||||
border-right: 1px solid #e1e4e8;
|
||||
border-left: 1px solid #e1e4e8;
|
||||
background: $bg-gray-light;
|
||||
border-right: 1px solid $border-gray-light;
|
||||
border-left: 1px solid $border-gray;
|
||||
overflow: hidden;
|
||||
|
||||
&.hidden {
|
||||
|
|
@ -223,11 +232,15 @@ $minimal-z-index: max($github-header-z-index, $github-pull-request-float-header-
|
|||
|
||||
.octicon {
|
||||
transition: transform 0.3s ease;
|
||||
color: rgba(3, 47, 98, 0.55);
|
||||
color: rgba($blue-800, 0.55);
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.octicon-color {
|
||||
color: rgba($blue-800, 0.55);
|
||||
}
|
||||
|
||||
.octicon-wrapper {
|
||||
display: inline-block;
|
||||
width: 16px;
|
||||
|
|
@ -235,10 +248,6 @@ $minimal-z-index: max($github-header-z-index, $github-pull-request-float-header-
|
|||
text-align: center;
|
||||
}
|
||||
|
||||
.octicon-color {
|
||||
color: rgba(3, 47, 98, 0.55);
|
||||
}
|
||||
|
||||
.#{$name}-side-bar-content {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
|
|
@ -247,20 +256,11 @@ $minimal-z-index: max($github-header-z-index, $github-pull-request-float-header-
|
|||
min-height: 0; // make content shrinkable
|
||||
|
||||
.meta-bar {
|
||||
position: relative;
|
||||
position: relative; // prevent overlap by outline of other elements
|
||||
padding: 10px;
|
||||
padding-right: 30px;
|
||||
font-size: 13px;
|
||||
line-height: 20px;
|
||||
color: #586069;
|
||||
background-color: #f1f8ff;
|
||||
border-bottom: 1px solid #c8e1ff;
|
||||
|
||||
a {
|
||||
// fix a weird bug:
|
||||
// when gitako failed loading repo, cursor hovering <a> in meta bar will be 'text'
|
||||
cursor: pointer;
|
||||
}
|
||||
padding-right: 30px; // space for toggle button
|
||||
background: $bg-blue-light;
|
||||
border-bottom: 1px solid $border-gray;
|
||||
|
||||
.repo-name {
|
||||
font-weight: bolder;
|
||||
|
|
@ -314,108 +314,96 @@ $minimal-z-index: max($github-header-z-index, $github-pull-request-float-header-
|
|||
|
||||
/* search input */
|
||||
.search-input-wrapper {
|
||||
input.form-control {
|
||||
.search-input {
|
||||
width: 100%;
|
||||
|
||||
&.error {
|
||||
border-color: #d73a49;
|
||||
border-color: $red;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.no-results {
|
||||
padding: 0px 10px;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.files {
|
||||
flex: 1;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.node-item-row {
|
||||
background: #fff;
|
||||
.node-item {
|
||||
background: $bg-white;
|
||||
&:hover {
|
||||
background: #f6f8fa;
|
||||
background: $bg-gray-light;
|
||||
}
|
||||
&.focused {
|
||||
background: #f0f0f6;
|
||||
&.focused,
|
||||
&:active {
|
||||
background: $bg-gray;
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
.node-item {
|
||||
pointer-events: none;
|
||||
color: #999999;
|
||||
color: $gray-light;
|
||||
}
|
||||
}
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin: 0;
|
||||
color: $blue;
|
||||
line-height: 20px;
|
||||
padding: 6px 10px;
|
||||
cursor: pointer;
|
||||
border-top: 1px solid $border-gray-light;
|
||||
white-space: nowrap;
|
||||
|
||||
@mixin icon-size() {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
.octicon-wrapper:first-child {
|
||||
margin-right: 6px;
|
||||
}
|
||||
|
||||
&-type-icon {
|
||||
margin-right: 4px;
|
||||
@include icon-size();
|
||||
|
||||
& + .octicon-wrapper,
|
||||
& + .node-item-icon {
|
||||
margin-right: 6px;
|
||||
}
|
||||
}
|
||||
|
||||
.node-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin: 0;
|
||||
color: #0366d6;
|
||||
line-height: 20px;
|
||||
padding: 6px 10px;
|
||||
cursor: pointer;
|
||||
border-top: 1px solid #eaecef;
|
||||
transition: all 0.5s ease;
|
||||
&-icon {
|
||||
@include icon-size();
|
||||
object-fit: contain;
|
||||
vertical-align: text-bottom;
|
||||
box-sizing: content-box;
|
||||
|
||||
&.dim {
|
||||
filter: sepia(1) hue-rotate(180deg);
|
||||
}
|
||||
}
|
||||
|
||||
// folder icon rotate when expand
|
||||
&.expanded .octicon.ChevronRight {
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
|
||||
.node-item-label {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.go-to-button {
|
||||
display: none;
|
||||
white-space: nowrap;
|
||||
|
||||
@mixin icon-size() {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
.octicon-wrapper:first-child {
|
||||
margin-right: 6px;
|
||||
}
|
||||
|
||||
&-type-icon {
|
||||
margin-right: 4px;
|
||||
@include icon-size();
|
||||
|
||||
& + .octicon-wrapper,
|
||||
& + .node-item-icon {
|
||||
margin-right: 6px;
|
||||
}
|
||||
}
|
||||
|
||||
&-icon {
|
||||
@include icon-size();
|
||||
object-fit: contain;
|
||||
vertical-align: text-bottom;
|
||||
box-sizing: content-box;
|
||||
|
||||
&.dim {
|
||||
filter: sepia(1) hue-rotate(180deg);
|
||||
}
|
||||
}
|
||||
|
||||
// folder icon rotate when expand
|
||||
&.expanded .octicon.ChevronRight {
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
|
||||
.node-item-label {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
&:hover .node-item-name {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
background: transparent;
|
||||
border: none;
|
||||
padding: 0;
|
||||
}
|
||||
&:hover {
|
||||
.go-to-button {
|
||||
display: none;
|
||||
white-space: nowrap;
|
||||
background: transparent;
|
||||
border: none;
|
||||
padding: 0;
|
||||
}
|
||||
&:hover {
|
||||
.go-to-button {
|
||||
display: inline-block;
|
||||
}
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -424,12 +412,12 @@ $minimal-z-index: max($github-header-z-index, $github-pull-request-float-header-
|
|||
|
||||
.#{$name}-settings-bar {
|
||||
z-index: 2;
|
||||
background: #fafbfc;
|
||||
background: $bg-gray-light;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
max-height: 100%;
|
||||
&-title {
|
||||
border-top: 1px solid #eaecef;
|
||||
border-top: 1px solid $border-gray-light;
|
||||
padding: 6px 10px;
|
||||
box-shadow: 0 1px 8px 0 rgba(0, 0, 0, 0.2), 0 3px 4px 0 rgba(0, 0, 0, 0.14),
|
||||
0 3px 3px -2px rgba(0, 0, 0, 0.12);
|
||||
|
|
@ -447,58 +435,60 @@ $minimal-z-index: max($github-header-z-index, $github-pull-request-float-header-
|
|||
height: 10px;
|
||||
top: 0;
|
||||
left: 0;
|
||||
background: #fafbfc;
|
||||
background: $bg-gray-light;
|
||||
z-index: 1;
|
||||
}
|
||||
&-section {
|
||||
.settings-section {
|
||||
&:not(:last-of-type) {
|
||||
padding-bottom: 16px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.description:hover {
|
||||
cursor: help;
|
||||
.field {
|
||||
margin-bottom: 4px;
|
||||
|
||||
label {
|
||||
display: inline-block;
|
||||
margin-bottom: 2px;
|
||||
font-weight: 500;
|
||||
}
|
||||
&.field-checkbox {
|
||||
padding-left: 20px;
|
||||
vertical-align: middle;
|
||||
label {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
input {
|
||||
&:disabled {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
input[type='checkbox'],
|
||||
input[type='radio'] {
|
||||
float: left;
|
||||
margin: 5px 0 0 -20px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
select {
|
||||
-moz-appearance: none;
|
||||
background: $bg-white;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* inputs for access token & shortcut were too wide */
|
||||
input.form-control {
|
||||
min-width: 100px;
|
||||
}
|
||||
|
||||
.form-checkbox {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
select {
|
||||
-moz-appearance: none;
|
||||
}
|
||||
.form-label {
|
||||
margin-bottom: 2px;
|
||||
.link-button {
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
.access-token {
|
||||
border-bottom: none; // prevent overwrite by github style
|
||||
.link-button {
|
||||
cursor: pointer;
|
||||
}
|
||||
.hint {
|
||||
color: #6a737d;
|
||||
}
|
||||
.hint {
|
||||
color: $gray;
|
||||
}
|
||||
.access-token-input-control {
|
||||
display: flex;
|
||||
margin-top: 8px;
|
||||
.access-token-input {
|
||||
flex: 1;
|
||||
|
||||
&:disabled {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
}
|
||||
.toggle-shortcut {
|
||||
.hint {
|
||||
color: #6a737d;
|
||||
}
|
||||
}
|
||||
.toggle-shortcut-input-control {
|
||||
|
|
@ -507,22 +497,14 @@ $minimal-z-index: max($github-header-z-index, $github-pull-request-float-header-
|
|||
flex: 1;
|
||||
}
|
||||
}
|
||||
.singleton {
|
||||
.hint {
|
||||
color: #6a737d;
|
||||
}
|
||||
}
|
||||
.header-row {
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 6px 10px;
|
||||
border-top: 1px solid #eaecef;
|
||||
border-top: 1px solid $border-gray-light;
|
||||
|
||||
.version {
|
||||
color: #999999;
|
||||
}
|
||||
.show-settings-icon {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
|
|
@ -534,10 +516,6 @@ $minimal-z-index: max($github-header-z-index, $github-pull-request-float-header-
|
|||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
input.form-control:not(:last-child) {
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue