Refactor: pull out text composer (Quill editor) into own component

parent 7efad627
<template>
<div>
<!-- Search box -->
<!-- TODO: Requires a clear button on the opposite side to the search icon. -->
<b-field position='is-centered'>
<b-autocomplete
rounded
v-model="searchTerm"
:data="filteredMockSearchData"
placeholder="Search"
icon="search"
@select="option => selected = option">
<template slot="empty">No results found</template>
</b-autocomplete>
</b-field>
<hr>
<h2>You can search for…</h2>
<ul>
<li>People (e.g., @ar.al)</li>
<li>Topics (e.g., #ethicaldesign)</li>
<li>Anything (e.g., a great restaurant)</li>
</ul>
</div>
</template>
<script>
export default {
data () {
return {
mockSearchData: [
'Laura Kalbag (laurakalbag.com)',
'Aral Balkan (ar.al)',
'#surveillancecapitalism',
'Aral Balkan (@aral@mastodon.ar.al)'
],
searchTerm: '',
selectedMockSearchResult: null
}
},
computed: {
filteredMockSearchData () {
return this.mockSearchData.filter( (option) => {
return option
.toString()
.toLowerCase()
.indexOf(this.searchTerm.toLowerCase()) >= 0
})
}
}
}
</script>
<style>
.autocomplete.control {
margin-left: auto;
margin-right: auto;
width: 42vmax;
font-size: 2vmax;
margin-top: 2vmax;
}
</style>
<template>
<div class='compose'>
<no-ssr>
<quill-editor
v-model='editorContent'
ref='textEditor'
:options='editorOption'
@change='editorChange($event)'
></quill-editor>
</no-ssr>
<div class='compose-tools'>
<button @click='editorContent=""' ref='clearButton' class='button is-medium'>Clear</button>
<button ref='postButton' class='button is-medium is-primary'>Post</button>
</div>
</div>
</template>
<script>
export default {
props: {
content: {
type: String,
required: false,
default: ''
}
},
data () {
return {
editorContent: this.content || '',
editorOption: {
placeholder: 'What’s on your mind?',
theme: 'snow',
modules: {
markdownShortcuts: {},
imageDrop: true,
blotFormatter: true,
toolbar: false
// toolbar: [
// [{ header: [1, 2, false] }],
// ['image', 'blockquote']
// ]
}
}
}
},
methods: {
editorChange ( { quill, html, text } ) {
this.$emit('composerChange', quill, html, text)
}
}
}
</script>
<style>
.button.is-medium {
font-size: 1.5vmax;
}
.button.is-medium:not(:first-of-type)
{
margin-left: 1vmax;
}
.compose {
margin-bottom: 2vmax;
}
.compose-tools {
height: 3.4vmax;
text-align: right;
}
.quill-editor {
margin-bottom: 1vmax;
margin-left: -2vmax;
margin-right: -2vmax;
}
.ql-editor {
font-size: 2vmax;
}
/* The editor only has a top and bottom border to mark its boundaries. Otherwise,
it is styled exactly like the rest of the content to underscore its purpose.
When a post is submitted, the minimal chrome around the editor simply fades
away and the content becomes part of the page. */
.ql-container.ql-snow {
border-left: none;
border-right: none;
}
.ql-editor p, .ql-snow .ql-editor blockquote, .ql-snow .ql-editor img {
margin-bottom: 2vmax;
}
.ql-snow .ql-editor h1 {
font-size: 4vmax;
margin-bottom: 1.5vmax;
}
.ql-editor h2 {
margin-bottom: .75em;
}
</style>
......@@ -3,68 +3,21 @@
<!-- Site header -->
<indie-header @followButtonPress='followModalActive = true' />
<!-- Tabs with hard-coded content in first. -->
<!-- Main tabs with currently hard-coded content. -->
<b-tabs position="is-centered" class="block">
<b-tab-item label="Me">
<!-- Filter by content type -->
<content-type-filter />
<!-- Vue Quill Editor -->
<div class='compose'>
<no-ssr>
<quill-editor
v-model='editorContent'
ref='textEditor'
:options='editorOption'
@change='editorChange($event)'
></quill-editor>
</no-ssr>
<div class='compose-tools'>
<button @click='editorContent=""' ref='clearButton' class='button is-medium'>Clear</button>
<button ref='postButton' class='button is-medium is-primary'>Post</button>
</div>
</div>
<pre style='word-break: break-word;'>{{ editorContent }}</pre>
</b-tab-item>
<b-tab-item label="Everyone"></b-tab-item>
<b-tab-item label='Search'>
<!-- Search box -->
<!-- TODO: Requires a clear button on the opposite side to the search icon. -->
<b-field position='is-centered'>
<b-autocomplete
rounded
v-model="searchTerm"
:data="filteredMockSearchData"
placeholder="Search"
icon="search"
@select="option => selected = option">
<template slot="empty">No results found</template>
</b-autocomplete>
</b-field>
<hr>
<h2>You can search for…</h2>
<ul>
<li>People (e.g., @ar.al)</li>
<li>Topics (e.g., #ethicaldesign)</li>
<li>Anything (e.g., a great restaurant)</li>
</ul>
</b-tab-item>
<!-- Settings tab -->
<b-tab-item label="Settings">
<settings />
<textComposer @composerChange='composerChange' />
<pre style='word-break: break-word;'>{{ composerContent }}</pre>
</b-tab-item>
<!-- “More” tab: other features will go here. -->
<b-tab-item label="…"></b-tab-item>
<b-tab-item label="Everyone"><!-- Nothing yet. --></b-tab-item>
<b-tab-item label='Search'><search /></b-tab-item>
<b-tab-item label="Settings"><settings /></b-tab-item>
<b-tab-item label="…"><!-- “More” tab: other features will go here. --></b-tab-item>
</b-tabs>
<!-- Follow modal -->
<follow-modal :isActive='followModalActive' @close='followModalActive = false' />
</div>
</template>
......@@ -76,68 +29,39 @@ import indieHeader from '~/components/indieHeader'
import followModal from '~/components/followModal'
import contentTypeFilter from '~/components/contentTypeFilter'
import settings from '~/components/settings'
import search from '~/components/search'
import textComposer from '~/components/textComposer'
export default {
components: {
indieHeader,
followModal,
contentTypeFilter,
settings
settings,
search,
textComposer
},
computed: {
name () { return this.$store.state.name },
bio () { return this.$store.state.bio },
filteredMockSearchData () {
return this.mockSearchData.filter( (option) => {
return option
.toString()
.toLowerCase()
.indexOf(this.searchTerm.toLowerCase()) >= 0
})
}
},
methods: {
editorChange ( { quill, html, text } ) {
console.log(quill, html, text)
}
},
data() {
data () {
return {
mockSearchData: [
'Laura Kalbag (laurakalbag.com)',
'Aral Balkan (ar.al)',
'#surveillancecapitalism',
'Aral Balkan (@aral@mastodon.ar.al)'
],
searchTerm: '',
selectedMockSearchResult: null,
followModalActive: false,
composerContent: ''
}
},
editorContent: '',
editorOption: {
placeholder: 'What’s on your mind?',
theme: 'snow',
modules: {
markdownShortcuts: {},
imageDrop: true,
blotFormatter: true,
toolbar: false
// toolbar: [
// [{ header: [1, 2, false] }],
// ['image', 'blockquote']
// ]
}
}
methods: {
composerChange (quill, html, text) {
this.composerContent = html
}
},
mounted () {
console.log(`Index component mounted. Quill instance is: ${this.myQuillEditor}`)
console.log(`Index component mounted.`)
}
}
</script>
......@@ -162,14 +86,6 @@ figcaption {
font-size: 1.5vmax;
}
.autocomplete.control {
margin-left: auto;
margin-right: auto;
width: 42vmax;
font-size: 2vmax;
margin-top: 2vmax;
}
nav {
margin-top: 1vmax;
}
......@@ -194,7 +110,6 @@ nav {
z-index: 9001;
}
.tab-content {
margin-top: 2vmax;
padding: 0;
......@@ -214,7 +129,6 @@ section {
font-style: italic;
}
h1 {
font-size: 5vmax;
margin-top: 3vmax;
......@@ -224,68 +138,9 @@ h2 {
font-size: 3.5vmax;
}
article h1 {
font-size: 4vmax;
margin-bottom: 1.5vmax;
}
.button.is-medium {
font-size: 1.5vmax;
}
.button.is-medium:not(:first-of-type)
{
margin-left: 1vmax;
}
.compose {
margin-bottom: 2vmax;
}
.compose-tools {
height: 3.4vmax;
text-align: right;
}
.quill-editor {
margin-bottom: 1vmax;
margin-left: -2vmax;
margin-right: -2vmax;
}
.ql-editor {
font-size: 2vmax;
}
/* The editor only has a top and bottom border to mark its boundaries. Otherwise,
it is styled exactly like the rest of the content to underscore its purpose.
When a post is submitted, the minimal chrome around the editor simply fades
away and the content becomes part of the page. */
.ql-container.ql-snow {
border-left: none;
border-right: none;
}
.ql-editor p, .ql-snow .ql-editor blockquote, .ql-snow .ql-editor img {
margin-bottom: 2vmax;
}
.ql-snow .ql-editor h1 {
font-size: 4vmax;
margin-bottom: 1.5vmax;
}
.ql-editor h2 {
margin-bottom: .75em;
}
/* Follow card */
div.card-content {
padding-top: 0;
}
</style>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment