Common Widgets

This module defines specialized field widgets, all designed to work in both CREATE and UPDATE modes for Jira work item operations.

This is how they’re organized:

Base Architecture

All widgets follow a consistent pattern by extending:

  • A Textual base widget (e.g., Input, TextArea, Select)

  • BaseFieldWidget: provides mode-aware field properties and configuration

  • BaseUpdateFieldWidget: provides update-mode-specific functionality

This multi-inheritance approach allows each widget to support both CREATE (new work items) and UPDATE (existing work items) contexts.

Widget Categories

Category

Widgets

Purpose

Date/Time Input

DateInputWidget, DateTimeInputWidget

ISO date and datetime entry with validation and change tracking

Text Input

TextInputWidget, URLWidget

General text and URL input with auto-formatting

Labels & Tags

LabelsWidget

Comma-separated label entry, converts to/from list format

Numeric Input

NumericInputWidget

Integer and float input with number validation

User Selection

SingleUserPickerWidget, MultiUserPickerWidget

Single or multiple Jira user selection by account ID

Selection/Dropdown

SelectionWidget, MultiSelectWidget

Single and multi-select dropdowns with checkboxes

Large Text

DescriptionWidget, PlainTextTextAreaWidget, ReadOnlyTextAreaWidget

TextArea-based widgets for descriptions and rich text

Specialized

SprintWidget, EpicLinkWidget, MultiIssuePickerWidget

Domain-specific widgets for sprints, epics, and issue links

Common Public Interface

All CREATE/UPDATE widgets expose a consistent API:

  • mode: FieldMode: Indicates whether the widget is in CREATE or UPDATE mode

  • original_value: The current value from Jira (UPDATE mode only)

  • get_value_for_create(): Returns the value formatted for Jira API create requests

  • get_value_for_update(): Returns the value formatted for Jira API update requests

  • value_has_changed: bool: Property indicating if the user modified the value (UPDATE mode only)

The return types vary by widget (e.g., strings, lists, dictionaries), but the pattern is consistent across all widgets.

Widgets defined in this module are meant to be used for 2 use cases:

  • creating new work items

  • updating work items

In these use cases these widgets are dynamically generated by a builder or factory function.

Widgets Included:

Date and DateTime Widgets

class DateInputWidget(mode: jiratui.widgets.commons.base.FieldMode, field_id: str, jira_field_key: str, title: str | None = None, required: bool = False, original_value: str | None = None, field_supports_update: bool = True)

Bases: jiratui.widgets.base.DateInput, jiratui.widgets.commons.base.BaseFieldWidget, jiratui.widgets.commons.base.BaseUpdateFieldWidget

Unified date input widget that works in both CREATE and UPDATE modes.

This widget extends DateInput (MaskedInput with template ‘9999-99-99’) and adds mode-aware behavior for create vs. update contexts.

Usage in CREATE mode:

 1widget = DateInputWidget(
 2    mode=FieldMode.CREATE,
 3    field_id='duedate',
 4    jira_field_key='duedate',
 5    title='Due Date',
 6    required=False,
 7)
 8# Widget is ready to use, collects ISO date string from
 9widget.value
10# get value when setting the value of the field to create a work item
11widget.get_value_for_create()

Usage in UPDATE mode:

 1widget = DateInputWidget(
 2    mode=FieldMode.UPDATE,
 3    field_id='duedate',
 4    jira_field_key='duedate',
 5    title='Due Date',
 6    original_value='2025-12-23',
 7    field_supports_update=True,
 8)
 9# check changes
10widget.value_has_changed
11# get value when setting the value of the field to create a work item
12widget.get_value_for_update()

Initialization

Initializes a DateInputWidget.

Parameters:
  • mode – The field mode (CREATE or UPDATE)

  • field_id – Field identifier (Jira field key)

  • jira_field_key – the key of the field that it is used for updating the field value in the API.

  • title – Display title (defaults to field_id)

  • required – Whether the field is required (mainly for CREATE mode)

  • original_value – Original date value from Jira (UPDATE mode only)

  • field_supports_update – Whether field can be updated (UPDATE mode only)

