import {
BlockDefinition,
ResolvableString,
ResolvableBoolean,
ResolvableArray,
} from '@ministryofjustice/hmpps-forge/core/components'
import { nunjucksComponent } from '../../utils/nunjucksComponent'
/**
* Menu alignment options for the button menu dropdown.
*/
export type MOJButtonMenuAlign = 'left' | 'right'
/**
* Configuration for the toggle button that opens/closes the menu.
*/
export interface MOJButtonMenuButton {
/**
* Text content for the toggle button.
*
* @example 'Actions'
* @example 'Options'
*/
text?: ResolvableString
/**
* Additional CSS classes for the toggle button.
*
* @example 'govuk-button--secondary'
*/
classes?: ResolvableString
}
/**
* Menu item configuration for a button in the menu.
* Based on GOV.UK Button component parameters.
*
* @see https://design-system.service.gov.uk/components/button/
*/
export interface MOJButtonMenuItem {
/**
* Whether to use an `input`, `button` or `a` element.
* Automatically configured if `href` or `html` is set.
*
* @example 'button'
* @example 'a'
*/
element?: 'input' | 'button' | 'a' | ResolvableString
/**
* Text content for the button or link.
* Required if `html` is not set.
*
* @example 'Archive'
* @example 'Delete'
*/
text?: ResolvableString
/**
* HTML content for the button or link.
* Required if `text` is not set.
*
* @example '+ Add item'
*/
html?: ResolvableString
/**
* Name attribute for input or button elements.
* Has no effect on anchor elements.
*
* @example 'action'
*/
name?: ResolvableString
/**
* Type attribute for input or button elements.
* Options: 'button', 'submit', 'reset'. Default: 'submit'.
* Has no effect on anchor elements.
*
* @example 'button'
*/
type?: 'button' | 'submit' | 'reset' | ResolvableString
/**
* Value attribute for button elements.
* Has no effect on anchor or input elements.
*
* @example 'archive'
*/
value?: ResolvableString
/**
* Whether the button should be disabled.
*
* @example true
*/
disabled?: ResolvableBoolean
/**
* URL that the button should link to.
* If set, `element` defaults to 'a'.
*
* @example '/actions/archive'
* @example '#archive'
*/
href?: ResolvableString
/**
* Additional CSS classes for the button.
*
* @example 'govuk-button--warning'
*/
classes?: ResolvableString
/**
* Additional HTML attributes for the button.
*
* @example { 'data-action': 'archive' }
*/
attributes?: Record
/**
* Prevent accidental double clicks from submitting forms multiple times.
*
* @example true
*/
preventDoubleClick?: ResolvableBoolean
/**
* Conditional visibility for this menu item.
* When the evaluated value is `false`, the item is omitted from rendering.
*/
visibleWhen?: ResolvableBoolean
}
/**
* MOJ Button Menu component.
* A dropdown button that reveals a menu of actions.
*
* The button menu component is useful for grouping secondary actions together
* to reduce visual clutter while keeping them easily accessible.
*
* @see https://design-patterns.service.justice.gov.uk/components/button-menu
* @example
* ```typescript
* MOJButtonMenu({
* button: {
* text: 'Actions',
* classes: 'govuk-button--secondary',
* },
* alignMenu: 'right',
* items: [
* { text: 'Archive', href: '#archive' },
* { text: 'Reassign', href: '#reassign' },
* { text: 'Delete', href: '#delete', classes: 'govuk-button--warning' },
* ],
* })
* ```
*/
export interface MOJButtonMenu extends BlockDefinition {
/**
* Configuration for the toggle button.
* Sets the text and styling of the button that opens the menu.
*
* @example { text: 'Actions', classes: 'govuk-button--secondary' }
*/
button?: MOJButtonMenuButton
/**
* Alignment of the dropdown menu relative to the toggle button.
* Options: 'left' (default), 'right'
*
* @example 'right'
*/
alignMenu?: MOJButtonMenuAlign | ResolvableString
/**
* Array of menu item button configurations.
* Each item becomes a button/link in the dropdown menu.
*
* @example [{ text: 'Archive', href: '#archive' }]
*/
items: ResolvableArray
/**
* Additional CSS classes for the menu container.
*
* @example 'app-button-menu--custom'
*/
classes?: ResolvableString
/**
* Additional HTML attributes for the menu container.
*
* @example { 'data-module': 'custom-menu' }
*/
attributes?: Record
}
/**
* MOJ Button Menu component.
* A dropdown button that reveals a menu of actions.
*
* The button menu component is useful for grouping secondary actions together
* to reduce visual clutter while keeping them easily accessible.
*
* @see https://design-patterns.service.justice.gov.uk/components/button-menu
* @example
* ```typescript
* MOJButtonMenu({
* button: {
* text: 'Actions',
* classes: 'govuk-button--secondary',
* },
* alignMenu: 'right',
* items: [
* { text: 'Archive', href: '#archive' },
* { text: 'Reassign', href: '#reassign' },
* { text: 'Delete', href: '#delete', classes: 'govuk-button--warning' },
* ],
* })
* ```
*/
export const MOJButtonMenu = nunjucksComponent('mojButtonMenu', {
render: (props, nunjucksEnv) => {
const params = {
button: props.button,
alignMenu: props.alignMenu,
items: props.items.filter(item => item.visibleWhen !== false),
classes: props.classes,
attributes: props.attributes,
}
return nunjucksEnv.render('moj/components/button-menu/template.njk', { params })
},
})