Date input field Component#1881
Conversation
ed160c9 to
84f096a
Compare
Accessibility Violations Found
|
Accessibility Violations Found
|
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
Accessibility Violations Found
|
- 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>
Accessibility Violations Found
|
1 similar comment
Accessibility Violations Found
|
Accessibility Violations Found
|
1 similar comment
Accessibility Violations Found
|
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 Security 1. innerHTML in editDialog.js — use textContent instead defaultDateTooltip.innerHTML = fieldDescription; 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 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 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 6. Default sub-field labels "Day" / "Month" / "Year" are not i18n-wrapped ${dateInput.titleDay ? dateInput.titleDay : 'Day'} 7. Default placeholder values are not i18n-wrapped placeholder="${dateInput.placeholderDay ? dateInput.placeholderDay : 'DD'}" 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 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 Coding Standards 10. @PostConstruct method is private — inconsistent with codebase convention @PostConstruct 11. excludeMinimum/excludeMaximum may duplicate parent fields DateInputImpl redeclares @ValueMapValue protected boolean excludeMinimum/excludeMaximum. If these are already declared in AbstractFieldImpl or DatePickerImpl 12. Test fixture uses non-ISO date strings "minimumDate": "Fri Feb 04 2022 05:30:00 GMT+0530" 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 14. Empty _cq_design_dialog tab The design dialog has a Formats tab containing only an XML comment: . This should be 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 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 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 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 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') 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 |
|
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>
Accessibility Violations Found
|
1 similar comment
Accessibility Violations Found
|
|
Thanks for the detailed review @iamsudhanshu! Triage and fixes pushed in the latest commit: Fixed
No change (verified)
Follow-up
Unit tests 26/26 and Cypress runtime 37/37 green. |
@armaang1729 yes, I used this skill, but there were gaps, I will update the skill with what I have observed and fixed. |
|
Mostly additive on top of @iamsudhanshu's earlier review — that comment already covers i18n fallbacks, sub-input submission, 1. Question: is the
|
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>
Accessibility Violations Found
|
1 similar comment
Accessibility Violations Found
|
|
Thanks @devgurjar ! All five addressed in the latest commit: 1. Shared 2. Default 3. Leading-zero stripping — 4. 5. Deferred Feb-29 day cap — documented in Unit tests 26/26 and Cypress runtime 37/37 green. |
Accessibility Violations Found
|
…#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>
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 foundationguidedateinputcomponent. The three sub-fields are assembled into a single ISOYYYY-MM-DDvalue submitted via a hidden combined input.Component capabilities
titleDay/Month/Year), placeholders (placeholderDay/Month/Year), and an option to hide the sub-labels (hideTitleDate).dateDisplayFormat, e.g.date{D/M/YYYY},date{M/D/YYYY},date{YYYY/M/D}); the JS view reorders the wrappers accordingly.DateInputinterface +DateInputImpl),FormConstants/ReservedPropertiesentries, 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.jsoverrides correctly extendFormFieldBase):updateValueno longer repopulates the sub-inputs while one is focused — model repaints on focus/enter were wiping the digit being typed (2024→024).updateValuecallsupdateEmptyStatus()so the--filled/--emptyBEM modifier stays in sync.updateEnabled/updateReadOnly/updateValiditycallsuperfirst, preserving the rootdata-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 calendardatepicker.How Has This Been Tested?
DateInputImplTest— 24/24 pass (exported type, field type, properties, min/max + exclusive constraints, JSON export).dateinput.runtime.cy.js— 37/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.dateinput.authoring.cy.jscovers Forms-editor and Sites-editor dialogs (Basic/Validation/Formats tabs, default value, timezone-agnostic min/max).Screenshots (if appropriate):
Types of changes
Checklist: