Skip to content

Date input field Component#1881

Open
im-shiv wants to merge 8 commits into
devfrom
date-input-field
Open

Date input field Component#1881
im-shiv wants to merge 8 commits into
devfrom
date-input-field

Conversation

@im-shiv

@im-shiv im-shiv commented May 14, 2026

Copy link
Copy Markdown
Contributor

Description

Adds a new Adaptive Form Date Input core component (core/fd/components/form/dateinput/v1/dateinput) — a split date widget with separate day / month / year text boxes, in parity with the foundation guidedateinput component. The three sub-fields are assembled into a single ISO YYYY-MM-DD value submitted via a hidden combined input.

Component capabilities

  • Three numeric sub-inputs with configurable per-field titles (titleDay/Month/Year), placeholders (placeholderDay/Month/Year), and an option to hide the sub-labels (hideTitleDate).
  • Field order and separator driven by an XFA picture clause (dateDisplayFormat, e.g. date{D/M/YYYY}, date{M/D/YYYY}, date{YYYY/M/D}); the JS view reorders the wrappers accordingly.
  • Smart input handling matching the foundation comb-widget: digit-only gating, per-field range caps (D 1–31, M 1–12, Y 4 digits), month-aware day capping (e.g. blocks day 31 in November, Feb 29 in non-leap years), and auto-advance between fields.
  • Cross-field calendar validation; the combined value is committed only for a real calendar date.
  • Min/max date constraints with exclusive bounds and custom messages, enabled/disabled, read-only, visibility, and rule-engine (set/clear/show/hide/enable) support.
  • Full layering: Sling Model (DateInput interface + DateInputImpl), FormConstants/ReservedProperties entries, HTL + site/editor clientlibs, _cq_dialog/_cq_design_dialog/_cq_styleConfig/_cq_template, runtime-all embed, examples component + Sites page, and IT sample content.

Review fixes included in this PR (view dateinputview.js overrides correctly extend FormFieldBase):

  • updateValue no longer repopulates the sub-inputs while one is focused — model repaints on focus/enter were wiping the digit being typed (2024024).
  • updateValue calls updateEmptyStatus() so the --filled/--empty BEM modifier stays in sync.
  • updateEnabled / updateReadOnly / updateValidity call super first, preserving the root data-cmp-* attributes and the rendered error message, then propagate state to the three sub-inputs.

Motivation and Context

Brings the split day/month/year date entry experience (foundation guidedateinput) to the Adaptive Forms core components, giving authors a keyboard-friendly, accessibility-aware alternative to the calendar datepicker.

How Has This Been Tested?

  • Unit tests: DateInputImplTest — 24/24 pass (exported type, field type, properties, min/max + exclusive constraints, JSON export).
  • Cypress runtime: dateinput.runtime.cy.js37/37 pass against a live AEM author instance (localhost:4502): init/HTML sync, model↔view sync, auto-advance, per-field guards, calendar validation, enable/disable/read-only/visibility, --filled/--empty, min/max error messaging, and rule-driven set/clear/show/hide/enable.
  • Cypress authoring: dateinput.authoring.cy.js covers Forms-editor and Sites-editor dialogs (Basic/Validation/Formats tabs, default value, timezone-agnostic min/max).

Screenshots (if appropriate):

dateinput-filled dateinput-empty

Types of changes

  • New feature (non-breaking change which adds functionality)

Checklist:

  • I have signed the Adobe Open Source CLA.
  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have read the CONTRIBUTING document.
  • I have added tests to cover my changes and the overall coverage did not decrease.
  • All unit tests pass on CircleCi.
  • I ran all tests locally and they pass.

@github-actions github-actions Bot force-pushed the date-input-field branch from ed160c9 to 84f096a Compare May 14, 2026 07:39
@adobe-bot

Copy link
Copy Markdown

Accessibility Violations Found

Id Impact
aria-required-attr critical
empty-heading minor
label-title-only serious
page-has-heading-one moderate
target-size serious

