diff --git a/src/displays/index.ts b/src/displays/index.ts
index 074ec1614f..7bf3d8673c 100644
--- a/src/displays/index.ts
+++ b/src/displays/index.ts
@@ -1,6 +1,7 @@
import DisplayIcon from './icon/';
import DisplayFormatTitle from './format-title/';
import DisplayStatusDot from './status-dot/';
+import DisplayStatusBadge from './status-badge/';
-export const displays = [DisplayIcon, DisplayFormatTitle, DisplayStatusDot];
+export const displays = [DisplayIcon, DisplayFormatTitle, DisplayStatusDot, DisplayStatusBadge];
export default displays;
diff --git a/src/displays/status-badge/index.ts b/src/displays/status-badge/index.ts
new file mode 100644
index 0000000000..c67a94de13
--- /dev/null
+++ b/src/displays/status-badge/index.ts
@@ -0,0 +1,11 @@
+import { defineDisplay } from '@/displays/define';
+import DisplayStatusBadge from './status-badge.vue';
+
+export default defineDisplay(({ i18n }) => ({
+ id: 'status-badge',
+ name: i18n.t('status_badge'),
+ types: ['status'],
+ icon: 'box',
+ handler: DisplayStatusBadge,
+ options: null,
+}));
diff --git a/src/displays/status-badge/readme.md b/src/displays/status-badge/readme.md
new file mode 100644
index 0000000000..aa775f658e
--- /dev/null
+++ b/src/displays/status-badge/readme.md
@@ -0,0 +1,4 @@
+# Status Badge
+
+Renders the set status formatted according to the status mapping set in the interface options.
+
diff --git a/src/displays/status-badge/status-badge.story.ts b/src/displays/status-badge/status-badge.story.ts
new file mode 100644
index 0000000000..7271e4141a
--- /dev/null
+++ b/src/displays/status-badge/status-badge.story.ts
@@ -0,0 +1,53 @@
+import withPadding from '../../../.storybook/decorators/with-padding';
+import { withKnobs, text, object } from '@storybook/addon-knobs';
+import readme from './readme.md';
+import { defineComponent } from '@vue/composition-api';
+
+export default {
+ title: 'Displays / Status (Badge)',
+ decorators: [withPadding, withKnobs],
+ parameters: {
+ notes: readme,
+ },
+};
+
+const defaultStatusMapping = {
+ published: {
+ name: 'Published',
+ value: 'published',
+ text_color: '#fff',
+ background_color: 'var(--primary)',
+ },
+ draft: {
+ name: 'Draft',
+ value: 'draft',
+ text_color: 'var(--primary-subdued)',
+ background_color: 'var(--background-subdued)',
+ },
+ deleted: {
+ name: 'Deleted',
+ value: 'deleted',
+ text_color: 'var(--danger)',
+ background_color: 'var(--danger-alt)',
+ },
+};
+
+export const basic = () =>
+ defineComponent({
+ props: {
+ value: {
+ default: text('Value', 'published'),
+ },
+ statusMapping: {
+ default: object('Status Mapping', defaultStatusMapping),
+ },
+ },
+ template: `
+
+ `,
+ });
diff --git a/src/displays/status-badge/status-badge.test.ts b/src/displays/status-badge/status-badge.test.ts
new file mode 100644
index 0000000000..f01154b007
--- /dev/null
+++ b/src/displays/status-badge/status-badge.test.ts
@@ -0,0 +1,75 @@
+import DisplayStatusBadge from './status-badge.vue';
+import { createLocalVue, shallowMount } from '@vue/test-utils';
+import VIcon from '@/components/v-icon';
+import VueCompositionAPI from '@vue/composition-api';
+import Tooltip from '@/directives/tooltip';
+
+const localVue = createLocalVue();
+localVue.component('v-icon', VIcon);
+localVue.use(VueCompositionAPI);
+localVue.directive('tooltip', Tooltip);
+
+describe('Displays / Status Badge', () => {
+ it('Renders an empty span if no value is passed', () => {
+ const component = shallowMount(DisplayStatusBadge, {
+ localVue,
+ propsData: {
+ value: null,
+ },
+ });
+
+ expect(component.find('span').exists()).toBe(true);
+ expect(component.find('span').text()).toBe('');
+ });
+
+ it('Renders a question mark icon is status is unknown in interface options', () => {
+ const component = shallowMount(DisplayStatusBadge, {
+ localVue,
+ propsData: {
+ value: 'draft',
+ interfaceOptions: {
+ status_mapping: {
+ published: {},
+ },
+ },
+ },
+ });
+
+ expect(component.find(VIcon).exists()).toBe(true);
+ expect(component.attributes('name')).toBe('help_outline');
+ });
+
+ it('Renders the badge with the correct colors', () => {
+ const component = shallowMount(DisplayStatusBadge, {
+ localVue,
+ propsData: {
+ value: 'draft',
+ interfaceOptions: {
+ status_mapping: {
+ draft: {
+ background_color: 'rgb(171, 202, 188)',
+ text_color: 'rgb(150, 100, 125)',
+ },
+ },
+ },
+ },
+ });
+
+ expect(component.exists()).toBe(true);
+ expect(component.attributes('style')).toBe(
+ 'background-color: rgb(171, 202, 188); color: rgb(150, 100, 125);'
+ );
+ });
+
+ it('Sets status to null if interface options are missing', () => {
+ const component = shallowMount(DisplayStatusBadge, {
+ localVue,
+ propsData: {
+ value: 'draft',
+ interfaceOptions: null,
+ },
+ });
+
+ expect((component.vm as any).status).toBe(null);
+ });
+});
diff --git a/src/displays/status-badge/status-badge.vue b/src/displays/status-badge/status-badge.vue
new file mode 100644
index 0000000000..e418e7c795
--- /dev/null
+++ b/src/displays/status-badge/status-badge.vue
@@ -0,0 +1,50 @@
+
+
+
+
+ {{ status.name }}
+
+
+
+
+
+
diff --git a/src/displays/status-dot/status-dot.story.ts b/src/displays/status-dot/status-dot.story.ts
index e69de29bb2..6e5d0596c5 100644
--- a/src/displays/status-dot/status-dot.story.ts
+++ b/src/displays/status-dot/status-dot.story.ts
@@ -0,0 +1,53 @@
+import withPadding from '../../../.storybook/decorators/with-padding';
+import { withKnobs, text, object } from '@storybook/addon-knobs';
+import readme from './readme.md';
+import { defineComponent } from '@vue/composition-api';
+
+export default {
+ title: 'Displays / Status (Dot)',
+ decorators: [withPadding, withKnobs],
+ parameters: {
+ notes: readme,
+ },
+};
+
+const defaultStatusMapping = {
+ published: {
+ name: 'Published',
+ value: 'published',
+ text_color: '#fff',
+ background_color: 'var(--primary)',
+ },
+ draft: {
+ name: 'Draft',
+ value: 'draft',
+ text_color: 'var(--primary-subdued)',
+ background_color: 'var(--background-subdued)',
+ },
+ deleted: {
+ name: 'Deleted',
+ value: 'deleted',
+ text_color: 'var(--danger)',
+ background_color: 'var(--danger-alt)',
+ },
+};
+
+export const basic = () =>
+ defineComponent({
+ props: {
+ value: {
+ default: text('Value', 'published'),
+ },
+ statusMapping: {
+ default: object('Status Mapping', defaultStatusMapping),
+ },
+ },
+ template: `
+
+ `,
+ });
diff --git a/src/displays/status-dot/status-dot.vue b/src/displays/status-dot/status-dot.vue
index 03b7191922..aeafec3293 100644
--- a/src/displays/status-dot/status-dot.vue
+++ b/src/displays/status-dot/status-dot.vue
@@ -1,6 +1,6 @@
-
+