validate(value: str) textual.validation.ValidationResult | None

Override validation to allow empty values when valid_empty is True.

MaskedInput validates against the template even when valid_empty=True, which causes empty fields with placeholder characters to be marked as invalid. This override allows empty values to pass validation without triggering the template validation.

Parameters:

value – The value to validate

Returns:

ValidationResult indicating whether validation succeeded

get_value_for_update() str | None

Returns the value formatted for Jira API updates (UPDATE mode).

Returns:

A date value in ISO format (YYYY-MM-DD), or None if empty or invalid

property value_has_changed: bool

Determines if the current value differs from the original value (UPDATE mode).

Returns:

True if value has changed, False otherwise

class DateTimeInputWidget(mode: jiratui.widgets.commons.base.FieldMode, field_id: str, jira_field_key: str, title: str | None = None, required: bool = False, original_value: str | None = None, field_supports_update: bool = True)

Bases: textual.widgets.MaskedInput, jiratui.widgets.commons.base.BaseFieldWidget, jiratui.widgets.commons.base.BaseUpdateFieldWidget

Unified datetime input widget that works in both CREATE and UPDATE modes.

Uses MaskedInput with template ‘9999-99-99 99:99:99’ for datetime entry.

Usage in CREATE mode:

1widget = DateTimeInputWidget(
2    mode=FieldMode.CREATE,
3    field_id='customfield_10001',
4    jira_field_key='customfield_10001',
5    title='Event Time',
6    required=False,
7)

Usage in UPDATE mode:

 1widget = DateTimeInputWidget(
 2    mode=FieldMode.UPDATE,
 3    field_id='customfield_10001',
 4    jira_field_key='customfield_10001',
 5    title='Event Time',
 6    original_value='2025-12-23 13:45:10',
 7    field_supports_update=True,
 8)
 9# Check changes with
10widget.value_has_changed
11# Get value for API with
12widget.get_value_for_update()

Initialization

Initializes a DateTimeInputWidget.

Parameters:
  • mode – The field mode (CREATE or UPDATE)

  • field_id – Field identifier (Jira field key)

  • title – Display title (defaults to field_id)

  • required – Whether the field is required (mainly for CREATE mode)

  • original_value – Original datetime value from Jira (UPDATE mode only)

  • field_supports_update – Whether field can be updated (UPDATE mode only)

get_value_for_update() str | None

Returns the value formatted for Jira API updates (UPDATE mode).

Returns:

A datetime value in ISO format, or None if empty or invalid

property value_has_changed: bool

Determines if the current value differs from the original value (UPDATE mode).

Returns:

True if value has changed, False otherwise

Text and String Widgets

class TextInputWidget(mode: jiratui.widgets.commons.base.FieldMode, field_id: str, jira_field_key: str, title: str | None = None, required: bool = False, placeholder: str = 'some string...', original_value: str | None = None, field_supports_update: bool = True)

Bases: textual.widgets.Input, jiratui.widgets.commons.base.BaseFieldWidget, jiratui.widgets.commons.base.BaseUpdateFieldWidget

Unified text input widget that works in both CREATE and UPDATE modes.

Extends Textual’s Input widget with mode-aware behavior and change tracking.

Usage in CREATE mode:

1widget = TextInputWidget(
2    mode=FieldMode.CREATE,
3    field_id='customfield_10002',
4    jira_field_key='customfield_10002',
5    title='Custom Text Field',
6    required=True,
7)

Usage in UPDATE mode:

 1widget = TextInputWidget(
 2    mode=FieldMode.UPDATE,
 3    field_id='customfield_10002',
 4    jira_field_key='customfield_10002',
 5    title='Custom Text Field',
 6    original_value='original text',
 7    field_supports_update=True,
 8)
 9# Check changes
10widget.value_has_changed
11# Get value for API
12widget.get_value_for_update()

Initialization

Initializes a TextInputWidget.