@adobe-bot

Copy link
Copy Markdown

Accessibility Violations Found

Id Impact
aria-required-attr critical
empty-heading minor
label-title-only serious
target-size serious

@codecov

codecov Bot commented May 14, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@adobe-bot

Copy link
Copy Markdown

Accessibility Violations Found

Id Impact
aria-required-attr critical
empty-heading minor
label-title-only serious
target-size serious

- updateValue: don't repopulate sub-inputs while one is focused (model
  repaints on focus/enter were wiping the digit being typed, e.g. 2024 -> 024)
- updateValue: call updateEmptyStatus() so --filled/--empty stays in sync
  (UIChange dispatched on typing is not echoed back to this field)
- updateEnabled/updateReadOnly/updateValidity: call super first so the root
  data-cmp-* attributes and the error message are kept in sync, then apply
  state to the three sub-inputs
- runtime test: exclude hidden combined input from be.visible check
- runtime test: split chained should('not.have.attr') calls (the first
  yields the attr value as subject, breaking the second)

All 37 runtime specs pass against a live instance; 24 unit tests pass.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@adobe-bot

Copy link
Copy Markdown

Accessibility Violations Found

Id Impact
aria-required-attr critical
empty-heading minor
label-title-only serious
target-size serious

1 similar comment
@adobe-bot

Copy link
Copy Markdown

Accessibility Violations Found

Id Impact
aria-required-attr critical
empty-heading minor
label-title-only serious
target-size serious

@im-shiv im-shiv requested a review from rismehta June 3, 2026 10:26
@adobe-bot

Copy link
Copy Markdown

Accessibility Violations Found

Id Impact
aria-required-attr critical
empty-heading minor
label-title-only serious
target-size serious

1 similar comment
@adobe-bot

Copy link
Copy Markdown

Accessibility Violations Found

Id Impact
aria-required-attr critical
empty-heading minor
label-title-only serious
target-size serious

@iamsudhanshu

Copy link
Copy Markdown
Collaborator

Review comments by Claude:

PR Review: #1881 — Date Input Field Component

Author: im-shiv (Shivam Agarwal) | State: Open (do not merge) | +2,860 / -1 across 35 files


Overview

This PR adds a new DateInput core component — a split day/month/year text-box widget — as an alternative to the existing calendar DatePicker. The
implementation is comprehensive: DateInput Java interface extending DatePicker, DateInputImpl Sling Model, HTL template, runtime JS view (dateinputview.js),
editor dialog clientlib, Cypress IT content, and 37 Cypress runtime tests. The JS view is well-structured with private class fields, auto-advance, smart digit
gating, and calendar validation.


Security

1. innerHTML in editDialog.js — use textContent instead

defaultDateTooltip.innerHTML = fieldDescription;
minDateTooltip.innerHTML = fieldDescription;
maxDateTooltip.innerHTML = fieldDescription;
fieldDescription comes from Granite.I18n.get(...) which today returns a fixed string, but if a translator adds HTML entities or AEM's i18n layer is ever
extended, this becomes an XSS vector. Change all three to .textContent =.

2. Sub-inputs will be submitted by the browser alongside the hidden combined field

The three visible sub-inputs all have name="${name}-day", name="${name}-month", name="${name}-year". On form submit, the browser will POST all three alongside
the hidden combined name. Server-side processors that don't explicitly filter these sub-field names will receive unexpected parameters. Consider omitting
name on the visible sub-inputs and relying solely on the hidden combined input for submission (use a data-* attribute for the JS to read the token type).

3. parseDateDisplayFormat — new RegExp(T, "i") inside a per-call function

The tokens are from a hardcoded ["D","M","Y"] array so there's no user-controlled ReDoS risk. However, the three RegExp objects are reconstructed on every
setModel() call. Hoist them to module-level constants.


Accessibility

4. aria-labelledby mismatch on the group

