Skip to content

Commit

Permalink
Add formfield components
Browse files Browse the repository at this point in the history
  • Loading branch information
emptynick committed May 30, 2020
1 parent b1ebc74 commit 0b04fde
Show file tree
Hide file tree
Showing 8 changed files with 240 additions and 42 deletions.
2 changes: 1 addition & 1 deletion resources/dist/tiptap.js

Large diffs are not rendered by default.

19 changes: 19 additions & 0 deletions resources/src/components/Formfield/Browse.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<template>
<div>
<slot v-if="show == 'query'"></slot>
<div v-else>
<span v-if="options.display_length > 0">
{{ value.slice(0, options.display_length) }}
</span>
<span v-else>
{{ value }}
</span>
</div>
</div>
</template>

<script>
export default {
props: ['show', 'options', 'value', 'translatable'],
};
</script>
62 changes: 62 additions & 0 deletions resources/src/components/Formfield/Builder.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<template>
<div>
<div v-if="show == 'list-options'">
<label for="length" class="label">{{ __('voyager::generic.display_length') }}</label>
<input type="text" id="length" class="input w-full" v-model="options.display_length">
</div>
<div v-else-if="show == 'view-options'">
<label class="label mt-4">Store JSON</label>
<input type="checkbox" class="input" v-model="options.as_json">

<label class="label mt-4">Unordered List</label>
<input type="checkbox" class="input" v-model="options.ul">

<label class="label mt-4">Heading</label>
<input type="checkbox" class="input" v-model="options.heading">

<label class="label mt-4">Horizontal Rule</label>
<input type="checkbox" class="input" v-model="options.hr">

<label class="label mt-4">Ordered List</label>
<input type="checkbox" class="input" v-model="options.ol">

<label class="label mt-4">Bold</label>
<input type="checkbox" class="input" v-model="options.bold">

<label class="label mt-4">Code</label>
<input type="checkbox" class="input" v-model="options.code">

<label class="label mt-4">Italic</label>
<input type="checkbox" class="input" v-model="options.italic">

<label class="label mt-4">Strike</label>
<input type="checkbox" class="input" v-model="options.strike">

<label class="label mt-4">Underline</label>
<input type="checkbox" class="input" v-model="options.underline">

<label class="label mt-4">History</label>
<input type="checkbox" class="input" v-model="options.history">
</div>
<div v-else-if="show == 'view'">
<tiptap
:as-json="options.as_json"
:ul="options.ul"
:heading="options.heading"
:hr="options.hr"
:ol="options.ol"
:bold="options.bold"
:code="options.code"
:italic="options.italic"
:strike="options.strike"
:underline="options.underline"
:history="options.history" />
</div>
</div>
</template>

<script>
export default {
props: ['options', 'column', 'show'],
};
</script>
24 changes: 24 additions & 0 deletions resources/src/components/Formfield/EditAdd.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<template>
<div>
<tiptap
:as-json="options.as_json"
:ul="options.ul"
:heading="options.heading"
:hr="options.hr"
:ol="options.ol"
:bold="options.bold"
:code="options.code"
:italic="options.italic"
:strike="options.strike"
:underline="options.underline"
:history="options.history"
v-bind:value="value"
@input="$emit('input', $event)" />
</div>
</template>

<script>
export default {
props: ['options', 'value'],
};
</script>
10 changes: 10 additions & 0 deletions resources/src/components/Formfield/Read.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<template>
<div v-html="translate(data, !translatable)">
</div>
</template>