Parameters:
  • mode – The field mode (CREATE or UPDATE)

  • field_id – Field identifier (Jira field key)

  • jira_field_key – the key of the field that it is used for updating the field value in the API.

  • title – Display title (defaults to field_id)

  • required – Whether the field is required (mainly for CREATE mode)

  • placeholder – Placeholder text for the input

  • original_value – Original text value from Jira (UPDATE mode only)

  • field_supports_update – Whether field can be updated (UPDATE mode only)

get_value_for_update() str

Returns the value formatted for Jira API updates (UPDATE mode).

Returns:

The string value

property value_has_changed: bool

Determines if the current value differs from the original value (UPDATE mode).

Returns:

True if value has changed, False otherwise

class SingleUserPickerWidget(mode: jiratui.widgets.commons.base.FieldMode, field_id: str, jira_field_key: str, title: str | None = None, required: bool = False, original_value: dict | None = None, supports_update: bool = True, **kwargs)

Bases: textual.widgets.Input

An input field for selecting a single Jira user.

This widget is specifically designed for dynamically composed widgets; i.e. widgets that are not defined in the compose() method of other widgets but are generated and added after composing the widget that hold them.

If you need to support single-user selection for statically created widgets then use JiraUserInput.

This widget holds the Jira user’s account id that is used to identify the user. This is useful for operations that create/update work items’ user fields, such as assignee, reporter, etc.

Initialization

Initializes the widget.

Parameters:
  • mode – either CREATE or UPDATE mode.

  • field_id – Jira field ID (e.g., “users” or “customfield_10001”)

  • jira_field_key – the key of the field that it is used for updating the field value in the API.

  • title – the display title for the field.

  • required – indicates whether the field is required or not.

  • original_value – the current value of the work item’s field associated to this widget. This is only relevant when the mode is FieldMode.UPDATE. It expects a list of dictionaries with the account_id and name of a Jira user.

  • supports_update – indicates whether the field can be updated. This is only relevant when the mode is FieldMode.UPDATE. **kwargs: additional arguments passed to the textual.widgets.Input widget.

get_value_for_create() dict | None

Retrieves the value of the widget when the widget is used in CREATE mode.

The value of this field is the account id of the selected Jira user.

Returns:

The a dictionary with the account id of the selected Jira user.

get_value_for_update() dict | None

Retrieves the value of the widget when the widget is used in UPDATE mode.

The value of this field is the account id of the selected Jira user.

Returns:

The a dictionary with the account id of the selected Jira user.

property value_has_changed: bool

Determines if the value of the widget has changed wrt. the original value.

This is only relevant when the mode is UPDATE.

Returns:

True if the selected user has changed, False otherwise.

clear()
class LabelsWidget(mode: jiratui.widgets.commons.base.FieldMode, field_id: str, jira_field_key: str, title: str | None = None, required: bool = False, original_value: list[str] | None = None, supports_update: bool = True, **kwargs)

Bases: textual.widgets.Input

Unified labels input widget that works in both CREATE and UPDATE modes.

This widget handles comma-separated label input and provides proper formatting for Jira API (list of strings).

Schema detection:

1custom_type == CustomFieldType.LABELS.value

or,

1schema.type == "array" AND schema.items == "string" AND field_id == "labels"

Usage in CREATE mode:

1widget = LabelsWidget(
2    mode=FieldMode.CREATE,
3    field_id='labels',
4    jira_field_key='labels',
5    title='Labels',
6    required=False,
7)
8# User enters: "bug, frontend, urgent"
9get_value_for_create() == ['bug', 'frontend', 'urgent']

Usage in UPDATE mode:

 1widget = LabelsWidget(
 2    mode=FieldMode.UPDATE,
 3    field_id="customfield_10001",
 4    jira_field_key="customfield_10001",
 5    title="Tags",
 6    original_value=["backend", "api"],
 7    supports_update=True
 8)
 9# Displays: "backend, api"
10# User changes to: "backend, database"
11get_value_for_update() returns: ["backend", "database"]
12value_has_changed == True

Initialization

Initializes the widget.

Parameters:
  • mode – CREATE or UPDATE mode

  • field_id – Jira field ID (e.g., “labels” or “customfield_10001”)

  • jira_field_key – the key of the field that it is used for updating the field value in the API.

  • title – Display title for the field

  • required – Whether the field is required

  • original_value – Original labels for UPDATE mode (list of strings)

  • supports_update – Whether field can be updated (UPDATE mode only) **kwargs: Additional arguments passed to Input

