@salesforce/afv-skills 1.54.0 → 1.56.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/skills/agentforce-generate/SKILL.md +8 -0
- package/skills/agentforce-generate/references/actions-reference.md +2 -2
- package/skills/agentforce-generate/references/voice-modality-reference.md +51 -15
- package/skills/agentforce-generate/references/voice-telephony-cli.md +193 -0
- package/skills/agentforce-observe/SKILL.md +13 -9
- package/skills/agentforce-observe/references/ahm-alerts.md +193 -14
- package/skills/automation-sandbox-post-copy-config-generate/SKILL.md +24 -15
- package/skills/automation-sandbox-post-copy-config-generate/assets/config_template.json +11 -0
- package/skills/automation-sandbox-post-copy-config-generate/assets/json_schema.json +33 -1
- package/skills/automation-sandbox-post-copy-config-generate/references/configuration_catalog.md +32 -1
- package/skills/automation-sandbox-post-copy-configure/SKILL.md +75 -71
- package/skills/automation-sandbox-post-copy-configure/assets/scheduled_apex_template.apex +13 -0
- package/skills/automation-sandbox-post-copy-configure/examples/sample_scheduled_apex_config.json +13 -0
- package/skills/automation-sandbox-post-copy-configure/references/scheduled_apex_path.md +155 -0
- package/skills/automation-sandbox-post-copy-configure/scripts/build-scheduled-apex.mjs +62 -0
- package/skills/automation-sandbox-post-copy-configure/scripts/soql-escape-job-name.mjs +28 -0
- package/skills/consumer-goods-accruals-datakit-deploy/SKILL.md +383 -0
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/setup.js +324 -0
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/00-check-prerequisites.js +63 -0
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/01-download-static-resource.js +100 -0
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/02-replace-org-id.js +46 -0
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/03-deploy-metadata.js +46 -0
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/04-deploy-engine.js +198 -0
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/05-deploy-tpm-accruals.js +231 -0
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/06-create-dataspace.js +82 -0
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/07-deploy-accruals-reports.js +517 -0
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/08-deploy-ui.js +416 -0
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/09-completion.js +44 -0
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/utils.js +514 -0
- package/skills/consumer-goods-sync-management-configure/SKILL.md +137 -0
- package/skills/consumer-goods-sync-management-configure/examples/scenarios.md +294 -0
- package/skills/consumer-goods-sync-management-configure/references/act1-setup-sync.md +333 -0
- package/skills/consumer-goods-sync-management-configure/references/act2-assign-users.md +324 -0
- package/skills/consumer-goods-sync-management-configure/references/act3-plan-verify.md +113 -0
- package/skills/consumer-goods-sync-management-configure/references/readiness-and-enablement.md +164 -0
- package/skills/consumer-goods-sync-management-configure/references/sync-management-app-install-backbone.md +159 -0
- package/skills/consumer-goods-sync-management-configure/references/transports-and-namespace.md +220 -0
- package/skills/consumer-goods-sync-management-configure/references/verify-and-smoke.md +175 -0
- package/skills/dx-org-analyze/README.md +310 -0
- package/skills/dx-org-analyze/SKILL.md +260 -0
- package/skills/dx-org-analyze/references/collection-details.md +88 -0
- package/skills/dx-org-analyze/references/report-format.md +67 -0
- package/skills/dx-org-analyze/scripts/collect_org_data.py +823 -0
- package/skills/dx-org-analyze/scripts/compute_diff.py +1101 -0
- package/skills/dx-org-analyze/scripts/introspect_org.py +400 -0
- package/skills/dx-org-analyze/tests/README.md +46 -0
- package/skills/dx-org-analyze/tests/fixtures/org_a.json +76 -0
- package/skills/dx-org-analyze/tests/fixtures/org_b.json +70 -0
- package/skills/dx-org-analyze/tests/test_compute_diff.sh +284 -0
- package/skills/dx-org-analyze/tests/test_consistency.sh +428 -0
- package/skills/dx-org-manage/SKILL.md +6 -50
- package/skills/dx-org-manage/examples/README.md +10 -16
- package/skills/dx-org-manage/references/scratch-org-create.md +1 -1
- package/skills/dx-org-manage/references/scratch-org-operations.md +1 -1
- package/skills/dx-org-shape-manage/SKILL.md +4 -3
- package/skills/education-cloud-domain-configure/references/gotchas-extended.md +1 -0
- package/skills/experience-accessibility-validate/SKILL.md +8 -5
- package/skills/experience-accessibility-validate/references/reviewers/sc-1-1-1-non-text-content.md +1 -4
- package/skills/experience-accessibility-validate/references/reviewers/sc-1-3-1-i-lists.md +0 -4
- package/skills/experience-accessibility-validate/references/reviewers/sc-1-3-1-ii-tables.md +20 -85
- package/skills/experience-accessibility-validate/references/reviewers/sc-1-3-1-iii-form-labels.md +4 -4
- package/skills/experience-accessibility-validate/references/reviewers/sc-1-3-1-iv-regions.md +0 -4
- package/skills/experience-accessibility-validate/references/reviewers/sc-1-3-1-v-groups.md +2 -4
- package/skills/experience-accessibility-validate/references/reviewers/sc-1-3-5-identify-input.md +0 -4
- package/skills/experience-accessibility-validate/references/reviewers/sc-1-4-3-contrast.md +4 -14
- package/skills/experience-accessibility-validate/references/reviewers/sc-2-1-1-keyboard.md +9 -5
- package/skills/experience-accessibility-validate/references/reviewers/sc-2-4-4-link-purpose.md +1 -4
- package/skills/experience-accessibility-validate/references/reviewers/sc-2-4-6-headings-labels.md +0 -4
- package/skills/experience-accessibility-validate/references/reviewers/sc-2-5-1-pointer-gestures.md +0 -4
- package/skills/experience-accessibility-validate/references/reviewers/sc-2-5-2-pointer-cancellation.md +0 -4
- package/skills/experience-accessibility-validate/references/reviewers/sc-2-5-3-label-in-name.md +0 -4
- package/skills/experience-accessibility-validate/references/reviewers/sc-2-5-7-dragging-movement.md +0 -4
- package/skills/experience-accessibility-validate/references/reviewers/sc-3-2-1-on-focus.md +0 -4
- package/skills/experience-accessibility-validate/references/reviewers/sc-3-2-2-on-input.md +1 -4
- package/skills/experience-accessibility-validate/references/reviewers/sc-3-3-1-error-identification.md +1 -4
- package/skills/experience-accessibility-validate/references/reviewers/sc-3-3-2-labels-instructions.md +1 -4
- package/skills/experience-accessibility-validate/references/reviewers/sc-3-3-3-error-suggestion.md +1 -4
- package/skills/experience-accessibility-validate/references/reviewers/sc-4-1-2-i-name.md +4 -5
- package/skills/experience-accessibility-validate/references/reviewers/sc-4-1-2-ii-role.md +1 -4
- package/skills/experience-accessibility-validate/references/reviewers/sc-4-1-2-iii-value.md +0 -4
- package/skills/experience-design-validate/SKILL.md +163 -0
- package/skills/experience-design-validate/references/ai.md +54 -0
- package/skills/experience-design-validate/references/components.md +61 -0
- package/skills/experience-design-validate/references/craft.md +158 -0
- package/skills/experience-design-validate/references/data.md +59 -0
- package/skills/experience-design-validate/references/forms-flows.md +57 -0
- package/skills/experience-design-validate/references/interaction.md +53 -0
- package/skills/experience-design-validate/references/navigation.md +51 -0
- package/skills/experience-design-validate/references/performance.md +56 -0
- package/skills/experience-design-validate/references/records.md +60 -0
- package/skills/experience-design-validate/references/responsive.md +48 -0
- package/skills/experience-design-validate/references/scoring-rubric.md +257 -0
- package/skills/experience-design-validate/references/state.md +53 -0
- package/skills/experience-design-validate/references/trust.md +47 -0
- package/skills/experience-design-validate/references/usability.md +35 -0
- package/skills/experience-design-validate/references/visual-system.md +183 -0
- package/skills/experience-lwc-accessibility-jest-run/SKILL.md +104 -25
- package/skills/experience-lwc-accessibility-jest-run/assets/jest.config.js +4 -0
- package/skills/experience-lwc-accessibility-jest-run/assets/sa11y-jest-setup.js +5 -0
- package/skills/experience-ui-bundle-app-coordinate/SKILL.md +5 -5
- package/skills/experience-ui-bundle-features-generate/SKILL.md +65 -36
- package/skills/experience-ui-bundle-features-generate/references/angular/features.md +74 -0
- package/skills/experience-ui-bundle-features-generate/references/react/features.md +59 -0
- package/skills/experience-ui-bundle-features-generate/scripts/detect-framework.sh +73 -0
- package/skills/experience-ui-bundle-frontend-generate/SKILL.md +2 -2
- package/skills/experience-ui-bundle-metadata-generate/SKILL.md +26 -14
- package/skills/experience-ui-bundle-metadata-generate/references/angular-metadata-generate.md +37 -0
- package/skills/experience-ui-bundle-metadata-generate/references/react-metadata-generate.md +32 -0
- package/skills/experience-ui-bundle-metadata-generate/scripts/detect-framework.sh +73 -0
- package/skills/experience-ui-bundle-metadata-generate/scripts/verify-bundle-location.sh +30 -8
- package/skills/field-service-data-capture-migrate/SKILL.md +391 -0
- package/skills/field-service-data-capture-migrate/assets/sample-legacy-flow.flow-meta.xml +163 -0
- package/skills/field-service-data-capture-migrate/references/architecture-notes.md +40 -0
- package/skills/field-service-data-capture-migrate/references/component-mapping.md +278 -0
- package/skills/field-service-data-capture-migrate/references/converter-builder-contract.md +183 -0
- package/skills/field-service-data-capture-migrate/references/dc-platform-rules.md +130 -0
- package/skills/field-service-data-capture-migrate/references/fsm-dc-capability-catalog.md +215 -0
- package/skills/field-service-data-capture-migrate/references/known-deploy-errors.md +36 -0
- package/skills/field-service-data-capture-migrate/references/migration-checklist.md +121 -0
- package/skills/field-service-data-capture-migrate/references/transformer-rules.md +132 -0
- package/skills/field-service-data-capture-migrate/scripts/analyze_flow.py +277 -0
- package/skills/field-service-data-capture-migrate/scripts/convert_to_dc_spec.py +1311 -0
- package/skills/field-service-data-capture-migrate/scripts/cud_analysis.py +402 -0
- package/skills/field-service-data-capture-migrate/scripts/deploy_flow.sh +230 -0
- package/skills/field-service-data-capture-migrate/scripts/discover_subflow_tree.py +230 -0
- package/skills/field-service-data-capture-migrate/scripts/flow_input.py +186 -0
- package/skills/field-service-data-capture-migrate/scripts/flow_xml_utils.py +39 -0
- package/skills/field-service-data-capture-migrate/scripts/fsm_dc_catalog.py +413 -0
- package/skills/field-service-data-capture-migrate/scripts/generate_summary.py +199 -0
- package/skills/field-service-data-capture-migrate/scripts/json_to_flow_xml.py +146 -0
- package/skills/field-service-data-capture-migrate/scripts/manual_review_flags.py +42 -0
- package/skills/field-service-data-capture-migrate/scripts/retrieve_flow_rest.sh +155 -0
- package/skills/field-service-data-capture-migrate/scripts/subflow_names.py +49 -0
- package/skills/field-service-data-capture-migrate/scripts/transform_flow.py +1661 -0
- package/skills/field-service-data-capture-migrate/scripts/validate_flow.sh +147 -0
- package/skills/field-service-data-capture-migrate/scripts/vendor/build_flow.py +1258 -0
- package/skills/life-sciences-fieldsalesrep-coordinate/SKILL.md +1 -1
- package/skills/life-sciences-fieldsalesrep-coordinate/references/orchestration-flow.md +1 -1
- package/skills/life-sciences-kam-coordinate/references/stage-5-data-and-plan-templates-overview.md +14 -1
- package/skills/mobile-apps-create/SKILL.md +1 -1
- package/skills/{platform-agentsetup-categories-fetch → platform-agenticsetup-categories-get}/SKILL.md +7 -7
- package/skills/platform-sandbox-configure/SKILL.md +108 -133
- package/skills/platform-sandbox-configure/references/api-response-shapes.md +39 -0
- package/skills/platform-sandbox-configure/references/definition-file-approach.md +73 -0
- package/skills/platform-widget-generate/SKILL.md +26 -18
- package/skills/platform-widget-generate/examples/formulas.json +191 -0
- package/skills/platform-widget-generate/references/widget-formulas.md +123 -0
- package/skills/platform-widget-generate/references/widget-meta-directives.md +4 -4
- package/skills/sales-call-scoring-configure/SKILL.md +318 -0
- package/skills/sales-call-scoring-configure/assets/best-practice-competencies.json +67 -0
- package/skills/sales-call-scoring-configure/assets/ootb-competencies.json +58 -0
- package/skills/sales-call-scoring-configure/references/admin-communication.md +79 -0
- package/skills/sales-call-scoring-configure/references/competency-crud.md +130 -0
- package/skills/sales-call-scoring-configure/scripts/create-competency.sh +166 -0
- package/skills/sales-call-scoring-configure/scripts/create-custom-competency.sh +166 -0
- package/skills/sales-call-scoring-configure/scripts/edit-competency.sh +185 -0
- package/skills/sales-call-scoring-configure/scripts/edit-custom-competency.sh +190 -0
- package/skills/sales-call-scoring-configure/scripts/enable-call-scoring.sh +436 -0
- package/skills/sales-call-scoring-configure/scripts/get-competency.sh +72 -0
- package/skills/sales-call-scoring-configure/scripts/get-custom-competency.sh +78 -0
- package/skills/sales-call-scoring-configure/scripts/install-best-practice-competencies.sh +223 -0
- package/skills/sales-call-scoring-configure/scripts/install-ootb-competencies.sh +237 -0
- package/skills/sales-call-scoring-configure/scripts/list-competencies.sh +99 -0
- package/skills/sales-call-scoring-configure/scripts/shared/auth.sh +116 -0
- package/skills/sales-call-scoring-configure/scripts/shared/cap.sh +86 -0
- package/skills/sales-call-scoring-configure/scripts/shared/soap.sh +267 -0
- package/skills/sales-call-scoring-configure/scripts/shared/soql.sh +25 -0
- package/skills/sales-call-scoring-configure/scripts/toggle-competency.sh +112 -0
- package/skills/sales-call-scoring-configure/scripts/toggle-custom-competency.sh +125 -0
- package/skills/sales-call-scoring-configure/scripts/verify-ootb-competencies.sh +116 -0
- package/skills/service-concierge-portal-generate/references/portal-deploy-runbook.md +1 -0
- package/skills/service-de-channel-activate/SKILL.md +6 -5
- package/skills/service-de-channel-create/SKILL.md +3 -3
- package/skills/service-de-channel-routing-configure/SKILL.md +3 -3
- package/skills/service-de-channel-settings-configure/SKILL.md +195 -0
- package/skills/service-de-channel-settings-configure/references/channel-settings-facets.md +152 -0
- package/skills/{service-de-channel-consent-configure → service-de-channel-settings-configure}/references/gotchas.md +3 -3
- package/skills/{service-de-channel-consent-configure → service-de-channel-settings-configure}/references/language-keywords.md +4 -4
- package/skills/{service-de-channel-consent-configure → service-de-channel-settings-configure}/references/worked-examples.md +14 -14
- package/skills/service-de-headless-channel-configure/SKILL.md +6 -6
- package/skills/service-de-headless-channel-configure/references/worked-examples.md +1 -1
- package/skills/service-helpagent-coordinate/SKILL.md +3 -2
- package/skills/service-helpagent-coordinate/references/channel-voice.md +15 -4
- package/skills/service-itsm-agentic-setup-agentforce-coordinate/SKILL.md +49 -31
- package/skills/service-itsm-agentic-setup-agentforce-coordinate/examples/output-templates.md +71 -6
- package/skills/service-itsm-agentic-setup-agentforce-coordinate/scripts/verify-child-verdict.mjs +26 -4
- package/skills/service-itsm-agentic-setup-cmdb-access-assign/SKILL.md +35 -10
- package/skills/service-itsm-agentic-setup-cmdb-access-assign/references/mcp-invocation.md +25 -5
- package/skills/service-itsm-agentic-setup-cmdb-bundle-deploy/SKILL.md +1 -1
- package/skills/service-itsm-agentic-setup-cmdb-configure/SKILL.md +5 -5
- package/skills/service-itsm-agentic-setup-cmdb-configure/references/mcp-invocation.md +1 -1
- package/skills/service-itsm-agentic-setup-cmdb-coordinate/SKILL.md +2 -2
- package/skills/service-itsm-agentic-setup-cmdb-coordinate/examples/output-templates.md +1 -1
- package/skills/service-itsm-agentic-setup-cmdb-discovery-configure/SKILL.md +25 -15
- package/skills/service-itsm-agentic-setup-employee-agent-configure/SKILL.md +8 -5
- package/skills/service-itsm-agentic-setup-employee-agent-configure/references/report-format.md +4 -2
- package/skills/service-itsm-agentic-setup-employee-agent-configure/references/workflow-detail.md +1 -1
- package/skills/service-itsm-agentic-setup-employee-agent-configure/scripts/render-report.mjs +29 -16
- package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/SKILL.md +8 -5
- package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/references/report-format.md +4 -2
- package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/references/workflow-detail.md +1 -1
- package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/scripts/render-report.mjs +29 -16
- package/skills/service-itsm-agentic-setup-incident-management/SKILL.md +138 -68
- package/skills/service-itsm-agentic-setup-incident-management/examples/output-templates.md +31 -15
- package/skills/service-itsm-agentic-setup-incident-management/references/incident-persona-psg.md +156 -0
- package/skills/service-itsm-agentic-setup-incident-management/references/incident-preferences.md +148 -0
- package/skills/service-itsm-agentic-setup-incident-management/references/major-incident-management.md +162 -0
- package/skills/service-itsm-agentic-setup-incident-management/references/service-mgmt-privilege.md +149 -0
- package/skills/service-itsm-agentic-setup-incident-sla-configure/SKILL.md +103 -89
- package/skills/service-itsm-agentic-setup-incident-sla-configure/assets/attach-milestone.json +2 -2
- package/skills/service-itsm-agentic-setup-incident-sla-configure/assets/predefined-incident-policy.json +21 -39
- package/skills/service-itsm-agentic-setup-incident-sla-configure/examples/milestone-patterns.md +3 -3
- package/skills/service-itsm-agentic-setup-incident-sla-configure/examples/output-templates.md +18 -1
- package/skills/service-itsm-agentic-setup-incident-sla-configure/references/mcp-invocation.md +63 -37
- package/skills/service-omni-attribute-routing-configure/SKILL.md +53 -0
- package/skills/service-omni-attribute-routing-configure/references/api-notes.md +7 -0
- package/skills/service-omni-attribute-routing-configure/scripts/configure-and-report.sh +224 -0
- package/skills/service-omni-attribute-routing-configure/scripts/tests/test_attribute_routing_contracts.py +137 -0
- package/skills/service-omni-channel-inventory-analyze/SKILL.md +96 -0
- package/skills/service-omni-channel-inventory-analyze/references/api-notes.md +52 -0
- package/skills/service-omni-channel-inventory-analyze/scripts/analyze.sh +185 -0
- package/skills/service-omni-channel-inventory-analyze/scripts/tests/_bootstrap.py +84 -0
- package/skills/service-omni-channel-inventory-analyze/scripts/tests/test_inventory_analyze_contracts.py +141 -0
- package/skills/service-omni-channel-limits-analyze/SKILL.md +70 -0
- package/skills/service-omni-channel-limits-analyze/references/api-notes.md +22 -0
- package/skills/service-omni-channel-limits-analyze/scripts/analyze.sh +159 -0
- package/skills/service-omni-channel-limits-analyze/scripts/tests/_bootstrap.py +87 -0
- package/skills/service-omni-channel-limits-analyze/scripts/tests/test_limits_analyze_contracts.py +99 -0
- package/skills/service-omni-channel-setup-coordinate/SKILL.md +12 -20
- package/skills/service-omni-channel-setup-coordinate/scripts/integration-driver.sh +55 -5
- package/skills/service-omni-channel-setup-coordinate/scripts/tests/test_omni_contracts.py +38 -0
- package/skills/service-omni-command-center-analyze/SKILL.md +2 -2
- package/skills/service-omni-command-center-analyze/scripts/analyze.sh +3 -3
- package/skills/dx-org-manage/examples/snapshots/error_output.json +0 -9
- package/skills/dx-org-manage/examples/snapshots/success_output.json +0 -15
- package/skills/dx-org-manage/references/cli_flags.md +0 -67
- package/skills/dx-org-manage/references/creating-snapshot.md +0 -103
- package/skills/dx-org-manage/references/snapshot_usage.md +0 -74
- package/skills/experience-accessibility-validate/scripts/contrast-ratio.py +0 -153
- package/skills/experience-lwc-accessibility-jest-run/references/running-sa11y-jest-tests.md +0 -205
- package/skills/experience-ui-bundle-features-generate/scripts/verify-react-bundle.sh +0 -14
- /package/skills/experience-ui-bundle-features-generate/references/{conflict-resolution-schema.json → common/conflict-resolution-schema.json} +0 -0
- /package/skills/{platform-agentsetup-categories-fetch → platform-agenticsetup-categories-get}/references/api-response-schema.md +0 -0
package/skills/experience-accessibility-validate/references/reviewers/sc-1-1-1-non-text-content.md
CHANGED
|
@@ -77,12 +77,9 @@ Rules to follow:
|
|
|
77
77
|
- Flag missing or generic alt text on informative images
|
|
78
78
|
- Flag overly descriptive alt text on clearly decorative images
|
|
79
79
|
- Consider the context and purpose of each image
|
|
80
|
+
- **This reviewer covers `<img>` elements only.** Do **not** flag non-image content: an `aria-hidden="true"` `<span>`, icon-font glyph, emoji, or decorative `<svg>` is intentionally removed from the accessibility tree and is correctly handled — it is not an `<img>` missing alt text. A decorative `<span aria-hidden="true">` is correct, not a violation.
|
|
80
81
|
|
|
81
82
|
- For each issue found, provide a separate, detailed report.
|
|
82
83
|
- Keep issues concise, avoid duplicated issues or unnecessary or non-applicable problems.
|
|
83
84
|
- Assume that any imported functionality works as expected and was already analyzed.
|
|
84
85
|
- Components do not supplement or provide global functionalities.
|
|
85
|
-
- Lightning base components (`lightning-input`, `lightning-combobox`, `lightning-textarea`, `lightning-icon`, etc.) provide their own accessible labeling, ARIA, and error handling in shadow DOM via their dedicated attributes (`label`, `alternative-text`, field-level validation). When such a component is given a `label` attribute it is already programmatically labeled — even with `variant="label-hidden"`, which hides the label visually but keeps it for assistive technology. Do **not** flag a sibling/wrapper `<label>` or `<span>` for a missing `for`/`id` when the actual control is a self-labeling Lightning component, and do not treat a visible heading as if it were the control's only label. This also covers navigation and icon base components (`lightning-vertical-navigation-item`, `lightning-vertical-navigation-item-icon`, `lightning-button-icon`, etc.): when a `label` (or `alternative-text`) attribute is supplied, the base component renders it as the visible link/control text **and** exposes it as the accessible name, and any `icon-name` is decorative — do not emit a 4.1.2 "verify the label is associated with the icon" warning, even a hedged one. The presence of the `label` attribute is the association.
|
|
86
|
-
- Resolve template bindings before judging them. A template expression like `{someValue}` refers to a property or getter on the component's controller (`.js`/`.ts`) — including `@api` properties and `get someValue()` getters — not to a module-level imported constant (which LWC templates cannot bind to). Check the controller for the binding's definition before concluding a value is undefined, empty, or missing. When reviewing a diff, verify which side is the corrected code; do not assume the change introduced the problem.
|
|
87
|
-
- Prefer a real `<button>` for actions; for a link, `href="#"` with `event.preventDefault()` (the canonical SLDS pattern). Don't recommend `href="javascript:void(0)"` as a first-line remediation — it's a no-op-anchor anti-pattern. It is acceptable only as a last resort when moving `<a>` → `<button>` is genuinely impossible, and even then only when paired with the full set of attributes that make the anchor behave as an accessible button (`role="button"`, keyboard activation, etc.) — `void(0)` on its own is an incomplete fix. Don't flag existing `javascript:void(0)` as a violation.
|
|
88
|
-
- ARIA attribute spelling depends on the element type. On a **plain HTML element** (`div`, `span`, `button`, `input`, `a`, `img`, `iframe`, …) the only valid spelling is the W3C form `aria-labelledby` / `aria-describedby`; the hyphen-split `aria-labelled-by` / `aria-described-by` there **is** a real bug — keep flagging it. But on an **LWC component tag** (`lightning-*` or a custom `ns-name` element), the hyphen-split form is the kebab-case binding of the component's `@api ariaLabelledBy` / `ariaDescribedBy` property (each capital letter maps to `-` + lowercase), and LWC reflects it to the spec-correct `aria-labelledby` in the rendered DOM. Do **not** flag `aria-labelled-by` on a component tag as a misspelling, and do not claim it "breaks the accessible name computation" — you cannot determine that from the attribute name alone, because both `aria-labelled-by` (via `@api` property kebab-casing) and `aria-labelledby` (via LWC's ARIA reflection) can wire to the same property depending on the component. Treat a hyphen-split ARIA attribute on a component tag as a valid binding, not a violation.
|
|
@@ -46,7 +46,3 @@ Rules to follow:
|
|
|
46
46
|
- Keep issues concise, avoid duplicated issues or unnecessary or non-applicable problems.
|
|
47
47
|
- Assume that any imported functionality works as expected and was already analyzed.
|
|
48
48
|
- Components do not supplement or provide global functionalities.
|
|
49
|
-
- Lightning base components (`lightning-input`, `lightning-combobox`, `lightning-textarea`, `lightning-icon`, etc.) provide their own accessible labeling, ARIA, and error handling in shadow DOM via their dedicated attributes (`label`, `alternative-text`, field-level validation). When such a component is given a `label` attribute it is already programmatically labeled — even with `variant="label-hidden"`, which hides the label visually but keeps it for assistive technology. Do **not** flag a sibling/wrapper `<label>` or `<span>` for a missing `for`/`id` when the actual control is a self-labeling Lightning component, and do not treat a visible heading as if it were the control's only label. This also covers navigation and icon base components (`lightning-vertical-navigation-item`, `lightning-vertical-navigation-item-icon`, `lightning-button-icon`, etc.): when a `label` (or `alternative-text`) attribute is supplied, the base component renders it as the visible link/control text **and** exposes it as the accessible name, and any `icon-name` is decorative — do not emit a 4.1.2 "verify the label is associated with the icon" warning, even a hedged one. The presence of the `label` attribute is the association.
|
|
50
|
-
- Resolve template bindings before judging them. A template expression like `{someValue}` refers to a property or getter on the component's controller (`.js`/`.ts`) — including `@api` properties and `get someValue()` getters — not to a module-level imported constant (which LWC templates cannot bind to). Check the controller for the binding's definition before concluding a value is undefined, empty, or missing. When reviewing a diff, verify which side is the corrected code; do not assume the change introduced the problem.
|
|
51
|
-
- Prefer a real `<button>` for actions; for a link, `href="#"` with `event.preventDefault()` (the canonical SLDS pattern). Don't recommend `href="javascript:void(0)"` as a first-line remediation — it's a no-op-anchor anti-pattern. It is acceptable only as a last resort when moving `<a>` → `<button>` is genuinely impossible, and even then only when paired with the full set of attributes that make the anchor behave as an accessible button (`role="button"`, keyboard activation, etc.) — `void(0)` on its own is an incomplete fix. Don't flag existing `javascript:void(0)` as a violation.
|
|
52
|
-
- ARIA attribute spelling depends on the element type. On a **plain HTML element** (`div`, `span`, `button`, `input`, `a`, `img`, `iframe`, …) the only valid spelling is the W3C form `aria-labelledby` / `aria-describedby`; the hyphen-split `aria-labelled-by` / `aria-described-by` there **is** a real bug — keep flagging it. But on an **LWC component tag** (`lightning-*` or a custom `ns-name` element), the hyphen-split form is the kebab-case binding of the component's `@api ariaLabelledBy` / `ariaDescribedBy` property (each capital letter maps to `-` + lowercase), and LWC reflects it to the spec-correct `aria-labelledby` in the rendered DOM. Do **not** flag `aria-labelled-by` on a component tag as a misspelling, and do not claim it "breaks the accessible name computation" — you cannot determine that from the attribute name alone, because both `aria-labelled-by` (via `@api` property kebab-casing) and `aria-labelledby` (via LWC's ARIA reflection) can wire to the same property depending on the component. Treat a hyphen-split ARIA attribute on a component tag as a valid binding, not a violation.
|
|
@@ -4,103 +4,38 @@ Information, structure, and relationships conveyed through presentation can be p
|
|
|
4
4
|
|
|
5
5
|
## SC: 1.3.1 (ii) - Tables Only
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
For every `<table>` element in the source, apply the criteria below and produce one fix entry per violation. Other SC 1.3.1 concerns (lists, regions, form-labels, groups) are out of scope — they are owned by sibling reviewers.
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
(Only tables from this rule should be considered). For all tables on the components, ensure that any information conveyed through presentation is programmatically determinable in order to determine if they meet SC 1.3.1 (ii).
|
|
9
|
+
### Structural criteria
|
|
11
10
|
|
|
12
|
-
For each
|
|
11
|
+
For each `<table>`, verify:
|
|
13
12
|
|
|
14
|
-
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
-
|
|
18
|
-
-
|
|
19
|
-
- Verify the presence of table header cells (`<th>`) when applicable: If the table includes headers, ensure that the header information is marked up using `<th>` elements, typically within the first `<tr>` element or within `<thead>` elements
|
|
20
|
-
- Check that all data content within the table is enclosed within `<td>` cell elements and that header content (if present) is within `<th>` elements
|
|
21
|
-
- For every `<table>` element identified, verify that it contains at least the following elements: `<tr>`, `<th>` (if headers are present, otherwise `<td>`), and `<td>`
|
|
22
|
-
- Providing an accessible name for a table is considered a best practice that significantly enhances usability for all users, especially those relying on assistive technologies.The accessible name can be provided in various ways:
|
|
23
|
-
- By either using a `aria-label` or `aria-labelledby` attributes or `<caption>` element in the table. Its a best practice and absence of accessible name is acceptable but not a violation.
|
|
24
|
-
- The objective of this technique is to associate header cells with data cells in simple data tables using the `scope` attribute.
|
|
25
|
-
- The `scope` attribute identifies whether the cell is a header for a row, column, or group of rows or columns
|
|
26
|
-
- Valid `scope` values: `row`, `col`, `rowgroup`, `colgroup`
|
|
13
|
+
- Contains at least one `<tr>` element.
|
|
14
|
+
- Each `<tr>` contains one or more cells appropriate to its content: `<th>` for headers and `<td>` for data. A header-only row containing only `<th>` cells is valid.
|
|
15
|
+
- Header content (if present) is marked up with `<th>` (typically in the first `<tr>` or inside `<thead>`).
|
|
16
|
+
- All data content is inside `<td>` cells; all header content is inside `<th>` cells.
|
|
17
|
+
- The table is either a recognizable data table (`<tr>`, `<td>`, plus `<th>` when headers exist) or a layout table (no relationships across rows and columns).
|
|
27
18
|
|
|
28
|
-
|
|
19
|
+
### Header-association criteria
|
|
29
20
|
|
|
30
|
-
-
|
|
31
|
-
|
|
32
|
-
-
|
|
33
|
-
|
|
34
|
-
- Verify `scope` values match the header's role (`row`/`col`/`rowgroup`/`colgroup`)
|
|
35
|
-
Note: For complex tables (multiple levels of headers, headers spanning rows/columns), use id and headers attributes instead (see H43)
|
|
36
|
-
- The objective of this technique is to associate each data cell (in a data table) with the appropriate headers.
|
|
37
|
-
Check for layout tables and data tables:
|
|
38
|
-
- For layout tables:
|
|
39
|
-
- Determine if content has a relationship with other content in both its column and row
|
|
40
|
-
- If "no", the table is a layout table
|
|
41
|
-
- For data tables:
|
|
42
|
-
- Check that any cell associated with multiple row/column headers contains a headers attribute listing all associated header IDs
|
|
43
|
-
- For cells with id or headers attributes:
|
|
44
|
-
- Verify each id in headers attribute matches a header element's id
|
|
45
|
-
- Verify headers attribute contains all associated header IDs
|
|
46
|
-
- Ensure all IDs are unique within the component
|
|
21
|
+
- **Simple data tables** with headers in the first row or column: `<th>` without `scope` is sufficient.
|
|
22
|
+
- **Simple data tables** with headers NOT in the first row or column: every `<th>` must carry a valid `scope` (`row` / `col` / `rowgroup` / `colgroup`) matching the header's role.
|
|
23
|
+
- **Irregular tables** with headers spanning rows or columns may use explicitly defined row or column groups with `scope="rowgroup"` or `scope="colgroup"`. Do not require `id` + `headers` solely because a table uses `rowspan`, `colspan`, or multiple header levels when groups and `scope` express the relationships.
|
|
24
|
+
- **Complex tables** whose data-cell relationships are too complex to identify using `<th>` alone or `<th>` with `scope` must provide programmatically determinable header-to-cell associations. Use `id` + `headers` attributes (see H43), or simplify the table so `<th>` and `scope` can express the relationships. Complex cases include tables whose headers repeat or change partway through the table or whose data cells are associated with three or more headers. When `id` + `headers` is used, verify that every `<th>` `id` is unique within the component and every id in a cell's `headers` attribute resolves to an actual `<th>`.
|
|
47
25
|
|
|
48
|
-
|
|
26
|
+
### Accessible-name criterion
|
|
49
27
|
|
|
50
|
-
|
|
51
|
-
Check for the presence of tabular information.
|
|
52
|
-
For each instance of the `<table>` element found, perform the following checks:
|
|
53
|
-
- Verify the presence of table rows (`<tr>`): Ensure that each `<table>` element contains at least one `<tr>` element
|
|
54
|
-
- Verify the presence of table data cells (`<td>`) within rows (`<tr>`): For each `<tr>` element within a `<table>`, confirm that it contains one or more `<td>` elements representing the data cells
|
|
55
|
-
- Verify the presence of table header cells (`<th>`) when applicable: If the table includes headers, ensure that the header information is marked up using `<th>` elements, typically within the first `<tr>` element or within `<thead>` elements
|
|
56
|
-
- Check that all data content within the table is enclosed within `<td>` cell elements and that header content (if present) is within `<th>` elements
|
|
57
|
-
- For every `<table>` element identified, verify that it contains at least the following elements: `<tr>`, `<th>` (if headers are present, otherwise `<td>`), and `<td>`
|
|
58
|
-
- Providing an accessible name for a table is considered a best practice that significantly enhances usability for all users, especially those relying on assistive technologies.The accessible name can be provided in various ways:
|
|
59
|
-
- By either using a `aria-label` or `aria-labelledby` attributes or `<caption>` element in the table. Its a best practice and absence of accessible name is acceptable but not a violation.
|
|
60
|
-
- The objective of this technique is to associate header cells with data cells in simple data tables using the `scope` attribute.
|
|
61
|
-
- The `scope` attribute identifies whether the cell is a header for a row, column, or group of rows or columns
|
|
62
|
-
- Valid `scope` values: `row`, `col`, `rowgroup`, `colgroup`
|
|
28
|
+
Providing an accessible name (via `aria-label`, `aria-labelledby`, or `<caption>`) is a best practice but not a violation when absent. Do not produce a fix entry purely for a missing accessible name.
|
|
63
29
|
|
|
64
|
-
|
|
30
|
+
### Layout-table criterion
|
|
65
31
|
|
|
66
|
-
|
|
67
|
-
- `th` elements without `scope` are sufficient
|
|
68
|
-
- If headers are not in the first row or column:
|
|
69
|
-
- Check that all `th` elements have a `scope` attribute
|
|
70
|
-
- Verify `scope` values match the header's role (`row`/`col`/`rowgroup`/`colgroup`)
|
|
71
|
-
Note: For complex tables (multiple levels of headers, headers spanning rows/columns), use id and headers attributes instead (see H43)
|
|
72
|
-
- The objective of this technique is to associate each data cell (in a data table) with the appropriate headers.
|
|
73
|
-
Check for layout tables and data tables:
|
|
74
|
-
- For layout tables:
|
|
75
|
-
- Determine if content has a relationship with other content in both its column and row
|
|
76
|
-
- If "no", the table is a layout table
|
|
77
|
-
- For data tables:
|
|
78
|
-
- Check that any cell associated with multiple row/column headers contains a headers attribute listing all associated header IDs
|
|
79
|
-
- For cells with id or headers attributes:
|
|
80
|
-
- Verify each id in headers attribute matches a header element's id
|
|
81
|
-
- Verify headers attribute contains all associated header IDs
|
|
82
|
-
- Ensure all IDs are unique within the component
|
|
32
|
+
When a table's content has no row/column relationships, classify it as a layout table. Layout tables should not use `<th>` or `scope`; emit a fix entry if they do.
|
|
83
33
|
|
|
84
|
-
|
|
34
|
+
### Output contract
|
|
85
35
|
|
|
86
|
-
|
|
87
|
-
- Headers are not in the first row or column
|
|
88
|
-
- Multiple levels of headers exist
|
|
89
|
-
- Cells are associated with multiple headers
|
|
90
|
-
- The table structure requires additional context to understand relationships between data
|
|
36
|
+
For each violation, produce one entry with: file + line number, which criterion above failed, and the corrected markup snippet. If every table satisfies the criteria, produce an empty list.
|
|
91
37
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
Rules to follow:
|
|
95
|
-
|
|
96
|
-
- Find all violations of SC 1.3.1 (ii) 'Tables' in the provided HTML and JS files
|
|
97
|
-
- Do not worry about violations of SC 1.3.1 that are not specific to tables (handled by other reviewers)
|
|
98
|
-
- If no changes are needed, then produce an empty list
|
|
99
|
-
- For each issue found, provide a separate, detailed report.
|
|
38
|
+
- For each issue found, provide a separate, detailed report.
|
|
100
39
|
- Keep issues concise, avoid duplicated issues or unnecessary or non-applicable problems.
|
|
101
40
|
- Assume that any imported functionality works as expected and was already analyzed.
|
|
102
41
|
- Components do not supplement or provide global functionalities.
|
|
103
|
-
- Lightning base components (`lightning-input`, `lightning-combobox`, `lightning-textarea`, `lightning-icon`, etc.) provide their own accessible labeling, ARIA, and error handling in shadow DOM via their dedicated attributes (`label`, `alternative-text`, field-level validation). When such a component is given a `label` attribute it is already programmatically labeled — even with `variant="label-hidden"`, which hides the label visually but keeps it for assistive technology. Do **not** flag a sibling/wrapper `<label>` or `<span>` for a missing `for`/`id` when the actual control is a self-labeling Lightning component, and do not treat a visible heading as if it were the control's only label. This also covers navigation and icon base components (`lightning-vertical-navigation-item`, `lightning-vertical-navigation-item-icon`, `lightning-button-icon`, etc.): when a `label` (or `alternative-text`) attribute is supplied, the base component renders it as the visible link/control text **and** exposes it as the accessible name, and any `icon-name` is decorative — do not emit a 4.1.2 "verify the label is associated with the icon" warning, even a hedged one. The presence of the `label` attribute is the association.
|
|
104
|
-
- Resolve template bindings before judging them. A template expression like `{someValue}` refers to a property or getter on the component's controller (`.js`/`.ts`) — including `@api` properties and `get someValue()` getters — not to a module-level imported constant (which LWC templates cannot bind to). Check the controller for the binding's definition before concluding a value is undefined, empty, or missing. When reviewing a diff, verify which side is the corrected code; do not assume the change introduced the problem.
|
|
105
|
-
- Prefer a real `<button>` for actions; for a link, `href="#"` with `event.preventDefault()` (the canonical SLDS pattern). Don't recommend `href="javascript:void(0)"` as a first-line remediation — it's a no-op-anchor anti-pattern. It is acceptable only as a last resort when moving `<a>` → `<button>` is genuinely impossible, and even then only when paired with the full set of attributes that make the anchor behave as an accessible button (`role="button"`, keyboard activation, etc.) — `void(0)` on its own is an incomplete fix. Don't flag existing `javascript:void(0)` as a violation.
|
|
106
|
-
- ARIA attribute spelling depends on the element type. On a **plain HTML element** (`div`, `span`, `button`, `input`, `a`, `img`, `iframe`, …) the only valid spelling is the W3C form `aria-labelledby` / `aria-describedby`; the hyphen-split `aria-labelled-by` / `aria-described-by` there **is** a real bug — keep flagging it. But on an **LWC component tag** (`lightning-*` or a custom `ns-name` element), the hyphen-split form is the kebab-case binding of the component's `@api ariaLabelledBy` / `ariaDescribedBy` property (each capital letter maps to `-` + lowercase), and LWC reflects it to the spec-correct `aria-labelledby` in the rendered DOM. Do **not** flag `aria-labelled-by` on a component tag as a misspelling, and do not claim it "breaks the accessible name computation" — you cannot determine that from the attribute name alone, because both `aria-labelled-by` (via `@api` property kebab-casing) and `aria-labelledby` (via LWC's ARIA reflection) can wire to the same property depending on the component. Treat a hyphen-split ARIA attribute on a component tag as a valid binding, not a violation.
|
package/skills/experience-accessibility-validate/references/reviewers/sc-1-3-1-iii-form-labels.md
CHANGED
|
@@ -61,6 +61,8 @@ Exceptions (No Label Required):
|
|
|
61
61
|
|
|
62
62
|
If they do not meet this success criterion, then flag this as a violation.
|
|
63
63
|
|
|
64
|
+
Trace how the control's own accessible name is provided in the source before flagging a missing or unassociated label. Valid sources include a `<label>` that contains the control, a `<label for>` / `<label htmlFor>` whose value matches the control's `id`, an `aria-label`, an `aria-labelledby` target, or a self-labeling component prop on an imported/custom control such as `<Input>` or `<TextField>` (see the general rules). An adjacent `<label>` is not sufficient unless it contains the control or has a matching `for` / `htmlFor` association. A `<fieldset><legend>` or named `role="group"` / `role="radiogroup"` supplies group context but does **not** name each descendant control. A dynamic `for` / `htmlFor` and its control's `id` bound to the **same expression** are matched, even when the literal value cannot be resolved at review time (see the general rules). Only flag when none of the valid control-level naming mechanisms supplies the name.
|
|
65
|
+
|
|
64
66
|
Rules to follow:
|
|
65
67
|
|
|
66
68
|
- Find all violations of SC 1.3.1 (iii) 'Form Labels' in the provided HTML and JS files
|
|
@@ -72,7 +74,5 @@ Rules to follow:
|
|
|
72
74
|
- Keep issues concise, avoid duplicated issues or unnecessary or non-applicable problems.
|
|
73
75
|
- Assume that any imported functionality works as expected and was already analyzed.
|
|
74
76
|
- Components do not supplement or provide global functionalities.
|
|
75
|
-
-
|
|
76
|
-
-
|
|
77
|
-
- Prefer a real `<button>` for actions; for a link, `href="#"` with `event.preventDefault()` (the canonical SLDS pattern). Don't recommend `href="javascript:void(0)"` as a first-line remediation — it's a no-op-anchor anti-pattern. It is acceptable only as a last resort when moving `<a>` → `<button>` is genuinely impossible, and even then only when paired with the full set of attributes that make the anchor behave as an accessible button (`role="button"`, keyboard activation, etc.) — `void(0)` on its own is an incomplete fix. Don't flag existing `javascript:void(0)` as a violation.
|
|
78
|
-
- ARIA attribute spelling depends on the element type. On a **plain HTML element** (`div`, `span`, `button`, `input`, `a`, `img`, `iframe`, …) the only valid spelling is the W3C form `aria-labelledby` / `aria-describedby`; the hyphen-split `aria-labelled-by` / `aria-described-by` there **is** a real bug — keep flagging it. But on an **LWC component tag** (`lightning-*` or a custom `ns-name` element), the hyphen-split form is the kebab-case binding of the component's `@api ariaLabelledBy` / `ariaDescribedBy` property (each capital letter maps to `-` + lowercase), and LWC reflects it to the spec-correct `aria-labelledby` in the rendered DOM. Do **not** flag `aria-labelled-by` on a component tag as a misspelling, and do not claim it "breaks the accessible name computation" — you cannot determine that from the attribute name alone, because both `aria-labelled-by` (via `@api` property kebab-casing) and `aria-labelledby` (via LWC's ARIA reflection) can wire to the same property depending on the component. Treat a hyphen-split ARIA attribute on a component tag as a valid binding, not a violation.
|
|
77
|
+
- ARIA attribute spelling depends on the element type. Plain HTML elements use `aria-labelledby` and `aria-describedby`; `aria-labelled-by` or `aria-described-by` is invalid there. On an LWC component tag, however, the hyphen-split spelling can be the kebab-case binding for an `@api ariaLabelledBy` or `ariaDescribedBy` property. Do not report the component spelling as a broken association without evidence that the component fails to forward it.
|
|
78
|
+
- Attach label associations to the actual focusable control. A `for`, `htmlFor`, or ARIA relationship on a non-focusable wrapper around a composite editor does not label the internal control unless the wrapper forwards it. Recommend extending the control to accept or forward the association, or using its supported labeling prop.
|
package/skills/experience-accessibility-validate/references/reviewers/sc-1-3-1-iv-regions.md
CHANGED
|
@@ -20,7 +20,3 @@ Rules to follow:
|
|
|
20
20
|
- Keep issues concise, avoid duplicated issues or unnecessary or non-applicable problems.
|
|
21
21
|
- Assume that any imported functionality works as expected and was already analyzed.
|
|
22
22
|
- Components do not supplement or provide global functionalities.
|
|
23
|
-
- Lightning base components (`lightning-input`, `lightning-combobox`, `lightning-textarea`, `lightning-icon`, etc.) provide their own accessible labeling, ARIA, and error handling in shadow DOM via their dedicated attributes (`label`, `alternative-text`, field-level validation). When such a component is given a `label` attribute it is already programmatically labeled — even with `variant="label-hidden"`, which hides the label visually but keeps it for assistive technology. Do **not** flag a sibling/wrapper `<label>` or `<span>` for a missing `for`/`id` when the actual control is a self-labeling Lightning component, and do not treat a visible heading as if it were the control's only label. This also covers navigation and icon base components (`lightning-vertical-navigation-item`, `lightning-vertical-navigation-item-icon`, `lightning-button-icon`, etc.): when a `label` (or `alternative-text`) attribute is supplied, the base component renders it as the visible link/control text **and** exposes it as the accessible name, and any `icon-name` is decorative — do not emit a 4.1.2 "verify the label is associated with the icon" warning, even a hedged one. The presence of the `label` attribute is the association.
|
|
24
|
-
- Resolve template bindings before judging them. A template expression like `{someValue}` refers to a property or getter on the component's controller (`.js`/`.ts`) — including `@api` properties and `get someValue()` getters — not to a module-level imported constant (which LWC templates cannot bind to). Check the controller for the binding's definition before concluding a value is undefined, empty, or missing. When reviewing a diff, verify which side is the corrected code; do not assume the change introduced the problem.
|
|
25
|
-
- Prefer a real `<button>` for actions; for a link, `href="#"` with `event.preventDefault()` (the canonical SLDS pattern). Don't recommend `href="javascript:void(0)"` as a first-line remediation — it's a no-op-anchor anti-pattern. It is acceptable only as a last resort when moving `<a>` → `<button>` is genuinely impossible, and even then only when paired with the full set of attributes that make the anchor behave as an accessible button (`role="button"`, keyboard activation, etc.) — `void(0)` on its own is an incomplete fix. Don't flag existing `javascript:void(0)` as a violation.
|
|
26
|
-
- ARIA attribute spelling depends on the element type. On a **plain HTML element** (`div`, `span`, `button`, `input`, `a`, `img`, `iframe`, …) the only valid spelling is the W3C form `aria-labelledby` / `aria-describedby`; the hyphen-split `aria-labelled-by` / `aria-described-by` there **is** a real bug — keep flagging it. But on an **LWC component tag** (`lightning-*` or a custom `ns-name` element), the hyphen-split form is the kebab-case binding of the component's `@api ariaLabelledBy` / `ariaDescribedBy` property (each capital letter maps to `-` + lowercase), and LWC reflects it to the spec-correct `aria-labelledby` in the rendered DOM. Do **not** flag `aria-labelled-by` on a component tag as a misspelling, and do not claim it "breaks the accessible name computation" — you cannot determine that from the attribute name alone, because both `aria-labelled-by` (via `@api` property kebab-casing) and `aria-labelledby` (via LWC's ARIA reflection) can wire to the same property depending on the component. Treat a hyphen-split ARIA attribute on a component tag as a valid binding, not a violation.
|
|
@@ -52,6 +52,8 @@ For each selection list:
|
|
|
52
52
|
|
|
53
53
|
- Check that links that are grouped and represent a section of page, are enclosed in a `nav` element or similar semantics.
|
|
54
54
|
|
|
55
|
+
Before flagging a group as unlabeled or improperly structured, resolve how the group is named. A `role="group"` / `role="radiogroup"` container with `aria-label` or `aria-labelledby` is a **valid and sufficient** grouping-and-naming technique (ARIA17) — it does **not** additionally require a `<fieldset>` / `<legend>`. Treat `<div role="group" aria-label={...}>` (including a dynamic `aria-label` / `aria-labelledby` expression such as `aria-label={section.title}`) as a properly labeled group; do **not** flag it for a missing `<legend>`, a missing `aria-label`, or a missing group name when an `aria-label` / `aria-labelledby` is present. Only flag a group that has **neither** a `fieldset` / `legend` **nor** a `role="group"` / `role="radiogroup"` carrying an accessible name.
|
|
56
|
+
|
|
55
57
|
_Rules to follow_:
|
|
56
58
|
|
|
57
59
|
- Require code to reinforce structure, relationships and information conveyed through presentation for groups of related elements, per this WCAG 2.2 SC 1.3.1 'Info and Relationships - Groups only' success criterion, in the provided HTML and JS files.
|
|
@@ -60,7 +62,3 @@ _Rules to follow_:
|
|
|
60
62
|
- Keep issues concise, avoid duplicated issues or unnecessary or non-applicable problems.
|
|
61
63
|
- Assume that any imported functionality works as expected and was already analyzed.
|
|
62
64
|
- Components do not supplement or provide global functionalities.
|
|
63
|
-
- Lightning base components (`lightning-input`, `lightning-combobox`, `lightning-textarea`, `lightning-icon`, etc.) provide their own accessible labeling, ARIA, and error handling in shadow DOM via their dedicated attributes (`label`, `alternative-text`, field-level validation). When such a component is given a `label` attribute it is already programmatically labeled — even with `variant="label-hidden"`, which hides the label visually but keeps it for assistive technology. Do **not** flag a sibling/wrapper `<label>` or `<span>` for a missing `for`/`id` when the actual control is a self-labeling Lightning component, and do not treat a visible heading as if it were the control's only label. This also covers navigation and icon base components (`lightning-vertical-navigation-item`, `lightning-vertical-navigation-item-icon`, `lightning-button-icon`, etc.): when a `label` (or `alternative-text`) attribute is supplied, the base component renders it as the visible link/control text **and** exposes it as the accessible name, and any `icon-name` is decorative — do not emit a 4.1.2 "verify the label is associated with the icon" warning, even a hedged one. The presence of the `label` attribute is the association.
|
|
64
|
-
- Resolve template bindings before judging them. A template expression like `{someValue}` refers to a property or getter on the component's controller (`.js`/`.ts`) — including `@api` properties and `get someValue()` getters — not to a module-level imported constant (which LWC templates cannot bind to). Check the controller for the binding's definition before concluding a value is undefined, empty, or missing. When reviewing a diff, verify which side is the corrected code; do not assume the change introduced the problem.
|
|
65
|
-
- Prefer a real `<button>` for actions; for a link, `href="#"` with `event.preventDefault()` (the canonical SLDS pattern). Don't recommend `href="javascript:void(0)"` as a first-line remediation — it's a no-op-anchor anti-pattern. It is acceptable only as a last resort when moving `<a>` → `<button>` is genuinely impossible, and even then only when paired with the full set of attributes that make the anchor behave as an accessible button (`role="button"`, keyboard activation, etc.) — `void(0)` on its own is an incomplete fix. Don't flag existing `javascript:void(0)` as a violation.
|
|
66
|
-
- ARIA attribute spelling depends on the element type. On a **plain HTML element** (`div`, `span`, `button`, `input`, `a`, `img`, `iframe`, …) the only valid spelling is the W3C form `aria-labelledby` / `aria-describedby`; the hyphen-split `aria-labelled-by` / `aria-described-by` there **is** a real bug — keep flagging it. But on an **LWC component tag** (`lightning-*` or a custom `ns-name` element), the hyphen-split form is the kebab-case binding of the component's `@api ariaLabelledBy` / `ariaDescribedBy` property (each capital letter maps to `-` + lowercase), and LWC reflects it to the spec-correct `aria-labelledby` in the rendered DOM. Do **not** flag `aria-labelled-by` on a component tag as a misspelling, and do not claim it "breaks the accessible name computation" — you cannot determine that from the attribute name alone, because both `aria-labelled-by` (via `@api` property kebab-casing) and `aria-labelledby` (via LWC's ARIA reflection) can wire to the same property depending on the component. Treat a hyphen-split ARIA attribute on a component tag as a valid binding, not a violation.
|
package/skills/experience-accessibility-validate/references/reviewers/sc-1-3-5-identify-input.md
CHANGED
|
@@ -64,7 +64,3 @@ Rules to follow:
|
|
|
64
64
|
- Keep issues concise, avoid duplicated issues or unnecessary or non-applicable problems.
|
|
65
65
|
- Assume that any imported functionality works as expected and was already analyzed.
|
|
66
66
|
- Components do not supplement or provide global functionalities.
|
|
67
|
-
- Lightning base components (`lightning-input`, `lightning-combobox`, `lightning-textarea`, `lightning-icon`, etc.) provide their own accessible labeling, ARIA, and error handling in shadow DOM via their dedicated attributes (`label`, `alternative-text`, field-level validation). When such a component is given a `label` attribute it is already programmatically labeled — even with `variant="label-hidden"`, which hides the label visually but keeps it for assistive technology. Do **not** flag a sibling/wrapper `<label>` or `<span>` for a missing `for`/`id` when the actual control is a self-labeling Lightning component, and do not treat a visible heading as if it were the control's only label. This also covers navigation and icon base components (`lightning-vertical-navigation-item`, `lightning-vertical-navigation-item-icon`, `lightning-button-icon`, etc.): when a `label` (or `alternative-text`) attribute is supplied, the base component renders it as the visible link/control text **and** exposes it as the accessible name, and any `icon-name` is decorative — do not emit a 4.1.2 "verify the label is associated with the icon" warning, even a hedged one. The presence of the `label` attribute is the association.
|
|
68
|
-
- Resolve template bindings before judging them. A template expression like `{someValue}` refers to a property or getter on the component's controller (`.js`/`.ts`) — including `@api` properties and `get someValue()` getters — not to a module-level imported constant (which LWC templates cannot bind to). Check the controller for the binding's definition before concluding a value is undefined, empty, or missing. When reviewing a diff, verify which side is the corrected code; do not assume the change introduced the problem.
|
|
69
|
-
- Prefer a real `<button>` for actions; for a link, `href="#"` with `event.preventDefault()` (the canonical SLDS pattern). Don't recommend `href="javascript:void(0)"` as a first-line remediation — it's a no-op-anchor anti-pattern. It is acceptable only as a last resort when moving `<a>` → `<button>` is genuinely impossible, and even then only when paired with the full set of attributes that make the anchor behave as an accessible button (`role="button"`, keyboard activation, etc.) — `void(0)` on its own is an incomplete fix. Don't flag existing `javascript:void(0)` as a violation.
|
|
70
|
-
- ARIA attribute spelling depends on the element type. On a **plain HTML element** (`div`, `span`, `button`, `input`, `a`, `img`, `iframe`, …) the only valid spelling is the W3C form `aria-labelledby` / `aria-describedby`; the hyphen-split `aria-labelled-by` / `aria-described-by` there **is** a real bug — keep flagging it. But on an **LWC component tag** (`lightning-*` or a custom `ns-name` element), the hyphen-split form is the kebab-case binding of the component's `@api ariaLabelledBy` / `ariaDescribedBy` property (each capital letter maps to `-` + lowercase), and LWC reflects it to the spec-correct `aria-labelledby` in the rendered DOM. Do **not** flag `aria-labelled-by` on a component tag as a misspelling, and do not claim it "breaks the accessible name computation" — you cannot determine that from the attribute name alone, because both `aria-labelled-by` (via `@api` property kebab-casing) and `aria-labelledby` (via LWC's ARIA reflection) can wire to the same property depending on the component. Treat a hyphen-split ARIA attribute on a component tag as a valid binding, not a violation.
|
|
@@ -11,16 +11,10 @@ This reviewer focuses on ensuring enough contrast between text and its backgroun
|
|
|
11
11
|
1. Identify all visible text elements (e.g., in tags like `<h1>`, `<div>`, `<p>`, `<label>`, `<button>`, etc.).
|
|
12
12
|
2. Determine the **color** (foreground) and **background color** (background) for each text element.
|
|
13
13
|
3. Determine the **font size** and **weight** to classify the text as Standard or Large-Scale.
|
|
14
|
-
4.
|
|
14
|
+
4. Calculate the contrast ratio using the WCAG formula: $(L1 + 0.05) / (L2 + 0.05)$, where L1 is the relative luminance of the lighter color, and L2 is the relative luminance of the darker color.
|
|
15
|
+
5. Check if the calculated ratio meets the required threshold (4.5:1 or 3:1).
|
|
15
16
|
|
|
16
|
-
|
|
17
|
-
python3 scripts/contrast-ratio.py FOREGROUND BACKGROUND [--large]
|
|
18
|
-
```
|
|
19
|
-
|
|
20
|
-
Pass the resolved foreground and background colors (`#RGB`, `#RRGGBB`, `rgb()`, or `rgba()`); add `--large` when the text is large-scale (≥24px, or ≥18.66px bold). The script alpha-composites a translucent *foreground* over the background, applies the exact WCAG formula $(L1 + 0.05) / (L2 + 0.05)$, and prints the ratio plus a `PASS`/`FAIL` verdict for both thresholds (exit code `0` = meets the applicable threshold, `1` = below it, `2` = parse error). The **background must be opaque** — a translucent `rgba()` background is rejected (exit code `2`) because its rendered color depends on the unknown layer beneath it; resolve the effective opaque background first and pass that. Use `--json` for a machine-readable object. The script's verdict is authoritative; use it rather than an estimate.
|
|
21
|
-
5. Treat the script's verdict against the required threshold (4.5:1 standard, 3:1 large) as the check result.
|
|
22
|
-
|
|
23
|
-
> **Do not estimate luminance by hand.** Mentally approximating relative luminance is unreliable — it has produced false positives and even different ratios for the _same_ color. Run `scripts/contrast-ratio.py` for the exact value. The verified reference below (sRGB gray `#NNNNNN` on `#FFFFFF`) is a quick sanity check for the common grayscale-text-on-white case, not a substitute for the script:
|
|
17
|
+
> **Do not estimate luminance by hand.** Mentally approximating relative luminance is unreliable — it has produced false positives and even different ratios for the _same_ color. Compute the WCAG formula exactly, or for the common grayscale-text-on-white case use this verified reference (sRGB gray `#NNNNNN` on `#FFFFFF`):
|
|
24
18
|
>
|
|
25
19
|
> | Gray | Ratio | Standard (4.5:1) | Large (3:1) |
|
|
26
20
|
> | --------- | ----- | ---------------- | --------------- |
|
|
@@ -104,12 +98,8 @@ Rules to follow:
|
|
|
104
98
|
- Flag color combinations that result in a contrast ratio **below 4.5:1 for Standard Text**.
|
|
105
99
|
- Flag color combinations that result in a contrast ratio **below 3:1 for Large-Scale Text**.
|
|
106
100
|
- **Ignore** text clearly marked as decorative, part of a logo, or permanently disabled/inactive components.
|
|
107
|
-
- Do not assume or estimate the contrast ratio — compute it
|
|
101
|
+
- Do not assume or estimate the contrast ratio — compute it exactly, or use the grayscale-on-white reference table above. When the exact ratio is uncertain (gradients, alpha compositing, images behind text, unknown background), do not flag.
|
|
108
102
|
- For each issue found, provide a separate, detailed report.
|
|
109
103
|
- Keep issues concise, avoid duplicated issues or unnecessary or non-applicable problems.
|
|
110
104
|
- Assume that any imported functionality works as expected and was already analyzed.
|
|
111
105
|
- Components do not supplement or provide global functionalities.
|
|
112
|
-
- Lightning base components (`lightning-input`, `lightning-combobox`, `lightning-textarea`, `lightning-icon`, etc.) provide their own accessible labeling, ARIA, and error handling in shadow DOM via their dedicated attributes (`label`, `alternative-text`, field-level validation). When such a component is given a `label` attribute it is already programmatically labeled — even with `variant="label-hidden"`, which hides the label visually but keeps it for assistive technology. Do **not** flag a sibling/wrapper `<label>` or `<span>` for a missing `for`/`id` when the actual control is a self-labeling Lightning component, and do not treat a visible heading as if it were the control's only label. This also covers navigation and icon base components (`lightning-vertical-navigation-item`, `lightning-vertical-navigation-item-icon`, `lightning-button-icon`, etc.): when a `label` (or `alternative-text`) attribute is supplied, the base component renders it as the visible link/control text **and** exposes it as the accessible name, and any `icon-name` is decorative — do not emit a 4.1.2 "verify the label is associated with the icon" warning, even a hedged one. The presence of the `label` attribute is the association.
|
|
113
|
-
- Resolve template bindings before judging them. A template expression like `{someValue}` refers to a property or getter on the component's controller (`.js`/`.ts`) — including `@api` properties and `get someValue()` getters — not to a module-level imported constant (which LWC templates cannot bind to). Check the controller for the binding's definition before concluding a value is undefined, empty, or missing. When reviewing a diff, verify which side is the corrected code; do not assume the change introduced the problem.
|
|
114
|
-
- Prefer a real `<button>` for actions; for a link, `href="#"` with `event.preventDefault()` (the canonical SLDS pattern). Don't recommend `href="javascript:void(0)"` as a first-line remediation — it's a no-op-anchor anti-pattern. It is acceptable only as a last resort when moving `<a>` → `<button>` is genuinely impossible, and even then only when paired with the full set of attributes that make the anchor behave as an accessible button (`role="button"`, keyboard activation, etc.) — `void(0)` on its own is an incomplete fix. Don't flag existing `javascript:void(0)` as a violation.
|
|
115
|
-
- ARIA attribute spelling depends on the element type. On a **plain HTML element** (`div`, `span`, `button`, `input`, `a`, `img`, `iframe`, …) the only valid spelling is the W3C form `aria-labelledby` / `aria-describedby`; the hyphen-split `aria-labelled-by` / `aria-described-by` there **is** a real bug — keep flagging it. But on an **LWC component tag** (`lightning-*` or a custom `ns-name` element), the hyphen-split form is the kebab-case binding of the component's `@api ariaLabelledBy` / `ariaDescribedBy` property (each capital letter maps to `-` + lowercase), and LWC reflects it to the spec-correct `aria-labelledby` in the rendered DOM. Do **not** flag `aria-labelled-by` on a component tag as a misspelling, and do not claim it "breaks the accessible name computation" — you cannot determine that from the attribute name alone, because both `aria-labelled-by` (via `@api` property kebab-casing) and `aria-labelledby` (via LWC's ARIA reflection) can wire to the same property depending on the component. Treat a hyphen-split ARIA attribute on a component tag as a valid binding, not a violation.
|
|
@@ -6,7 +6,14 @@ All functionality of the content is operable through a keyboard interface withou
|
|
|
6
6
|
|
|
7
7
|
Analyze the given file using the following framework:
|
|
8
8
|
|
|
9
|
-
Review the provided HTML and JS files for accessibility violations per WCAG 2.2 SC 2.1.1, 'Keyboard'.
|
|
9
|
+
Review the provided HTML and JS files for accessibility violations per WCAG 2.2 SC 2.1.1, 'Keyboard'.
|
|
10
|
+
|
|
11
|
+
**Scope — this criterion applies to _interactive_ elements only; native controls pass.** A violation requires an element that is operable by mouse/pointer (a click/pointer/mouse handler, or a custom control role) but is **not** equivalently operable by keyboard. Before flagging anything, apply these two gates — an element that clears them **passes** and must not be flagged:
|
|
12
|
+
|
|
13
|
+
- **Native interactive HTML is keyboard-operable for free.** `<a href>`, `<button>`, `<input>` (including `type="checkbox"`, `type="radio"`, `type="submit"`, etc.), `<select>`, `<textarea>`, and `<summary>` receive focus and handle keyboard activation by default. Do **not** flag a native control for a missing `tabindex`, missing keyboard handler, or keyboard inoperability unless its native behavior has been explicitly overridden or suppressed.
|
|
14
|
+
- **Non-interactive elements are out of scope.** A `<div>`, `<span>`, `<li>`, `<p>`, etc. that has **no** click/pointer/key handler and no interactive role is not a control — it does not need `tabindex` and must not be flagged. Only a non-semantic element that _carries a click/pointer handler_ (making it a de-facto control) needs `tabindex="0"` plus a keyboard handler.
|
|
15
|
+
|
|
16
|
+
For an element that is in scope (an interactive control), ensure it exposes via keyboard all interactivity achievable via mouse; if it does not, flag it as a violation. The exception is when the underlying functionality requires path-based movement.
|
|
10
17
|
|
|
11
18
|
Interactive controls must be accessible when using the keyboard alone, and when using a keyboard along with assistive technology, such as a screen reader, without requiring specific timings for keystrokes. The exception to this is when the underlying functionality requires path-based movement.
|
|
12
19
|
|
|
@@ -41,7 +48,4 @@ Rules to follow:
|
|
|
41
48
|
- Keep issues concise, avoid duplicated issues or unnecessary or non-applicable problems.
|
|
42
49
|
- Assume that any imported functionality works as expected and was already analyzed.
|
|
43
50
|
- Components do not supplement or provide global functionalities.
|
|
44
|
-
-
|
|
45
|
-
- Resolve template bindings before judging them. A template expression like `{someValue}` refers to a property or getter on the component's controller (`.js`/`.ts`) — including `@api` properties and `get someValue()` getters — not to a module-level imported constant (which LWC templates cannot bind to). Check the controller for the binding's definition before concluding a value is undefined, empty, or missing. When reviewing a diff, verify which side is the corrected code; do not assume the change introduced the problem.
|
|
46
|
-
- Prefer a real `<button>` for actions; for a link, `href="#"` with `event.preventDefault()` (the canonical SLDS pattern). Don't recommend `href="javascript:void(0)"` as a first-line remediation — it's a no-op-anchor anti-pattern. It is acceptable only as a last resort when moving `<a>` → `<button>` is genuinely impossible, and even then only when paired with the full set of attributes that make the anchor behave as an accessible button (`role="button"`, keyboard activation, etc.) — `void(0)` on its own is an incomplete fix. Don't flag existing `javascript:void(0)` as a violation.
|
|
47
|
-
- ARIA attribute spelling depends on the element type. On a **plain HTML element** (`div`, `span`, `button`, `input`, `a`, `img`, `iframe`, …) the only valid spelling is the W3C form `aria-labelledby` / `aria-describedby`; the hyphen-split `aria-labelled-by` / `aria-described-by` there **is** a real bug — keep flagging it. But on an **LWC component tag** (`lightning-*` or a custom `ns-name` element), the hyphen-split form is the kebab-case binding of the component's `@api ariaLabelledBy` / `ariaDescribedBy` property (each capital letter maps to `-` + lowercase), and LWC reflects it to the spec-correct `aria-labelledby` in the rendered DOM. Do **not** flag `aria-labelled-by` on a component tag as a misspelling, and do not claim it "breaks the accessible name computation" — you cannot determine that from the attribute name alone, because both `aria-labelled-by` (via `@api` property kebab-casing) and `aria-labelledby` (via LWC's ARIA reflection) can wire to the same property depending on the component. Treat a hyphen-split ARIA attribute on a component tag as a valid binding, not a violation.
|
|
51
|
+
- Prefer a real `<button>` for actions. If an anchor must act as a control, use the canonical SLDS `href="#"` plus `event.preventDefault()` pattern and supply the complete button-like semantics and keyboard behavior. Do not recommend `href="javascript:void(0)"` as a first-line fix, and do not flag that value alone as a keyboard violation.
|
package/skills/experience-accessibility-validate/references/reviewers/sc-2-4-4-link-purpose.md
CHANGED
|
@@ -33,7 +33,4 @@ Rules to follow:
|
|
|
33
33
|
- Keep issues concise, avoid duplicated issues or unnecessary or non-applicable problems.
|
|
34
34
|
- Assume that any imported functionality works as expected and was already analyzed.
|
|
35
35
|
- Components do not supplement or provide global functionalities.
|
|
36
|
-
-
|
|
37
|
-
- Resolve template bindings before judging them. A template expression like `{someValue}` refers to a property or getter on the component's controller (`.js`/`.ts`) — including `@api` properties and `get someValue()` getters — not to a module-level imported constant (which LWC templates cannot bind to). Check the controller for the binding's definition before concluding a value is undefined, empty, or missing. When reviewing a diff, verify which side is the corrected code; do not assume the change introduced the problem.
|
|
38
|
-
- Prefer a real `<button>` for actions; for a link, `href="#"` with `event.preventDefault()` (the canonical SLDS pattern). Don't recommend `href="javascript:void(0)"` as a first-line remediation — it's a no-op-anchor anti-pattern. It is acceptable only as a last resort when moving `<a>` → `<button>` is genuinely impossible, and even then only when paired with the full set of attributes that make the anchor behave as an accessible button (`role="button"`, keyboard activation, etc.) — `void(0)` on its own is an incomplete fix. Don't flag existing `javascript:void(0)` as a violation.
|
|
39
|
-
- ARIA attribute spelling depends on the element type. On a **plain HTML element** (`div`, `span`, `button`, `input`, `a`, `img`, `iframe`, …) the only valid spelling is the W3C form `aria-labelledby` / `aria-describedby`; the hyphen-split `aria-labelled-by` / `aria-described-by` there **is** a real bug — keep flagging it. But on an **LWC component tag** (`lightning-*` or a custom `ns-name` element), the hyphen-split form is the kebab-case binding of the component's `@api ariaLabelledBy` / `ariaDescribedBy` property (each capital letter maps to `-` + lowercase), and LWC reflects it to the spec-correct `aria-labelledby` in the rendered DOM. Do **not** flag `aria-labelled-by` on a component tag as a misspelling, and do not claim it "breaks the accessible name computation" — you cannot determine that from the attribute name alone, because both `aria-labelled-by` (via `@api` property kebab-casing) and `aria-labelledby` (via LWC's ARIA reflection) can wire to the same property depending on the component. Treat a hyphen-split ARIA attribute on a component tag as a valid binding, not a violation.
|
|
36
|
+
- Judge whether link text describes its destination, not whether the destination opens in a new window. `target="_blank"` and click handlers that call `window.open(...)` are not SC 2.4.4 failures. If new-tab behavior is mentioned, describe indicating it as an optional enhancement rather than a warning or violation.
|
package/skills/experience-accessibility-validate/references/reviewers/sc-2-4-6-headings-labels.md
CHANGED
|
@@ -44,7 +44,3 @@ Rules to follow:
|
|
|
44
44
|
- Keep issues concise, avoid duplicated issues or unnecessary or non-applicable problems.
|
|
45
45
|
- Assume that any imported functionality works as expected and was already analyzed.
|
|
46
46
|
- Components do not supplement or provide global functionalities.
|
|
47
|
-
- Lightning base components (`lightning-input`, `lightning-combobox`, `lightning-textarea`, `lightning-icon`, etc.) provide their own accessible labeling, ARIA, and error handling in shadow DOM via their dedicated attributes (`label`, `alternative-text`, field-level validation). When such a component is given a `label` attribute it is already programmatically labeled — even with `variant="label-hidden"`, which hides the label visually but keeps it for assistive technology. Do **not** flag a sibling/wrapper `<label>` or `<span>` for a missing `for`/`id` when the actual control is a self-labeling Lightning component, and do not treat a visible heading as if it were the control's only label. This also covers navigation and icon base components (`lightning-vertical-navigation-item`, `lightning-vertical-navigation-item-icon`, `lightning-button-icon`, etc.): when a `label` (or `alternative-text`) attribute is supplied, the base component renders it as the visible link/control text **and** exposes it as the accessible name, and any `icon-name` is decorative — do not emit a 4.1.2 "verify the label is associated with the icon" warning, even a hedged one. The presence of the `label` attribute is the association.
|
|
48
|
-
- Resolve template bindings before judging them. A template expression like `{someValue}` refers to a property or getter on the component's controller (`.js`/`.ts`) — including `@api` properties and `get someValue()` getters — not to a module-level imported constant (which LWC templates cannot bind to). Check the controller for the binding's definition before concluding a value is undefined, empty, or missing. When reviewing a diff, verify which side is the corrected code; do not assume the change introduced the problem.
|
|
49
|
-
- Prefer a real `<button>` for actions; for a link, `href="#"` with `event.preventDefault()` (the canonical SLDS pattern). Don't recommend `href="javascript:void(0)"` as a first-line remediation — it's a no-op-anchor anti-pattern. It is acceptable only as a last resort when moving `<a>` → `<button>` is genuinely impossible, and even then only when paired with the full set of attributes that make the anchor behave as an accessible button (`role="button"`, keyboard activation, etc.) — `void(0)` on its own is an incomplete fix. Don't flag existing `javascript:void(0)` as a violation.
|
|
50
|
-
- ARIA attribute spelling depends on the element type. On a **plain HTML element** (`div`, `span`, `button`, `input`, `a`, `img`, `iframe`, …) the only valid spelling is the W3C form `aria-labelledby` / `aria-describedby`; the hyphen-split `aria-labelled-by` / `aria-described-by` there **is** a real bug — keep flagging it. But on an **LWC component tag** (`lightning-*` or a custom `ns-name` element), the hyphen-split form is the kebab-case binding of the component's `@api ariaLabelledBy` / `ariaDescribedBy` property (each capital letter maps to `-` + lowercase), and LWC reflects it to the spec-correct `aria-labelledby` in the rendered DOM. Do **not** flag `aria-labelled-by` on a component tag as a misspelling, and do not claim it "breaks the accessible name computation" — you cannot determine that from the attribute name alone, because both `aria-labelled-by` (via `@api` property kebab-casing) and `aria-labelledby` (via LWC's ARIA reflection) can wire to the same property depending on the component. Treat a hyphen-split ARIA attribute on a component tag as a valid binding, not a violation.
|
package/skills/experience-accessibility-validate/references/reviewers/sc-2-5-1-pointer-gestures.md
CHANGED
|
@@ -48,7 +48,3 @@ Rules to follow:
|
|
|
48
48
|
- Keep issues concise, avoid duplicated issues or unnecessary or non-applicable problems.
|
|
49
49
|
- Assume that any imported functionality works as expected and was already analyzed.
|
|
50
50
|
- Components do not supplement or provide global functionalities.
|
|
51
|
-
- Lightning base components (`lightning-input`, `lightning-combobox`, `lightning-textarea`, `lightning-icon`, etc.) provide their own accessible labeling, ARIA, and error handling in shadow DOM via their dedicated attributes (`label`, `alternative-text`, field-level validation). When such a component is given a `label` attribute it is already programmatically labeled — even with `variant="label-hidden"`, which hides the label visually but keeps it for assistive technology. Do **not** flag a sibling/wrapper `<label>` or `<span>` for a missing `for`/`id` when the actual control is a self-labeling Lightning component, and do not treat a visible heading as if it were the control's only label. This also covers navigation and icon base components (`lightning-vertical-navigation-item`, `lightning-vertical-navigation-item-icon`, `lightning-button-icon`, etc.): when a `label` (or `alternative-text`) attribute is supplied, the base component renders it as the visible link/control text **and** exposes it as the accessible name, and any `icon-name` is decorative — do not emit a 4.1.2 "verify the label is associated with the icon" warning, even a hedged one. The presence of the `label` attribute is the association.
|
|
52
|
-
- Resolve template bindings before judging them. A template expression like `{someValue}` refers to a property or getter on the component's controller (`.js`/`.ts`) — including `@api` properties and `get someValue()` getters — not to a module-level imported constant (which LWC templates cannot bind to). Check the controller for the binding's definition before concluding a value is undefined, empty, or missing. When reviewing a diff, verify which side is the corrected code; do not assume the change introduced the problem.
|
|
53
|
-
- Prefer a real `<button>` for actions; for a link, `href="#"` with `event.preventDefault()` (the canonical SLDS pattern). Don't recommend `href="javascript:void(0)"` as a first-line remediation — it's a no-op-anchor anti-pattern. It is acceptable only as a last resort when moving `<a>` → `<button>` is genuinely impossible, and even then only when paired with the full set of attributes that make the anchor behave as an accessible button (`role="button"`, keyboard activation, etc.) — `void(0)` on its own is an incomplete fix. Don't flag existing `javascript:void(0)` as a violation.
|
|
54
|
-
- ARIA attribute spelling depends on the element type. On a **plain HTML element** (`div`, `span`, `button`, `input`, `a`, `img`, `iframe`, …) the only valid spelling is the W3C form `aria-labelledby` / `aria-describedby`; the hyphen-split `aria-labelled-by` / `aria-described-by` there **is** a real bug — keep flagging it. But on an **LWC component tag** (`lightning-*` or a custom `ns-name` element), the hyphen-split form is the kebab-case binding of the component's `@api ariaLabelledBy` / `ariaDescribedBy` property (each capital letter maps to `-` + lowercase), and LWC reflects it to the spec-correct `aria-labelledby` in the rendered DOM. Do **not** flag `aria-labelled-by` on a component tag as a misspelling, and do not claim it "breaks the accessible name computation" — you cannot determine that from the attribute name alone, because both `aria-labelled-by` (via `@api` property kebab-casing) and `aria-labelledby` (via LWC's ARIA reflection) can wire to the same property depending on the component. Treat a hyphen-split ARIA attribute on a component tag as a valid binding, not a violation.
|
|
@@ -43,7 +43,3 @@ Rules to follow:
|
|
|
43
43
|
- Keep issues concise, avoid duplicated issues or unnecessary or non-applicable problems.
|
|
44
44
|
- Assume that any imported functionality works as expected and was already analyzed.
|
|
45
45
|
- Components do not supplement or provide global functionalities.
|
|
46
|
-
- Lightning base components (`lightning-input`, `lightning-combobox`, `lightning-textarea`, `lightning-icon`, etc.) provide their own accessible labeling, ARIA, and error handling in shadow DOM via their dedicated attributes (`label`, `alternative-text`, field-level validation). When such a component is given a `label` attribute it is already programmatically labeled — even with `variant="label-hidden"`, which hides the label visually but keeps it for assistive technology. Do **not** flag a sibling/wrapper `<label>` or `<span>` for a missing `for`/`id` when the actual control is a self-labeling Lightning component, and do not treat a visible heading as if it were the control's only label. This also covers navigation and icon base components (`lightning-vertical-navigation-item`, `lightning-vertical-navigation-item-icon`, `lightning-button-icon`, etc.): when a `label` (or `alternative-text`) attribute is supplied, the base component renders it as the visible link/control text **and** exposes it as the accessible name, and any `icon-name` is decorative — do not emit a 4.1.2 "verify the label is associated with the icon" warning, even a hedged one. The presence of the `label` attribute is the association.
|
|
47
|
-
- Resolve template bindings before judging them. A template expression like `{someValue}` refers to a property or getter on the component's controller (`.js`/`.ts`) — including `@api` properties and `get someValue()` getters — not to a module-level imported constant (which LWC templates cannot bind to). Check the controller for the binding's definition before concluding a value is undefined, empty, or missing. When reviewing a diff, verify which side is the corrected code; do not assume the change introduced the problem.
|
|
48
|
-
- Prefer a real `<button>` for actions; for a link, `href="#"` with `event.preventDefault()` (the canonical SLDS pattern). Don't recommend `href="javascript:void(0)"` as a first-line remediation — it's a no-op-anchor anti-pattern. It is acceptable only as a last resort when moving `<a>` → `<button>` is genuinely impossible, and even then only when paired with the full set of attributes that make the anchor behave as an accessible button (`role="button"`, keyboard activation, etc.) — `void(0)` on its own is an incomplete fix. Don't flag existing `javascript:void(0)` as a violation.
|
|
49
|
-
- ARIA attribute spelling depends on the element type. On a **plain HTML element** (`div`, `span`, `button`, `input`, `a`, `img`, `iframe`, …) the only valid spelling is the W3C form `aria-labelledby` / `aria-describedby`; the hyphen-split `aria-labelled-by` / `aria-described-by` there **is** a real bug — keep flagging it. But on an **LWC component tag** (`lightning-*` or a custom `ns-name` element), the hyphen-split form is the kebab-case binding of the component's `@api ariaLabelledBy` / `ariaDescribedBy` property (each capital letter maps to `-` + lowercase), and LWC reflects it to the spec-correct `aria-labelledby` in the rendered DOM. Do **not** flag `aria-labelled-by` on a component tag as a misspelling, and do not claim it "breaks the accessible name computation" — you cannot determine that from the attribute name alone, because both `aria-labelled-by` (via `@api` property kebab-casing) and `aria-labelledby` (via LWC's ARIA reflection) can wire to the same property depending on the component. Treat a hyphen-split ARIA attribute on a component tag as a valid binding, not a violation.
|
package/skills/experience-accessibility-validate/references/reviewers/sc-2-5-3-label-in-name.md
CHANGED
|
@@ -71,7 +71,3 @@ Rules to follow:
|
|
|
71
71
|
- Keep issues concise, avoid duplicated issues or unnecessary or non-applicable problems.
|
|
72
72
|
- Assume that any imported functionality works as expected and was already analyzed.
|
|
73
73
|
- Components do not supplement or provide global functionalities.
|
|
74
|
-
- Lightning base components (`lightning-input`, `lightning-combobox`, `lightning-textarea`, `lightning-icon`, etc.) provide their own accessible labeling, ARIA, and error handling in shadow DOM via their dedicated attributes (`label`, `alternative-text`, field-level validation). When such a component is given a `label` attribute it is already programmatically labeled — even with `variant="label-hidden"`, which hides the label visually but keeps it for assistive technology. Do **not** flag a sibling/wrapper `<label>` or `<span>` for a missing `for`/`id` when the actual control is a self-labeling Lightning component, and do not treat a visible heading as if it were the control's only label. This also covers navigation and icon base components (`lightning-vertical-navigation-item`, `lightning-vertical-navigation-item-icon`, `lightning-button-icon`, etc.): when a `label` (or `alternative-text`) attribute is supplied, the base component renders it as the visible link/control text **and** exposes it as the accessible name, and any `icon-name` is decorative — do not emit a 4.1.2 "verify the label is associated with the icon" warning, even a hedged one. The presence of the `label` attribute is the association.
|
|
75
|
-
- Resolve template bindings before judging them. A template expression like `{someValue}` refers to a property or getter on the component's controller (`.js`/`.ts`) — including `@api` properties and `get someValue()` getters — not to a module-level imported constant (which LWC templates cannot bind to). Check the controller for the binding's definition before concluding a value is undefined, empty, or missing. When reviewing a diff, verify which side is the corrected code; do not assume the change introduced the problem.
|
|
76
|
-
- Prefer a real `<button>` for actions; for a link, `href="#"` with `event.preventDefault()` (the canonical SLDS pattern). Don't recommend `href="javascript:void(0)"` as a first-line remediation — it's a no-op-anchor anti-pattern. It is acceptable only as a last resort when moving `<a>` → `<button>` is genuinely impossible, and even then only when paired with the full set of attributes that make the anchor behave as an accessible button (`role="button"`, keyboard activation, etc.) — `void(0)` on its own is an incomplete fix. Don't flag existing `javascript:void(0)` as a violation.
|
|
77
|
-
- ARIA attribute spelling depends on the element type. On a **plain HTML element** (`div`, `span`, `button`, `input`, `a`, `img`, `iframe`, …) the only valid spelling is the W3C form `aria-labelledby` / `aria-describedby`; the hyphen-split `aria-labelled-by` / `aria-described-by` there **is** a real bug — keep flagging it. But on an **LWC component tag** (`lightning-*` or a custom `ns-name` element), the hyphen-split form is the kebab-case binding of the component's `@api ariaLabelledBy` / `ariaDescribedBy` property (each capital letter maps to `-` + lowercase), and LWC reflects it to the spec-correct `aria-labelledby` in the rendered DOM. Do **not** flag `aria-labelled-by` on a component tag as a misspelling, and do not claim it "breaks the accessible name computation" — you cannot determine that from the attribute name alone, because both `aria-labelled-by` (via `@api` property kebab-casing) and `aria-labelledby` (via LWC's ARIA reflection) can wire to the same property depending on the component. Treat a hyphen-split ARIA attribute on a component tag as a valid binding, not a violation.
|
package/skills/experience-accessibility-validate/references/reviewers/sc-2-5-7-dragging-movement.md
CHANGED
|
@@ -39,7 +39,3 @@ _Rules to follow_:
|
|
|
39
39
|
- Keep issues concise, avoid duplicated issues or unnecessary or non-applicable problems.
|
|
40
40
|
- Assume that any imported functionality works as expected and was already analyzed.
|
|
41
41
|
- Components do not supplement or provide global functionalities.
|
|
42
|
-
- Lightning base components (`lightning-input`, `lightning-combobox`, `lightning-textarea`, `lightning-icon`, etc.) provide their own accessible labeling, ARIA, and error handling in shadow DOM via their dedicated attributes (`label`, `alternative-text`, field-level validation). When such a component is given a `label` attribute it is already programmatically labeled — even with `variant="label-hidden"`, which hides the label visually but keeps it for assistive technology. Do **not** flag a sibling/wrapper `<label>` or `<span>` for a missing `for`/`id` when the actual control is a self-labeling Lightning component, and do not treat a visible heading as if it were the control's only label. This also covers navigation and icon base components (`lightning-vertical-navigation-item`, `lightning-vertical-navigation-item-icon`, `lightning-button-icon`, etc.): when a `label` (or `alternative-text`) attribute is supplied, the base component renders it as the visible link/control text **and** exposes it as the accessible name, and any `icon-name` is decorative — do not emit a 4.1.2 "verify the label is associated with the icon" warning, even a hedged one. The presence of the `label` attribute is the association.
|
|
43
|
-
- Resolve template bindings before judging them. A template expression like `{someValue}` refers to a property or getter on the component's controller (`.js`/`.ts`) — including `@api` properties and `get someValue()` getters — not to a module-level imported constant (which LWC templates cannot bind to). Check the controller for the binding's definition before concluding a value is undefined, empty, or missing. When reviewing a diff, verify which side is the corrected code; do not assume the change introduced the problem.
|
|
44
|
-
- Prefer a real `<button>` for actions; for a link, `href="#"` with `event.preventDefault()` (the canonical SLDS pattern). Don't recommend `href="javascript:void(0)"` as a first-line remediation — it's a no-op-anchor anti-pattern. It is acceptable only as a last resort when moving `<a>` → `<button>` is genuinely impossible, and even then only when paired with the full set of attributes that make the anchor behave as an accessible button (`role="button"`, keyboard activation, etc.) — `void(0)` on its own is an incomplete fix. Don't flag existing `javascript:void(0)` as a violation.
|
|
45
|
-
- ARIA attribute spelling depends on the element type. On a **plain HTML element** (`div`, `span`, `button`, `input`, `a`, `img`, `iframe`, …) the only valid spelling is the W3C form `aria-labelledby` / `aria-describedby`; the hyphen-split `aria-labelled-by` / `aria-described-by` there **is** a real bug — keep flagging it. But on an **LWC component tag** (`lightning-*` or a custom `ns-name` element), the hyphen-split form is the kebab-case binding of the component's `@api ariaLabelledBy` / `ariaDescribedBy` property (each capital letter maps to `-` + lowercase), and LWC reflects it to the spec-correct `aria-labelledby` in the rendered DOM. Do **not** flag `aria-labelled-by` on a component tag as a misspelling, and do not claim it "breaks the accessible name computation" — you cannot determine that from the attribute name alone, because both `aria-labelled-by` (via `@api` property kebab-casing) and `aria-labelledby` (via LWC's ARIA reflection) can wire to the same property depending on the component. Treat a hyphen-split ARIA attribute on a component tag as a valid binding, not a violation.
|
|
@@ -49,7 +49,3 @@ _Rules to follow_:
|
|
|
49
49
|
- Keep issues concise, avoid duplicated issues or unnecessary or non-applicable problems.
|
|
50
50
|
- Assume that any imported functionality works as expected and was already analyzed.
|
|
51
51
|
- Components do not supplement or provide global functionalities.
|
|
52
|
-
- Lightning base components (`lightning-input`, `lightning-combobox`, `lightning-textarea`, `lightning-icon`, etc.) provide their own accessible labeling, ARIA, and error handling in shadow DOM via their dedicated attributes (`label`, `alternative-text`, field-level validation). When such a component is given a `label` attribute it is already programmatically labeled — even with `variant="label-hidden"`, which hides the label visually but keeps it for assistive technology. Do **not** flag a sibling/wrapper `<label>` or `<span>` for a missing `for`/`id` when the actual control is a self-labeling Lightning component, and do not treat a visible heading as if it were the control's only label. This also covers navigation and icon base components (`lightning-vertical-navigation-item`, `lightning-vertical-navigation-item-icon`, `lightning-button-icon`, etc.): when a `label` (or `alternative-text`) attribute is supplied, the base component renders it as the visible link/control text **and** exposes it as the accessible name, and any `icon-name` is decorative — do not emit a 4.1.2 "verify the label is associated with the icon" warning, even a hedged one. The presence of the `label` attribute is the association.
|
|
53
|
-
- Resolve template bindings before judging them. A template expression like `{someValue}` refers to a property or getter on the component's controller (`.js`/`.ts`) — including `@api` properties and `get someValue()` getters — not to a module-level imported constant (which LWC templates cannot bind to). Check the controller for the binding's definition before concluding a value is undefined, empty, or missing. When reviewing a diff, verify which side is the corrected code; do not assume the change introduced the problem.
|
|
54
|
-
- Prefer a real `<button>` for actions; for a link, `href="#"` with `event.preventDefault()` (the canonical SLDS pattern). Don't recommend `href="javascript:void(0)"` as a first-line remediation — it's a no-op-anchor anti-pattern. It is acceptable only as a last resort when moving `<a>` → `<button>` is genuinely impossible, and even then only when paired with the full set of attributes that make the anchor behave as an accessible button (`role="button"`, keyboard activation, etc.) — `void(0)` on its own is an incomplete fix. Don't flag existing `javascript:void(0)` as a violation.
|
|
55
|
-
- ARIA attribute spelling depends on the element type. On a **plain HTML element** (`div`, `span`, `button`, `input`, `a`, `img`, `iframe`, …) the only valid spelling is the W3C form `aria-labelledby` / `aria-describedby`; the hyphen-split `aria-labelled-by` / `aria-described-by` there **is** a real bug — keep flagging it. But on an **LWC component tag** (`lightning-*` or a custom `ns-name` element), the hyphen-split form is the kebab-case binding of the component's `@api ariaLabelledBy` / `ariaDescribedBy` property (each capital letter maps to `-` + lowercase), and LWC reflects it to the spec-correct `aria-labelledby` in the rendered DOM. Do **not** flag `aria-labelled-by` on a component tag as a misspelling, and do not claim it "breaks the accessible name computation" — you cannot determine that from the attribute name alone, because both `aria-labelled-by` (via `@api` property kebab-casing) and `aria-labelledby` (via LWC's ARIA reflection) can wire to the same property depending on the component. Treat a hyphen-split ARIA attribute on a component tag as a valid binding, not a violation.
|
|
@@ -45,7 +45,4 @@ _Rules to follow_ :
|
|
|
45
45
|
- Keep issues concise, avoid duplicated issues or unnecessary or non-applicable problems.
|
|
46
46
|
- Assume that any imported functionality works as expected and was already analyzed.
|
|
47
47
|
- Components do not supplement or provide global functionalities.
|
|
48
|
-
-
|
|
49
|
-
- Resolve template bindings before judging them. A template expression like `{someValue}` refers to a property or getter on the component's controller (`.js`/`.ts`) — including `@api` properties and `get someValue()` getters — not to a module-level imported constant (which LWC templates cannot bind to). Check the controller for the binding's definition before concluding a value is undefined, empty, or missing. When reviewing a diff, verify which side is the corrected code; do not assume the change introduced the problem.
|
|
50
|
-
- Prefer a real `<button>` for actions; for a link, `href="#"` with `event.preventDefault()` (the canonical SLDS pattern). Don't recommend `href="javascript:void(0)"` as a first-line remediation — it's a no-op-anchor anti-pattern. It is acceptable only as a last resort when moving `<a>` → `<button>` is genuinely impossible, and even then only when paired with the full set of attributes that make the anchor behave as an accessible button (`role="button"`, keyboard activation, etc.) — `void(0)` on its own is an incomplete fix. Don't flag existing `javascript:void(0)` as a violation.
|
|
51
|
-
- ARIA attribute spelling depends on the element type. On a **plain HTML element** (`div`, `span`, `button`, `input`, `a`, `img`, `iframe`, …) the only valid spelling is the W3C form `aria-labelledby` / `aria-describedby`; the hyphen-split `aria-labelled-by` / `aria-described-by` there **is** a real bug — keep flagging it. But on an **LWC component tag** (`lightning-*` or a custom `ns-name` element), the hyphen-split form is the kebab-case binding of the component's `@api ariaLabelledBy` / `ariaDescribedBy` property (each capital letter maps to `-` + lowercase), and LWC reflects it to the spec-correct `aria-labelledby` in the rendered DOM. Do **not** flag `aria-labelled-by` on a component tag as a misspelling, and do not claim it "breaks the accessible name computation" — you cannot determine that from the attribute name alone, because both `aria-labelled-by` (via `@api` property kebab-casing) and `aria-labelledby` (via LWC's ARIA reflection) can wire to the same property depending on the component. Treat a hyphen-split ARIA attribute on a component tag as a valid binding, not a violation.
|
|
48
|
+
- Opening a link or button target in a new browser tab or window (`target="_blank"` or a click handler that calls `window.open(...)`) is not an SC 3.2.2 violation. This criterion concerns unexpected context changes caused by changing a form control's value or state, not the expected result of deliberately activating a link or button. Treat indicating new-tab behavior as optional advisory guidance, never as a Level A or AA failure.
|
|
@@ -78,7 +78,4 @@ Rules to follow:
|
|
|
78
78
|
- Keep issues concise, avoid duplicated issues or unnecessary or non-applicable problems.
|
|
79
79
|
- Assume that any imported functionality works as expected and was already analyzed.
|
|
80
80
|
- Components do not supplement or provide global functionalities.
|
|
81
|
-
-
|
|
82
|
-
- Resolve template bindings before judging them. A template expression like `{someValue}` refers to a property or getter on the component's controller (`.js`/`.ts`) — including `@api` properties and `get someValue()` getters — not to a module-level imported constant (which LWC templates cannot bind to). Check the controller for the binding's definition before concluding a value is undefined, empty, or missing. When reviewing a diff, verify which side is the corrected code; do not assume the change introduced the problem.
|
|
83
|
-
- Prefer a real `<button>` for actions; for a link, `href="#"` with `event.preventDefault()` (the canonical SLDS pattern). Don't recommend `href="javascript:void(0)"` as a first-line remediation — it's a no-op-anchor anti-pattern. It is acceptable only as a last resort when moving `<a>` → `<button>` is genuinely impossible, and even then only when paired with the full set of attributes that make the anchor behave as an accessible button (`role="button"`, keyboard activation, etc.) — `void(0)` on its own is an incomplete fix. Don't flag existing `javascript:void(0)` as a violation.
|
|
84
|
-
- ARIA attribute spelling depends on the element type. On a **plain HTML element** (`div`, `span`, `button`, `input`, `a`, `img`, `iframe`, …) the only valid spelling is the W3C form `aria-labelledby` / `aria-describedby`; the hyphen-split `aria-labelled-by` / `aria-described-by` there **is** a real bug — keep flagging it. But on an **LWC component tag** (`lightning-*` or a custom `ns-name` element), the hyphen-split form is the kebab-case binding of the component's `@api ariaLabelledBy` / `ariaDescribedBy` property (each capital letter maps to `-` + lowercase), and LWC reflects it to the spec-correct `aria-labelledby` in the rendered DOM. Do **not** flag `aria-labelled-by` on a component tag as a misspelling, and do not claim it "breaks the accessible name computation" — you cannot determine that from the attribute name alone, because both `aria-labelled-by` (via `@api` property kebab-casing) and `aria-labelledby` (via LWC's ARIA reflection) can wire to the same property depending on the component. Treat a hyphen-split ARIA attribute on a component tag as a valid binding, not a violation.
|
|
81
|
+
- Associate error text with the actual focusable control. An `aria-describedby` or `aria-errormessage` on a non-focusable wrapper does not reach a composite editor's internal control unless the wrapper forwards it. A disabled control cannot receive focus, so attaching the only error explanation to it also cannot make that explanation available on focus. Use an adjacent visible message, a live region where appropriate, or the control's supported error-association API.
|
|
@@ -44,7 +44,4 @@ Rules to follow:
|
|
|
44
44
|
- Keep issues concise, avoid duplicated issues or unnecessary or non-applicable problems.
|
|
45
45
|
- Assume that any imported functionality works as expected and was already analyzed.
|
|
46
46
|
- Components do not supplement or provide global functionalities.
|
|
47
|
-
-
|
|
48
|
-
- Resolve template bindings before judging them. A template expression like `{someValue}` refers to a property or getter on the component's controller (`.js`/`.ts`) — including `@api` properties and `get someValue()` getters — not to a module-level imported constant (which LWC templates cannot bind to). Check the controller for the binding's definition before concluding a value is undefined, empty, or missing. When reviewing a diff, verify which side is the corrected code; do not assume the change introduced the problem.
|
|
49
|
-
- Prefer a real `<button>` for actions; for a link, `href="#"` with `event.preventDefault()` (the canonical SLDS pattern). Don't recommend `href="javascript:void(0)"` as a first-line remediation — it's a no-op-anchor anti-pattern. It is acceptable only as a last resort when moving `<a>` → `<button>` is genuinely impossible, and even then only when paired with the full set of attributes that make the anchor behave as an accessible button (`role="button"`, keyboard activation, etc.) — `void(0)` on its own is an incomplete fix. Don't flag existing `javascript:void(0)` as a violation.
|
|
50
|
-
- ARIA attribute spelling depends on the element type. On a **plain HTML element** (`div`, `span`, `button`, `input`, `a`, `img`, `iframe`, …) the only valid spelling is the W3C form `aria-labelledby` / `aria-describedby`; the hyphen-split `aria-labelled-by` / `aria-described-by` there **is** a real bug — keep flagging it. But on an **LWC component tag** (`lightning-*` or a custom `ns-name` element), the hyphen-split form is the kebab-case binding of the component's `@api ariaLabelledBy` / `ariaDescribedBy` property (each capital letter maps to `-` + lowercase), and LWC reflects it to the spec-correct `aria-labelledby` in the rendered DOM. Do **not** flag `aria-labelled-by` on a component tag as a misspelling, and do not claim it "breaks the accessible name computation" — you cannot determine that from the attribute name alone, because both `aria-labelled-by` (via `@api` property kebab-casing) and `aria-labelledby` (via LWC's ARIA reflection) can wire to the same property depending on the component. Treat a hyphen-split ARIA attribute on a component tag as a valid binding, not a violation.
|
|
47
|
+
- Attach instructions to the actual focusable control. An `aria-describedby` on a disabled control cannot expose the instructions on focus, and an association on a non-focusable wrapper does not reach a composite editor's internal control unless the wrapper forwards it. Use adjacent visible instructions or the control's supported association API instead.
|
package/skills/experience-accessibility-validate/references/reviewers/sc-3-3-3-error-suggestion.md
CHANGED
|
@@ -58,7 +58,4 @@ Rules to follow:
|
|
|
58
58
|
- Keep issues concise, avoid duplicated issues or unnecessary or non-applicable problems.
|
|
59
59
|
- Assume that any imported functionality works as expected and was already analyzed.
|
|
60
60
|
- Components do not supplement or provide global functionalities.
|
|
61
|
-
-
|
|
62
|
-
- Resolve template bindings before judging them. A template expression like `{someValue}` refers to a property or getter on the component's controller (`.js`/`.ts`) — including `@api` properties and `get someValue()` getters — not to a module-level imported constant (which LWC templates cannot bind to). Check the controller for the binding's definition before concluding a value is undefined, empty, or missing. When reviewing a diff, verify which side is the corrected code; do not assume the change introduced the problem.
|
|
63
|
-
- Prefer a real `<button>` for actions; for a link, `href="#"` with `event.preventDefault()` (the canonical SLDS pattern). Don't recommend `href="javascript:void(0)"` as a first-line remediation — it's a no-op-anchor anti-pattern. It is acceptable only as a last resort when moving `<a>` → `<button>` is genuinely impossible, and even then only when paired with the full set of attributes that make the anchor behave as an accessible button (`role="button"`, keyboard activation, etc.) — `void(0)` on its own is an incomplete fix. Don't flag existing `javascript:void(0)` as a violation.
|
|
64
|
-
- ARIA attribute spelling depends on the element type. On a **plain HTML element** (`div`, `span`, `button`, `input`, `a`, `img`, `iframe`, …) the only valid spelling is the W3C form `aria-labelledby` / `aria-describedby`; the hyphen-split `aria-labelled-by` / `aria-described-by` there **is** a real bug — keep flagging it. But on an **LWC component tag** (`lightning-*` or a custom `ns-name` element), the hyphen-split form is the kebab-case binding of the component's `@api ariaLabelledBy` / `ariaDescribedBy` property (each capital letter maps to `-` + lowercase), and LWC reflects it to the spec-correct `aria-labelledby` in the rendered DOM. Do **not** flag `aria-labelled-by` on a component tag as a misspelling, and do not claim it "breaks the accessible name computation" — you cannot determine that from the attribute name alone, because both `aria-labelled-by` (via `@api` property kebab-casing) and `aria-labelledby` (via LWC's ARIA reflection) can wire to the same property depending on the component. Treat a hyphen-split ARIA attribute on a component tag as a valid binding, not a violation.
|
|
61
|
+
- Associate an error suggestion with the actual focusable control. An `aria-describedby` or `aria-errormessage` on a non-focusable wrapper does not reach a composite editor's internal control unless the wrapper forwards it. A disabled control cannot expose described text on focus. Use adjacent visible guidance, a live region where appropriate, or the control's supported error-association API.
|