<script>
export default {
props: ['options', 'data', 'translatable'],
};
</script>
127 changes: 90 additions & 37 deletions resources/src/components/TipTap.vue
Original file line number Diff line number Diff line change
@@ -1,112 +1,165 @@
<template>
<div class="tiptap">
<div class="tiptap input cursor-text" @click="editor.focus()">
<editor-menu-bar :editor="editor" v-slot="{ commands, isActive }">
<div class="button-group">
<button class="button font-bold small icon-only" :class="[isActive.bold() ? 'dark-gray' : 'accent']" @click="commands.bold" v-tooltip="__('voyager::wysiwyg.bold')">
<button v-if="bold" class="button font-bold small icon-only" :class="[isActive.bold() ? 'dark-gray' : 'accent']" @click="commands.bold" v-tooltip="__('voyager::wysiwyg.bold')">
B
</button>
<button class="button italic small icon-only" :class="[isActive.italic() ? 'dark-gray' : 'accent']" @click="commands.italic" v-tooltip="__('voyager::wysiwyg.italic')">
<button v-if="italic" class="button italic small icon-only" :class="[isActive.italic() ? 'dark-gray' : 'accent']" @click="commands.italic" v-tooltip="__('voyager::wysiwyg.italic')">
I
</button>
<button class="button line-through small icon-only" :class="[isActive.strike() ? 'dark-gray' : 'accent']" @click="commands.strike" v-tooltip="__('voyager::wysiwyg.strike')">
<button v-if="strike" class="button line-through small icon-only" :class="[isActive.strike() ? 'dark-gray' : 'accent']" @click="commands.strike" v-tooltip="__('voyager::wysiwyg.strike')">
S
</button>
<button class="button underline small icon-only" :class="[isActive.underline() ? 'dark-gray' : 'accent']" @click="commands.underline" v-tooltip="__('voyager::wysiwyg.underline')">
<button v-if="underline" class="button underline small icon-only" :class="[isActive.underline() ? 'dark-gray' : 'accent']" @click="commands.underline" v-tooltip="__('voyager::wysiwyg.underline')">
U
</button>
<div class="divider"></div>
<button class="button small icon-only" :class="[isActive.code() ? 'dark-gray' : 'accent']" @click="commands.code" v-tooltip="__('voyager::wysiwyg.code')">
<icon icon="code" :size="6"></icon>
<button v-if="code" class="button small icon-only" :class="[isActive.code() ? 'dark-gray' : 'accent']" @click="commands.code" v-tooltip="__('voyager::wysiwyg.code')">
<icon icon="code" :size="5"></icon>
</button>
<button class="button small icon-only" :class="[isActive.paragraph() ? 'dark-gray' : 'accent']" @click="commands.paragraph" v-tooltip="__('voyager::wysiwyg.paragraph')">
P
</button>
<button class="button small icon-only" :class="[isActive.bullet_list() ? 'dark-gray' : 'accent']" @click="commands.bullet_list" v-tooltip="__('voyager::wysiwyg.bullet_list')">
<button v-if="ul" class="button small icon-only" :class="[isActive.bullet_list() ? 'dark-gray' : 'accent']" @click="commands.bullet_list" v-tooltip="__('voyager::wysiwyg.bullet_list')">
UL
</button>
<button class="button small icon-only" :class="[isActive.ordered_list() ? 'dark-gray' : 'accent']" @click="commands.ordered_list" v-tooltip="__('voyager::wysiwyg.ordered_list')">
<button v-if="ol" class="button small icon-only" :class="[isActive.ordered_list() ? 'dark-gray' : 'accent']" @click="commands.ordered_list" v-tooltip="__('voyager::wysiwyg.ordered_list')">
OL
</button>
<button class="button small icon-only" :class="[isActive.horizontal_rule() ? 'dark-gray' : 'accent']" @click="commands.horizontal_rule" v-tooltip="__('voyager::wysiwyg.horizontal_rule')">
<button v-if="hr" class="button small icon-only" :class="[isActive.horizontal_rule() ? 'dark-gray' : 'accent']" @click="commands.horizontal_rule" v-tooltip="__('voyager::wysiwyg.horizontal_rule')">
HR
</button>
<div class="divider"></div>
<button class="button small icon-only" :class="[isActive.heading({ level: 1 }) ? 'dark-gray' : 'accent']" @click="commands.heading({ level: 1 })" v-tooltip="__('voyager::wysiwyg.heading_1')">
<button v-if="heading" class="button small icon-only" :class="[isActive.heading({ level: 1 }) ? 'dark-gray' : 'accent']" @click="commands.heading({ level: 1 })" v-tooltip="__('voyager::wysiwyg.heading_1')">
H1
</button>
<button class="button small icon-only" :class="[isActive.heading({ level: 2 }) ? 'dark-gray' : 'accent']" @click="commands.heading({ level: 2 })" v-tooltip="__('voyager::wysiwyg.heading_2')">
<button v-if="heading" class="button small icon-only" :class="[isActive.heading({ level: 2 }) ? 'dark-gray' : 'accent']" @click="commands.heading({ level: 2 })" v-tooltip="__('voyager::wysiwyg.heading_2')">
H2
</button>
<button class="button small icon-only" :class="[isActive.heading({ level: 3 }) ? 'dark-gray' : 'accent']" @click="commands.heading({ level: 3 })" v-tooltip="__('voyager::wysiwyg.heading_3')">
<button v-if="heading" class="button small icon-only" :class="[isActive.heading({ level: 3 }) ? 'dark-gray' : 'accent']" @click="commands.heading({ level: 3 })" v-tooltip="__('voyager::wysiwyg.heading_3')">
H3
</button>
<div class="divider"></div>
<button class="button small icon-only accent" @click="commands.undo" v-tooltip="__('voyager::wysiwyg.undo')">
<icon icon="arrow-left" mirrored :size="6"></icon>
<div class="divider" v-if="heading"></div>
<button v-if="history" class="button small icon-only accent" @click="commands.undo" v-tooltip="__('voyager::wysiwyg.undo')">
&lt;
</button>
<button class="button small icon-only accent" @click="commands.redo" v-tooltip="__('voyager::wysiwyg.redo')">
<icon icon="arrow-right" :size="6"></icon>
<button v-if="history" class="button small icon-only accent" @click="commands.redo" v-tooltip="__('voyager::wysiwyg.redo')">
&gt;
</button>
</div>
</editor-menu-bar>