The outer field label is rendered via label.label @ componentId=widgetId where widgetId = "{id}-widget". The label template generates an element with id="{componentId}__label" → "{id}-widget__label". But the group references "{id}__label" (without -widget). This is a broken aria-labelledby reference — it points to a non-existent element, so screen readers will not announce the group's label. Either pass componentId=dateInput.id to the label template, or reference ${dateInput.id + '-widget'}__label in the group.

5. required on all three sub-inputs triggers browser native validation separately

When dateInput.required is true, all three sub-inputs get required. The browser will fire native validation tooltips on whichever sub-input it evaluates
first, not on the logical combined field. This is especially jarring when the form container doesn't use novalidate. Other AF components suppress this via
novalidate on the form — confirm that the container already handles this, or remove required from the visible sub-inputs and express it only on the hidden
combined field.

6. Default sub-field labels "Day" / "Month" / "Year" are not i18n-wrapped

${dateInput.titleDay ? dateInput.titleDay : 'Day'}
When no titleDay is authored, the fallback literal 'Day' is always English. HTL supports inline i18n: use ${dateInput.titleDay ? dateInput.titleDay : 'Day' @
i18n}. Same applies to 'Month' and 'Year'. For a component targeting global form authors, this is a localization defect that also indirectly affects
accessibility (AT reads "Day" to French/German/Japanese users).

7. Default placeholder values are not i18n-wrapped

placeholder="${dateInput.placeholderDay ? dateInput.placeholderDay : 'DD'}"
'DD', 'MM', 'YYYY' are format hints. If they are intended to remain format-neutral, don't run them through i18n. If locale-specific hints are wanted, they
need @ i18n. Currently they are silently hardcoded English. Be explicit about the intent.

8. Auto-advance focus shift not announced to screen readers

When a sub-field auto-advances on digit completion, focus moves silently to the next field. AT users who use screen readers may not know which field they've
entered. Consider adding a brief aria-live="polite" announcement (e.g., via a visually-hidden helper div) when auto-advance fires, or ensure the sub-field
labels are always visible to AT (even when CSS-hidden).

9. hideTitleDate hides labels visually but not from AT

The --hidden BEM modifier hides the with CSS. The label is still in the DOM and still for-associated with the input — screen readers will still
announce "Day", "Month", "Year". If the intent is visually-hidden-but-AT-accessible (the correct pattern), this is fine. If the intent is to truly suppress
the sub-labels entirely, aria-label should be used instead on the inputs, and the elements should be removed or given aria-hidden="true". Clarify
intent in the interface Javadoc.


Coding Standards

10. @PostConstruct method is private — inconsistent with codebase convention

@PostConstruct
private void initDateInputModel() { ... }
Every other @PostConstruct in this codebase uses protected (e.g., DatePickerImpl#initModel). Sling Models resolve via reflection so private works, but it
prevents subclasses from calling super.initDateInputModel() and breaks the override pattern the codebase relies on.

11. excludeMinimum/excludeMaximum may duplicate parent fields

DateInputImpl redeclares @ValueMapValue protected boolean excludeMinimum/excludeMaximum. If these are already declared in AbstractFieldImpl or DatePickerImpl
(which is the superclass chain), this creates a shadowed field and the @PostConstruct may operate on the child's field while the parent's injection operates
on its own copy. Verify the parent chain doesn't already inject these.

12. Test fixture uses non-ISO date strings

"minimumDate": "Fri Feb 04 2022 05:30:00 GMT+0530"
This is Date.toString() format, which is JVM timezone and locale dependent. Every other component in this repo uses ISO 8601 in test fixtures:
{Date}2022-02-04T00:00:00.000Z. This test can produce different results depending on the CI server's JVM timezone.

13. Copyright year "2026" on all new files

All new Java, XML, and JS files carry Copyright 2026 Adobe. Given today's date is 2026-06-03 this is correct, but the XML files in the UI (_cq_dialog, design
dialog) use 2026 while others in the same repo use 2024. Confirm this aligns with the project's copyright policy (it's fine if intentional).

