An open API service indexing awesome lists of open source software.

https://github.com/servicestack/servicestack-editor

ServiceStack Markdown Editor for Vuetify
https://github.com/servicestack/servicestack-editor

Last synced: 10 months ago
JSON representation

ServiceStack Markdown Editor for Vuetify

Awesome Lists containing this project

README

          

# @servicestack/editor

ServiceStack Markdown Editor is a developer-friendly Markdown Editor for Vuetify Apps which is optimized [GitHub Flavored Markdown](https://guides.github.com/features/mastering-markdown/) where it supports popular short-cuts for editing and documenting code like tab block un/indenting, single-line and code and comments blocks.

![](https://i.imgur.com/YPlfplv.png)

## Live Demo

This component was built for [techstacks.io](https://techstacks.io) website where it's used extensively for all posts, comments and anywhere else allowing rich markup using Markdown.

## Install

$ npm install @servicestack/editor

## Usage

Import and register the Editor Vuetify component with your Vue Component to use it like a Vue Input Control, e.g:

```html

import Editor from "@servicestack/editor";

export default {
components: { Editor },
}

```

As it's a wrapper around a [Vuetify text field](https://vuetifyjs.com/en/components/text-fields) it has access to a lot of the rich standard functionality available in Vuetify controls:

Vuetify properties:

- `v-model`
- `label`
- `counter`
- `rows`
- `rules`
- `errorMessages`
- `autofocus`
- `disabled`

Editor properties:

- `lang` - which language to use for syntax highlighting in code comment blocks

Events:

- `@save` - method to invoke when user clicks **Save** icon or `Ctrl+S` keyboard shortcut
- `@close` - method to invoke when user presses the `ESC` key

## Keyboard Shortcuts

For added productivity the Editor supports many of the popular Keyboard shortcuts in found in common IDEs:

![](https://i.imgur.com/PXqkSuN.png)

> Note: pressing the shortcut multiple times toggles on/off the respective functionality

## Example Usage

The [CommentEdit.vue](https://github.com/NetCoreApps/TechStacks/blob/master/src/TechStacks/src/components/CommentEdit.vue)
shows a nice small and complete example of using the Editor for editing existing comments or submitting new ones.

It provides a user-friendly UX with declartive client and server-side validation where 'content' field validation errors
show up next to the Editor dialog whilst other errors are displayed in the FORM's `` summary message.

Annotations were added to the implementation below to describe how the component works:

```html





{{ errorMessage() }}




Submit
Close



import Editor from "@servicestack/editor";
import { mapGetters } from "vuex";
import { errorResponse } from "@servicestack/client";
import { createPostComment, updatePostComment } from "~/shared/gateway";

// Editable comment fields
const comment = {
postId: null,
content: null
};

export default {
components: { Editor },
props: ['post', 'comment', 'replyId', 'autofocus'],

methods: {
// Show top-level error messages or errors for the 'postId' field in the <v-alert/> summary dialog
errorMessage() {
return this.errorResponse() || this.errorResponse('postId');
},

// Clear the form back to its original state
reset(added){
this.responseStatus = this.content = null;
this.valid = true;
this.$emit('done', added);
},

// Submit the comment to the server and overlay any error responses back on the form
async submit() {
if (this.$refs.form.validate()) { // Check if form passes all client validation rules
try {
this.$store.commit('loading', true); // indicate to the App that an API request is pending

// If component was initialized with an existing `comment` update it, otherwise create anew
const response = this.comment != null
? await updatePostComment(this.comment.id, this.post.id, this.content)
: await createPostComment(this.postId, this.content, this.replyId);

this.reset(true); // Clear the form back to a new state when successful

} catch(e) {
this.valid = false; // mark this form as invalid
this.responseStatus = e.responseStatus || e; // populate the server error response
} finally {
this.$store.commit('loading', false); // indicate to the App that the API request is done
}
}
},

// Register `errorResponse` function so it's available in the template
errorResponse,
},

// Initialize the component data from its properties
mounted() {
if (this.post) {
this.postId = this.post.id;
}
if (this.comment) {
this.content = this.comment.content;
}
},

data: () => ({
...comment, // Create reactive properties for all `comment` fields
valid: true, // Holds whether the form is in an invalid state requiring user input to correct
responseStatus: null, // Captures the servers structured error response
}),
}

```

The `errorResponse` method from the [@servicestack/client](https://github.com/ServiceStack/servicestack-client) npm package is opinionated
in handling ServiceStack's [structured API Response Errors](http://docs.servicestack.net/error-handling) but will work for any API returning
the simple error response schema below:

```json
{
"errorCode": "ErrorCode",
"message": "Descriptive Summary Error Message",
"errors": [
{
"fieldName": "content",
"errorCode": "NotEmpty",
"message": "Descriptive Error Message for 'content' Field"
}
]
}
```

Which will check the components `this.responseStatus` property to return different error messages based on what field it was called with, e.g:

```js
errorResponse() //= Descriptive Summary Error Message
errorResponse('postId') //= undefined
errorResponse('content') //= Descriptive Error Message for Field Error
```

## Feedback and Support

ServiceStack Customers can ask questions, report issues or submit feature requests from the [ServiceStack Community](https://techstacks.io/servicestack).

If you're not a Customer, please [ask Questions on StackOverflow](https://stackoverflow.com) with the `[servicestack]` hash tag.

Pull Requests for fixes and new features are welcome!