Skip to content

[#9] Added a date picker calendar widget.#32

Open
AlexSkrypnyk wants to merge 7 commits into
mainfrom
feature/9-date-picker
Open

[#9] Added a date picker calendar widget.#32
AlexSkrypnyk wants to merge 7 commits into
mainfrom
feature/9-date-picker

Conversation

@AlexSkrypnyk

@AlexSkrypnyk AlexSkrypnyk commented Jul 10, 2026

Copy link
Copy Markdown
Member

Closes #9

Summary

Adds a date field type: a month-calendar widget navigable by day, week and month, returning a normalized ISO YYYY-MM-DD string. The widget is wired through the full stack - builder (minDate/maxDate/weekStart), config (DateBounds, Weekday), factory, engine validation, and JSON schema/agent-help - so the range and week-start declared on a field behave identically whether the value comes from the interactive TUI or headless collection. Navigation is routed through the configurable key map, like every other widget.

Changes

  • Widget: src/Widget/DateWidget.php renders a "Month YYYY" heading, a weekday header ordered from the configured week-start day, and a day grid. Day and week movement and Accept resolve through the injected key map - so the arrow keys, the vim preset's h/j/k/l and any consumer remap all reach them - while PageUp/PageDown change month and Home/End jump to the first/last day of the month. The cursor is always clamped into the declared range; out-of-range days stay visible but dimmed. The widget draws its own key-hint line (rendersHint() returns TRUE), and playground/3-widgets/widgets.php skips the generic hint line for such widgets so the two can't contradict.
  • Bounds and week model: src/Config/DateBounds.php holds an optional inclusive min/max (DateTimeImmutable) and a Weekday, and rejects a minimum declared after the maximum in its own constructor. It provides strict Y-m-d parsing (round-tripped so a malformed or rolled-over value like 2026-02-30 is rejected rather than silently normalized), contains(), clamp(), a human describe() range phrase, and a violation() check shared by the widget, engine and schema validator. src/Config/Weekday.php is a new ISO-8601-backed enum (Monday = 1 ... Sunday = 7) with abbreviation(), fromDate(), sequence() (the seven weekdays in display order from a given start) and columnOf() (grid column placement).
  • Key bindings: VimKeyMap binds h/j/k/l to the date scope's move actions - safe because the calendar takes no typed input, like the single-choice list - so the vim preset drives the calendar the same way it drives the panel navigator.
  • Builder wiring: PanelBuilder::date() adds a date field; FieldBuilder::minDate(), maxDate() and weekStart() declare the range and first weekday, assembled into a DateBounds on build() via FieldBuilder::buildDateBounds(). An invalid bound string or a min declared after max throws ConfigException; the date setters are inert when called on a non-date field.
  • Config and factory: Field gains a dateBounds property alongside the existing bounds; FieldType::Date is a new enum case; WidgetFactory seeds a DateWidget from the field's current string value and declared bounds.
  • Headless engine: Engine::validateValue() checks dateBounds?->violation() alongside the existing number-bounds check, so a --prompts or environment value outside the declared range is rejected with the same range phrase the interactive widget shows.
  • Schema and agent help: SchemaValidator type-checks date values (an empty string, or a strict Y-m-d date) and enforces the declared range; SchemaGenerator emits min_date, max_date and week_start on the field's schema entry; AgentHelp appends a range annotation (or YYYY-MM-DD when unbounded) to a date field's help line.
  • Demo and docs: playground/3-widgets/widget-date.php is a new standalone demo; widgets.php and show.php include the date widget in the combined showcase; docs/util/update-assets.php adds an expect script and row count for the date widget and regenerates the four combined widgets*.svg assets plus four new per-widget widget-date*.svg assets; README.md documents the date field (usage, bounds, key hints, screenshots) and updates the widget count to include it.
  • Tests: new DateBoundsTest, WeekdayTest and DateWidgetTest cover the added classes directly - navigation (including vim-preset remapping through an injected key map), bounds clamping and dimming on both edges, week-start layout, the constructor invariant, and boundary/impossible-date cases; FormTest, WidgetFactoryTest, EngineDeclaredBehaviourTest, InputResolverTest, SchemaGeneratorTest, SchemaValidatorTest and AgentHelpTest are extended to cover the date field type end to end. The full suite passes with 100% coverage on all new and touched classes.

Before / After

+-- BEFORE: no `date` type ------------------------------+
| FieldType surface (no calendar type):
|   text  number  textarea  password  select
|   multiselect  suggest  search  multisearch
|   confirm  toggle  filepicker  multifilepicker  pause
|
| A release date is entered as plain text - no range
| check, no calendar, no day/week/month navigation:
|
|   $p->text('release', 'Release date')
|     ->default('2026-07-15');
+----------------------------------------------------------+

                          |
                          v

+-- AFTER: a `date` calendar widget -----------------------+
| FieldType surface (adds `date`):
|   text  number  date  textarea  password  select
|   multiselect  suggest  search  multisearch
|   confirm  toggle  filepicker  multifilepicker  pause
|
|   $p->date('release', 'Release date')
|     ->minDate('2026-01-01')->maxDate('2026-12-31')
|     ->weekStart(Weekday::Sunday);
|
|            July 2026
|   Su Mo Tu We Th Fr Sa
|             1  2  3  4
|    5  6  7  8  9 10 11
|   12 13 14 [15] 16 17 18
|   19 20 21 22 23 24 25
|   26 27 28 29 30 31
|
|   arrows/hjkl day + week   PgUp/PgDn month
|   Enter accept   Esc cancel
|
|   Range and week-start are enforced in the widget AND
|   in headless collection (env vars / --prompts).
+------------------------------------------------------------+

@AlexSkrypnyk AlexSkrypnyk added the A3 Board worker 3 label Jul 10, 2026
@coderabbitai

coderabbitai Bot commented Jul 10, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds a date field type with bounded calendar navigation, configurable week starts, ISO output, headless validation and schema metadata, interactive examples, tests, static assets, and README documentation.

Changes

Date picker feature

Layer / File(s) Summary
Date contracts and builder configuration
src/Config/*, src/Builder/*, tests/phpunit/Unit/Config/*, tests/phpunit/Unit/Builder/FormTest.php
Adds FieldType::Date, Weekday, DateBounds, date field storage, fluent date configuration, strict parsing, bounds validation, and unit coverage.
Calendar widget and interactive wiring
src/Widget/DateWidget.php, src/Widget/WidgetFactory.php, playground/3-widgets/*, tests/phpunit/Unit/Widget/*
Adds month-calendar navigation, ISO date acceptance, bounds clamping, themed rendering, factory integration, playground examples, and widget tests.
Validation and schema integration
src/Engine/Engine.php, src/Schema/*, tests/phpunit/Unit/{Engine,Resolver,Schema}/*
Adds date type and range validation, headless string handling, generated date metadata, and date annotations in agent help.
Documentation and static widget assets
README.md, docs/util/update-assets.php
Documents date navigation, output, defaults, bounds, week starts, headless behavior, and updates static asset generation for the date widget.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant WidgetFactory
  participant DateWidget
  participant DateBounds
  User->>WidgetFactory: create date field widget
  WidgetFactory->>DateWidget: seed value and bounds
  User->>DateWidget: navigate calendar
  DateWidget->>DateBounds: clamp cursor
  User->>DateWidget: confirm selection
  DateWidget-->>User: return ISO date
Loading

Suggested labels: A1

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 42.86% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The change set matches the issue goals: date widget, bounds, week-start, schema, headless flow, theming, README, and tests are all covered.
Out of Scope Changes check ✅ Passed The files and behavior changed are all directly related to the new date picker feature; no unrelated scope is evident.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely summarizes the main change: adding a new date picker calendar widget.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/9-date-picker

Comment @coderabbitai help to get the list of available commands.

@github-actions

This comment has been minimized.

@codecov

codecov Bot commented Jul 10, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.54%. Comparing base (8cd42c8) to head (075ee98).
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@            Coverage Diff             @@
##             main      #32      +/-   ##
==========================================
+ Coverage   99.51%   99.54%   +0.03%     
==========================================
  Files          70       73       +3     
  Lines        2082     2221     +139     
==========================================
+ Hits         2072     2211     +139     
  Misses         10       10              

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/Engine/Engine.php (1)

190-204: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Reject malformed FieldType::Date input in Engine::validateValue()
Tui::collect() feeds raw --prompts/env values into Engine::collect(), and this path only checks dateBounds; DateBounds::violation() returns NULL on parse failure, so bad date strings can still be accepted unchanged. Add a strict date parse/type check here.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/Engine/Engine.php` around lines 190 - 204, The validateValue() method
must reject malformed FieldType::Date inputs before applying date bounds. Add a
strict type check and date parse validation for fields whose type is
FieldType::Date, returning an appropriate validation error when the value is not
a valid date; preserve the existing bounds and custom validator behavior for
other field types.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/Schema/SchemaGenerator.php`:
- Around line 53-55: In the schema-generation method, serialize dateBounds
weekStart consistently with other enums by replacing the weekStart ->name access
with ->value, unless the schema explicitly requires the enum case name rather
than its backing value.

---

Outside diff comments:
In `@src/Engine/Engine.php`:
- Around line 190-204: The validateValue() method must reject malformed
FieldType::Date inputs before applying date bounds. Add a strict type check and
date parse validation for fields whose type is FieldType::Date, returning an
appropriate validation error when the value is not a valid date; preserve the
existing bounds and custom validator behavior for other field types.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: e73611b6-6658-414e-8cc7-42beb57aeb45

📥 Commits

Reviewing files that changed from the base of the PR and between 1b768e2 and 8209113.

⛔ Files ignored due to path filters (8)
  • docs/assets/widget-date-ascii-no-ansi.svg is excluded by !**/*.svg
  • docs/assets/widget-date-ascii.svg is excluded by !**/*.svg
  • docs/assets/widget-date-no-ansi.svg is excluded by !**/*.svg
  • docs/assets/widget-date.svg is excluded by !**/*.svg
  • docs/assets/widgets-ascii-no-ansi.svg is excluded by !**/*.svg
  • docs/assets/widgets-ascii.svg is excluded by !**/*.svg
  • docs/assets/widgets-no-ansi.svg is excluded by !**/*.svg
  • docs/assets/widgets.svg is excluded by !**/*.svg
📒 Files selected for processing (27)
  • README.md
  • docs/util/update-assets.php
  • playground/3-widgets/show.php
  • playground/3-widgets/widget-date.php
  • playground/3-widgets/widgets.php
  • src/Builder/FieldBuilder.php
  • src/Builder/PanelBuilder.php
  • src/Config/DateBounds.php
  • src/Config/Field.php
  • src/Config/FieldType.php
  • src/Config/Weekday.php
  • src/Engine/Engine.php
  • src/Schema/AgentHelp.php
  • src/Schema/SchemaGenerator.php
  • src/Schema/SchemaValidator.php
  • src/Widget/DateWidget.php
  • src/Widget/WidgetFactory.php
  • tests/phpunit/Unit/Builder/FormTest.php
  • tests/phpunit/Unit/Config/DateBoundsTest.php
  • tests/phpunit/Unit/Config/WeekdayTest.php
  • tests/phpunit/Unit/Engine/EngineDeclaredBehaviourTest.php
  • tests/phpunit/Unit/Resolver/InputResolverTest.php
  • tests/phpunit/Unit/Schema/AgentHelpTest.php
  • tests/phpunit/Unit/Schema/SchemaGeneratorTest.php
  • tests/phpunit/Unit/Schema/SchemaValidatorTest.php
  • tests/phpunit/Unit/Widget/DateWidgetTest.php
  • tests/phpunit/Unit/Widget/WidgetFactoryTest.php

Comment thread src/Schema/SchemaGenerator.php Outdated
@github-actions

This comment has been minimized.

@AlexSkrypnyk AlexSkrypnyk force-pushed the feature/9-date-picker branch from 778d723 to e47aff7 Compare July 10, 2026 22:59
@github-actions

This comment has been minimized.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
src/Schema/SchemaValidator.php (1)

116-138: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Same bounds-precedence duplication as Engine::validateValue().

checkBounds() and checkDateBounds() are structurally identical aside from which bound property they read, and together they replicate the same "prefer number bounds, fall back to date bounds" precedence duplicated in src/Engine/Engine.php (Line 196). Consolidating via a shared Field::boundsViolation() helper (mirroring the existing optionError() precedent) would collapse both methods into one and keep the two validators from silently diverging.

♻️ Proposed consolidation
-    $bounds_error = $this->checkBounds($field, $value);
-    if ($bounds_error !== NULL) {
-      return $bounds_error;
-    }
-
-    $date_error = $this->checkDateBounds($field, $value);
-    if ($date_error !== NULL) {
-      return $date_error;
-    }
+    $violation = $field->boundsViolation($value);
+    if ($violation !== NULL) {
+      return sprintf('Question "%s" must be %s.', $field->id, $violation);
+    }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/Schema/SchemaValidator.php` around lines 116 - 138, Consolidate bound
selection into a shared Field::boundsViolation() helper, applying the existing
precedence of numeric bounds before date bounds. Update
SchemaValidator::checkBounds() and checkDateBounds() to use this helper, remove
the duplicate date-specific method, and update Engine::validateValue() to use
the same centralized logic so all validators remain consistent.
src/Engine/Engine.php (1)

195-209: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider consolidating the bounds-precedence logic into Field.

This line duplicates the exact same "prefer number bounds, fall back to date bounds" precedence that SchemaValidator::checkBounds()/checkDateBounds() implement separately (see src/Schema/SchemaValidator.php Lines 116-138). Field already exposes optionError() as a shared helper consumed by both Engine and SchemaValidator for the analogous options-validation concern — the same pattern here would prevent the two call sites from silently diverging if the precedence or bounds types ever change.

♻️ Proposed consolidation (requires adding a method to Field.php, not shown in this batch)
// In src/Config/Field.php
public function boundsViolation(mixed $value): ?string {
  return $this->bounds?->violation($value) ?? $this->dateBounds?->violation($value);
}
 protected function validateValue(Field $field, mixed $value): ?string {
-    $violation = $field->bounds?->violation($value) ?? $field->dateBounds?->violation($value);
+    $violation = $field->boundsViolation($value);
     if ($violation !== NULL) {
       return sprintf('must be %s.', $violation);
     }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/Engine/Engine.php` around lines 195 - 209, Consolidate bounds precedence
in Field by adding a boundsViolation(mixed $value): ?string helper that prefers
bounds over dateBounds. Update Engine::validateValue and
SchemaValidator::checkBounds/checkDateBounds to call this shared method instead
of duplicating null-coalescing logic, preserving the existing violation handling
and messages.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@README.md`:
- Around line 150-152: Update the README configuration example to import
DrevOps\Tui\Config\Weekday alongside the other imports, so the Weekday::Sunday
reference resolves when copied.

In `@src/Builder/FieldBuilder.php`:
- Around line 692-693: The parseBoundDate method currently accepts an
unrestricted string for the min/max selector; introduce a pure or backed enum
representing these two values, update parseBoundDate and related logic to accept
the enum, and pass the enum cases from the min/max calls around the affected
validation block. Use the enum’s value only when constructing exception
messages, including all branches covering the selector.

In `@src/Config/DateBounds.php`:
- Around line 30-35: Validate the bound ordering in the DateBounds constructor:
when both min and max are provided, reject cases where min is later than max,
using the class’s existing exception or validation convention. Keep null bounds
valid and ensure every direct DateBounds instantiation preserves the invariant
consumed by contains(), describe(), and clamp().

In `@src/Widget/WidgetFactory.php`:
- Line 60: The DateWidget currently hard-codes navigation keys instead of using
WidgetFactory’s injected keymap, so custom date bindings are ignored. Update
DateWidget::handle() and move() to resolve navigation through the configured
Action bindings, and ensure WidgetFactory passes that keymap when creating the
DateWidget; add a test covering remapped date navigation.

In `@tests/phpunit/Unit/Widget/DateWidgetTest.php`:
- Around line 201-212: Add symmetric max-bound coverage to
testDimsOutOfRangeDays by creating DateBounds with a max date and asserting a
day after that maximum is rendered with the theme description/dimmed styling,
while preserving the existing cursor-day assertion.

---

Outside diff comments:
In `@src/Engine/Engine.php`:
- Around line 195-209: Consolidate bounds precedence in Field by adding a
boundsViolation(mixed $value): ?string helper that prefers bounds over
dateBounds. Update Engine::validateValue and
SchemaValidator::checkBounds/checkDateBounds to call this shared method instead
of duplicating null-coalescing logic, preserving the existing violation handling
and messages.

In `@src/Schema/SchemaValidator.php`:
- Around line 116-138: Consolidate bound selection into a shared
Field::boundsViolation() helper, applying the existing precedence of numeric
bounds before date bounds. Update SchemaValidator::checkBounds() and
checkDateBounds() to use this helper, remove the duplicate date-specific method,
and update Engine::validateValue() to use the same centralized logic so all
validators remain consistent.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 3f35571a-5b1e-49b2-85df-a56813e95d9e

📥 Commits

Reviewing files that changed from the base of the PR and between 8209113 and e47aff7.

⛔ Files ignored due to path filters (8)
  • docs/assets/widget-date-ascii-no-ansi.svg is excluded by !**/*.svg
  • docs/assets/widget-date-ascii.svg is excluded by !**/*.svg
  • docs/assets/widget-date-no-ansi.svg is excluded by !**/*.svg
  • docs/assets/widget-date.svg is excluded by !**/*.svg
  • docs/assets/widgets-ascii-no-ansi.svg is excluded by !**/*.svg
  • docs/assets/widgets-ascii.svg is excluded by !**/*.svg
  • docs/assets/widgets-no-ansi.svg is excluded by !**/*.svg
  • docs/assets/widgets.svg is excluded by !**/*.svg
📒 Files selected for processing (27)
  • README.md
  • docs/util/update-assets.php
  • playground/3-widgets/show.php
  • playground/3-widgets/widget-date.php
  • playground/3-widgets/widgets.php
  • src/Builder/FieldBuilder.php
  • src/Builder/PanelBuilder.php
  • src/Config/DateBounds.php
  • src/Config/Field.php
  • src/Config/FieldType.php
  • src/Config/Weekday.php
  • src/Engine/Engine.php
  • src/Schema/AgentHelp.php
  • src/Schema/SchemaGenerator.php
  • src/Schema/SchemaValidator.php
  • src/Widget/DateWidget.php
  • src/Widget/WidgetFactory.php
  • tests/phpunit/Unit/Builder/FormTest.php
  • tests/phpunit/Unit/Config/DateBoundsTest.php
  • tests/phpunit/Unit/Config/WeekdayTest.php
  • tests/phpunit/Unit/Engine/EngineDeclaredBehaviourTest.php
  • tests/phpunit/Unit/Resolver/InputResolverTest.php
  • tests/phpunit/Unit/Schema/AgentHelpTest.php
  • tests/phpunit/Unit/Schema/SchemaGeneratorTest.php
  • tests/phpunit/Unit/Schema/SchemaValidatorTest.php
  • tests/phpunit/Unit/Widget/DateWidgetTest.php
  • tests/phpunit/Unit/Widget/WidgetFactoryTest.php

Comment thread README.md
Comment thread src/Builder/FieldBuilder.php Outdated
Comment thread src/Config/DateBounds.php
Comment thread src/Widget/WidgetFactory.php
Comment thread tests/phpunit/Unit/Widget/DateWidgetTest.php
@github-actions

Copy link
Copy Markdown
Code Coverage Report:
  2026-07-10 23:28:13

 Summary:
  Classes: 93.15% (68/73)
  Methods: 98.28% (514/523)
  Lines:   99.55% (2211/2221)

DrevOps\Tui\Answers\Answer
  Methods: 100.00% ( 1/ 1)   Lines: 100.00% (  1/  1)
DrevOps\Tui\Answers\Answers
  Methods: 100.00% ( 9/ 9)   Lines: 100.00% ( 20/ 20)
DrevOps\Tui\Answers\SummaryFormatter
  Methods: 100.00% ( 3/ 3)   Lines: 100.00% ( 20/ 20)
DrevOps\Tui\Builder\FieldBuilder
  Methods: 100.00% (34/34)   Lines: 100.00% (116/116)
DrevOps\Tui\Builder\Form
  Methods:  93.33% (14/15)   Lines:  98.44% ( 63/ 64)
DrevOps\Tui\Builder\PanelBuilder
  Methods: 100.00% (20/20)   Lines: 100.00% ( 32/ 32)
DrevOps\Tui\Condition\CompositeCondition
  Methods: 100.00% ( 4/ 4)   Lines: 100.00% ( 19/ 19)
DrevOps\Tui\Condition\Condition
  Methods: 100.00% (10/10)   Lines: 100.00% ( 38/ 38)
DrevOps\Tui\Config\Config
  Methods: 100.00% ( 5/ 5)   Lines: 100.00% ( 17/ 17)
DrevOps\Tui\Config\DateBounds
  Methods: 100.00% ( 6/ 6)   Lines: 100.00% ( 25/ 25)
DrevOps\Tui\Config\Field
  Methods: 100.00% ( 5/ 5)   Lines: 100.00% ( 30/ 30)
DrevOps\Tui\Config\FieldType
  Methods: 100.00% ( 2/ 2)   Lines: 100.00% (  2/  2)
DrevOps\Tui\Config\NumberBounds
  Methods: 100.00% ( 6/ 6)   Lines: 100.00% ( 20/ 20)
DrevOps\Tui\Config\Option
  Methods: 100.00% ( 3/ 3)   Lines: 100.00% (  9/  9)
DrevOps\Tui\Config\Panel
  Methods: 100.00% ( 1/ 1)   Lines: 100.00% (  1/  1)
DrevOps\Tui\Config\Weekday
  Methods: 100.00% ( 4/ 4)   Lines: 100.00% ( 15/ 15)
DrevOps\Tui\Derive\Derive
  Methods: 100.00% ( 4/ 4)   Lines: 100.00% ( 14/ 14)
DrevOps\Tui\Derive\Deriver
  Methods: 100.00% ( 1/ 1)   Lines: 100.00% ( 13/ 13)
DrevOps\Tui\Derive\Transform
  Methods: 100.00% ( 3/ 3)   Lines: 100.00% (  7/  7)
DrevOps\Tui\Discovery\AbstractDiscover
  Methods: 100.00% ( 1/ 1)   Lines: 100.00% (  1/  1)
DrevOps\Tui\Discovery\Dotenv
  Methods: 100.00% ( 3/ 3)   Lines: 100.00% ( 19/ 19)
DrevOps\Tui\Discovery\JsonValue
  Methods: 100.00% ( 4/ 4)   Lines: 100.00% ( 16/ 16)
DrevOps\Tui\Discovery\PathExists
  Methods: 100.00% ( 3/ 3)   Lines: 100.00% (  3/  3)
DrevOps\Tui\Discovery\Scan
  Methods: 100.00% ( 3/ 3)   Lines: 100.00% ( 20/ 20)
DrevOps\Tui\Engine\Engine
  Methods: 100.00% (12/12)   Lines: 100.00% ( 95/ 95)
DrevOps\Tui\Handler\HandlerRegistry
  Methods:  85.71% ( 6/ 7)   Lines:  95.45% ( 21/ 22)
DrevOps\Tui\Input\ArrayKeyStream
  Methods: 100.00% ( 3/ 3)   Lines: 100.00% ( 12/ 12)
DrevOps\Tui\Input\Binding
  Methods: 100.00% ( 1/ 1)   Lines: 100.00% (  1/  1)
DrevOps\Tui\Input\DefaultKeyMap
  Methods: 100.00% ( 1/ 1)   Lines: 100.00% ( 33/ 33)
DrevOps\Tui\Input\Key
  Methods: 100.00% ( 7/ 7)   Lines: 100.00% (  7/  7)
DrevOps\Tui\Input\KeyMap
  Methods: 100.00% (12/12)   Lines: 100.00% ( 65/ 65)
DrevOps\Tui\Input\KeyMapManager
  Methods: 100.00% ( 2/ 2)   Lines: 100.00% (  8/  8)
DrevOps\Tui\Input\KeyParser
  Methods: 100.00% ( 6/ 6)   Lines: 100.00% ( 68/ 68)
DrevOps\Tui\Input\Scope
  Methods: 100.00% ( 7/ 7)   Lines: 100.00% ( 11/ 11)
DrevOps\Tui\Input\ScopedKeyMap
  Methods: 100.00% ( 4/ 4)   Lines: 100.00% (  4/  4)
DrevOps\Tui\Input\VimKeyMap
  Methods: 100.00% ( 1/ 1)   Lines: 100.00% ( 12/ 12)
DrevOps\Tui\Render\Ansi
  Methods: 100.00% ( 4/ 4)   Lines: 100.00% (  5/  5)
DrevOps\Tui\Render\Box
  Methods: 100.00% ( 3/ 3)   Lines: 100.00% ( 15/ 15)
DrevOps\Tui\Render\ExternalEditor
  Methods: 100.00% ( 6/ 6)   Lines: 100.00% ( 27/ 27)
DrevOps\Tui\Render\Navigator
  Methods: 100.00% ( 6/ 6)   Lines: 100.00% ( 15/ 15)
DrevOps\Tui\Render\PanelController
  Methods: 100.00% (16/16)   Lines: 100.00% ( 95/ 95)
DrevOps\Tui\Render\Scroller
  Methods: 100.00% ( 4/ 4)   Lines: 100.00% ( 12/ 12)
DrevOps\Tui\Render\Terminal
  Methods: 100.00% (12/12)   Lines: 100.00% ( 35/ 35)
DrevOps\Tui\Render\TerminalControl
  Methods: 100.00% ( 9/ 9)   Lines: 100.00% (  9/  9)
DrevOps\Tui\Render\Viewport
  Methods: 100.00% ( 1/ 1)   Lines: 100.00% (  1/  1)
DrevOps\Tui\Resolver\InputResolver
  Methods: 100.00% ( 6/ 6)   Lines: 100.00% ( 27/ 27)
DrevOps\Tui\Schema\AgentHelp
  Methods: 100.00% ( 4/ 4)   Lines: 100.00% ( 29/ 29)
DrevOps\Tui\Schema\SchemaGenerator
  Methods: 100.00% ( 3/ 3)   Lines: 100.00% ( 33/ 33)
DrevOps\Tui\Schema\SchemaValidator
  Methods: 100.00% ( 9/ 9)   Lines: 100.00% ( 44/ 44)
DrevOps\Tui\Theme\DefaultTheme
  Methods:  92.42% (61/66)   Lines:  97.26% (213/219)
DrevOps\Tui\Theme\ThemeManager
  Methods: 100.00% ( 2/ 2)   Lines: 100.00% (  8/  8)
DrevOps\Tui\Tui
  Methods: 100.00% (12/12)   Lines: 100.00% ( 26/ 26)
DrevOps\Tui\Widget\AbstractWidget
  Methods: 100.00% (13/13)   Lines: 100.00% ( 24/ 24)
DrevOps\Tui\Widget\ChoiceListTrait
  Methods: 100.00% ( 7/ 7)   Lines: 100.00% ( 21/ 21)
DrevOps\Tui\Widget\ConfirmWidget
  Methods: 100.00% ( 5/ 5)   Lines: 100.00% ( 22/ 22)
DrevOps\Tui\Widget\DateWidget
  Methods: 100.00% (13/13)   Lines: 100.00% ( 59/ 59)
DrevOps\Tui\Widget\FilePickerWidget
  Methods: 100.00% (30/30)   Lines: 100.00% (187/187)
DrevOps\Tui\Widget\MultiSearchWidget
  Methods: 100.00% ( 1/ 1)   Lines: 100.00% (  1/  1)
DrevOps\Tui\Widget\MultiSelectWidget
  Methods: 100.00% (11/11)   Lines: 100.00% ( 86/ 86)
DrevOps\Tui\Widget\NumberWidget
  Methods: 100.00% ( 9/ 9)   Lines: 100.00% ( 37/ 37)
DrevOps\Tui\Widget\PasswordDisplay
  Methods: 100.00% ( 1/ 1)   Lines: 100.00% (  5/  5)
DrevOps\Tui\Widget\PasswordWidget
  Methods: 100.00% ( 8/ 8)   Lines: 100.00% ( 44/ 44)
DrevOps\Tui\Widget\PauseWidget
  Methods: 100.00% ( 4/ 4)   Lines: 100.00% ( 10/ 10)
DrevOps\Tui\Widget\SearchWidget
  Methods: 100.00% ( 6/ 6)   Lines: 100.00% ( 46/ 46)
DrevOps\Tui\Widget\SelectWidget
  Methods: 100.00% ( 5/ 5)   Lines: 100.00% ( 29/ 29)
DrevOps\Tui\Widget\SuggestWidget
  Methods: 100.00% ( 5/ 5)   Lines: 100.00% ( 38/ 38)
DrevOps\Tui\Widget\TextWidget
  Methods: 100.00% ( 7/ 7)   Lines: 100.00% ( 31/ 31)
DrevOps\Tui\Widget\TextareaWidget
  Methods: 100.00% ( 8/ 8)   Lines: 100.00% ( 52/ 52)
DrevOps\Tui\Widget\ToggleWidget
  Methods: 100.00% ( 7/ 7)   Lines: 100.00% ( 31/ 31)
DrevOps\Tui\Widget\WidgetFactory
  Methods: 100.00% ( 4/ 4)   Lines: 100.00% ( 31/ 31)
DrevOps\Tui\Widget\WidgetRunner
  Methods: 100.00% ( 1/ 1)   Lines: 100.00% (  5/  5)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A3 Board worker 3

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add a date picker (calendar) widget

1 participant