14. Empty _cq_design_dialog tab

The design dialog has a Formats tab containing only an XML comment: . This should be
removed before merge — a design dialog tab with no content adds noise. Either populate it or omit the dialog entirely until there's content.


Test Coverage

15. getConstraintMessages() override is not unit-tested

DateInputImpl.getConstraintMessages() adds MINIMUM and MAXIMUM entries but this override has no dedicated test. Add a test using PATH_DATE_INPUT_MESSAGE to
assert both entries are present.

16. isHideTitleDate(true) path is not tested

Only the default false case is tested. Add a node to test-content.json with hideTitleDate: true and a corresponding test.

17. No JSON export test for customized properties

testJSONExport only tests PATH_DATE_INPUT (the minimal node). There's no assertion that placeholderDay, titleDay, dateDisplayFormat, hideTitleDate etc. appear
correctly in the serialized JSON when authored. Add a testJSONExportCustomized against PATH_DATE_INPUT_CUSTOMIZED.

18. No test that exclusive constraints clear the non-exclusive min/max

testExclusiveDateConstraints asserts getExclusiveMinimumDate() is not null but doesn't assert getMinimumDate() is null (the @PostConstruct nulls it out). This
side-effect is critical to the component's behavior — it prevents double-submission of the constraint.

19. Missing CHANGELOG.md and filter.xml updates

No CHANGELOG entry for the new component. No META-INF/vault/filter.xml change is visible in the diff — new component paths typically need to be declared there
for proper package installation.


Localization

20. Granite.I18n.get('YYYY-MM-DD', ...) in editor dialog is semantically incorrect

emptyText = Granite.I18n.get('YYYY-MM-DD', null, 'placeholder text to retain format across locale')
The hint comment says "retain format across locale" — meaning translators should NOT change this. If it should never change, don't put it through I18n.get at
all — just use a constant. Wrapping a format string in I18n.get invites translators to "fix" it in future translation rounds.

21. Error messages in _cq_dialog validation tabs need i18n review

The constraintMessage fields in the dialog (min/max date validation messages) are free-text strings authored by the form author. Ensure the dialog clearly
communicates that these messages may need to be translated per locale if the form is multilingual, either via a dialog hint or Granite validation.

@armaang1729

Copy link
Copy Markdown
Collaborator

Have we used this particular skill https://github.com/adobe/aem-core-forms-components/tree/createCoreComponentSkill/.claude/skills to create dateInput component ?

- editDialog: use textContent instead of innerHTML for tooltips; make the
  ISO format hint a plain constant instead of an I18n lookup
- html: drop name from the visible day/month/year sub-inputs (only the
  hidden combined input is submitted); fix broken aria-labelledby (the label
  template emits no id) by using aria-label; i18n the default sub-labels
- css: add the visually-hidden rule for --field-label--hidden so
  hideTitleDate actually hides labels while keeping them for screen readers
- view: hoist per-call RegExp in parseDateDisplayFormat to module scope
- interface: clarify hideTitleDate is visually-hidden-but-AT-accessible
- remove empty _cq_design_dialog
- tests: add getConstraintMessages and hideTitleDate=true coverage

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@adobe-bot

Copy link
Copy Markdown

Accessibility Violations Found

Id Impact
aria-required-attr critical
empty-heading minor
label-title-only serious
target-size serious

1 similar comment
@adobe-bot

Copy link
Copy Markdown

Accessibility Violations Found

Id Impact
aria-required-attr critical
empty-heading minor
label-title-only serious
target-size serious

@im-shiv

im-shiv commented Jun 5, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for the detailed review @iamsudhanshu! Triage and fixes pushed in the latest commit:

Fixed

  • (1) editDialog.js tooltips now use textContent not innerHTML.
  • (2) Removed name from the visible day/month/year sub-inputs — only the hidden combined input is submitted.
  • (3) Hoisted the per-call RegExp in parseDateDisplayFormat to module scope.
  • (4) Fixed the broken aria-labelledby (the label template emits no id) — the group now uses aria-label.
  • (6) @ i18n on the default Day/Month/Year sub-labels.
  • (9) hideTitleDate had no CSS so it did nothing — added the visually-hidden (AT-accessible) rule and clarified the intent in the interface Javadoc.
  • (14) Removed the empty _cq_design_dialog.
  • (15,16) Added unit tests for getConstraintMessages() and hideTitleDate=true.
  • (20) 'YYYY-MM-DD' is now a plain constant, not an I18n.get lookup.

No change (verified)

  • (10) private @PostConstruct is the codebase norm (8 of 9 impls, incl. DatePickerImpl).
  • (11) No shadowing — excludeMinimum/Maximum are not declared in AbstractFieldImpl.
  • (12) Test-fixture date format matches the datepicker fixtures (consistent).
  • (18) Already covered — testExclusiveDateConstraints asserts min/max are nulled.
  • (19) filter.xml uses broad roots that already cover the component; repo has no CHANGELOG.md.
  • (5,7,13,21) required on widgets and the DD/MM/YYYY format hints follow the existing sibling-component pattern.

Follow-up

  • (8) aria-live announcement on auto-advance — agreed it's worthwhile; tracking as a follow-up since it needs a live region.

Unit tests 26/26 and Cypress runtime 37/37 green.

@im-shiv

im-shiv commented Jun 5, 2026

Copy link
Copy Markdown
Contributor Author

Have we used this particular skill https://github.com/adobe/aem-core-forms-components/tree/createCoreComponentSkill/.claude/skills to create dateInput component ?

@armaang1729 yes, I used this skill, but there were gaps, I will update the skill with what I have observed and fixed.
Here is the PR: #1898

@devgurjar

Copy link
Copy Markdown
Contributor

Mostly additive on top of @iamsudhanshu's earlier review — that comment already covers i18n fallbacks, sub-input submission, required on sub-inputs, aria-labelledby mismatch, @PostConstruct visibility, field-shadowing, JVM-timezone test fixtures, CHANGELOG / filter.xml, etc. Five items I didn't see called out there:

1. Question: is the getFieldType() value "date-input" intentionally shared with DatePickerImpl?

Both classes do super.getFieldType(FieldType.DATE_INPUT):

  • DatePickerImpl.java:92 (the calendar widget)
  • DateInputImpl.java:108 (the new split widget)

So in the exported CRISPR JSON, two semantically different components have the same fieldType value. Runtime consumers can only distinguish them via the resource type (:type), not the field type contract.

Is this intentional — i.e. you want both to be date-input so existing rule-engine / theme code doesn't need to special-case the split variant, and :type is the canonical discriminator? Or was this a copy-paste from DatePickerImpl that should become its own enum value (e.g. SPLIT_DATE_INPUT("split-date-input"))? Either answer is defensible; worth a one-line comment in DateInputImpl#getFieldType() documenting the intent so future readers don't trip over it.

2. Default dateDisplayFormat lives in HTL only — Sling Model exposes null

DateInputImpl.getDateDisplayFormat() returns null when not authored. dateinput.html:32 applies the default:

data-cmp-date-display-format="${dateInput.dateDisplayFormat ? dateInput.dateDisplayFormat : 'date{D/M/YYYY}'}"

The JS view always gets a sensible value via the data attribute, but headless / CRISPR consumers of the Sling Model JSON get null and have to know to default themselves. The Javadoc says “or null if not set (defaults to date{D/M/YYYY})” — but the model doesn't actually apply that default.

Suggest moving the default into the model: return dateDisplayFormat == null ? "date{D/M/YYYY}" : dateDisplayFormat;. HTL then becomes ${dateInput.dateDisplayFormat} with no fallback needed.