property original_value: list[str]

Get the original labels from Jira.

get_value_for_create() list[str]

Returns labels formatted for Jira API create requests (CREATE mode).

Returns:

List of label strings (leading/trailing whitespace stripped, internal spaces removed, empty labels filtered out)

get_value_for_update() list[str]

Returns labels formatted for Jira API update requests (UPDATE mode).

Returns:

List of label strings (leading/trailing whitespace stripped, internal spaces removed, empty labels filtered out)

property value_has_changed: bool

Determines if labels have changed from original value (UPDATE mode).

Uses set comparison to ignore order and whitespace differences. Comparison is case-insensitive (treats “Backend” and “backend” as same), but original casing is preserved when sending to Jira API.

Returns:

True if labels have changed, False otherwise

class URLWidget(mode: jiratui.widgets.commons.base.FieldMode, field_id: str, jira_field_key: str, title: str | None = None, required: bool = False, placeholder: str = 'https://example.com', original_value: str | None = None, field_supports_update: bool = True, **kwargs: Any)

Bases: textual.widgets.Input, jiratui.widgets.commons.base.BaseFieldWidget, jiratui.widgets.commons.base.BaseUpdateFieldWidget

Unified URL input widget supporting both CREATE and UPDATE modes.

Auto-adds ‘https://’ prefix on blur if not present. Handles URL field creation and updates via Jira API.

Initialization

Initialise the Input widget.

Parameters:
  • value – An optional default value for the input.

  • placeholder – Optional placeholder text for the input.

  • highlighter – An optional highlighter for the input.

  • password – Flag to say if the field should obfuscate its content.

  • restrict – A regex to restrict character inputs.

  • type – The type of the input.

  • max_length – The maximum length of the input, or 0 for no maximum length.

  • suggester – [Suggester][textual.suggester.Suggester] associated with this input instance.

  • validators – An iterable of validators that the Input value will be checked against.

  • validate_on – Zero or more of the values “blur”, “changed”, and “submitted”, which determine when to do input validation. The default is to do validation for all messages.

  • valid_empty – Empty values are valid.

  • select_on_focus – Whether to select all text on focus.

  • name – Optional name for the input widget.

  • id – Optional ID for the widget.

  • classes – Optional initial classes for the widget.

  • disabled – Whether the input is disabled or not.

  • tooltip – Optional tooltip.

  • compact – Enable compact style (without borders).

property original_value: str

Get the original value from Jira.

on_input_blurred(event: textual.widgets.Input.Changed) None

Auto-add https:// prefix if not present.

get_value_for_create() str

Get value for create work item request.

get_value_for_update() str

Get value for update work item request.

property value_has_changed: bool

Check if the value has changed from original.

class EpicLinkWidget(mode: jiratui.widgets.commons.base.FieldMode, field_id: str, jira_field_key: str, title: str | None = None, required: bool = False, original_value: str | None = None, field_supports_update: bool = True, **kwargs: Any)

Bases: textual.widgets.Input, jiratui.widgets.commons.base.BaseFieldWidget, jiratui.widgets.commons.base.BaseUpdateFieldWidget

Unified Input widget for specifying the key of an (Epic) issue supporting both CREATE and UPDATE modes.

Initialization

Initialise the Input widget.

Parameters:
  • value – An optional default value for the input.

  • placeholder – Optional placeholder text for the input.

  • highlighter – An optional highlighter for the input.

  • password – Flag to say if the field should obfuscate its content.

  • restrict – A regex to restrict character inputs.

  • type – The type of the input.

  • max_length – The maximum length of the input, or 0 for no maximum length.

  • suggester – [Suggester][textual.suggester.Suggester] associated with this input instance.

  • validators – An iterable of validators that the Input value will be checked against.

  • validate_on – Zero or more of the values “blur”, “changed”, and “submitted”, which determine when to do input validation. The default is to do validation for all messages.

  • valid_empty – Empty values are valid.

  • select_on_focus – Whether to select all text on focus.

  • name – Optional name for the input widget.

  • id – Optional ID for the widget.

  • classes – Optional initial classes for the widget.

  • disabled – Whether the input is disabled or not.

  • tooltip – Optional tooltip.

  • compact – Enable compact style (without borders).

