diff --git a/packages/vira-book/src/element-book/all-element-book-entries.ts b/packages/vira-book/src/element-book/all-element-book-entries.ts index 81fe4ffc..3ccbb141 100644 --- a/packages/vira-book/src/element-book/all-element-book-entries.ts +++ b/packages/vira-book/src/element-book/all-element-book-entries.ts @@ -1,4 +1,7 @@ import {elementsBookPage} from './elements.book'; +import {ViraDropdownItemPage} from './entries/dropdown/vira-dropdown-item.element.book'; +import {dropdownPage} from './entries/dropdown/vira-dropdown.book'; +import {viraDropdownPage} from './entries/dropdown/vira-dropdown.element.book'; import {iconsBookPage} from './entries/icons.book'; import {viraButtonBookPage} from './entries/vira-button.element.book'; import {viraCollapsibleBookPage} from './entries/vira-collapsible-wrapper.element.book'; @@ -9,12 +12,15 @@ import {viraLinkBookPage} from './entries/vira-link.element.book'; export const allElementBookEntries = [ elementsBookPage, - iconsBookPage, + dropdownPage, + viraButtonBookPage, viraCollapsibleBookPage, + ViraDropdownItemPage, + viraDropdownPage, viraIconBookPage, viraImageBookPage, viraInputBookPage, viraLinkBookPage, -]; +].sort((a, b) => a.title.localeCompare(b.title)); diff --git a/packages/vira-book/src/element-book/entries/dropdown/vira-dropdown-item.element.book.ts b/packages/vira-book/src/element-book/entries/dropdown/vira-dropdown-item.element.book.ts new file mode 100644 index 00000000..22d18cb9 --- /dev/null +++ b/packages/vira-book/src/element-book/entries/dropdown/vira-dropdown-item.element.book.ts @@ -0,0 +1,86 @@ +import {BookPageControlTypeEnum, defineBookPage, definePageControl} from 'element-book'; +import {CSSResult, HTMLTemplateResult, html} from 'element-vir'; +import {ViraDropdownItem} from 'vira'; +import {dropdownPage} from './vira-dropdown.book'; + +const examples: ReadonlyArray<{ + title: string; + inputs?: typeof ViraDropdownItem.inputsType; + customStyle?: CSSResult; + customTemplate?: HTMLTemplateResult; +}> = [ + { + title: 'unselected', + inputs: { + label: 'my label', + selected: false, + }, + }, + { + title: 'selected', + inputs: { + label: 'my label', + selected: true, + }, + }, + { + title: 'with custom child', + inputs: { + label: 'custom child', + selected: true, + }, + customTemplate: html` + This is custom + `, + }, +]; + +export const ViraDropdownItemPage = defineBookPage({ + title: ViraDropdownItem.tagName, + parent: dropdownPage, + controls: { + Selected: definePageControl({ + controlType: BookPageControlTypeEnum.Dropdown, + initValue: '', + options: [ + '', + 'all', + 'none', + ], + }), + Label: definePageControl({ + controlType: BookPageControlTypeEnum.Text, + initValue: '', + }), + }, + elementExamplesCallback({defineExample}) { + examples.forEach((example) => { + defineExample({ + title: example.title, + stateInitStatic: { + selected: example.inputs?.selected || [], + }, + renderCallback({controls}) { + const finalInputs: typeof ViraDropdownItem.inputsType = { + label: controls.Label || example.inputs?.label || '', + selected: controls.Selected + ? controls.Selected === 'all' + : !!example.inputs?.selected, + }; + + if (example.customTemplate) { + return html` + <${ViraDropdownItem.assign(finalInputs)}> + ${example.customTemplate} + + `; + } else { + return html` + <${ViraDropdownItem.assign(finalInputs)}> + `; + } + }, + }); + }); + }, +}); diff --git a/packages/vira-book/src/element-book/entries/dropdown/vira-dropdown.book.ts b/packages/vira-book/src/element-book/entries/dropdown/vira-dropdown.book.ts new file mode 100644 index 00000000..545ade5d --- /dev/null +++ b/packages/vira-book/src/element-book/entries/dropdown/vira-dropdown.book.ts @@ -0,0 +1,7 @@ +import {defineBookPage} from 'element-book'; +import {elementsBookPage} from '../../elements.book'; + +export const dropdownPage = defineBookPage({ + parent: elementsBookPage, + title: 'Dropdown', +}); diff --git a/packages/vira-book/src/element-book/entries/dropdown/vira-dropdown.element.book.ts b/packages/vira-book/src/element-book/entries/dropdown/vira-dropdown.element.book.ts new file mode 100644 index 00000000..05bfa91f --- /dev/null +++ b/packages/vira-book/src/element-book/entries/dropdown/vira-dropdown.element.book.ts @@ -0,0 +1,206 @@ +import {isTruthy} from '@augment-vir/common'; +import {BookPageControlTypeEnum, defineBookPage, definePageControl} from 'element-book'; +import {CSSResult, html, listen} from 'element-vir'; +import {ViraDropdown, ViraDropdownOption, allIconsByName} from 'vira'; +import {dropdownPage} from './vira-dropdown.book'; + +const exampleDropdownOptions: ReadonlyArray> = [ + { + label: 'Option 1', + id: 1, + }, + { + label: 'Option 2', + id: 2, + }, + { + label: 'Option 3', + id: 3, + }, + { + label: 'Really really super duper long option', + id: 4, + }, + { + label: 'Really really super duper long option', + id: 5, + }, + { + label: 'Really really super duper long option', + id: 6, + }, + { + label: 'Really really super duper long option', + id: 7, + }, + { + label: "Really really super duper long it just keeps going because it's so long option", + id: 8, + }, +]; + +const examples: ReadonlyArray<{ + title: string; + inputs?: Partial; + customStyle?: CSSResult; +}> = [ + { + title: 'default', + }, + { + title: 'disabled', + inputs: { + isDisabled: true, + }, + }, + { + title: 'multi select', + inputs: { + isMultiSelect: true, + }, + }, + { + title: 'long selection', + inputs: { + selected: [8], + }, + }, + { + title: 'with custom template', + inputs: { + selected: [8], + options: [ + ...exampleDropdownOptions, + { + id: 42, + label: 'custom template', + template: html` + + `, + }, + ], + }, + }, + { + title: 'with disabled item', + inputs: { + selected: [8], + options: [ + ...exampleDropdownOptions, + { + id: 42, + label: 'this is disabled', + disabled: true, + }, + ], + }, + }, + // { + // title: 'forced open', + // inputs: { + // z_debug_forceOpenState: true, + // selected: [1], + // }, + // }, +]; + +export const viraDropdownPage = defineBookPage({ + title: ViraDropdown.tagName, + parent: dropdownPage, + controls: { + Selected: definePageControl({ + controlType: BookPageControlTypeEnum.Dropdown, + initValue: '', + options: [ + '', + ...exampleDropdownOptions.map((option) => option.label), + ], + }), + Prefix: definePageControl({ + controlType: BookPageControlTypeEnum.Text, + initValue: '', + }), + 'Force State': definePageControl({ + controlType: BookPageControlTypeEnum.Dropdown, + options: [ + '', + 'force open', + 'force closed', + ], + initValue: '', + }), + 'Multi Select': definePageControl({ + controlType: BookPageControlTypeEnum.Dropdown, + options: [ + '', + 'all', + 'none', + ], + initValue: '', + }), + Icon: definePageControl({ + controlType: BookPageControlTypeEnum.Dropdown, + initValue: '', + options: [ + '', + ...Object.keys(allIconsByName), + ], + }), + Disabled: definePageControl({ + controlType: BookPageControlTypeEnum.Dropdown, + options: [ + '', + 'all', + 'none', + ], + initValue: '', + }), + }, + elementExamplesCallback({defineExample}) { + examples.forEach((example) => { + defineExample({ + title: example.title, + stateInitStatic: { + selected: example.inputs?.selected || [], + }, + renderCallback({state, updateState, controls}) { + const finalInputs: typeof ViraDropdown.inputsType = { + options: example.inputs?.options || exampleDropdownOptions, + selected: controls.Selected + ? [ + exampleDropdownOptions.find( + (option) => option.label === controls.Selected, + )?.id, + ].filter(isTruthy) + : state.selected, + buttonPrefix: controls.Prefix || example.inputs?.buttonPrefix, + isDisabled: controls.Disabled + ? controls.Disabled === 'all' + : example.inputs?.isDisabled, + icon: controls.Icon + ? allIconsByName[controls.Icon as keyof typeof allIconsByName] + : example.inputs?.icon, + isMultiSelect: controls['Multi Select'] + ? controls['Multi Select'] === 'all' + : example.inputs?.isMultiSelect, + z_debug_forceOpenState: controls['Force State'] + ? controls['Force State'] === 'force open' + : example.inputs?.z_debug_forceOpenState, + }; + + return html` + <${ViraDropdown.assign(finalInputs)} + ${listen(ViraDropdown.events.selectedChange, (event) => { + updateState({selected: event.detail}); + })} + > + `; + }, + }); + }); + }, +});