@storybook/addons#Args TypeScript Examples

The following examples show how to use @storybook/addons#Args. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: Checkbox.stories.ts    From wvui with GNU General Public License v2.0 6 votes vote down vote up
Configurable = ( args : Args, { argTypes } : StoryContext ): Vue.Component =>
	Vue.extend( {
		components: { WvuiCheckbox },
		props: Object.keys( argTypes ),
		data() {
			return {
				currentValue: false
			};
		},
		computed: {
			actionListeners() {
				return makeActionListeners( args, argTypes );
			},
			filteredProps() {
				return filterKeys( this.$props, [ 'default', 'vModel' ] );
			},
			slotContents() {
				return this.default;
			}
		},
		template: `
			<div class="sb-checkbox-wrapper">
				<wvui-checkbox
					v-model="currentValue"
					v-bind="filteredProps"
					v-on="actionListeners"
				>
					{{ slotContents }}
				</wvui-checkbox>
			</div>
		`
	} )
Example #2
Source File: Checkbox.stories.ts    From wvui with GNU General Public License v2.0 6 votes vote down vote up
InlineCheckboxes = ( args : Args, { argTypes } : StoryContext ): Vue.Component =>
	Vue.extend( {
		components: { WvuiCheckbox },
		props: Object.keys( argTypes ),
		data() {
			return {
				checkboxesValue: [ 'checkbox-1' ],
				checkboxes: [
					{
						label: 'Checkbox 1',
						value: 'checkbox-1'
					},
					{
						label: 'Checkbox 2',
						value: 'checkbox-2'
					}
				]
			};
		},
		computed: {
			actionListeners() {
				return makeActionListeners( args, argTypes );
			}
		},
		template: `
			<div class="sb-checkbox-wrapper">
				<wvui-checkbox
					v-for="checkbox in checkboxes"
					:key="checkbox.value"
					v-model="checkboxesValue"
					:input-value="checkbox.value"
					:inline="true"
					v-on="actionListeners"
				>
					{{ checkbox.label }}
				</wvui-checkbox>
			</div>
		`
	} )
Example #3
Source File: Dropdown.stories.ts    From wvui with GNU General Public License v2.0 6 votes vote down vote up
Configurable = ( args : Args, { argTypes } : StoryContext ): Vue.Component =>
	Vue.extend( {
		components: { WvuiDropdown },
		props: Object.keys( argTypes ),
		data: () => ( {
			currentValue: null
		} ),
		computed: {
			actionListeners() {
				return makeActionListeners( args, argTypes );
			},
			filteredProps() {
				return filterKeys( this.$props, [ 'selectedItem', 'menuItem', 'vModel' ] );
			}
		},
		template: `
			<div>
				<p>
					v-model value: <input v-model="currentValue" />
				</p>
				<wvui-dropdown
					v-model="currentValue"
					v-bind="filteredProps"
					v-on="actionListeners"
				/>
			</div>
		`
	} )
Example #4
Source File: Dropdown.stories.ts    From wvui with GNU General Public License v2.0 6 votes vote down vote up
CustomSlots = ( args: Args, { argTypes } : StoryContext ): Vue.Component =>
	Vue.extend( {
		components: { WvuiDropdown, WvuiButton },
		props: Object.keys( argTypes ),
		data: () => ( {
			currentValue: null
		} ),
		computed: {
			actionListeners() {
				return makeActionListeners( args, argTypes );
			},
			filteredProps() {
				return filterKeys( this.$props, [ 'selectedItem', 'menuItem', 'vModel' ] );
			}
		},
		template: `
			<div>
				<wvui-dropdown
					v-model="currentValue"
					v-bind="filteredProps"
					v-on="actionListeners"
				>
					<template #menuItem="{ item }">
						{{ item.label }} (ID: {{item.id}})
					</template>
					<template #selectedItem="{ item, defaultLabel }">
						<template v-if="item">
							Selected item: {{ item.label }} (ID: {{item.id}} )
						</template>
						<template v-else>
							No item selected: {{ defaultLabel }}
						</template>
					</template>
				</wvui-dropdown>
				<wvui-button @click="currentValue = null">Clear selection</wvui-button>
			</div>
		`
	} )