property original_value: str

Get the original value from Jira.

get_value_for_create() str

Get value for create work item request.

get_value_for_update() str

Get value for update work item request.

property value_has_changed: bool

Check if the value has changed from original.

class SprintWidget(mode: jiratui.widgets.commons.base.FieldMode, field_id: str, jira_field_key: str, title: str | None = None, required: bool = False, placeholder='Sprint ID, e.g. 123', original_value: str | None = None, field_supports_update: bool = True, **kwargs: Any)

Bases: textual.widgets.Input, jiratui.widgets.commons.base.BaseFieldWidget, jiratui.widgets.commons.base.BaseUpdateFieldWidget

Unified Input widget for specifying the ID of a Sprint supporting both CREATE and UPDATE modes.

Initialization

Initialise the Input widget.

Parameters:
  • value – An optional default value for the input.

  • placeholder – Optional placeholder text for the input.

  • highlighter – An optional highlighter for the input.

  • password – Flag to say if the field should obfuscate its content.

  • restrict – A regex to restrict character inputs.

  • type – The type of the input.

  • max_length – The maximum length of the input, or 0 for no maximum length.

  • suggester – [Suggester][textual.suggester.Suggester] associated with this input instance.

  • validators – An iterable of validators that the Input value will be checked against.

  • validate_on – Zero or more of the values “blur”, “changed”, and “submitted”, which determine when to do input validation. The default is to do validation for all messages.

  • valid_empty – Empty values are valid.

  • select_on_focus – Whether to select all text on focus.

  • name – Optional name for the input widget.

  • id – Optional ID for the widget.

  • classes – Optional initial classes for the widget.

  • disabled – Whether the input is disabled or not.

  • tooltip – Optional tooltip.

  • compact – Enable compact style (without borders).

property original_value: str

Get the original value from Jira.

get_value_for_create() str

Get value for create work item request.

get_value_for_update() str

Get value for update work item request.

property value_has_changed: bool

Check if the value has changed from original.

class MultiUserPickerWidget(mode: jiratui.widgets.commons.base.FieldMode, field_id: str, jira_field_key: str, title: str | None = None, required: bool = False, placeholder='Type in user name or email...', original_value: list[dict] | None = None, field_supports_update: bool = True, **kwargs)

Bases: textual.widgets.Input

An Input widget that displays multiple users’ names and that works in both CREATE and UPDATE modes.

This widget handles comma-separated users’ names input and provides proper formatting for Jira API (list of strings).

Schema detection:

1custom_type == CustomFieldType.MULTI_USER_PICKER.value

Usage in CREATE mode:

1widget = MultiUserPickerWidget(
2    mode=FieldMode.CREATE,
3    field_id='approvers',
4    jira_field_key='approvers',
5    title='Approvers',
6    required=False,
7)
8# User enters: "bart, homer"
9get_value_for_create() == [{'id': '123'}, {'id': '456'}]

Usage in UPDATE mode:

 1widget = MultiUserPickerWidget(
 2    mode=FieldMode.UPDATE,
 3    field_id='approvers',
 4    jira_field_key='approvers',
 5    title='Approvers',
 6    original_value=[{'name': 'bart', 'id': '123'}, {'name': 'homer', 'id': '456'}],
 7    field_supports_update=True,
 8)
 9# Displays: "bart, homer"
10# User changes to: "bart, lisa"
11get_value_for_update() == [{'id': '123'}, {'id': '456'}]
12value_has_changed == True

Initialization

Initializes the widget.

Parameters:
  • mode – CREATE or UPDATE mode

  • field_id – Jira field ID (e.g., “labels” or “customfield_10001”)

  • jira_field_key – the key of the field that it is used for updating the field value in the API.

  • title – display title for the field.

  • required – whether the field is required.

  • placeholder – an optional placeholder text for the field. Default is ‘Type in user name or email…’.

  • original_value – original users for UPDATE mode (list of dictionaries with the id and name of a user).

  • supports_update – whether field can be updated (UPDATE mode only). **kwargs: additional arguments passed to Input.