3. #splitISOValue strips leading zeros for D and M — UX inconsistency

dateinputview.js:222-223:

this.#getInputByToken("M").value = parts[1] ? String(parseInt(parts[1], 10)) : "";
this.#getInputByToken("D").value = parts[2] ? String(parseInt(parts[2], 10)) : "";

A model value "2024-03-05" populates the inputs as "5" and "3". But the placeholder is "DD" / "MM" (two-digit) and maxlength="2" signals “two digits expected.” Visually the field says “two digits” but the loaded value is one — likely to surprise authors and end-users on reload of a saved draft.

This mirrors the foundation guidedateinput behaviour. Since this is a brand-new core component there's no backward-compat constraint to keep it. Suggest one of: always pad (05/03), or drive padding from the dateDisplayFormat token (D stripped, DD padded).

4. getFormat() vs getDateDisplayFormat() — naming confusion

getFormat() is inherited from AbstractFieldImpl and returns the hardcoded string "date" (the existing test at line 158 confirms this). On the same class getDateDisplayFormat() returns the XFA picture clause. Two format methods with completely different semantics on one class — likely to bite a future maintainer.

Low-effort fix: add a one-line @see / Javadoc on getDateDisplayFormat() explicitly stating it's not getFormat().

5. #getMaxDayForCurrentMonth() deferred-error UX (minor)

dateinputview.js:184-193 — when the year field is empty, the method uses 2000 (leap) as the year for the day-cap calculation. So a user can type day=29, month=2, then year=2023 (non-leap), and only learns about Feb-29 invalidity at year-blur via the cross-field check.

The in-code comment calls this “the conservative permissive choice” — that's defensible. But it's the visible-typing analogue to @iamsudhanshu's #8 (auto-advance not announced to AT): silent until blur. Worth either a brief authoring-doc note, or eager re-validation of the day field when the year-blur fires (the cross-field check already runs on year blur, so day's aria-invalid flip should be visible to AT — confirm in a Cypress AT-snapshot test if you have one).