<editor-content class="content voyager-input" spellcheck="false" :editor="editor" />
<editor-content class="content mt-2" spellcheck="false" :editor="editor" />
</div>
</template>
<script>
// https://github.com/scrumpy/tiptap
import { Editor, EditorContent, EditorMenuBar } from "tiptap";
import { Editor, EditorContent, EditorMenuBar } from 'tiptap';
import {
HardBreak,
Heading,
HorizontalRule,
OrderedList,
BulletList,
ListItem,
TodoItem,
TodoList,
Bold,
Code,
Italic,
Strike,
Underline,
History
} from "tiptap-extensions";
} from 'tiptap-extensions';
export default {
props: ['value'],
props: {
value: {
type: String,
default: '',
},
ul: {
type: Boolean,
default: true,
},
heading: {
type: Boolean,
default: true,
},
hr: {
type: Boolean,
default: true,
},
ol: {
type: Boolean,
default: true,
},
bold: {
type: Boolean,
default: true,
},
code: {
type: Boolean,
default: true,
},
italic: {
type: Boolean,
default: true,
},
strike: {
type: Boolean,
default: true,
},
underline: {
type: Boolean,
default: true,
},
history: {
type: Boolean,
default: true,
},
asJson: {
type: Boolean,
default: false,
}
},
components: {
EditorContent,
EditorMenuBar
},
data: function() {
var vm = this;
return {
editor: new Editor({
extensions: [
new BulletList(),
new HardBreak(),
new Heading({ levels: [1, 2, 3] }),
new HorizontalRule(),
new ListItem(),
new OrderedList(),
new TodoItem(),
new TodoList(),
new Bold(),
new Code(),
new Italic(),
new Strike(),
new Underline(),
new History()
],
content: '',
content: vm.value,
onUpdate: function ({ getHTML, getJSON }) {
if (vm.asJson) {
vm.$emit('input', getJSON());
} else {
vm.$emit('input', getHTML());
}
},
parseOptions: {
preserveWhitespace: true,
}
})
};
},
methods: {
},
computed: {
watch: {
value: function (value) {
this.editor.setContent(value);
}
},
beforeDestroy: function () {
this.editor.destroy();
Expand All @@ -116,16 +169,16 @@ export default {

<style lang="scss" scoped>
.tiptap {
.content {
@apply min-h-64;
min-height: 16rem;
}
}
</style>

<style lang="scss">
.ProseMirror {
@apply h-full w-full;
height: 100%;
width: 100%;
&:focus {
outline: none !important;
}
Expand Down
15 changes: 13 additions & 2 deletions resources/src/tiptap.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
import Vue from 'vue';
import Tiptap from './components/Tiptap';
Vue.component('tiptap', Tiptap);
Vue.component('tiptap', Tiptap);

import TiptapBrowse from './components/Formfield/Browse';
Vue.component('formfield-tiptap-browse', TiptapBrowse);

import TiptapEditAdd from './components/Formfield/EditAdd';
Vue.component('formfield-tiptap-edit-add', TiptapEditAdd);

import TiptapRead from './components/Formfield/Read';
Vue.component('formfield-tiptap-read', TiptapRead);

import TiptapBuilder from './components/Formfield/Builder';
Vue.component('formfield-tiptap-builder', TiptapBuilder);
23 changes: 21 additions & 2 deletions src/TiptapFormfield.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,30 @@ public function name(): string

public function listOptions(): array
{
return [];
return [
'display_length' => 50,
];
}

public function viewOptions(): array
{
return [];
return [
'as_json' => false,
'ul' => true,
'heading' => true,
'hr' => true,
'ol' => true,
'bold' => true,
'code' => true,
'italic' => true,
'strike' => true,
'underline' => true,
'history' => true,
];
}

public function browse($input)
{
return strip_tags($input);
}
}

0 comments on commit 0b04fde

Please sign in to comment.