property original_value: list[dict]

Gets the original users.

get_value_for_create() list[dict]

Returns users account ids formatted for Jira API create requests (CREATE mode).

The attribute self._users may contain account ids of users that are not among the ones displayed by the Input widget. This can happen when the user deletes a user’s name form the input. To make sure this widget always return the account ids of the final list of users we need to process the ids in self._users based on their names.

Returns:

A list of dictionaries with the id of a user’s account.

Examples

self._users = {'123': 'Bart', '456': 'Homer'}
self.value = 'Bart'
result = get_value_for_create()
[{'id': '123'}]
get_value_for_update() list[dict]

Returns users account ids formatted for Jira API update requests (UPDATE mode).

The attribute self._users may contain account ids of users that are not among the ones displayed by the Input widget. This can happen when the user deletes a user’s name form the input. To make sure this widget always return the account ids of the final list of users we need to process the ids in self._users based on their names.

Returns:

A list of dictionaries with the id of a user’s account.

Examples

self._users = {'123': 'Bart', '456': 'Homer'}
self.value = 'Bart'
result = get_value_for_update()
[{'id': '123', 'name': 'Bart'}]
property value_has_changed: bool

Determines if names have changed from original value (UPDATE mode).

Uses set comparison to ignore order and whitespace differences. Comparison is case-insensitive (treats “Backend” and “backend” as same), but original casing is preserved when sending to Jira API.

Returns:

True if names have changed, False otherwise.

class PlainTextTextAreaWidget(mode: jiratui.widgets.commons.base.FieldMode, jira_field_key: str, field_id: str, title: str | None = None, required: bool = False, original_value: str | None = None, field_supports_update: bool = True)

Bases: textual.widgets.TextArea, jiratui.widgets.commons.base.BaseFieldWidget, jiratui.widgets.commons.base.BaseUpdateFieldWidget

Unified textarea widget for non-ADF fields that supports CREATE and UPDATE modes.

Features:

  • Multi-line text input for descriptions

  • Mode-aware behavior (CREATE vs UPDATE)

  • Change tracking for UPDATE mode

  • Required field support

Usage in CREATE mode:

1widget = PlainTextTextAreaWidget(
2    mode=FieldMode.CREATE, field_id='description', title='Description', required=False
3)
4# Get value:
5widget.text

Usage in UPDATE mode:

 1widget = PlainTextTextAreaWidget(
 2    mode=FieldMode.UPDATE,
 3    field_id='description',
 4    title='Description',
 5    original_value='Original description text',
 6    field_supports_update=True,
 7)
 8# Check changes:
 9widget.value_has_changed
10# Get value for API updates:
11widget.get_value_for_update()
12# Get value for API creation operations:
13widget.get_value_for_create()

Initialization

Initializes a PlainTextTextAreaWidget.

Parameters:
  • mode – the field mode (CREATE or UPDATE)

  • jira_field_key – the key of the field that it is used for updating the field value in the API.

  • field_id – field identifier (defaults to ‘description’)

  • title – display title (defaults to ‘Description’)

  • required – whether the field is required (mainly for CREATE mode)

  • original_value – original description text from Jira (UPDATE mode only)

  • field_supports_update – whether field can be updated (UPDATE mode only)

class EditContent

Bases: textual.message.Message

get_value_for_update() str | None

Returns the value formatted for Jira API updates (UPDATE mode).

Returns:

The plain text or None if empty.

get_value_for_create() str | None

Returns the value formatted for Jira API creation (CREATE mode).

Returns:

The plain text or None if empty.

property original_value: str

Get the original plain text from Jira.

property value_has_changed: bool

Determines if the current value differs from the original value (UPDATE mode).

Returns:

True if value has changed, False otherwise.

set_original_value(value: str) None

Sets the original value for change tracking (UPDATE mode).

Parameters:

value – the original plain text from Jira.

class ReadOnlyPlainTextTextAreaWidget(field_id: str, jira_field_key: str, title: str | None = None, required: bool = False, original_value: str | None = None)

Bases: textual.widgets.TextArea

A read-only TextArea widget for displaying non-ADF text.

This widget can be used when we want to display fields that support plain text. Jira DC and Jira Cloud Platform API v2 use such fields.

Use it in the Info tab or to display comment’s content or to display fields in the read-only work item details screen.

Initialization

Initializes an ReadOnlyTextAreaWidget.

Parameters:
  • field_id – field identifier, e.g., ‘customfield_10745’.

  • jira_field_key – the key of the field that it is used for updating the field value in the API; e.g., customfield_10745.

  • title – display title for the field.

  • required – whether the field is required.

  • original_value – the original value from Jira - always string.

property required: bool

Checks if this field is required.

mark_required() None

Marks this field as required by adding subtitle and CSS class.

Numeric and Selection Widgets

class NumericInputWidget(mode: jiratui.widgets.commons.base.FieldMode, field_id: str, jira_field_key: str, title: str | None = None, required: bool = False, placeholder: str = '123.45', original_value: float | None = None, field_supports_update: bool = True)

Bases: textual.widgets.Input, jiratui.widgets.commons.base.BaseFieldWidget, jiratui.widgets.commons.base.BaseUpdateFieldWidget

Unified numeric/float input widget that works in both CREATE and UPDATE modes.

Features:

  • Numeric validation via Textual’s Number validator

  • Mode-aware behavior (CREATE vs UPDATE)

  • Change tracking for UPDATE mode

  • Proper formatting for Jira API

Initialization

Initialize a NumericInputWidget.

Parameters:
  • mode – The field mode (CREATE or UPDATE)

  • field_id – Field identifier (Jira field key)

  • jira_field_key – the key of the field that it is used for updating the field value in the API.

  • title – Display title (defaults to field_id)

  • required – Whether the field is required (mainly for CREATE mode)

  • placeholder – Placeholder text for the input

  • original_value – Original value from Jira (UPDATE mode only)

  • field_supports_update – Whether field can be updated (UPDATE mode only)

get_value_for_update() float | None

Returns the value formatted for Jira API updates (UPDATE mode).

Returns:

A float value, or None if the field has no value or invalid format

get_value_for_create() float | None

Returns the value formatted for Jira API creation (CREATE mode).

Returns:

A float value, or None if the field has no value or invalid format

on_key(event: textual.events.Key) None

Handle key press events to restrict input to numeric characters and decimal point.

Only allows:

  • Digits (0-9)

  • Decimal point (.) - but only one

  • Backspace, Delete, Arrow keys, Home, End (for editing)

  • Minus sign (-) at the beginning for negative numbers

Parameters:

event – The key event

property value_has_changed: bool

Determines if the current value differs from the original value (UPDATE mode).

Returns:

True if value has changed, False otherwise

class SelectionWidget(mode: jiratui.widgets.commons.base.FieldMode, field_id: str, jira_field_key: str, options: list[tuple[str, str]], title: str | None = None, required: bool = False, initial_value: Any = Select.NULL, original_value: str | None = None, field_supports_update: bool = True, allow_blank: bool = True, prompt: str | None = None)

Bases: textual.widgets.Select, jiratui.widgets.commons.base.BaseFieldWidget, jiratui.widgets.commons.base.BaseUpdateFieldWidget

Unified selection widget that works in both CREATE and UPDATE modes.

Features:

  • Dropdown selection from allowed values

  • Mode-aware behavior (CREATE vs UPDATE)

  • Change tracking for UPDATE mode

  • Proper formatting for Jira API

  • Support for required/optional fields

Usage in CREATE mode:

 1widget = SelectionWidget(
 2    mode=FieldMode.CREATE,
 3    field_id='customfield_10002',
 4    jira_field_key='customfield_10002',
 5    title='Priority',
 6    options=[('High', '1'), ('Medium', '2'), ('Low', '3')],
 7    required=True,
 8    allow_blank=False,
 9)
10# Get value (returns the id)
11widget.value

Usage in UPDATE mode:

 1widget = SelectionWidget(
 2    mode=FieldMode.UPDATE,
 3    field_id='customfield_10002',
 4    jira_field_key='customfield_10002',
 5    title='Priority',
 6    options=[('High', '1'), ('Medium', '2'), ('Low', '3')],
 7    original_value='2',
 8    field_supports_update=True,
 9    allow_blank=True,
10)
11# Check changes
12widget.value_has_changed
13# Get value for API
14widget.get_value_for_update()

Initialization

Initializes a SelectionWidget.

Parameters:
  • mode – The field mode (CREATE or UPDATE)

  • field_id – Field identifier (Jira field key)

  • jira_field_key – the key of the field that it is used for updating the field value in the API.

  • options – List of (display_name, value) tuples for the dropdown

  • title – Display title (defaults to field_id)

  • required – Whether the field is required (mainly for CREATE mode)

  • initial_value – Initial selected value (CREATE mode only)

  • original_value – Original value from Jira (UPDATE mode only)

  • field_supports_update – Whether field can be updated (UPDATE mode only)

  • allow_blank – Whether to allow blank/empty selection

  • prompt – Prompt text for the dropdown

get_value_for_update() dict | None

Returns the value formatted for Jira API updates (UPDATE mode).

Returns:

A dictionary with the id of the selected option, or None if no selection

get_value_for_create() dict | None

Returns the value formatted for Jira API creation (CREATE mode).

Returns:

A dictionary with the id of the selected option, or None if no selection

property value_has_changed: bool

Determines if the current value differs from the original value (UPDATE mode).

Returns:

True if value has changed, False otherwise

class MultiSelectWidget(mode: jiratui.widgets.commons.base.FieldMode, field_id: str, jira_field_key: str, options: list[tuple[str, str]], title: str | None = None, required: bool = False, initial_value: list[str] | None = None, original_value: list[str] | None = None, field_supports_update: bool = True)

Bases: textual.widgets.SelectionList[str], jiratui.widgets.commons.base.BaseFieldWidget, jiratui.widgets.commons.base.BaseUpdateFieldWidget

Multi-select widget using Textual’s native SelectionList for array fields.

This widget handles array fields (like components) that allow multiple selections. Uses Textual’s SelectionList widget for inline multi-select with checkboxes.

Features:

  • Native Textual SelectionList with checkboxes

  • Mode-aware behavior (CREATE vs UPDATE)

  • Change tracking for UPDATE mode

  • Proper formatting for Jira API

Usage in UPDATE mode:

 1widget = MultiSelectWidget(
 2    mode=FieldMode.UPDATE,
 3    field_id='components',
 4    jira_field_key='components',
 5    title='Components',
 6    options=[('Backend', '10001'), ('Frontend', '10002')],
 7    original_value=['10001'],
 8    field_supports_update=True,
 9)
10# Check changes
11widget.value_has_changed
12# Get value for API
13widget.get_value_for_update()

Initialization

Initializes a MultiSelectWidget.

Parameters:
  • mode – The field mode (CREATE or UPDATE)

  • field_id – Field identifier (Jira field key)

  • jira_field_key – the key of the field that it is used for updating the field value in the API.

  • options – List of (display_name, value) tuples for checkboxes

  • title – Display title (defaults to field_id)

  • required – Whether the field is required (mainly for CREATE mode)

  • initial_value – Initial selected values as list of IDs (CREATE mode)

  • original_value – Original values from Jira as list of IDs (UPDATE mode)

  • field_supports_update – Whether field can be updated (UPDATE mode)

get_value_for_update() list[dict] | None

Returns the value formatted for Jira API updates (UPDATE and CREATE modes).

Returns:

A list of dicts with IDs of selected options, or empty list if no selection

get_value_for_create() list[dict] | None

Returns the value formatted for Jira API creation (CREATE mode).

Returns:

A list of dicts with IDs of selected options, or None if no selection

property value_has_changed: bool

Determines if the current selection differs from the original value (UPDATE mode).

Returns:

True if selection has changed, False otherwise