Example #5
Source File: Icon.stories.ts    From wvui with GNU General Public License v2.0 6 votes vote down vote up
Configurable = ( args: Args, { argTypes } : StoryContext ) : Vue.Component =>
	Vue.extend( {
		components: { WvuiIcon },
		props: Object.keys( argTypes ),
		computed: {
			iconData() : AnyIcon {
				return lookupIcon( this.icon as string );
			},
			actionListeners() {
				return makeActionListeners( args, argTypes );
			},
			filteredProps() {
				return filterKeys( this.$props, [ 'dir' ] );
			}
		},
		// HACK: the Icon component computes its dir at mount time, so changing the dir value
		// later doesn't cause it to react, breaking flipping for IconVariedByDir icons (although
		// flipping does work for IconFlipForRTL icons, since that's CSS-based).
		// To work around this, change the "key" attribute when changing dir, which causes Vue
		// to rerender the component and rerun the mounted() lifecycle hook.
		template: `
			<div :dir="dir">
				<wvui-icon
					:key="dir"
					:icon="iconData"
					v-bind="filteredProps"
					v-on="actionListeners"
				/>
			</div>
		`
	} )
Example #6
Source File: Input.stories.ts    From wvui with GNU General Public License v2.0 6 votes vote down vote up
Configurable = ( args: Args, { argTypes } : StoryContext ) : Vue.Component =>
	Vue.extend( {
		components: { WvuiInput },
		props: Object.keys( argTypes ),
		computed: {
			startIconData() {
				return lookupIcon( this.startIcon );
			},
			endIconData() {
				return lookupIcon( this.endIcon );
			},
			actionListeners() {
				return makeActionListeners( args, argTypes );
			}
		},
		template: `
			<div class="sb-input">
				<wvui-input
					:startIcon="startIconData"
					:endIcon="endIconData"
					v-bind="$props"
					v-on="actionListeners"
				/>
			</div>
		`
	} )
Example #7
Source File: Button.stories.ts    From wvui with GNU General Public License v2.0 6 votes vote down vote up
Configurable = ( args : Args, { argTypes } : StoryContext ): Vue.Component =>
	Vue.extend( {
		components: { WvuiButton, WvuiIcon },
		props: Object.keys( argTypes ),
		computed: {
			slotContents() {
				return this.default;
			},
			iconData() {
				return lookupIcon( this.icon );
			},
			actionListeners() {
				return makeActionListeners( args, argTypes );
			},
			filteredProps() {
				return filterKeys( this.$props, [ 'default', 'icon' ] );
			}
		},
		template: `
			<wvui-button v-bind="filteredProps" v-on="actionListeners">
				<wvui-icon v-if="iconData" :icon="iconData" />
				{{ slotContents }}
			</wvui-button>
		`
	} )
Example #8
Source File: Input.stories.ts    From wvui with GNU General Public License v2.0 6 votes vote down vote up
WithButton = ( args: Args, context: StoryContext ) : Vue.Component =>
	Vue.extend( {
		components: {
			StoryConfigurable: Configurable( args, context ),
			WvuiButton
		},
		props: Object.keys( context.argTypes ),
		template: `
			<div class="sb-input--has-button">
				<story-configurable v-bind="$props" />
				<wvui-button :disabled="disabled">Search</wvui-button>
			</div>
		`
	} )
Example #9
Source File: Radio.stories.ts    From wvui with GNU General Public License v2.0 6 votes vote down vote up
Configurable = ( args : Args, { argTypes } : StoryContext ): Vue.Component =>
	Vue.extend( {
		components: { WvuiRadio },
		props: Object.keys( argTypes ),
		data() {
			return {
				currentValue: ''
			};
		},
		computed: {
			actionListeners() {
				return makeActionListeners( args, argTypes );
			},
			filteredProps() {
				return filterKeys( this.$props, [ 'default', 'vModel' ] );
			},
			slotContents() {
				return this.default;
			}
		},
		template: `
			<div class="sb-radio-wrapper">
				<wvui-radio
					v-model="currentValue"
					v-bind="filteredProps"
					v-on="actionListeners"
				>
					{{ slotContents }}
				</wvui-radio>
			</div>
		`
	} )
