Skip to content

Commit

Permalink
types of csf properties (#3)
Browse files Browse the repository at this point in the history
types of csf properties
  • Loading branch information
shilman authored Jan 30, 2020
2 parents 045f8e1 + a65b41a commit 4ee0750
Show file tree
Hide file tree
Showing 3 changed files with 352 additions and 0 deletions.
28 changes: 28 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import startCase from 'lodash/startCase';
import { StoryProperties } from './properties';

export * from './properties';

/**
* Remove punctuation and illegal characters from a story ID.
Expand Down Expand Up @@ -82,3 +85,28 @@ export const parseKind = (kind: string, { rootSeparator, groupSeparator }: Separ
groups,
};
};

/**
* csf story metadata attached to the story export function
*/
export interface StoryMetadata {
story?: {
/**
* story name if different from the export name
*/
name?: string;

/**
* optional collection of properties, which values
* will be passed onto the story function
*/
properties?: StoryProperties;

/**
* optional collection of story parameters
*/
parameters?: {
[key: string]: any;
};
};
}
12 changes: 12 additions & 0 deletions src/properties.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { PropertyTypes, StoryProperty } from '.';

describe('properties', () => {
it('type PropertyTypes.TEXT', () => {
expect(() => {
const prop: StoryProperty = {
type: PropertyTypes.TEXT,
};
return prop.type === 'text';
}).toBeTruthy();
});
});
312 changes: 312 additions & 0 deletions src/properties.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,312 @@
/**
* Property field types
* examples are provided for the different types:
*
*/
export enum PropertyTypes {
/**
* userName: {
* type: csf.PropertyTypes.TEXT,
* label: 'Name',
* value: 'Storyteller',
* },
*/
TEXT = 'text',

/**
* age: {
* type: csf.PropertyTypes.NUMBER,
* label: 'Age',
* value: 78,
* range: true,
* min: 0,
* max: 90,
* step: 5,
* },
*/
NUMBER = 'number',

/**
* nice: {
* type: csf.PropertyTypes.BOOLEAN,
* label: 'Nice',
* value: true,
* },
*/
BOOLEAN = 'boolean',

/**
* fruit: {
* type: csf.PropertyTypes.OPTIONS,
* label: 'Fruit',
* value: 'apple',
* options: {
* Apple: 'apple',
* Banana: 'banana',
* Cherry: 'cherry',
* },
* },
*/
OPTIONS = 'options',

/**
* birthday: {
* type: csf.PropertyTypes.DATE,
* label: 'Birthday',
* value: new Date(),
* },
*/
DATE = 'date',

/**
* color: {
* type: 'color',
* value: '#000000',
* },
*/
COLOR = 'color',

/**
* button: {
* type: csf.PropertyTypes.BUTTON,
* onClick: () => {
* ... code to modify some variables
* }
* },
*/
BUTTON = 'button',

/**
* otherStyles: {
* type: csf.PropertyTypes.OBJECT,
* label: 'Styles',
* value: {
* border: '2px dashed silver',
* borderRadius: 10,
* padding: 10,
* },
* },
*/
OBJECT = 'object',

/**
* items: {
* type: csf.PropertyTypes.ARRAY,
* label: 'Items',
* value: ['Laptop', 'Book', 'Whiskey'],
* },
*/
ARRAY = 'array',

/**
* images: {
* type: csf.PropertyTypes.FILES,
* label: 'Happy Picture',
* accept: 'image/*',
* value: [
* 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAQAAAC1+jfqAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QA/4ePzL8AAAAHdElNRQfiARwMCyEWcOFPAAAAP0lEQVQoz8WQMQoAIAwDL/7/z3GwghSp4KDZyiUpBMCYUgd8rehtH16/l3XewgU2KAzapjXBbNFaPS6lDMlKB6OiDv3iAH1OAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE4LTAxLTI4VDEyOjExOjMzLTA3OjAwlAHQBgAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxOC0wMS0yOFQxMjoxMTozMy0wNzowMOVcaLoAAAAASUVORK5CYII=',
* ],
* },
*/
FILES = 'files',
}

export interface StoryPropertyBase<T> {
type: PropertyTypes;

/**
* label to display next to the field editor
* by default uses the property name itself
*/

label?: string;

/**
* a default value for the property
*/
value?: T;

/**
* hide the label from the property editor
*/
hideLabel?: boolean;
/**
* hide the property editor for this property
* will only use the value
*/

hidden?: boolean;
/**
* allows grouping of the properties
* in a property editor
* for example different editor tabs
*/
groupId?: string;

/**
* allows custom sorting of the properties
* if 'order' is not provided, the props
* will be sorted by the order/key of the object (unreliable)
*/
order?: number;
}

export interface StoryPropertyText extends StoryPropertyBase<string> {
type: PropertyTypes.TEXT;

/**
* placeholder for empty properties
* either undefined initial value
* or user clears the field
*/
placeholder?: string;

/**
* number of rows in a TextArea field
* by default, only 1 row = means a Input field
*/
maxRows?: number;
}

export interface StoryPropertyBoolean extends StoryPropertyBase<boolean> {
type: PropertyTypes.BOOLEAN;
}

export interface StoryPropertyColor extends StoryPropertyBase<string> {
type: PropertyTypes.COLOR;
}

export interface StoryPropertyDate extends StoryPropertyBase<Date> {
type: PropertyTypes.DATE;
/**
* whether to display a date picker (calendar).
* default: true
*/
datePicker?: boolean;

/**
* whether to display a time picker (calendar).
* default: true
*/

timePicker?: boolean;
}

export interface StoryPropertyFiles extends StoryPropertyBase<string[]> {
type: PropertyTypes.FILES;
/**
* type of files to accept user to open
* ex 'image/*',
*/
accept?: string;
}

export interface StoryPropertyArray extends StoryPropertyBase<string[]> {
type: PropertyTypes.ARRAY;
/**
* the array items separator, by default comma
*/
separator?: string;
}

export interface StoryPropertyObject extends StoryPropertyBase<object> {
type: PropertyTypes.OBJECT;
}

export interface StoryPropertyButton extends StoryPropertyBase<void> {
type: PropertyTypes.BUTTON;

/**
* for button type fields, an onClick handler
*/
onClick?: (prop: StoryPropertyButton) => void;
}

export type OptionsValueType<T = unknown> =
| T
| string
| number
| string[]
| number[]
| { label: string; value: any };

/**
* value/label pairs or array of OptionsValueType
*/
export type OptionsListType<T = unknown> = { [key: string]: T } | OptionsValueType<T>[];

/**
* list of options can be
* 1. key-value pair object: in format { label: value }
* 2. array of strings
* 3. array of key-value pair objects
*/

export interface StoryPropertyOptions<T = unknown> extends StoryPropertyBase<OptionsValueType<T>> {
type: PropertyTypes.OPTIONS;

options: OptionsListType<T>;
/**
* how to render selecting the options:
* default is 'select'
*/

display?: 'select' | 'multi-select' | 'radio' | 'inline-radio' | 'check' | 'inline-check';
}

export interface StoryPropertyNumber extends StoryPropertyBase<number> {
type: PropertyTypes.NUMBER;
/**
* for numeric type fields
*/

/**
* if true, will display a range type slider editor
*/
range?: boolean;

/**
* minimum allowed value for numeric property
*/
min?: number;

/**
* maximum allowed value for numeric property
*/
max?: number;

/**
* stepper for numeric editor /i nc/dec value
*/

step?: number;
}

/**
* StoryProperty is a either an object of property settings
* or a shortcut can be used:
* properties: {
* text: 'Hello',
* },
*/

export type StoryProperty =
| StoryPropertyText
| StoryPropertyBoolean
| StoryPropertyColor
| StoryPropertyDate
| StoryPropertyObject
| StoryPropertyButton
| StoryPropertyOptions
| StoryPropertyNumber
| StoryPropertyArray
| StoryPropertyFiles;

/**
* StoryProperties are defined in key value pairs
* the name of the property is the key
* and the value is the StoryProperty
*/
export interface StoryProperties {
[name: string]: StoryProperty;
}

0 comments on commit 4ee0750

Please sign in to comment.