Overall the implementation looks solid — most of these are polish-or-clarify, not blockers (with the possible exception of #1, depending on the intent answer).

im-shiv pushed a commit that referenced this pull request Jun 8, 2026
Update the create-core-component skill so the defects found while building and
reviewing the Date Input component (PR #1881) can't recur:

- runtime-view-js.md (new): the FormFieldBase override contract — call super on
  update* handlers, updateEmptyStatus() in overridden updateValue, and the
  composite/split-widget rules (hidden combined input, name only on combined,
  don't repopulate a focused sub-input)
- cypress-tests.md (new): required runtime + authoring specs, IT content,
  formsConstants entry and runtime-all embed, plus the hidden-input visibility
  and chained should('(not.)have.attr') gotchas
- accessibility-checklist.md: rewrite the misleading "JS View Methods" table to
  require super; document the broken aria-labelledby (label template emits no id)
- component-anatomy.md: add Cypress specs, _cq_styleConfig, runtime-all embed and
  formsConstants to the checklist; fix the IT path and .less -> .css; add the
  composite-widget base-class category
- SKILL.md: HTL i18n / no-name-on-sub-inputs / BEM-modifier-needs-CSS notes,
  editor-JS textContent + format-string rules, a Cypress runtime-verification
  phase, and new Critical Rules
- validate_component.py: new checks for the override contract, editor-JS
  innerHTML, BEM modifiers without CSS, empty design dialogs, and Cypress
  spec/wiring existence + gotcha lints

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- getFieldType: document that the date-input field type is intentionally shared
  with DatePicker (data contract is the same; :type is the discriminator)
- getDateDisplayFormat: apply the date{D/M/YYYY} default in the model so Java/HTL
  consumers never see null; @JsonIgnore it (it is a render-time picture clause, not
  part of the closed-enum AF JSON model schema) and simplify the HTL fallback
- DateInput javadoc: clarify it differs from getFormat() and is never null
- view: zero-pad day/month to two digits when populating from a value so the loaded
  value matches the DD/MM placeholders; note that the deferred Feb-29 day cap is
  re-validated (aria-invalid) on year blur
- tests: assert the default dateDisplayFormat; update the padded sub-input assertion

Unit 26/26, Cypress runtime 37/37 green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@adobe-bot

Copy link
Copy Markdown

Accessibility Violations Found

Id Impact
aria-required-attr critical
empty-heading minor
label-title-only serious
target-size serious

1 similar comment
@adobe-bot

Copy link
Copy Markdown

Accessibility Violations Found

Id Impact
aria-required-attr critical
empty-heading minor
label-title-only serious
target-size serious

@im-shiv

im-shiv commented Jun 8, 2026

Copy link
Copy Markdown
Contributor Author

Thanks @devgurjar ! All five addressed in the latest commit:

1. Shared date-input field type — intentional, now documented on DateInputImpl#getFieldType(): both date components share the field type (same data contract — a date value) while the rendered widget differs; consumers use the resource type (:type) as the discriminator.

2. Default dateDisplayFormat in the model — the date{D/M/YYYY} default is now applied in the model (so Java/HTL consumers never see null), and the HTL fallback is removed. One caveat: the AF JSON model schema is a closed enum and rejects dateDisplayFormat as a top-level property (the export test fails on it), so it's @JsonIgnored and documented as a render-time picture clause. Side benefit: this also closes a latent bug where the authored value would have failed schema validation on export.

3. Leading-zero stripping#splitISOValue now zero-pads day/month to two digits when populating from a value, so a loaded 2024-03-05 shows 05 / 03, matching the DD/MM placeholders and maxlength="2". Cypress assertion updated.

4. getFormat() vs getDateDisplayFormat() — added Javadoc on getDateDisplayFormat() explicitly distinguishing it from the inherited Field#getFormat() (which returns the generic "date" value type).

5. Deferred Feb-29 day cap — documented in #getMaxDayForCurrentMonth(). The deferred case (e.g. day=29 + month=2 typed before a non-leap year) is re-validated on year blur: the blur handler runs #validateFullDate(), which flips the day field's aria-invalid so the error is announced to AT (covered by the existing aria-invalid runtime tests).

Unit tests 26/26 and Cypress runtime 37/37 green.

@adobe-bot

Copy link
Copy Markdown

Accessibility Violations Found

Id Impact
aria-required-attr critical
empty-heading minor
label-title-only serious
target-size serious

im-shiv added a commit that referenced this pull request Jun 9, 2026
…#1898)

Update the create-core-component skill so the defects found while building and
reviewing the Date Input component (PR #1881) can't recur:

- runtime-view-js.md (new): the FormFieldBase override contract — call super on
  update* handlers, updateEmptyStatus() in overridden updateValue, and the
  composite/split-widget rules (hidden combined input, name only on combined,
  don't repopulate a focused sub-input)
- cypress-tests.md (new): required runtime + authoring specs, IT content,
  formsConstants entry and runtime-all embed, plus the hidden-input visibility
  and chained should('(not.)have.attr') gotchas
- accessibility-checklist.md: rewrite the misleading "JS View Methods" table to
  require super; document the broken aria-labelledby (label template emits no id)
- component-anatomy.md: add Cypress specs, _cq_styleConfig, runtime-all embed and
  formsConstants to the checklist; fix the IT path and .less -> .css; add the
  composite-widget base-class category
- SKILL.md: HTL i18n / no-name-on-sub-inputs / BEM-modifier-needs-CSS notes,
  editor-JS textContent + format-string rules, a Cypress runtime-verification
  phase, and new Critical Rules
- validate_component.py: new checks for the override contract, editor-JS
  innerHTML, BEM modifiers without CSS, empty design dialogs, and Cypress
  spec/wiring existence + gotcha lints

Co-authored-by: Shivam Agarwal <shivama@adobe.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants