mirror of
https://github.com/BoostIo/Boostnote
synced 2025-12-13 17:56:25 +00:00
cleanup style and class name of ArticleDetail
This commit is contained in:
@@ -37,27 +37,9 @@ export default class ModeSelect extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
handleIdleSelectClick (e) {
|
handleIdleSelectClick (e) {
|
||||||
this.setState({mode: EDIT_MODE})
|
this.setState({mode: EDIT_MODE, search: this.props.value}, () => {
|
||||||
}
|
ReactDOM.findDOMNode(this.refs.search).select()
|
||||||
|
})
|
||||||
componentDidUpdate (prevProps, prevState) {
|
|
||||||
if (prevState.mode !== this.state.mode && this.state.mode === EDIT_MODE) {
|
|
||||||
let searchElement = ReactDOM.findDOMNode(this.refs.search)
|
|
||||||
searchElement.focus()
|
|
||||||
if (this.searchKeyDownListener == null) {
|
|
||||||
this.searchKeyDownListener = e => this.handleSearchKeyDown
|
|
||||||
}
|
|
||||||
searchElement.addEventListener('keydown', this.searchKeyDownListener)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
componentWillUpdate (nextProps, nextState) {
|
|
||||||
if (nextProps.mode !== this.state.mode && nextState.mode === IDLE_MODE) {
|
|
||||||
let searchElement = ReactDOM.findDOMNode(this.refs.search)
|
|
||||||
if (searchElement != null && this.searchKeyDownListener != null) {
|
|
||||||
searchElement.removeEventListener('keydown', this.searchKeyDownListener)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
handleModeOptionClick (modeName) {
|
handleModeOptionClick (modeName) {
|
||||||
@@ -82,9 +64,9 @@ export default class ModeSelect extends React.Component {
|
|||||||
case 40:
|
case 40:
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
{
|
{
|
||||||
|
let search = _.escapeRegExp(this.state.search)
|
||||||
let filteredModes = modes
|
let filteredModes = modes
|
||||||
.filter(mode => {
|
.filter(mode => {
|
||||||
let search = this.state.search
|
|
||||||
let nameMatched = mode.name.match(search)
|
let nameMatched = mode.name.match(search)
|
||||||
let aliasMatched = _.some(mode.alias, alias => alias.match(search))
|
let aliasMatched = _.some(mode.alias, alias => alias.match(search))
|
||||||
return nameMatched || aliasMatched
|
return nameMatched || aliasMatched
|
||||||
@@ -97,9 +79,9 @@ export default class ModeSelect extends React.Component {
|
|||||||
case 13:
|
case 13:
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
{
|
{
|
||||||
|
let search = _.escapeRegExp(this.state.search)
|
||||||
let filteredModes = modes
|
let filteredModes = modes
|
||||||
.filter(mode => {
|
.filter(mode => {
|
||||||
let search = this.state.search
|
|
||||||
let nameMatched = mode.name.match(search)
|
let nameMatched = mode.name.match(search)
|
||||||
let aliasMatched = _.some(mode.alias, alias => alias.match(search))
|
let aliasMatched = _.some(mode.alias, alias => alias.match(search))
|
||||||
return nameMatched || aliasMatched
|
return nameMatched || aliasMatched
|
||||||
@@ -148,33 +130,31 @@ export default class ModeSelect extends React.Component {
|
|||||||
if (this.state.mode === IDLE_MODE) {
|
if (this.state.mode === IDLE_MODE) {
|
||||||
let mode = _.findWhere(modes, {name: this.props.value})
|
let mode = _.findWhere(modes, {name: this.props.value})
|
||||||
let modeName = mode != null ? mode.name : 'text'
|
let modeName = mode != null ? mode.name : 'text'
|
||||||
let modeLabel = mode != null ? mode.label : 'Plain text'
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={className + ' idle'} onClick={e => this.handleIdleSelectClick(e)}>
|
<div className={className + ' idle'} onClick={e => this.handleIdleSelectClick(e)}>
|
||||||
<ModeIcon mode={modeName}/>
|
<ModeIcon mode={modeName}/>
|
||||||
<span className='modeLabel'>{modeLabel}</span>
|
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let search = _.escapeRegExp(this.state.search)
|
||||||
let filteredOptions = modes
|
let filteredOptions = modes
|
||||||
.filter(mode => {
|
.filter(mode => {
|
||||||
let search = this.state.search
|
let nameMatched = mode.name.match(search)
|
||||||
let nameMatched = mode.name.match(_.escapeRegExp(search))
|
let aliasMatched = _.some(mode.alias, alias => alias.match(search))
|
||||||
let aliasMatched = _.some(mode.alias, alias => alias.match(_.escapeRegExp(search)))
|
|
||||||
return nameMatched || aliasMatched
|
return nameMatched || aliasMatched
|
||||||
})
|
})
|
||||||
.map((mode, index) => {
|
.map((mode, index) => {
|
||||||
return (
|
return (
|
||||||
<div key={mode.name} className={index === this.state.focusIndex ? 'option active' : 'option'} onClick={e => this.handleModeOptionClick(mode.name)(e)}><ModeIcon mode={mode.name}/>{mode.label}</div>
|
<div key={mode.name} className={index === this.state.focusIndex ? 'ModeSelect-options-item active' : 'ModeSelect-options-item'} onClick={e => this.handleModeOptionClick(mode.name)(e)}><ModeIcon mode={mode.name}/>{mode.label}</div>
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={className + ' edit'}>
|
<div className={className + ' edit'}>
|
||||||
<input onKeyDown={e => this.handleSearchKeyDown(e)} ref='search' onChange={e => this.handleSearchChange(e)} value={this.state.search} type='text'/>
|
<input onKeyDown={e => this.handleSearchKeyDown(e)} ref='search' onChange={e => this.handleSearchChange(e)} value={this.state.search} type='text'/>
|
||||||
<div ref='options' className='modeOptions hide'>
|
<div ref='options' className='ModeSelect-options hide'>
|
||||||
{filteredOptions}
|
{filteredOptions}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -117,10 +117,10 @@ export default class TagSelect extends React.Component {
|
|||||||
|
|
||||||
let tagElements = _.isArray(tags)
|
let tagElements = _.isArray(tags)
|
||||||
? this.props.tags.map(tag => (
|
? this.props.tags.map(tag => (
|
||||||
<span key={tag} className='tagItem'>
|
<div key={tag} className='TagSelect-tags-item'>
|
||||||
<button onClick={e => this.handleItemRemoveButton(tag)(e)} className='tagRemoveBtn'><i className='fa fa-fw fa-times'/></button>
|
<button onClick={e => this.handleItemRemoveButton(tag)(e)} className='TagSelect-tags-item-remove'><i className='fa fa-fw fa-times'/></button>
|
||||||
<span className='tagLabel'>{tag}</span>
|
<div className='TagSelect-tags-item-label'>{tag}</div>
|
||||||
</span>))
|
</div>))
|
||||||
: null
|
: null
|
||||||
|
|
||||||
let suggestElements = this.shouldShowSuggest() ? suggestTags
|
let suggestElements = this.shouldShowSuggest() ? suggestTags
|
||||||
@@ -134,7 +134,7 @@ export default class TagSelect extends React.Component {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='TagSelect' onClick={e => this.handleThisClick(e)}>
|
<div className='TagSelect' onClick={e => this.handleThisClick(e)}>
|
||||||
<div className='tags'>
|
<div className='TagSelect-tags'>
|
||||||
{tagElements}
|
{tagElements}
|
||||||
<input
|
<input
|
||||||
type='text'
|
type='text'
|
||||||
@@ -142,13 +142,13 @@ export default class TagSelect extends React.Component {
|
|||||||
ref='tagInput'
|
ref='tagInput'
|
||||||
valueLink={this.linkState('input')}
|
valueLink={this.linkState('input')}
|
||||||
placeholder='Click here to add tags'
|
placeholder='Click here to add tags'
|
||||||
className='tagInput'
|
className='TagSelect-input'
|
||||||
onFocus={e => this.handleInputFocus(e)}
|
onFocus={e => this.handleInputFocus(e)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{suggestElements != null && suggestElements.length > 0
|
{suggestElements != null && suggestElements.length > 0
|
||||||
? (
|
? (
|
||||||
<div ref='suggestTags' className='suggestTags'>
|
<div ref='suggestTags' className='TagSelect-suggest'>
|
||||||
{suggestElements}
|
{suggestElements}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ export default class ShareButton extends React.Component {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
</button>
|
</button>
|
||||||
<div ref='dropdown' className={'share-dropdown' + (this.state.openDropdown ? '' : ' hide')}>
|
<div ref='dropdown' className={'ShareButton-dropdown' + (this.state.openDropdown ? '' : ' hide')}>
|
||||||
{
|
{
|
||||||
!hasPublicURL ? (
|
!hasPublicURL ? (
|
||||||
<button
|
<button
|
||||||
|
|||||||
@@ -174,119 +174,6 @@ export default class ArticleDetail extends React.Component {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
handleEditButtonClick (e) {
|
|
||||||
let { dispatch } = this.props
|
|
||||||
dispatch(switchMode(EDIT_MODE))
|
|
||||||
}
|
|
||||||
|
|
||||||
handleDeleteButtonClick (e) {
|
|
||||||
this.setState({openDeleteConfirmMenu: true})
|
|
||||||
}
|
|
||||||
|
|
||||||
handleDeleteConfirmButtonClick (e) {
|
|
||||||
let { dispatch, activeArticle } = this.props
|
|
||||||
|
|
||||||
dispatch(destroyArticle(activeArticle.key))
|
|
||||||
activityRecord.emit('ARTICLE_DESTROY')
|
|
||||||
this.setState({openDeleteConfirmMenu: false})
|
|
||||||
}
|
|
||||||
|
|
||||||
handleDeleteCancelButtonClick (e) {
|
|
||||||
this.setState({openDeleteConfirmMenu: false})
|
|
||||||
}
|
|
||||||
|
|
||||||
renderIdle () {
|
|
||||||
let { status, activeArticle, folders, user } = this.props
|
|
||||||
|
|
||||||
let tags = activeArticle.tags != null ? activeArticle.tags.length > 0
|
|
||||||
? activeArticle.tags.map(tag => {
|
|
||||||
return (<TagLink key={tag} tag={tag}/>)
|
|
||||||
})
|
|
||||||
: (
|
|
||||||
<span className='noTags'>Not tagged yet</span>
|
|
||||||
) : null
|
|
||||||
|
|
||||||
let folder = _.findWhere(folders, {key: activeArticle.FolderKey})
|
|
||||||
|
|
||||||
let title = activeArticle.title.trim().length === 0
|
|
||||||
? <small>(Untitled)</small>
|
|
||||||
: activeArticle.title
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className='ArticleDetail idle'>
|
|
||||||
{this.state.openDeleteConfirmMenu
|
|
||||||
? (
|
|
||||||
<div className='deleteConfirm'>
|
|
||||||
<div className='right'>
|
|
||||||
Are you sure to delete this article?
|
|
||||||
<button onClick={e => this.handleDeleteConfirmButtonClick(e)} className='primary'>
|
|
||||||
<i className='fa fa-fw fa-check'/> Sure
|
|
||||||
</button>
|
|
||||||
<button onClick={e => this.handleDeleteCancelButtonClick(e)}>
|
|
||||||
<i className='fa fa-fw fa-times'/> Cancel
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
: (
|
|
||||||
<div className='detailInfo'>
|
|
||||||
<div className='left'>
|
|
||||||
<div className='info'>
|
|
||||||
<FolderMark color={folder.color}/> <span className='folderName'>{folder.name}</span>
|
|
||||||
Created : {moment(activeArticle.createdAt).format('YYYY/MM/DD')}
|
|
||||||
Updated : {moment(activeArticle.updatedAt).format('YYYY/MM/DD')}
|
|
||||||
</div>
|
|
||||||
<div className='tags'><i className='fa fa-fw fa-tags'/>{tags}</div>
|
|
||||||
</div>
|
|
||||||
<div className='right'>
|
|
||||||
<ShareButton
|
|
||||||
article={activeArticle}
|
|
||||||
user={user}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<button onClick={e => this.handleClipboardButtonClick(e)} className='editBtn'>
|
|
||||||
<i className='fa fa-fw fa-clipboard'/><span className='tooltip'>Copy to clipboard</span>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<button onClick={e => this.handleEditButtonClick(e)} className='editBtn'>
|
|
||||||
<i className='fa fa-fw fa-edit'/><span className='tooltip'>Edit (e)</span>
|
|
||||||
</button>
|
|
||||||
<button onClick={e => this.handleDeleteButtonClick(e)} className='deleteBtn'>
|
|
||||||
<i className='fa fa-fw fa-trash'/><span className='tooltip'>Delete (d)</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{status.isTutorialOpen ? editDeleteTutorialElement : null}
|
|
||||||
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
<div className='detailBody'>
|
|
||||||
<div className='detailPanel'>
|
|
||||||
<div className='header'>
|
|
||||||
<ModeIcon className='mode' mode={activeArticle.mode}/>
|
|
||||||
<div className='title'>{title}</div>
|
|
||||||
</div>
|
|
||||||
{activeArticle.mode === 'markdown'
|
|
||||||
? <MarkdownPreview content={activeArticle.content}/>
|
|
||||||
: <CodeEditor readOnly onChange={(e, value) => this.handleContentChange(e, value)} mode={activeArticle.mode} code={activeArticle.content}/>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
handleCancelButtonClick (e) {
|
|
||||||
let { activeArticle, dispatch } = this.props
|
|
||||||
|
|
||||||
if (activeArticle.status === NEW) {
|
|
||||||
dispatch(switchArticle(null))
|
|
||||||
}
|
|
||||||
dispatch(switchMode(IDLE_MODE))
|
|
||||||
}
|
|
||||||
|
|
||||||
handleSaveButtonClick (e) {
|
handleSaveButtonClick (e) {
|
||||||
let { dispatch, folders, status } = this.props
|
let { dispatch, folders, status } = this.props
|
||||||
let article = this.state.article
|
let article = this.state.article
|
||||||
@@ -485,8 +372,8 @@ export default class ArticleDetail extends React.Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
renderEdit () {
|
render () {
|
||||||
let { folders, status, tags } = this.props
|
let { folders, status, tags, activeArticle, user } = this.props
|
||||||
|
|
||||||
let folderOptions = folders.map(folder => {
|
let folderOptions = folders.map(folder => {
|
||||||
return (
|
return (
|
||||||
@@ -495,11 +382,11 @@ export default class ArticleDetail extends React.Component {
|
|||||||
})
|
})
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='ArticleDetail edit'>
|
<div className='ArticleDetail'>
|
||||||
<div className='detailInfo'>
|
<div className='ArticleDetail-info'>
|
||||||
<div className='left'>
|
<div className='ArticleDetail-info-row'>
|
||||||
<select
|
<select
|
||||||
className='folder'
|
className='ArticleDetail-info-folder'
|
||||||
value={this.state.article.FolderKey}
|
value={this.state.article.FolderKey}
|
||||||
onChange={e => this.handleFolderKeyChange(e)}
|
onChange={e => this.handleFolderKeyChange(e)}
|
||||||
>
|
>
|
||||||
@@ -507,6 +394,26 @@ export default class ArticleDetail extends React.Component {
|
|||||||
</select>
|
</select>
|
||||||
{this.state.isArticleEdited ? ' (edited)' : ''}
|
{this.state.isArticleEdited ? ' (edited)' : ''}
|
||||||
|
|
||||||
|
<div className='ArticleDetail-info-control'>
|
||||||
|
<ShareButton
|
||||||
|
article={activeArticle}
|
||||||
|
user={user}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<button onClick={e => this.handleClipboardButtonClick(e)}>
|
||||||
|
<i className='fa fa-fw fa-clipboard'/><span className='tooltip'>Copy to clipboard</span>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button onClick={e => this.handleEditButtonClick(e)}>
|
||||||
|
<i className='fa fa-fw fa-edit'/><span className='tooltip'>Save (⌘ + s)</span>
|
||||||
|
</button>
|
||||||
|
<button onClick={e => this.handleDeleteButtonClick(e)}>
|
||||||
|
<i className='fa fa-fw fa-trash'/><span className='tooltip'>Delete</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{status.isTutorialOpen ? editDeleteTutorialElement : null}
|
||||||
|
<div>
|
||||||
<TagSelect
|
<TagSelect
|
||||||
tags={this.state.article.tags}
|
tags={this.state.article.tags}
|
||||||
onChange={(tags, tag) => this.handleTagsChange(tags, tag)}
|
onChange={(tags, tag) => this.handleTagsChange(tags, tag)}
|
||||||
@@ -514,87 +421,46 @@ export default class ArticleDetail extends React.Component {
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
{status.isTutorialOpen ? tagSelectTutorialElement : null}
|
{status.isTutorialOpen ? tagSelectTutorialElement : null}
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className='right'>
|
|
||||||
{
|
|
||||||
this.state.article.mode === 'markdown'
|
|
||||||
? (<button className='preview' onClick={e => this.handleTogglePreviewButtonClick(e)}>
|
|
||||||
{
|
|
||||||
!this.state.previewMode
|
|
||||||
? 'Preview'
|
|
||||||
: 'Edit'
|
|
||||||
}
|
|
||||||
<span className='tooltip'>{process.platform === 'darwin' ? '⌘' : '^'} + p</span>
|
|
||||||
</button>)
|
|
||||||
: null
|
|
||||||
}
|
|
||||||
<button onClick={e => this.handleCancelButtonClick(e)} className='cancelBtn'>
|
|
||||||
Cancel
|
|
||||||
<span className='tooltip'>Esc</span>
|
|
||||||
</button>
|
|
||||||
<button onClick={e => this.handleSaveButtonClick(e)} className='saveBtn'>
|
|
||||||
Save
|
|
||||||
<span className='tooltip'>{process.platform === 'darwin' ? '⌘' : '^'} + s</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className='detailBody'>
|
|
||||||
<div className='detailPanel'>
|
<div className='ArticleDetail-panel'>
|
||||||
<div className='header'>
|
<div className='ArticleDetail-panel-header'>
|
||||||
<div className='title'>
|
<ModeSelect
|
||||||
<input
|
ref='mode'
|
||||||
onKeyDown={e => this.handleTitleKeyDown(e)}
|
onChange={e => this.handleModeChange(e)}
|
||||||
placeholder={this.state.article.createdAt == null
|
value={this.state.article.mode}
|
||||||
? `Created at ${moment().format('YYYY/MM/DD HH:mm')}`
|
className='ArticleDetail-panel-header-mode'
|
||||||
: 'Title'}
|
onBlur={() => this.handleModeSelectBlur()}
|
||||||
ref='title'
|
/>
|
||||||
value={this.state.article.title}
|
<div className='ArticleDetail-panel-header-title'>
|
||||||
onChange={e => this.handleTitleChange(e)}
|
<input
|
||||||
/>
|
onKeyDown={e => this.handleTitleKeyDown(e)}
|
||||||
</div>
|
placeholder={this.state.article.createdAt == null
|
||||||
<ModeSelect
|
? `Created at ${moment().format('YYYY/MM/DD HH:mm')}`
|
||||||
ref='mode'
|
: 'Title'}
|
||||||
onChange={e => this.handleModeChange(e)}
|
ref='title'
|
||||||
value={this.state.article.mode}
|
value={this.state.article.title}
|
||||||
className='mode'
|
onChange={e => this.handleTitleChange(e)}
|
||||||
onBlur={() => this.handleModeSelectBlur()}
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{status.isTutorialOpen ? modeSelectTutorialElement : null}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{this.state.previewMode
|
|
||||||
? <MarkdownPreview ref='preview' content={this.state.article.content}/>
|
|
||||||
: (<CodeEditor
|
|
||||||
ref='code'
|
|
||||||
onChange={(e, value) => this.handleContentChange(e, value)}
|
|
||||||
readOnly={false}
|
|
||||||
mode={this.state.article.mode}
|
|
||||||
code={this.state.article.content}
|
|
||||||
/>)
|
|
||||||
}
|
|
||||||
</div>
|
</div>
|
||||||
|
{status.isTutorialOpen ? modeSelectTutorialElement : null}
|
||||||
|
|
||||||
|
{this.state.previewMode
|
||||||
|
? <MarkdownPreview ref='preview' content={this.state.article.content}/>
|
||||||
|
: (<CodeEditor
|
||||||
|
ref='code'
|
||||||
|
onChange={(e, value) => this.handleContentChange(e, value)}
|
||||||
|
readOnly={false}
|
||||||
|
mode={this.state.article.mode}
|
||||||
|
code={this.state.article.content}
|
||||||
|
/>)
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
|
||||||
let { status, activeArticle } = this.props
|
|
||||||
|
|
||||||
if (activeArticle == null) return this.renderEmpty()
|
|
||||||
|
|
||||||
switch (status.mode) {
|
|
||||||
case EDIT_MODE:
|
|
||||||
return this.renderEdit()
|
|
||||||
case IDLE_MODE:
|
|
||||||
default:
|
|
||||||
return this.renderIdle()
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ArticleDetail.propTypes = {
|
ArticleDetail.propTypes = {
|
||||||
|
|||||||
@@ -1,6 +1,21 @@
|
|||||||
noTagsColor = #999
|
noTagsColor = #999
|
||||||
iptFocusBorderColor = #369DCD
|
iptFocusBorderColor = #369DCD
|
||||||
|
|
||||||
|
infoButton()
|
||||||
|
display inline-block
|
||||||
|
border-radius 16.5px
|
||||||
|
cursor pointer
|
||||||
|
height 33px
|
||||||
|
width 33px
|
||||||
|
border none
|
||||||
|
margin-right 5px
|
||||||
|
font-size 18px
|
||||||
|
color inactiveTextColor
|
||||||
|
background-color white
|
||||||
|
padding 0
|
||||||
|
&:hover
|
||||||
|
color inherit
|
||||||
|
|
||||||
.ArticleDetail
|
.ArticleDetail
|
||||||
absolute right bottom
|
absolute right bottom
|
||||||
top 60px
|
top 60px
|
||||||
@@ -10,414 +25,231 @@ iptFocusBorderColor = #369DCD
|
|||||||
border-top 1px solid borderColor
|
border-top 1px solid borderColor
|
||||||
border-left 1px solid borderColor
|
border-left 1px solid borderColor
|
||||||
*
|
*
|
||||||
-webkit-user-select all
|
-webkit-user-select none
|
||||||
.deleteConfirm
|
.ArticleDetail-info
|
||||||
width 100%
|
|
||||||
height 70px
|
|
||||||
.right
|
|
||||||
float right
|
|
||||||
button
|
|
||||||
cursor pointer
|
|
||||||
height 33px
|
|
||||||
padding 0 10px
|
|
||||||
margin-left 5px
|
|
||||||
font-size 14px
|
|
||||||
color inactiveTextColor
|
|
||||||
background-color darken(white, 5%)
|
|
||||||
border solid 1px borderColor
|
|
||||||
border-radius 5px
|
|
||||||
&:hover
|
|
||||||
background-color white
|
|
||||||
&.primary
|
|
||||||
border none
|
|
||||||
background-color brandColor
|
|
||||||
color white
|
|
||||||
&:hover
|
|
||||||
color white
|
|
||||||
background-color lighten(brandColor, 10%)
|
|
||||||
|
|
||||||
.detailInfo
|
|
||||||
height 70px
|
height 70px
|
||||||
width 100%
|
width 100%
|
||||||
font-size 12px
|
font-size 12px
|
||||||
position relative
|
&>.tutorial
|
||||||
.left
|
position fixed
|
||||||
absolute top left bottom
|
z-index 35
|
||||||
right 120px
|
.ArticleDetail-info-folder
|
||||||
.folderName
|
display inline-block
|
||||||
|
max-width 100px
|
||||||
|
overflow ellipsis
|
||||||
|
height 10px
|
||||||
|
width 150px
|
||||||
|
height 27px
|
||||||
|
outline none
|
||||||
|
background-color darken(white, 5%)
|
||||||
|
border 1px solid transparent
|
||||||
|
&:hover
|
||||||
|
background-color white
|
||||||
|
&:focus
|
||||||
|
border-color iptFocusBorderColor
|
||||||
|
&>.tutorial
|
||||||
|
position fixed
|
||||||
|
z-index 35
|
||||||
|
.ArticleDetail-info-control
|
||||||
|
float right
|
||||||
|
.ShareButton
|
||||||
display inline-block
|
display inline-block
|
||||||
max-width 100px
|
&>button, .ShareButton-open-button
|
||||||
overflow ellipsis
|
infoButton()
|
||||||
height 10px
|
.tooltip
|
||||||
.right
|
tooltip()
|
||||||
absolute top right
|
margin-top 30px
|
||||||
.detailBody
|
&:hover
|
||||||
absolute left right bottom
|
.tooltip
|
||||||
|
opacity 1
|
||||||
|
&:nth-child(1) .tooltip
|
||||||
|
margin-left -40px
|
||||||
|
&:nth-child(2) .tooltip
|
||||||
|
margin-left -80px
|
||||||
|
&:nth-child(3) .tooltip
|
||||||
|
margin-left -60px
|
||||||
|
&:nth-child(4) .tooltip
|
||||||
|
margin-left -50px
|
||||||
|
.ShareButton-dropdown
|
||||||
|
position fixed
|
||||||
|
&.hide
|
||||||
|
display none
|
||||||
|
|
||||||
|
.TagSelect
|
||||||
|
margin-top 5px
|
||||||
|
.TagSelect-tags
|
||||||
|
white-space nowrap
|
||||||
|
overflow-x auto
|
||||||
|
position relative
|
||||||
|
noSelect()
|
||||||
|
z-index 30
|
||||||
|
background-color #E6E6E6
|
||||||
|
clearfix()
|
||||||
|
.TagSelect-tags-item
|
||||||
|
background-color transparent
|
||||||
|
color white
|
||||||
|
margin 0 2px
|
||||||
|
padding 0
|
||||||
|
height 17px
|
||||||
|
float left
|
||||||
|
button.TagSelect-tags-item-remove
|
||||||
|
display block
|
||||||
|
float left
|
||||||
|
background-color transparent
|
||||||
|
border none
|
||||||
|
font-size 8px
|
||||||
|
color white
|
||||||
|
width 15px
|
||||||
|
height 17px
|
||||||
|
text-align center
|
||||||
|
line-height 12px
|
||||||
|
padding 0
|
||||||
|
margin 0
|
||||||
|
border-top solid 1px darken(brandColor, 5%)
|
||||||
|
border-bottom solid 1px darken(brandColor, 5%)
|
||||||
|
border-left solid 1px darken(brandColor, 5%)
|
||||||
|
border-radius left 2px
|
||||||
|
background-color brandColor
|
||||||
|
&:hover
|
||||||
|
background-color lighten(brandColor, 10%)
|
||||||
|
border-color lighten(brandColor, 10%)
|
||||||
|
.TagSelect-tags-item-label
|
||||||
|
background-color brandColor
|
||||||
|
float left
|
||||||
|
font-size 12px
|
||||||
|
border-top solid 1px darken(brandColor, 5%)
|
||||||
|
border-bottom solid 1px darken(brandColor, 5%)
|
||||||
|
border-right solid 1px darken(brandColor, 5%)
|
||||||
|
line-height 15px
|
||||||
|
padding 0 5px
|
||||||
|
border-radius right 2px
|
||||||
|
input.TagSelect-input
|
||||||
|
background-color transparent
|
||||||
|
border none
|
||||||
|
outline none
|
||||||
|
margin 0 2px
|
||||||
|
transition 0.15s
|
||||||
|
height 18px
|
||||||
|
&:focus
|
||||||
|
font-size 13px
|
||||||
|
.TagSelect-suggest
|
||||||
|
position fixed
|
||||||
|
width 150px
|
||||||
|
max-height 150px
|
||||||
|
background-color white
|
||||||
|
z-index 5
|
||||||
|
border 1px solid borderColor
|
||||||
|
border-radius 5px
|
||||||
|
&>button
|
||||||
|
width 100%
|
||||||
|
display block
|
||||||
|
padding 0 15px
|
||||||
|
height 33px
|
||||||
|
line-height 33px
|
||||||
|
background-color transparent
|
||||||
|
border none
|
||||||
|
text-align left
|
||||||
|
font-size 14px
|
||||||
|
&:hover
|
||||||
|
background-color darken(white, 10%)
|
||||||
|
.ArticleDetail-panel
|
||||||
|
position absolute
|
||||||
top 70px
|
top 70px
|
||||||
|
left 10px
|
||||||
|
right 10px
|
||||||
|
bottom 10px
|
||||||
overflow-x hidden
|
overflow-x hidden
|
||||||
overflow-y auto
|
overflow-y auto
|
||||||
.detailPanel
|
background-color white
|
||||||
absolute top
|
border-radius 5px
|
||||||
left 10px
|
border solid 1px lighten(borderColor, 15%)
|
||||||
right 10px
|
&>.ArticleDetail-panel-header
|
||||||
bottom 10px
|
display block
|
||||||
background-color white
|
height 60px
|
||||||
border-radius 5px
|
|
||||||
border solid 1px borderColor
|
|
||||||
&>.header
|
|
||||||
absolute top left right
|
|
||||||
height 60px
|
|
||||||
.MarkdownPreview
|
|
||||||
absolute left right bottom
|
|
||||||
top 60px
|
|
||||||
marked()
|
|
||||||
box-sizing border-box
|
|
||||||
padding 5px 15px
|
|
||||||
border-top solid 1px borderColor
|
|
||||||
overflow-y auto
|
|
||||||
.CodeEditor
|
|
||||||
absolute left right bottom
|
|
||||||
top 60px
|
|
||||||
border-top solid 1px borderColor
|
|
||||||
min-height 300px
|
|
||||||
border-bottom-left-radius 5px
|
|
||||||
border-bottom-right-radius 5px
|
|
||||||
&.edit
|
|
||||||
.detailInfo
|
|
||||||
.left
|
|
||||||
&>.tutorial
|
|
||||||
position fixed
|
|
||||||
z-index 35
|
|
||||||
font-style italic
|
|
||||||
.folder
|
|
||||||
border none
|
|
||||||
width 150px
|
|
||||||
height 27px
|
|
||||||
outline none
|
|
||||||
background-color darken(white, 5%)
|
|
||||||
&:hover
|
|
||||||
background-color white
|
|
||||||
.TagSelect
|
|
||||||
.tags
|
|
||||||
white-space nowrap
|
|
||||||
overflow-x auto
|
|
||||||
position relative
|
|
||||||
max-width 350px
|
|
||||||
margin-top 5px
|
|
||||||
noSelect()
|
|
||||||
z-index 30
|
|
||||||
background-color #E6E6E6
|
|
||||||
.tagItem
|
|
||||||
background-color brandColor
|
|
||||||
border-radius 2px
|
|
||||||
color white
|
|
||||||
margin 0 2px
|
|
||||||
padding 0
|
|
||||||
border 1px solid darken(brandColor, 10%)
|
|
||||||
button.tagRemoveBtn
|
|
||||||
color white
|
|
||||||
border-radius 2px
|
|
||||||
border none
|
|
||||||
background-color transparent
|
|
||||||
padding 4px 2px
|
|
||||||
border-right 1px solid #E6E6E6
|
|
||||||
font-size 8px
|
|
||||||
line-height 12px
|
|
||||||
transition 0.1s
|
|
||||||
&:hover
|
|
||||||
background-color lighten(brandColor, 10%)
|
|
||||||
.tagLabel
|
|
||||||
padding 4px 4px
|
|
||||||
font-size 12px
|
|
||||||
line-height 12px
|
|
||||||
input.tagInput
|
|
||||||
background-color transparent
|
|
||||||
outline none
|
|
||||||
margin 0 2px
|
|
||||||
border-radius 2px
|
|
||||||
border none
|
|
||||||
transition 0.1s
|
|
||||||
height 18px
|
|
||||||
.suggestTags
|
|
||||||
position fixed
|
|
||||||
width 150px
|
|
||||||
max-height 150px
|
|
||||||
background-color white
|
|
||||||
z-index 5
|
|
||||||
border 1px solid borderColor
|
|
||||||
border-radius 5px
|
|
||||||
button
|
|
||||||
width 100%
|
|
||||||
display block
|
|
||||||
padding 0 15px
|
|
||||||
height 33px
|
|
||||||
line-height 33px
|
|
||||||
background-color transparent
|
|
||||||
border none
|
|
||||||
text-align left
|
|
||||||
font-size 14px
|
|
||||||
&:hover
|
|
||||||
background-color darken(white, 10%)
|
|
||||||
.right
|
|
||||||
z-index 30
|
|
||||||
button
|
|
||||||
cursor pointer
|
|
||||||
height 33px
|
|
||||||
width 55px
|
|
||||||
margin-left 5px
|
|
||||||
font-size 14px
|
|
||||||
color inactiveTextColor
|
|
||||||
background-color darken(white, 5%)
|
|
||||||
border solid 1px borderColor
|
|
||||||
border-radius 5px
|
|
||||||
&>.tooltip
|
|
||||||
tooltip()
|
|
||||||
top 105px
|
|
||||||
&.preview
|
|
||||||
width inherit
|
|
||||||
.tooltip
|
|
||||||
margin-left -55px
|
|
||||||
&:hover
|
|
||||||
background-color white
|
|
||||||
.tooltip
|
|
||||||
opacity 1
|
|
||||||
&.cancelBtn
|
|
||||||
.tooltip
|
|
||||||
margin-left -25px
|
|
||||||
&.saveBtn
|
|
||||||
border none
|
|
||||||
background-color brandColor
|
|
||||||
color white
|
|
||||||
.tooltip
|
|
||||||
margin-left -45px
|
|
||||||
&:hover
|
|
||||||
color white
|
|
||||||
background-color lighten(brandColor, 10%)
|
|
||||||
.detailBody
|
|
||||||
.detailPanel
|
|
||||||
&>.header
|
|
||||||
&>.tutorial
|
|
||||||
fixed right
|
|
||||||
z-index 35
|
|
||||||
font-style italic
|
|
||||||
.mode
|
|
||||||
position relative
|
|
||||||
z-index 30
|
|
||||||
absolute top bottom right
|
|
||||||
display block
|
|
||||||
height 33px
|
|
||||||
margin-top 12px
|
|
||||||
width 150px
|
|
||||||
margin-right 15px
|
|
||||||
border-radius 5px
|
|
||||||
border solid 1px borderColor
|
|
||||||
transition 0.1s
|
|
||||||
&.idle
|
|
||||||
background-color darken(white, 5%)
|
|
||||||
cursor pointer
|
|
||||||
&:hover
|
|
||||||
background-color white
|
|
||||||
.ModeIcon
|
|
||||||
float left
|
|
||||||
width 25px
|
|
||||||
line-height 33px
|
|
||||||
text-align center
|
|
||||||
.modeLabel
|
|
||||||
line-height 30px
|
|
||||||
&.edit
|
|
||||||
background-color white
|
|
||||||
input
|
|
||||||
width 150px
|
|
||||||
line-height 30px
|
|
||||||
padding 0 10px
|
|
||||||
border none
|
|
||||||
outline none
|
|
||||||
background-color transparent
|
|
||||||
font-size 14px
|
|
||||||
.modeOptions
|
|
||||||
position fixed
|
|
||||||
width 150px
|
|
||||||
z-index 10
|
|
||||||
margin-top 5px
|
|
||||||
border 1px solid borderColor
|
|
||||||
border-radius 5px
|
|
||||||
background-color white
|
|
||||||
max-height 250px
|
|
||||||
overflow-y auto
|
|
||||||
.option
|
|
||||||
height 33px
|
|
||||||
line-height 33px
|
|
||||||
cursor pointer
|
|
||||||
&.active, &:hover.active
|
|
||||||
background-color brandColor
|
|
||||||
color white
|
|
||||||
.ModeIcon
|
|
||||||
width 30px
|
|
||||||
text-align center
|
|
||||||
display inline-block
|
|
||||||
&:hover
|
|
||||||
background-color darken(white, 10%)
|
|
||||||
.title
|
|
||||||
absolute left top bottom
|
|
||||||
right 150px
|
|
||||||
padding 0 15px
|
|
||||||
input
|
|
||||||
width 100%
|
|
||||||
border none
|
|
||||||
background-color transparent
|
|
||||||
line-height 60px
|
|
||||||
font-size 24px
|
|
||||||
outline none
|
|
||||||
&.idle
|
|
||||||
.detailInfo
|
|
||||||
&>.tutorial
|
&>.tutorial
|
||||||
fixed top right
|
fixed right
|
||||||
z-index 35
|
z-index 35
|
||||||
font-style italic
|
font-style italic
|
||||||
.left
|
.ArticleDetail-panel-header-mode
|
||||||
right 99px
|
|
||||||
.info
|
|
||||||
padding 5px
|
|
||||||
overflow ellipsis
|
|
||||||
.tags
|
|
||||||
padding 10px 10px 5px
|
|
||||||
color articleItemColor
|
|
||||||
a
|
|
||||||
background-color brandColor
|
|
||||||
color white
|
|
||||||
border-radius 2px
|
|
||||||
padding 1.5px 5px
|
|
||||||
margin 2px
|
|
||||||
font-size 10px
|
|
||||||
opacity 0.8
|
|
||||||
cursor pointer
|
|
||||||
&:hover
|
|
||||||
opacity 1
|
|
||||||
span.noTags
|
|
||||||
color noTagsColor
|
|
||||||
.right
|
|
||||||
z-index 30
|
z-index 30
|
||||||
div.share-dropdown
|
background-color white
|
||||||
position absolute
|
absolute top bottom
|
||||||
right 5px
|
left 10px
|
||||||
top 30px
|
display block
|
||||||
background-color transparentify(invBackgroundColor, 80%)
|
height 33px
|
||||||
padding 5px 0
|
margin-top 14px
|
||||||
width 200px
|
width 33px
|
||||||
&.hide
|
margin-right 15px
|
||||||
display none
|
border solid 1px transparent
|
||||||
&>button
|
border-radius 5px
|
||||||
width 200px
|
transition width 0.15s
|
||||||
text-align left
|
&.idle
|
||||||
display block
|
cursor pointer
|
||||||
height 33px
|
&:hover
|
||||||
background-color transparent
|
background-color darken(white, 5%)
|
||||||
color white
|
border-color borderColor
|
||||||
font-size 14px
|
.ModeIcon
|
||||||
|
float left
|
||||||
|
width 100%
|
||||||
|
line-height 33px
|
||||||
|
text-align center
|
||||||
|
&.edit
|
||||||
|
width 150px
|
||||||
|
border-color iptFocusBorderColor
|
||||||
|
input
|
||||||
|
width 150px
|
||||||
|
line-height 31px
|
||||||
padding 0 10px
|
padding 0 10px
|
||||||
border none
|
border none
|
||||||
&:hover
|
outline none
|
||||||
background-color transparentify(lighten(invBackgroundColor, 30%), 80%)
|
background-color transparent
|
||||||
&>.ShareButton-url
|
font-size 14px
|
||||||
clearfix()
|
.ModeSelect-options
|
||||||
input.ShareButton-url-input
|
position fixed
|
||||||
width 155px
|
width 150px
|
||||||
margin 0 0 0 5px
|
z-index 10
|
||||||
height 25px
|
border 1px solid borderColor
|
||||||
outline none
|
border-radius 5px
|
||||||
border none
|
background-color white
|
||||||
border-top-left-radius 5px
|
max-height 250px
|
||||||
border-bottom-left-radius 5px
|
overflow-y auto
|
||||||
float left
|
margin-top 5px
|
||||||
padding 5px
|
.ModeSelect-options-item
|
||||||
button.ShareButton-url-button
|
height 33px
|
||||||
width 35px
|
line-height 33px
|
||||||
height 25px
|
cursor pointer
|
||||||
border none
|
&.active, &:hover.active
|
||||||
margin 0 5px 0 0
|
background-color brandColor
|
||||||
outline none
|
color white
|
||||||
border-top-right-radius 5px
|
.ModeIcon
|
||||||
border-bottom-right-radius 5px
|
width 30px
|
||||||
background-color darken(white, 5%)
|
text-align center
|
||||||
color inactiveTextColor
|
display inline-block
|
||||||
float right
|
|
||||||
div.ShareButton-url-button-tooltip
|
|
||||||
tooltip()
|
|
||||||
right 10px
|
|
||||||
&:hover
|
&:hover
|
||||||
color textColor
|
background-color darken(white, 10%)
|
||||||
div.ShareButton-url-button-tooltip
|
.ArticleDetail-panel-header-title
|
||||||
opacity 1
|
absolute left top right
|
||||||
div.ShareButton-url-alert
|
left 33px
|
||||||
float left
|
padding 0 15px
|
||||||
height 25px
|
background-color transparent
|
||||||
line-height 25px
|
input
|
||||||
padding 0 15px
|
|
||||||
color white
|
|
||||||
|
|
||||||
.ShareButton
|
|
||||||
display inline-block
|
|
||||||
button.ShareButton-open-button
|
|
||||||
border-radius 16.5px
|
|
||||||
cursor pointer
|
|
||||||
height 33px
|
|
||||||
width 33px
|
|
||||||
border none
|
|
||||||
margin-right 5px
|
|
||||||
font-size 18px
|
|
||||||
color inactiveTextColor
|
|
||||||
background-color darken(white, 5%)
|
|
||||||
padding 0
|
|
||||||
.tooltip
|
|
||||||
tooltip()
|
|
||||||
margin-top 25px
|
|
||||||
margin-left -40px
|
|
||||||
&:hover
|
|
||||||
color textColor
|
|
||||||
.tooltip
|
|
||||||
opacity 1
|
|
||||||
|
|
||||||
&>button
|
|
||||||
border-radius 16.5px
|
|
||||||
cursor pointer
|
|
||||||
height 33px
|
|
||||||
width 33px
|
|
||||||
border none
|
border none
|
||||||
margin-right 5px
|
line-height 60px
|
||||||
font-size 18px
|
width 100%
|
||||||
color inactiveTextColor
|
font-size 24px
|
||||||
background-color darken(white, 5%)
|
outline none
|
||||||
padding 0
|
.MarkdownPreview
|
||||||
.tooltip
|
absolute left right bottom
|
||||||
tooltip()
|
top 60px
|
||||||
&.editBtn .tooltip
|
marked()
|
||||||
margin-top 25px
|
box-sizing border-box
|
||||||
margin-left -45px
|
padding 5px 15px
|
||||||
&.deleteBtn .tooltip
|
border-top solid 1px borderColor
|
||||||
margin-top 25px
|
overflow-y auto
|
||||||
margin-left -73px
|
.CodeEditor
|
||||||
&:hover
|
absolute left right bottom
|
||||||
color textColor
|
top 60px
|
||||||
.tooltip
|
border-top solid 1px borderColor
|
||||||
opacity 1
|
min-height 300px
|
||||||
.detailBody
|
border-bottom-left-radius 5px
|
||||||
.detailPanel
|
border-bottom-right-radius 5px
|
||||||
&>.header
|
|
||||||
.mode
|
|
||||||
display block
|
|
||||||
line-height 60px
|
|
||||||
width 45px
|
|
||||||
height 60px
|
|
||||||
font-size 18px
|
|
||||||
text-align center
|
|
||||||
.title
|
|
||||||
absolute top bottom
|
|
||||||
left 45px
|
|
||||||
right 15px
|
|
||||||
font-size 24px
|
|
||||||
line-height 60px
|
|
||||||
white-space nowrap
|
|
||||||
overflow-x auto
|
|
||||||
overflow-y hidden
|
|
||||||
small
|
|
||||||
color #AAA
|
|
||||||
|
|||||||
Reference in New Issue
Block a user