Example #10
Source File: TypeaheadSearch.stories.ts    From wvui with GNU General Public License v2.0 6 votes vote down vote up
Configurable = ( args: Args, { argTypes } : StoryContext ) : Vue.Component =>
	Vue.extend( {
		components: { WvuiTypeaheadSearch },
		props: Object.keys( argTypes )
			.filter( ( propName ) => ![ 'client', 'urlGenerator' ].includes( propName ) ),
		computed: {
			actionListeners() {
				return makeActionListeners( args, argTypes );
			},
			filteredProps() {
				return filterKeys( this.$props, [ 'default' ] );
			}
		},
		template: `
			<div class="sb-typeahead-search">
				<wvui-typeahead-search
					v-bind="filteredProps"
					v-on="actionListeners"
				>
					<template v-if="${'default' in args}" #default>
						${args.default}
					</template>
					<!-- eslint-disable-next-line max-len -->
					<template v-if="${'search-footer' in args}" #search-footer="{ searchQuery }">
						${args[ 'search-footer' ]}
					</template>
				</wvui-typeahead-search>
			</div>
		`
	} )
Example #11
Source File: ToggleButton.stories.ts    From wvui with GNU General Public License v2.0 6 votes vote down vote up
AllCombinations = ( _args: Args, { argTypes } : StoryContext ): Vue.Component =>
	Vue.extend( {
		components: { WvuiToggleButton },
		props: Object.keys( argTypes ),
		computed: {
			slotContents() {
				return this.default;
			}
		},
		template: `
			<table class="sb-toggle-button-combinations">
				<thead>
					<th></th>
					<th>Default</th>
					<th>Active</th>
				</thead>
				<tbody>
					<tr v-for="disabled in [ false, true ]" :key="'toggle' + disabled">
						<th scope="row">
							{{ disabled ? 'Disabled' : 'Enabled' }}
						</th>
						<td v-for="isActive in [ false, true ]"
							:key="'toggle' + disabled + isActive"
						>
							<wvui-toggle-button
								:is-active="isActive"
								:disabled="disabled"
							>
								{{ slotContents }}
							</wvui-toggle-button>
						</td>
					</tr>
				</tbody>
			</table>
		`
	} )
Example #12
Source File: ToggleButton.stories.ts    From wvui with GNU General Public License v2.0 6 votes vote down vote up
Configurable = ( _args : Args, { argTypes } : StoryContext ): Vue.Component =>
	Vue.extend( {
		components: { WvuiToggleButton },
		props: Object.keys( argTypes ),
		data: () => ( {
			// Don't use the isActive arg at all
			reallyIsActive: false
		} ),
		computed: {
			slotContents() {
				return this.default;
			}
		},
		methods: {
			onChange( newValue: boolean ) {
				this.reallyIsActive = newValue;
			}
		},
		template: `
			<wvui-toggle-button
				v-bind:is-active="reallyIsActive"
				v-bind:disabled="disabled"
				v-on:change="onChange"
			>
				{{ slotContents }}
			</wvui-toggle-button>
		`
	} )
Example #13
Source File: Input.stories.ts    From wvui with GNU General Public License v2.0 5 votes vote down vote up
CommonUses = ( _args: Args, { argTypes } : StoryContext ) : Vue.Component =>
	Vue.extend( {
		components: { WvuiInput },
		props: Object.keys( argTypes ),
		data: () => ( {
			searchIcon: wvuiIconSearch,
			infoFilledIcon: wvuiIconInfoFilled,
			InputType
		} ),
		template: `
			<div class="sb-input">
				<p>
					With start icon:
					<wvui-input
						:disabled="disabled"
						:type="InputType.Search"
						:start-icon="searchIcon"
						placeholder="Search…"
					/>
				</p>
				<p>
					With end icon:
					<wvui-input
						:disabled="disabled"
						:type="InputType.Search"
						:end-icon="infoFilledIcon"
						placeholder="Search…"
					/>
				</p>
				<p>
					With clear action:
					<wvui-input
						:disabled="disabled"
						:type="InputType.Search"
						placeholder="Type something…"
						clearable
						value="Some text"
					/>
				</p>
			</div>
		`
	} )
