Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MNT Add to storybook #204

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
159 changes: 159 additions & 0 deletions client/src/components/LinkField/LinkField-story.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
/* global window */
import React from 'react';
import { Component as LinkField } from 'components/LinkField/LinkField';

// mock global ss config
if (!window.ss) {
window.ss = {};
}
if (!window.ss.config) {
window.ss.config = {
sections: [
{
name: 'SilverStripe\\LinkField\\Controllers\\LinkFieldController',
form: {
linkForm: {
dataUrl: '',
}
}
},
]
};
}

// mock toast actions
const mockedActions = {
toasts: {
error: () => {},
success: () => {},
}
};

// predetermine link types
const linkTypes = {
sitetree: {
key: 'sitetree',
title: 'Page on this site',
handlerName: 'FormBuilderModal',
priority: 0,
icon: 'font-icon-page',
allowed: true
},
file: {
key: 'file',
title: 'Link to a file',
handlerName: 'FormBuilderModal',
priority: 10,
icon: 'font-icon-image',
allowed: true
},
external: {
key: 'external',
title: 'Link to external URL',
handlerName: 'FormBuilderModal',
priority: 20,
icon: 'font-icon-external-link',
allowed: true
},
email: {
key: 'email',
title: 'Link to email address',
handlerName: 'FormBuilderModal',
priority: 30,
icon: 'font-icon-p-mail',
allowed: true
},
phone: {
key: 'phone',
title: 'Phone number',
handlerName: 'FormBuilderModal',
priority: 40,
icon: 'font-icon-mobile',
allowed: true
}
};

export default {
title: 'Linkfield/LinkField',
component: LinkField,
tags: ['autodocs'],
parameters: {
docs: {
description: {
component: 'The LinkField component. Note that the form modal for creating, editing, and viewing link data is disabled for the storybook.'
},
canvas: {
sourceState: 'shown',
},
controls: {
exclude: [
'onChange',
'value',
'ownerID',
'ownerClass',
'ownerRelation',
'actions',
],
},
},
},
argTypes: {
types: {
description: 'Types of links that are allowed in this field. The actual prop is a JSON object with some metadata about each type.',
control: 'inline-check',
options: Object.keys(linkTypes),
},
isMulti: {
description: 'Whether the field supports multiple links or not.',
},
canCreate: {
description: 'Whether the current user has create permission or not.',
},
readonly: {
description: 'Whether the field is readonly or not.',
},
disabled: {
description: 'Whether the field is disabled or not.',
},
ownerSaved: {
description: 'Whether the record which owns the link field has been saved or not. The actual props for this are OwnerID, OwnerClass, and OwnerRelation.',
},
},
};

export const _LinkField = {
name: 'LinkField',
args: {
value: [0],
onChange: () => {},
types: Object.keys(linkTypes),
actions: mockedActions,
isMulti: false,
canCreate: true,
readonly: false,
disabled: false,
ownerSaved: true,
ownerClass: '',
ownerRelation: '',
},
render: (args) => {
const { types, ownerSaved } = args;
delete args.ownerSaved;
delete args.hasLinks;

// `types` must be an array in args so controls can be used to toggle them.
// Because of that, we need to turn that back into the JSON object before
// passing that prop.
args.types = {};
types.sort((a, b) => linkTypes[a].priority - linkTypes[b].priority);
// eslint-disable-next-line no-restricted-syntax
for (const type of types) {
args.types[type] = linkTypes[type];
}

// Determine whether the link is rendered as though the parent record is saved or not
args.ownerID = ownerSaved ? 1 : 0;

return <LinkField {...args} />;
},
};
110 changes: 110 additions & 0 deletions client/src/components/LinkPicker/LinkPickerTitle-story.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import React from 'react';
import LinkPickerTitle from 'components/LinkPicker/LinkPickerTitle';
import { LinkFieldContext } from '../LinkField/LinkField';

// mock toast actions
const mockedActions = {
toasts: {
error: () => {},
success: () => {},
}
};

export default {
title: 'LinkField/LinkPicker/LinkPickerTitle',
component: LinkPickerTitle,
tags: ['autodocs'],
parameters: {
docs: {
description: {
component: 'The LinkPickerTitle component. Used to display a link inside the link field'
},
canvas: {
sourceState: 'shown',
},
controls: {
exclude: [
'id',
'onDelete',
'onClick',
'onUnpublishedVersionedState',
'isFirst',
'isLast',
'isSorting',
'canCreate',
],
},
},
},
argTypes: {
versionState: {
description: 'The current versioned state of the link. "unsaved" and "unversioned" are effectively identical.',
control: 'select',
options: ['unversioned', 'unsaved', 'published', 'draft', 'modified'],
},
title: {
description: 'The title (aka link text) for the link.',
},
typeTitle: {
description: 'Text that informs the user what type of link this is.',
},
description: {
description: 'The URL, or information about what the link is linking to.',
},
typeIcon: {
description: 'CSS class of an icon for this type of link (usually prefixed with "font-icon-"). See the Admin/Icons story for the full set of options.',
},
isMulti: {
description: 'Whether this link is inside a link field that supports multiple links or not.',
},
canDelete: {
description: 'Whether the current user has the permissions necessary to delete (or archive) this link.',
},
readonly: {
description: 'Whether the link field is readonly.',
},
disabled: {
description: 'Whether the link field is disabled.',
},
loading: {
description: 'Whether the link field is loading. This is passed as part of the context, not as a prop, but is here for demonstration purposes.',
},
},
};

export const _LinkPickerTitle = {
name: 'LinkPickerTitle',
args: {
id: 1,
title: 'Example link',
typeTitle: 'External URL',
description: 'https://www.example.com',
typeIcon: 'font-icon-external-link',
versionState: 'unversioned',
onDelete: () => {},
onClick: () => {},
onUnpublishedVersionedState: () => {},
isFirst: true,
isLast: true,
isMulti: false,
canCreate: true,
canDelete: true,
isSorting: false,
readonly: false,
disabled: false,
loading: false,
},
render: (args) => {
const providerArgs = {
ownerID: 1,
ownerClass: '',
ownerRelation: '',
actions: mockedActions,
loading: args.loading,
};
delete args.loading;
return <LinkFieldContext.Provider value={providerArgs}>
<LinkPickerTitle {...args} />
</LinkFieldContext.Provider>;
}
};
Loading