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}
+ ${ViraDropdownItem}>
+ `;
+ } else {
+ return html`
+ <${ViraDropdownItem.assign(finalInputs)}>${ViraDropdownItem}>
+ `;
+ }
+ },
+ });
+ });
+ },
+});
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});
+ })}
+ >${ViraDropdown}>
+ `;
+ },
+ });
+ });
+ },
+});