Example #14
Source File: StoryUtils.ts    From wvui with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Map event names to action listeners.
 *
 * Finds entries in argTypes that have the 'action' property set, and returns an object mapping
 * those event names to the listeners for those actions.
 *
 * To use this for e.g. the 'click' and 'mouseover' events, add the following to argTypes in either
 * the file's export default or to an individual story:
 *     argTypes: {
 *         // other stuff
 *         ...makeActionArgTypes( [ 'click', 'mouseover' ] )
 *     }
 *
 * Then in your story component, add a computed property:
 *     computed: {
 *         actionListeners() {
 *             return makeActionListeners( args, argTypes );
 *         }
 *     }
 *
 * and pass this computed property to the component's v-on in the template:
 *
 *     template: `
 *         <wvui-button
 *             v-bind="$props"
 *             v-on="actionListeners"
 *         />
 *     `
 *
 * @param args The args parameter passed to the story
 * @param argTypes The argTypes parameter passed to the story
 * @return Object for use in v-on=""
 */
export function makeActionListeners( args: Args, argTypes: ArgTypes ) : Record<string, () => void> {
	const listeners = {} as Record<string, () => void>;
	for ( const argName in argTypes ) {
		const argType = argTypes[ argName ];
		if ( argType.action ) {
			listeners[ argName ] = args[ argName ] as () => void;
		}
	}
	return listeners;
}
Example #15
Source File: TypeaheadSuggestion.stories.ts    From wvui with GNU General Public License v2.0 5 votes vote down vote up
Configurable = ( args: Args, { argTypes } : StoryContext ) : Vue.Component =>
	Vue.extend( {
		components: { WvuiTypeaheadSuggestion },
		props: Object.keys( argTypes )
			.filter( ( prop ) => ![ 'urlGenerator', 'suggestion' ].includes( prop ) ),
		computed: {
			suggestion(): SearchResult {
				return {
					id: 42,
					key: this.suggestionTitle as string,
					title: this.suggestionTitle as string,
					description: this.suggestionDescription as string,
					thumbnail: this.suggestionHasThumbnail as boolean ?
						{ url: this.suggestionThumbnailUrl as string } : undefined
				};
			},
			actionListeners() {
				return makeActionListeners( args, argTypes );
			},
			filteredProps() {
				return filterKeys( this.$props, [
					'suggestionTitle',
					'suggestionDescription',
					'suggestionHasThumbnail',
					'suggestionThumbnailUrl'
				] );
			}
		},
		template: `
			<ol class="sb-search__suggestions" role="listbox">
				<li role="option">
					<wvui-typeahead-suggestion
						:suggestion="suggestion"
						v-bind="filteredProps"
						v-on="actionListeners"
					/>
				</li>
			</ol>
		`
	} )
Example #16
Source File: TypeaheadSuggestion.stories.ts    From wvui with GNU General Public License v2.0 5 votes vote down vote up
function makeExampleListStory( suggestionsList : SuggestionsList, defaultQuery: string ) :
	( ( args: Args, context: StoryContext ) => Vue.Component ) {
	const story = ( args: Args, { argTypes } : StoryContext ) : Vue.Component =>
		Vue.extend( {
			components: { WvuiTypeaheadSuggestion },
			props: Object.keys( argTypes )
				.filter( ( prop ) => ![ 'urlGenerator', 'suggestion' ].includes( prop ) ),
			data() {
				return {
					suggestionsList: suggestionsList.pages,
					activeIndex: -1
				};
			},
			computed: {
				actionListeners() {
					return makeActionListeners( args, argTypes );
				}
			},
			methods: {
				onSuggestionMouseOver( index: number ) {
					this.activeIndex = index;
				}
			},
			template: `
			<ol class="sb-search__suggestions">
				<li v-for="(suggestion, index) in suggestionsList" >
					<wvui-typeahead-suggestion
						v-bind="$props"
						v-on="actionListeners"
						@mouseover="onSuggestionMouseOver( index )"
						:active="activeIndex === index"
						:suggestion="suggestion"
						:key="suggestion.id"
					/>
				</li>
			</ol>
			`
		} );
	story.argTypes = {
		active: {
			table: {
				disable: true
			}
		},
		query: {
			defaultValue: defaultQuery
		}
	};
	return story;
}
Example #17
Source File: Radio.stories.ts    From wvui with GNU General Public License v2.0 5 votes vote down vote up
InlineRadios = ( args : Args, { argTypes } : StoryContext ): Vue.Component =>
	Vue.extend( {
		components: { WvuiRadio },
		props: Object.keys( argTypes ),
		data() {
			return {
				radioValue: 'radio-1',
				radios: [
					{
						label: 'Radio 1',
						value: 'radio-1'
					},
					{
						label: 'Radio 2',
						value: 'radio-2'
					}
				]
			};
		},
		computed: {
			actionListeners() {
				return makeActionListeners( args, argTypes );
			}
		},
		template: `
			<div class="sb-radio-wrapper">
				<wvui-radio
					v-for="radio in radios"
					:key="'radio-' + radio.value"
					v-model="radioValue"
					:input-value="radio.value"
					:name="$props.name"
					:inline="true"
					v-on="actionListeners"
				>
					{{ radio.label }}
				</wvui-radio>
			</div>
		`
	} )
Example #18
Source File: Radio.stories.ts    From wvui with GNU General Public License v2.0 5 votes vote down vote up
RadioGroup = ( args : Args, { argTypes } : StoryContext ): Vue.Component =>
	Vue.extend( {
		components: { WvuiRadio },
		props: Object.keys( argTypes ),
		data() {
			return {
				radioValue: 'radio-2',
				radios: [
					{
						label: 'Radio 1',
						value: 'radio-1',
						disabled: false
					},
					{
						label: 'Radio 2 (initially selected)',
						value: 'radio-2',
						disabled: false
					},
					{
						label: 'Radio 3, which has a very long label that spans onto a second line',
						value: 'radio-3',
						disabled: false
					},
					{
						label: 'Radio 4 (disabled)',
						value: 'radio-4',
						disabled: true
					}
				]
			};
		},
		computed: {
			actionListeners() {
				return makeActionListeners( args, argTypes );
			}
		},
		template: `
			<div class="sb-radio-wrapper">
				<wvui-radio
					v-for="radio in radios"
					:key="'radio-' + radio.value"
					v-model="radioValue"
					:input-value="radio.value"
					:name="$props.name"
					:disabled="radio.disabled"
					v-on="actionListeners"
				>
					{{ radio.label }}
				</wvui-radio>
			</div>
		`
	} )
Example #19
Source File: Icon.stories.ts    From wvui with GNU General Public License v2.0 5 votes vote down vote up
AllIcons = ( _args: Args, { argTypes } : StoryContext ) : Vue.Component =>
	Vue.extend( {
		components: { WvuiIcon },
		props: Object.keys( argTypes ),
		computed: {
			flattenedIcons() {
				const filteredProps = filterKeys( this.$props, [ 'dir' ] );
				const flattened = [];
				for ( const iconName in icons ) {
					const icon = lookupIcon( iconName );
					if (
						typeof icon !== 'string' &&
						( 'langCodeMap' in icon || 'shouldFlipExceptions' in icon )
					) {
						const langCodes = 'langCodeMap' in icon ? Object.keys( icon.langCodeMap ) :
							icon.shouldFlipExceptions || [];
						for ( const langCode of langCodes ) {
							flattened.push( {
								label: `${iconName} (${langCode})`,
								props: { ...filteredProps, icon, langCode }
							} );
						}
						flattened.push( {
							label: `${iconName} (other languages)`,
							props: { ...filteredProps, icon, langCode: '' }
						} );
					} else {
						flattened.push( {
							label: iconName,
							props: { ...filteredProps, icon }
						} );
					}
				}
				return flattened;
			}
		},
		template: `
			<table>
				<thead>
					<tr>
						<th scope="col"></th>
						<th scope="col">LTR</th>
						<th scope="col">RTL</th>
					</tr>
				</thead>
				<tbody>
					<tr v-for="icon in flattenedIcons">
						<td>{{ icon.label }}</td>
						<td dir="ltr"><wvui-icon v-bind="icon.props" /></td>
						<td dir="rtl"><wvui-icon v-bind="icon.props" /></td>
					</tr>
				</tbody>
			</table>
		`
	} )
Example #20
Source File: Checkbox.stories.ts    From wvui with GNU General Public License v2.0 5 votes vote down vote up
CheckboxGroup = ( args : Args, { argTypes } : StoryContext ): Vue.Component =>
	Vue.extend( {
		components: { WvuiCheckbox },
		props: Object.keys( argTypes ),
		data() {
			return {
				checkboxesValue: [
					'checkbox-1',
					'checkbox-2',
					'checkbox-6'
				],
				checkboxes: [
					{
						label: 'Checkbox 1',
						value: 'checkbox-1',
						disabled: false
					},
					{
						label: 'Checkbox 2 (initially selected)',
						value: 'checkbox-2',
						disabled: false
					},
					{
						label: 'Checkbox 3, with a very long label that spans onto a second line',
						value: 'checkbox-3',
						disabled: false
					},
					{
						label: 'Checkbox 4 (indeterminate)',
						value: 'checkbox-4',
						indeterminate: true,
						disabled: false
					},
					{
						label: 'Checkbox 5 (disabled)',
						value: 'checkbox-5',
						disabled: true
					},
					{
						label: 'Checkbox 6 (initially selected, disabled)',
						value: 'checkbox-6',
						disabled: true
					}
				]
			};
		},
		computed: {
			actionListeners() {
				return makeActionListeners( args, argTypes );
			}
		},
		template: `
			<div class="sb-checkbox-wrapper">
				<wvui-checkbox
					v-for="checkbox in checkboxes"
					:key="checkbox.value"
					v-model="checkboxesValue"
					:input-value="checkbox.value"
					:disabled="checkbox.disabled"
					:indeterminate="checkbox.indeterminate"
					v-on="actionListeners"
				>
					{{ checkbox.label }}
				</wvui-checkbox>
			</div>
		`
	} )
Example #21
Source File: Button.stories.ts    From wvui with GNU General Public License v2.0 5 votes vote down vote up
AllCombinations = ( _args: Args, { argTypes } : StoryContext ): Vue.Component =>
	Vue.extend( {
		components: { WvuiButton, WvuiIcon },
		props: Object.keys( argTypes ),
		data() {
			return {
				types: ButtonType,
				actions: ButtonAction
			};
		},
		computed: {
			slotContents() {
				return this.default;
			},
			iconData() {
				return lookupIcon( this.icon );
			}
		},
		template: `
			<table class="sb-button-combinations">
				<thead>
					<th></th>
					<th v-for="(action, actionName) in actions" :key="action" scope="col">
						{{ actionName }}
					</th>
				</thead>
				<tbody>
					<template v-for="(type, typeName) in types">
						<tr v-for="disabled in [ false, true ]" :key="type + disabled">
							<th scope="row">
								{{ typeName }} {{ disabled ? 'disabled' : '' }}
							</th>
							<td v-for="(action, actionName) in actions" :key="action">
								<wvui-button
									:action="action"
									:type="type"
									:disabled="disabled"
								>
									<wvui-icon
										v-if="iconData"
										:icon="iconData"
									/>
									{{ slotContents }}
								</wvui-button>
							</td>
						</tr>
					</template>
				</tbody>
				<tfoot class="sb-button-combinations-hint-mobile">
					<tr>
						<td
							:colspan="Object.keys( actions ).length + 1"
						>
							Please scroll horizontally to see all combinations.
						</td>
					</tr>
				</tfoot>
			</table>
		`
	} )