@salesforce/afv-skills 1.37.0 → 1.38.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/README.md +20 -3
- package/skills/agentforce-generate/SKILL.md +253 -440
- package/skills/agentforce-generate/assets/agent-spec-template.md +6 -2
- package/skills/agentforce-generate/assets/agents/order-service.agent +16 -12
- package/skills/agentforce-generate/assets/agents/production-faq.agent +4 -4
- package/skills/agentforce-generate/assets/agents/router-first.agent +5 -5
- package/skills/agentforce-generate/assets/agents/template-single-subagent.agent +4 -4
- package/skills/agentforce-generate/assets/agents/verification-gate.agent +8 -6
- package/skills/agentforce-generate/assets/agents/voice-knowledge-grounded.agent +9 -9
- package/skills/agentforce-generate/assets/agents/voice-service-agent.agent +7 -7
- package/skills/agentforce-generate/assets/patterns/README.md +3 -3
- package/skills/agentforce-generate/assets/patterns/action-callbacks.agent +5 -5
- package/skills/agentforce-generate/assets/patterns/advanced-input-bindings.agent +6 -8
- package/skills/agentforce-generate/assets/patterns/bidirectional-routing.agent +11 -13
- package/skills/agentforce-generate/assets/patterns/critical-input-collection.agent +11 -16
- package/skills/agentforce-generate/assets/patterns/lifecycle-events.agent +2 -3
- package/skills/agentforce-generate/assets/patterns/llm-controlled-actions.agent +6 -7
- package/skills/agentforce-generate/assets/patterns/open-gate-routing.agent +3 -3
- package/skills/agentforce-generate/assets/patterns/prompt-template-action.agent +14 -19
- package/skills/agentforce-generate/assets/patterns/system-instruction-overrides.agent +11 -20
- package/skills/agentforce-generate/references/actions-reference.md +2 -2
- package/skills/agentforce-generate/references/agent-audit-and-repair.md +135 -0
- package/skills/agentforce-generate/references/agent-audit-candidate-verification.md +160 -0
- package/skills/agentforce-generate/references/agent-audit-diagnostic-catalog.md +156 -0
- package/skills/agentforce-generate/references/agent-audit-diagnostics-actions-state.md +176 -0
- package/skills/agentforce-generate/references/agent-audit-diagnostics-architecture-evaluation.md +68 -0
- package/skills/agentforce-generate/references/agent-audit-diagnostics-instructions-routing.md +283 -0
- package/skills/agentforce-generate/references/agent-audit-evaluation-loop.md +191 -0
- package/skills/agentforce-generate/references/agent-audit-repair-report.md +143 -0
- package/skills/agentforce-generate/references/agent-audit-scope-path-review.md +180 -0
- package/skills/agentforce-generate/references/agent-design-and-spec-creation.md +105 -59
- package/skills/agentforce-generate/references/agent-script-core-language.md +144 -61
- package/skills/agentforce-generate/references/agent-subagent-map-diagrams.md +33 -23
- package/skills/agentforce-generate/references/agent-validation-and-debugging.md +37 -11
- package/skills/agentforce-generate/references/agentscript-toolchain.md +112 -0
- package/skills/agentforce-generate/references/architecture-patterns.md +81 -18
- package/skills/agentforce-generate/references/common-control-flow-pitfalls.md +255 -0
- package/skills/agentforce-generate/references/control-flow-actions-sequencing.md +198 -0
- package/skills/agentforce-generate/references/control-flow-lifecycle-side-effects.md +87 -0
- package/skills/agentforce-generate/references/examples.md +22 -22
- package/skills/agentforce-generate/references/instruction-resolution.md +123 -83
- package/skills/agentforce-generate/references/known-issues.md +1 -2
- package/skills/agentforce-generate/references/optimization-pattern-1-data-flow.md +4 -0
- package/skills/agentforce-generate/references/optimization-pattern-2-deterministic-logic.md +33 -0
- package/skills/agentforce-generate/references/optimization-pattern-3-reference-syntax.md +32 -3
- package/skills/agentforce-generate/references/optimization-pattern-4-escalation.md +2 -2
- package/skills/agentforce-generate/references/patterns-by-requirement.md +3 -1
- package/skills/agentforce-generate/references/posture-and-determinism.md +103 -22
- package/skills/agentforce-generate/references/reference-map.md +19 -3
- package/skills/agentforce-generate/references/scoring-rubric.md +1 -1
- package/skills/agentforce-generate/references/voice-latency-heuristics.md +4 -0
- package/skills/agentforce-generate/references/voice-modality-reference.md +4 -4
- package/skills/agentforce-generate/references/zen-of-agentscript.md +139 -23
- package/skills/agentforce-generate/scripts/agentscript-sdk-loader.mjs +133 -0
- package/skills/agentforce-generate/scripts/index-agent.mjs +141 -0
- package/skills/agentforce-generate/scripts/setup-agentscript-sdk.mjs +337 -0
- package/skills/automation-sandbox-post-copy-config-generate/SKILL.md +1 -1
- package/skills/automation-sandbox-post-copy-configure/SKILL.md +433 -0
- package/skills/automation-sandbox-post-copy-configure/assets/api_request_templates.json +89 -0
- package/skills/automation-sandbox-post-copy-configure/examples/sample_config_input.json +40 -0
- package/skills/automation-sandbox-post-copy-configure/examples/sample_execution_summary.md +79 -0
- package/skills/automation-sandbox-post-copy-configure/references/api_endpoints.md +273 -0
- package/skills/automation-sandbox-post-copy-configure/references/authentication.md +94 -0
- package/skills/automation-sandbox-post-copy-configure/references/execution_phasing.md +93 -0
- package/skills/automation-sandbox-post-copy-configure/references/rules_gotchas.md +35 -0
- package/skills/automation-sandbox-post-copy-configure/scripts/classify-patch-result.mjs +88 -0
- package/skills/automation-sandbox-post-copy-configure/scripts/map-metadata-key.mjs +98 -0
- package/skills/automation-sandbox-post-copy-configure/scripts/plan-phases.mjs +98 -0
- package/skills/automation-sandbox-post-copy-configure/scripts/resolve-target-org.mjs +56 -0
- package/skills/design-systems-slds-validate/SKILL.md +14 -13
- package/skills/dx-code-analyzer-custom-rule-create/examples/xpath-examples.md +1 -1
- package/skills/dx-code-analyzer-custom-rule-create/references/xpath-patterns-security.md +1 -1
- package/skills/dx-org-devhub-configure/SKILL.md +268 -0
- package/skills/dx-org-devhub-configure/examples/status-output.md +39 -0
- package/skills/dx-org-devhub-configure/scripts/devhub.sh +650 -0
- package/skills/dx-org-devhub-configure/scripts/test-devhub.sh +116 -0
- package/skills/dx-org-manage/SKILL.md +135 -42
- package/skills/dx-org-manage/assets/derive-alias.sh +95 -0
- package/skills/dx-org-manage/assets/scratch-def.seed.json +6 -0
- package/skills/dx-org-manage/examples/README.md +1 -1
- package/skills/dx-org-manage/examples/scratch-orgs/delete_output.json +8 -0
- package/skills/dx-org-manage/examples/scratch-orgs/display_output.json +23 -0
- package/skills/dx-org-manage/examples/scratch-orgs/list_output.json +58 -0
- package/skills/dx-org-manage/examples/scratch-orgs/resume_output.json +38 -0
- package/skills/dx-org-manage/examples/scratch-orgs/success_definition_file.json +1 -1
- package/skills/dx-org-manage/examples/scratch-orgs/success_edition.json +1 -1
- package/skills/dx-org-manage/examples/scratch-orgs/success_shape.json +41 -0
- package/skills/dx-org-manage/examples/scratch-orgs/success_snapshot.json +1 -1
- package/skills/dx-org-manage/examples/snapshots/error_output.json +3 -3
- package/skills/dx-org-manage/references/creating-scratch-org.md +2 -2
- package/skills/dx-org-manage/references/creating-snapshot.md +1 -2
- package/skills/dx-org-manage/references/definition_file_options.md +24 -0
- package/skills/dx-org-manage/references/edition_types.md +10 -8
- package/skills/dx-org-manage/references/opening-org.md +11 -12
- package/skills/dx-org-manage/references/scratch-org-create.md +303 -0
- package/skills/dx-org-manage/references/scratch-org-operations.md +135 -0
- package/skills/experience-aura-lwc-migrate/SKILL.md +120 -0
- package/skills/experience-aura-lwc-migrate/references/aura-api-expert.md +170 -0
- package/skills/experience-aura-lwc-migrate/references/aura-data-expert.md +172 -0
- package/skills/experience-aura-lwc-migrate/references/aura-migration-guidelines.md +299 -0
- package/skills/experience-aura-lwc-migrate/references/aura-prd-framework.md +79 -0
- package/skills/experience-aura-lwc-migrate/references/aura-redundant-code-expert.md +24 -0
- package/skills/experience-aura-lwc-migrate/references/aura-reference-expert.md +140 -0
- package/skills/experience-aura-lwc-migrate/references/aura-resolver-expert.md +115 -0
- package/skills/experience-aura-lwc-migrate/references/aura-slots-expert.md +67 -0
- package/skills/experience-aura-lwc-migrate/references/aura-style-expert.md +62 -0
- package/skills/experience-aura-lwc-migrate/references/aura-to-lwc-completeness-checklist.md +188 -0
- package/skills/experience-aura-lwc-migrate/references/aura-values-expert.md +67 -0
- package/skills/experience-content-media-search/SKILL.md +17 -12
- package/skills/experience-content-media-stock-image-search/SKILL.md +192 -0
- package/skills/experience-content-media-stock-image-search/scripts/download-stock-image.py +102 -0
- package/skills/experience-lds-best-practices-apply/SKILL.md +245 -0
- package/skills/experience-lds-best-practices-apply/references/adapter-apis.md +1640 -0
- package/skills/experience-lds-best-practices-apply/references/lds-data-consistency.md +126 -0
- package/skills/experience-lds-best-practices-apply/references/lds-expert.md +429 -0
- package/skills/experience-lds-best-practices-apply/references/lds-referential-integrity.md +322 -0
- package/skills/experience-lds-best-practices-apply/references/wire-adapter-types.md +1511 -0
- package/skills/experience-lds-graphql-generate/SKILL.md +222 -0
- package/skills/experience-lds-graphql-generate/references/generation-guide.md +236 -0
- package/skills/experience-lds-graphql-generate/references/generation-mutation.md +277 -0
- package/skills/experience-lds-graphql-generate/references/generation-query.md +237 -0
- package/skills/experience-lds-graphql-generate/scripts/fetch-lds-graphql-schema.sh +230 -0
- package/skills/experience-lds-graphql-generate/scripts/test-lds-graphql-query.sh +128 -0
- package/skills/experience-lwc-accessibility-validate/SKILL.md +112 -0
- package/skills/experience-lwc-accessibility-validate/references/reviewers/sc-1-1-1-non-text-content.md +88 -0
- package/skills/experience-lwc-accessibility-validate/references/reviewers/sc-1-3-1-i-lists.md +52 -0
- package/skills/experience-lwc-accessibility-validate/references/reviewers/sc-1-3-1-ii-tables.md +106 -0
- package/skills/experience-lwc-accessibility-validate/references/reviewers/sc-1-3-1-iii-form-labels.md +78 -0
- package/skills/experience-lwc-accessibility-validate/references/reviewers/sc-1-3-1-iv-regions.md +26 -0
- package/skills/experience-lwc-accessibility-validate/references/reviewers/sc-1-3-1-v-groups.md +66 -0
- package/skills/experience-lwc-accessibility-validate/references/reviewers/sc-1-3-5-identify-input.md +70 -0
- package/skills/experience-lwc-accessibility-validate/references/reviewers/sc-1-4-3-contrast.md +115 -0
- package/skills/experience-lwc-accessibility-validate/references/reviewers/sc-2-1-1-keyboard.md +47 -0
- package/skills/experience-lwc-accessibility-validate/references/reviewers/sc-2-4-4-link-purpose.md +39 -0
- package/skills/experience-lwc-accessibility-validate/references/reviewers/sc-2-4-6-headings-labels.md +50 -0
- package/skills/experience-lwc-accessibility-validate/references/reviewers/sc-2-5-1-pointer-gestures.md +54 -0
- package/skills/experience-lwc-accessibility-validate/references/reviewers/sc-2-5-2-pointer-cancellation.md +49 -0
- package/skills/experience-lwc-accessibility-validate/references/reviewers/sc-2-5-3-label-in-name.md +77 -0
- package/skills/experience-lwc-accessibility-validate/references/reviewers/sc-2-5-7-dragging-movement.md +45 -0
- package/skills/experience-lwc-accessibility-validate/references/reviewers/sc-3-2-1-on-focus.md +55 -0
- package/skills/experience-lwc-accessibility-validate/references/reviewers/sc-3-2-2-on-input.md +51 -0
- package/skills/experience-lwc-accessibility-validate/references/reviewers/sc-3-3-1-error-identification.md +84 -0
- package/skills/experience-lwc-accessibility-validate/references/reviewers/sc-3-3-2-labels-instructions.md +50 -0
- package/skills/experience-lwc-accessibility-validate/references/reviewers/sc-3-3-3-error-suggestion.md +64 -0
- package/skills/experience-lwc-accessibility-validate/references/reviewers/sc-4-1-2-i-name.md +105 -0
- package/skills/experience-lwc-accessibility-validate/references/reviewers/sc-4-1-2-ii-role.md +99 -0
- package/skills/experience-lwc-accessibility-validate/references/reviewers/sc-4-1-2-iii-value.md +97 -0
- package/skills/experience-lwc-accessibility-validate/references/vision/sc-1-1-1-non-text-content.md +83 -0
- package/skills/experience-lwc-accessibility-validate/references/vision/sc-1-4-1-use-of-color.md +62 -0
- package/skills/experience-lwc-accessibility-validate/references/vision/sc-1-4-10-resize-reflow.md +18 -0
- package/skills/experience-lwc-accessibility-validate/references/vision/sc-1-4-11-non-text-contrast.md +43 -0
- package/skills/experience-lwc-accessibility-validate/references/vision/sc-1-4-3-contrast.md +25 -0
- package/skills/experience-lwc-accessibility-validate/scripts/contrast-ratio.py +153 -0
- package/skills/experience-lwc-design-generate/SKILL.md +261 -0
- package/skills/experience-lwc-design-generate/references/figma-to-prd-blueprint.md +66 -0
- package/skills/experience-lwc-design-generate/references/prd-analysis-template.md +17 -0
- package/skills/experience-lwc-design-generate/scripts/check-component-name.sh +75 -0
- package/skills/experience-lwc-design-generate/scripts/detect-project-tools.sh +97 -0
- package/skills/experience-lwc-runtime-observe/SKILL.md +244 -0
- package/skills/experience-lwc-runtime-observe/examples/component-preview-and-dom.md +41 -0
- package/skills/experience-lwc-runtime-observe/scripts/extract-dom.sh +79 -0
- package/skills/experience-lwc-runtime-observe/scripts/open-frontdoor.sh +46 -0
- package/skills/experience-lwc-runtime-observe/scripts/verify-toolchain.sh +48 -0
- package/skills/experience-lwc-security-validate/SKILL.md +151 -0
- package/skills/experience-lwc-security-validate/examples/review-report.md +6 -0
- package/skills/experience-lwc-security-validate/examples/score-report.sarif.json +32 -0
- package/skills/experience-lwc-security-validate/references/lws-security-expert.md +986 -0
- package/skills/experience-lwc-security-validate/references/security-analysis.md +611 -0
- package/skills/experience-lwc-security-validate/scripts/check-lwc-import.sh +166 -0
- package/skills/experience-lwc-security-validate/scripts/validate-sarif.sh +131 -0
- package/skills/experience-ui-bundle-2gp-deploy/SKILL.md +454 -0
- package/skills/experience-ui-bundle-2gp-deploy/assets/CustomApplication.app-meta.xml +12 -0
- package/skills/experience-ui-bundle-2gp-deploy/assets/PermissionSet.permissionset-meta.xml +9 -0
- package/skills/experience-ui-bundle-2gp-deploy/scripts/find-bundle-package-dir.sh +53 -0
- package/skills/experience-ui-bundle-agentforce-client-generate/SKILL.md +104 -26
- package/skills/experience-ui-bundle-agentforce-client-generate/references/constraints.md +35 -24
- package/skills/experience-ui-bundle-agentforce-client-generate/references/examples.md +92 -1
- package/skills/experience-ui-bundle-agentforce-client-generate/references/style-tokens.md +2 -0
- package/skills/experience-ui-bundle-agentforce-client-generate/references/troubleshooting.md +14 -1
- package/skills/experience-ui-bundle-agentforce-client-generate/scripts/detect-framework.sh +67 -0
- package/skills/experience-ui-bundle-deploy/SKILL.md +83 -14
- package/skills/experience-ui-bundle-deploy/assets/Communities.settings-meta.xml +19 -0
- package/skills/experience-ui-bundle-deploy/assets/org-setup.config.template.json +5 -0
- package/skills/experience-ui-bundle-deploy/assets/social-login-auth-providers.apex +158 -0
- package/skills/experience-ui-bundle-deploy/references/config-scaffold.md +13 -1
- package/skills/experience-ui-bundle-deploy/references/social-login.md +179 -0
- package/skills/experience-ui-bundle-frontend-generate/SKILL.md +14 -0
- package/skills/experience-ui-bundle-mfa-configure/SKILL.md +6 -5
- package/skills/experience-ui-bundle-mfa-configure/references/social-login.md +15 -7
- package/skills/experience-ui-bundle-salesforce-data-access/SKILL.md +41 -5
- package/skills/experience-ui-bundle-salesforce-data-access/references/caching.md +10 -22
- package/skills/experience-ui-bundle-salesforce-data-access/references/graphql-hand-authoring.md +4 -19
- package/skills/experience-ui-bundle-salesforce-data-access/references/migration.md +5 -0
- package/skills/experience-ui-bundle-salesforce-data-access/references/sdk-api.md +33 -150
- package/skills/mobile-platform-native-capabilities-integrate/references/nfc.md +35 -0
- package/skills/platform-apex-generate/SKILL.md +8 -7
- package/skills/platform-apex-test-generate/SKILL.md +3 -1
- package/skills/platform-apex-test-run/SKILL.md +9 -8
- package/skills/platform-lightning-type-widget-coordinate/SKILL.md +1 -1
- package/skills/platform-lightning-type-widget-coordinate/examples/existing-lightning-type-with-widget-prompt.md +1 -1
- package/skills/platform-lightning-type-widget-coordinate/examples/new-lightning-type-with-widget-prompt.md +1 -1
- package/skills/platform-lightning-type-widget-coordinate/references/validation-gates.md +3 -3
- package/skills/platform-mcp-tool-widget-coordinate/SKILL.md +43 -67
- package/skills/platform-mcp-tool-widget-coordinate/examples/action-name-source-prompt.md +1 -2
- package/skills/platform-mcp-tool-widget-coordinate/examples/apex-invocable-source-prompt.md +2 -3
- package/skills/platform-mcp-tool-widget-coordinate/examples/nested-object-list-source-prompt.md +163 -0
- package/skills/platform-mcp-tool-widget-coordinate/examples/nested-object-single-source-prompt.md +198 -0
- package/skills/platform-mcp-tool-widget-coordinate/examples/pasted-tool-output-prompt.md +0 -1
- package/skills/platform-mcp-tool-widget-coordinate/references/build-plan-format.md +17 -11
- package/skills/platform-mcp-tool-widget-coordinate/references/mcp-tool-output-discovery.md +48 -15
- package/skills/platform-mcp-tool-widget-coordinate/references/two-clt-modeling.md +73 -10
- package/skills/platform-mcp-tool-widget-coordinate/references/validation-gates.md +48 -8
- package/skills/platform-policy-rule-generate/SKILL.md +22 -12
- package/skills/platform-policy-rule-generate/references/deploy-errors.md +1 -1
- package/skills/platform-policy-rule-generate/references/policy-schema-full.md +8 -29
- package/skills/platform-policy-rule-generate/references/templates-advanced.md +1 -1
- package/skills/platform-sharing-owd-configure/SKILL.md +20 -8
- package/skills/platform-sharing-owd-configure/references/access_levels.md +14 -1
- package/skills/platform-sharing-rules-generate/SKILL.md +67 -35
- package/skills/platform-sharing-rules-generate/examples/create-cases.md +16 -17
- package/skills/platform-sharing-rules-generate/examples/delete-cases.md +34 -79
- package/skills/platform-sharing-rules-generate/examples/edit-cases.md +13 -26
- package/skills/platform-sharing-rules-generate/scripts/count-remaining-rules.sh +33 -0
- package/skills/platform-widget-generate/SKILL.md +3 -5
- package/skills/platform-widget-generate/examples/conditional.json +18 -13
- package/skills/platform-widget-generate/examples/list-with-foreach.json +2 -2
- package/skills/platform-widget-generate/examples/single-object.json +2 -2
- package/skills/platform-widget-generate/references/schema-from-lightning-type.md +27 -6
- package/skills/platform-widget-generate/references/widget-bundle-layout.md +4 -3
- package/skills/service-itsm-agentic-setup-cmdb-access-assign/SKILL.md +287 -0
- package/skills/service-itsm-agentic-setup-cmdb-access-assign/references/mcp-invocation.md +260 -0
- package/skills/service-itsm-agentic-setup-cmdb-bundle-deploy/SKILL.md +252 -0
- package/skills/service-itsm-agentic-setup-cmdb-bundle-deploy/references/mcp-invocation.md +204 -0
- package/skills/service-itsm-agentic-setup-cmdb-configure/SKILL.md +259 -0
- package/skills/service-itsm-agentic-setup-cmdb-configure/references/mcp-invocation.md +188 -0
- package/skills/service-itsm-agentic-setup-cmdb-coordinate/SKILL.md +197 -0
- package/skills/service-itsm-agentic-setup-cmdb-coordinate/examples/output-templates.md +77 -0
- package/skills/service-itsm-agentic-setup-cmdb-discovery-configure/SKILL.md +316 -0
- package/skills/service-itsm-agentic-setup-cmdb-discovery-configure/references/mcp-invocation.md +221 -0
- package/skills/service-itsm-incident-priority-configure/SKILL.md +168 -0
- package/skills/service-itsm-incident-priority-configure/examples/matrix-operations.md +200 -0
- package/skills/service-itsm-incident-priority-configure/examples/render-matrix.md +54 -0
- package/skills/service-itsm-incident-priority-configure/examples/seed-full-matrix.md +52 -0
- package/skills/service-itsm-incident-priority-configure/references/sf-cli-invocation.md +264 -0
- package/skills/platform-mcp-tool-widget-coordinate/examples/nested-object-source-prompt.md +0 -191
- package/skills/platform-policy-rule-generate/references/fixtures-index.md +0 -29
package/skills/experience-lwc-accessibility-validate/references/reviewers/sc-1-3-1-ii-tables.md
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
## SC 1.3.1 - Info and Relationships (Level A)
|
|
2
|
+
|
|
3
|
+
Information, structure, and relationships conveyed through presentation can be programmatically determined or are available in text.
|
|
4
|
+
|
|
5
|
+
## SC: 1.3.1 (ii) - Tables Only
|
|
6
|
+
|
|
7
|
+
Analyze the given files using the following framework:
|
|
8
|
+
|
|
9
|
+
Review the provided HTML and JS files for accessibility violations per WCAG 2.2 SC 1.3.1 (ii), 'Tables'.
|
|
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).
|
|
11
|
+
|
|
12
|
+
For each of these elements, check if any of the following conditions of WCAG 2.2 SC 1.3.1 (ii), 'Tables' are true:
|
|
13
|
+
|
|
14
|
+
- The objective of this technique is to present tabular information in a way that preserves relationships within the information even when users cannot see the table or the presentation format is changed. Information is considered tabular when logical relationships among text, numbers, images, or other data exist in two dimensions (vertical and horizontal). These relationships are represented in columns and rows, and the columns and rows must be recognizable in order for the logical relationships to be perceived.
|
|
15
|
+
Check for the presence of tabular information.
|
|
16
|
+
For each instance of the `<table>` element found, perform the following checks:
|
|
17
|
+
- Verify the presence of table rows (`<tr>`): Ensure that each `<table>` element contains at least one `<tr>` element
|
|
18
|
+
- 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
|
|
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`
|
|
27
|
+
|
|
28
|
+
For simple data tables:
|
|
29
|
+
|
|
30
|
+
- If headers are in the first row or column:
|
|
31
|
+
- `th` elements without `scope` are sufficient
|
|
32
|
+
- If headers are not in the first row or column:
|
|
33
|
+
- Check that all `th` elements have a `scope` attribute
|
|
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
|
|
47
|
+
|
|
48
|
+
In order to fix a violation for a given element, you must examine the given component code and apply the most logical fix available such that the element satisfies one of the following conditions of WCAG 2.2 SC 1.3.1 (ii), 'Tables':
|
|
49
|
+
|
|
50
|
+
- The objective of this technique is to present tabular information in a way that preserves relationships within the information even when users cannot see the table or the presentation format is changed. Information is considered tabular when logical relationships among text, numbers, images, or other data exist in two dimensions (vertical and horizontal). These relationships are represented in columns and rows, and the columns and rows must be recognizable in order for the logical relationships to be perceived.
|
|
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`
|
|
63
|
+
|
|
64
|
+
For simple data tables:
|
|
65
|
+
|
|
66
|
+
- If headers are in the first row or column:
|
|
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
|
|
83
|
+
|
|
84
|
+
Note: A complex table is one where:
|
|
85
|
+
|
|
86
|
+
- Headers span multiple rows or columns
|
|
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
|
|
91
|
+
|
|
92
|
+
If they do not meet this success criterion, then flag this as a violation.
|
|
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.
|
|
100
|
+
- Keep issues concise, avoid duplicated issues or unnecessary or non-applicable problems.
|
|
101
|
+
- Assume that any imported functionality works as expected and was already analyzed.
|
|
102
|
+
- 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.
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
## SC 1.3.1 - Info and Relationships (Level A)
|
|
2
|
+
|
|
3
|
+
Information, structure, and relationships conveyed through presentation can be programmatically determined or are available in text.
|
|
4
|
+
|
|
5
|
+
## SC: 1.3.1 (iii) - Info and Relationships - Form Labels
|
|
6
|
+
|
|
7
|
+
Key Requirements:
|
|
8
|
+
|
|
9
|
+
1. Every form control must have a programmatic label via one of these methods:
|
|
10
|
+
|
|
11
|
+
- Label must be `<label>` with matching `for`/`id` attributes.
|
|
12
|
+
- `aria-label`/`aria-labelledby` (when visual labels are not feasible)
|
|
13
|
+
- `label` attribute, on `lightning-` prefixed namespace components (when applicable).
|
|
14
|
+
|
|
15
|
+
2. Label Content:
|
|
16
|
+
|
|
17
|
+
- Must be descriptive and meaningful
|
|
18
|
+
- No nested interactive elements
|
|
19
|
+
- Not just placeholder or title text
|
|
20
|
+
- Group controls need group and individual labels
|
|
21
|
+
|
|
22
|
+
3. Common Issues:
|
|
23
|
+
|
|
24
|
+
- Missing or empty labels
|
|
25
|
+
- Non-matching `for`/`id` attributes
|
|
26
|
+
- Placeholder text as labels
|
|
27
|
+
- Nested interactive elements in labels
|
|
28
|
+
|
|
29
|
+
4. Improper Label Content: Nested Interactive Elements:
|
|
30
|
+
|
|
31
|
+
- Examine the content of all label elements.
|
|
32
|
+
- Ensure no `<label>` contains interactive HTML elements as direct children or descendants. This includes:
|
|
33
|
+
- `<a>`, `<button>`, `<summary>` or any custom elements with interactive roles.
|
|
34
|
+
|
|
35
|
+
Following are some sufficient techniques that a user can use to meet this success criterion:
|
|
36
|
+
|
|
37
|
+
Form controls must have programmatically associated labels that clearly identify their purpose.
|
|
38
|
+
|
|
39
|
+
Required Label Associations:
|
|
40
|
+
|
|
41
|
+
1. Standard HTML Elements:
|
|
42
|
+
- All input types (`text`, `date`, `email`, `number`, `password`, `search`, `checkbox`, etc.)
|
|
43
|
+
- `select`, `textarea` elements
|
|
44
|
+
|
|
45
|
+
Some cases where the `label` HTML element is ignored:
|
|
46
|
+
|
|
47
|
+
- `button` element when the label is provided by the content
|
|
48
|
+
- `input type="button"` when the label is provided by the content
|
|
49
|
+
- `input type="hidden"`
|
|
50
|
+
- `input type="image"` when the label is provided by the `alt` attribute
|
|
51
|
+
- `input type="reset"` when the label is provided by the `value` attribute
|
|
52
|
+
- `input type="submit"` when the label is provided by the `value` attribute
|
|
53
|
+
- `input type="search"` when there is a `button` element with label next to search `input`
|
|
54
|
+
|
|
55
|
+
Exceptions (No Label Required):
|
|
56
|
+
|
|
57
|
+
- Buttons with descriptive content
|
|
58
|
+
- Hidden inputs
|
|
59
|
+
- Image inputs with alt text
|
|
60
|
+
- Submit/reset with value text
|
|
61
|
+
|
|
62
|
+
If they do not meet this success criterion, then flag this as a violation.
|
|
63
|
+
|
|
64
|
+
Rules to follow:
|
|
65
|
+
|
|
66
|
+
- Find all violations of SC 1.3.1 (iii) 'Form Labels' in the provided HTML and JS files
|
|
67
|
+
- Report only form label violations
|
|
68
|
+
- Provide specific control and issue details
|
|
69
|
+
- Keep reports concise and non-redundant
|
|
70
|
+
|
|
71
|
+
- For each issue found, provide a separate, detailed report.
|
|
72
|
+
- Keep issues concise, avoid duplicated issues or unnecessary or non-applicable problems.
|
|
73
|
+
- Assume that any imported functionality works as expected and was already analyzed.
|
|
74
|
+
- Components do not supplement or provide global functionalities.
|
|
75
|
+
- 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.
|
|
76
|
+
- 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.
|
|
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.
|
package/skills/experience-lwc-accessibility-validate/references/reviewers/sc-1-3-1-iv-regions.md
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
## SC 1.3.1 - Info and Relationships (Level A)
|
|
2
|
+
|
|
3
|
+
Information, structure, and relationships conveyed through presentation can be programmatically determined or are available in text.
|
|
4
|
+
|
|
5
|
+
## SC: 1.3.1 (iv) - Info And Relationships - Regions (A)
|
|
6
|
+
|
|
7
|
+
Review the provided HTML and JS files for accessibility violations per WCAG 2.2 SC 1.3.1 (iv), 'Info and Relationships'
|
|
8
|
+
(Only regions from this rule should be considered). For all regions on the page, ensure that any information conveyed through presentation is programmatically determinable in order to determine if they meet SC 1.3.1 (iv).
|
|
9
|
+
If they do not meet this success criterion, flag it as a violation.
|
|
10
|
+
|
|
11
|
+
Rules to follow:
|
|
12
|
+
|
|
13
|
+
- Find all violations of SC 1.3.1 'Info and Relationships - Regions' in the provided HTML and JS files.
|
|
14
|
+
- Do not worry about violations of SC 1.3.1 that are not specific to regions. These will be handled by other reviewers.
|
|
15
|
+
- Use semantic HTML elements (`<header>`, `<nav>`, `<main>`, `<aside>`, `<footer>`, `<section>`) to mark up regions. There cannot be more than one `<main>` element that does not have a hidden attribute specified.
|
|
16
|
+
- When semantic elements cannot be used, use ARIA landmark roles (`role="banner"`, `role="navigation"`, `role="main"`, `role="complementary"`, `role="contentinfo"`, `role="region"`).
|
|
17
|
+
- Each region should have a descriptive label or heading that identifies its purpose.
|
|
18
|
+
- Regions should be properly nested and not overlap.
|
|
19
|
+
- For each issue found, provide a separate, detailed report.
|
|
20
|
+
- Keep issues concise, avoid duplicated issues or unnecessary or non-applicable problems.
|
|
21
|
+
- Assume that any imported functionality works as expected and was already analyzed.
|
|
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.
|
package/skills/experience-lwc-accessibility-validate/references/reviewers/sc-1-3-1-v-groups.md
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
## SC 1.3.1 - Info and Relationships (Level A)
|
|
2
|
+
|
|
3
|
+
Information, structure, and relationships conveyed through presentation can be programmatically determined or are available in text.
|
|
4
|
+
|
|
5
|
+
## SC: 1.3.1 (v) - Info And Relationships - Groups only
|
|
6
|
+
|
|
7
|
+
Analyze the files using following context:
|
|
8
|
+
|
|
9
|
+
_Goal_: Information, structure and relationships conveyed through presentation can be programmatically determined or available in text.
|
|
10
|
+
|
|
11
|
+
_What to do_: Review the provided HTML and JS files for accessibility violations per WCAG 2.2 SC 1.3.1, 'Info and Relationships' with focus on groups requirements only.
|
|
12
|
+
|
|
13
|
+
Having structures and relationships programmatically determinable ensures that important information necessary for comprehension will be perceivable to all users. Grouping controls is most important for related radio buttons and checkboxes.
|
|
14
|
+
|
|
15
|
+
Examples:
|
|
16
|
+
|
|
17
|
+
- Form fields may be positioned as groups that share text labels.
|
|
18
|
+
- A multiple choice test with a question and set of radio buttons to present possible answers; the radio buttons are contained within a `fieldset` while the question is tagged with `legend` element.
|
|
19
|
+
- A user profile page allows users to indicate personal interests using checkboxes; the checkboxes are contained within a `fieldset`, and the `legend` element prompts the user to select one or more interests.
|
|
20
|
+
|
|
21
|
+
Following are some sufficient techniques that WCAG working group deems sufficient to meet this success criterion:
|
|
22
|
+
|
|
23
|
+
- ARIA17: Using grouping roles to identify related form controls within a form. Any label associated with group also serves as a common label for individual controls in this group.
|
|
24
|
+
This is a viable alternative to using `fieldset` / `legend` technique (H71). For a group of radio buttons, `role="radiogroup"` should be used instead of `role="group"` and is not meant to be used for wrapping all controls on a form within a single container with `role="group"`.
|
|
25
|
+
|
|
26
|
+
- For groups of related controls where individual labels for each control do not provide sufficient description, and additional group level description is needed
|
|
27
|
+
- Check that group of logically related input or select elements are contained within an element with `role="group"`, or `role="radiogroup"` depending on the type of elements in group.
|
|
28
|
+
- Check that this group has an accessible name describing it's purpose using `aria-label` or `aria-labelledby` attribute.
|
|
29
|
+
- The objective of this technique is to allow users to understand the relationship of form controls by providing semantic grouping and interact quickly.
|
|
30
|
+
Form controls can be grouped by enclosing them within `fieldset` element. All controls within a given `fieldset` are then related. The first element inside `fieldset` must be a `legend` element. Avoid nesting fieldsets unnecessarily, as this can lead to confusion.
|
|
31
|
+
A set of radio buttons or checkboxes are said to be related when they all submit values to single named field.
|
|
32
|
+
- They work same as selection lists that allow users to choose from set of options, except selection lists are single controls while radio buttons and checkboxes are multiple controls.
|
|
33
|
+
- The individual label associated with each radio button or checkbox control may not fully convey group's descriptive context.
|
|
34
|
+
It can also be helpful to group other sets of controls less tightly related than radio buttons and checkboxes, like form fields that collect user address might be grouped together with `legend` of "Address".
|
|
35
|
+
Authors sometimes avoid using `fieldset` element because the default display style draws a border around the grouped controls. However, this style can be modified with CSS by overriding 'border' property of `fieldset` and 'position' property of `legend`.
|
|
36
|
+
|
|
37
|
+
For groups of related controls where individual labels for each control do not provide sufficient context description, and additional group level description is needed; ensure following are true:
|
|
38
|
+
|
|
39
|
+
- Check that the group of logically related elements, like either `input` or `select` elements are contained within `fieldset` elements.
|
|
40
|
+
- Check that each `fieldset` has a `legend` element that is first child and includes a description for the group.
|
|
41
|
+
- The objective of this technique is to group items in a selection list.
|
|
42
|
+
A selection list is a set of allowed values for a form control such as multi-select list or combo box. In semantic HTML, the `select` element is used to create both multi-select lists and combo boxes, where various allowed options are each indicated with `option` elements, grouped together using `optgroup` element, and labeled the group with `label`.
|
|
43
|
+
|
|
44
|
+
For each selection list:
|
|
45
|
+
|
|
46
|
+
- Check the set of options within the list to see if there are groups of related options.
|
|
47
|
+
- If there are groups of related options, check that they are properly grouped (like using `optgroup` element)
|
|
48
|
+
|
|
49
|
+
- The objective of this technique is to group navigation links using HTML `nav` element or similar semantic sectioning elements. Using this markup can make groups of links easier to locate and navigate.
|
|
50
|
+
When such element is employed more than once on a page, distinguish navigation groups by using `aria-label` or `aria-labelledby` attribute.
|
|
51
|
+
Not all groups of links need to use `nav` element for markup. For example, links maybe grouped in other structures like lists or may use ARIA markup if do not present a discrete section of the page.
|
|
52
|
+
|
|
53
|
+
- Check that links that are grouped and represent a section of page, are enclosed in a `nav` element or similar semantics.
|
|
54
|
+
|
|
55
|
+
_Rules to follow_:
|
|
56
|
+
|
|
57
|
+
- 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.
|
|
58
|
+
- Do not worry about violations of SC 1.3.1 that are not specific to groups. These will be handled by other reviewers.
|
|
59
|
+
- For each issue found, provide a separate, detailed report.
|
|
60
|
+
- Keep issues concise, avoid duplicated issues or unnecessary or non-applicable problems.
|
|
61
|
+
- Assume that any imported functionality works as expected and was already analyzed.
|
|
62
|
+
- 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-lwc-accessibility-validate/references/reviewers/sc-1-3-5-identify-input.md
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
## SC 1.3.5 - Identify Input Purpose (Level AA)
|
|
2
|
+
|
|
3
|
+
The purpose of each input field collecting information about the user can be programmatically determined when the input field serves a purpose identified in the Input Purposes for User Interface Components section, and the content is implemented using technologies with support for identifying the expected meaning for form input data.
|
|
4
|
+
|
|
5
|
+
## SC: 1.3.5 - Identify Input Purpose Only
|
|
6
|
+
|
|
7
|
+
Analyze the given file using the following framework:
|
|
8
|
+
|
|
9
|
+
Review the provided HTML and JS files for accessibility violations per WCAG 2.2 SC 1.3.5, 'Identify Input Purpose'.
|
|
10
|
+
|
|
11
|
+
Specific guidance on `autocomplete` for certain input fields:
|
|
12
|
+
|
|
13
|
+
- **Non-personal information fields** (e.g., search, quantity selectors): These fields should EITHER have no `autocomplete` attribute OR use `autocomplete="off"`. Using any other specific `autocomplete` token on these fields is a violation.
|
|
14
|
+
- **Security-sensitive fields** (e.g., security questions): These fields MUST use `autocomplete="off"`. If the `autocomplete` attribute is missing or has any other value, it is a violation.
|
|
15
|
+
- **Fields for non-primary users** (e.g., spouse\'s name, emergency contact information such as emergency contact name, emergency contact phone etc):
|
|
16
|
+
- The ABSENCE of an `autocomplete` attribute on these fields is PERMISSIBLE and IS NOT a violation.
|
|
17
|
+
- IMPORTANT Instruction: DO NOT suggest adding an `autocomplete` attribute (such as `autocomplete="off"` or any other token) if it is missing for these fields simply because they pertain to a non-primary user.
|
|
18
|
+
- A violation should only be flagged for these fields if an `autocomplete` attribute is EXPLICITLY PRESENT AND uses an incorrect token (i.e., a token not from the H98Procedure list that doesn\'t match the input\'s apparent purpose, and is not `off`).
|
|
19
|
+
|
|
20
|
+
Common violations to check:
|
|
21
|
+
|
|
22
|
+
- Missing `autocomplete` attributes on personal information fields
|
|
23
|
+
- Using generic "on/off" instead of specific tokens
|
|
24
|
+
- Using invalid or non-standard `autocomplete` tokens. `Autocomplete` tokens must exactly match the standardized values listed in the H98Procedure (e.g., `given-name`, `email`, `tel`). Combinations of tokens (e.g., "email home") or more specific, non-standard variations (e.g., "tel mobile" instead of `tel`) are incorrect.
|
|
25
|
+
- Using incorrect capitalization in `autocomplete` values
|
|
26
|
+
- Using invalid formats (like "email, home")
|
|
27
|
+
- Missing `autocomplete` on dynamic/conditional fields
|
|
28
|
+
|
|
29
|
+
Following are some sufficient techniques that a user can use to meet this success criterion:
|
|
30
|
+
|
|
31
|
+
- The objective of this technique is to programmatically link a pre-defined and published taxonomic term to the input, so that the inputs can also be machine-interpreted.
|
|
32
|
+
The technique works by adding the appropriate `autocomplete` token to each form field on the form to make the identified inputs programmatically determinable. This will help people with cognitive disabilities who may not immediately know the purpose of the field because the label used by the author is not familiar to them. When inputs have been programmatically assigned, third party plugins and software can manipulate these form fields to make them more accessible to people with cognitive disabilities.
|
|
33
|
+
|
|
34
|
+
For each form field that collects information about the primary user and corresponds to an autocomplete field, check the following:
|
|
35
|
+
|
|
36
|
+
- The form field has a valid and well-formed `autocomplete` attribute and value pair
|
|
37
|
+
- The purpose of the form field indicated by the label corresponds with the `autocomplete` token on the input
|
|
38
|
+
- The `autocomplete` token matches the standardized values:
|
|
39
|
+
- For name: `name`
|
|
40
|
+
- For first-name: `given-name`
|
|
41
|
+
- For last-name: `family-name`
|
|
42
|
+
- For email: `email`
|
|
43
|
+
- For phone number: `tel`, `tel-national`
|
|
44
|
+
- For birthdays: `bday`
|
|
45
|
+
- For addresses: `street-address`(for the full street address, potentially across multiple lines), `address-line1`(for the first line of the address, example "123, main st"), `address-level2`(for the city), `country`
|
|
46
|
+
- For credentials: `username`(for username), `current-password`(for the password ), `new-password` (for signing up)
|
|
47
|
+
- Non-personal information fields such as search, quantity selectors should omit `autocomplete` or use `off`
|
|
48
|
+
- Security-sensitive fields such as security questions should use `autocomplete="off"`
|
|
49
|
+
|
|
50
|
+
For each form field that collects information about the other users, check the following:
|
|
51
|
+
|
|
52
|
+
- Please disregard the absence of an `autocomplete` attribute for fields that collect information about individuals other than the primary user such as spouse's name, emergency contact name, emergency contact phone no etc. and do not flag this as a violation.
|
|
53
|
+
|
|
54
|
+
If they do not meet this success criterion, then flag this as a violation.
|
|
55
|
+
|
|
56
|
+
Rules to follow:
|
|
57
|
+
|
|
58
|
+
- Find all violations of SC 1.3.5 'Identify Input Purpose' in the provided HTML and JS files
|
|
59
|
+
- Focus on form inputs that collect user information
|
|
60
|
+
- If no changes or action are needed, then produce an empty list.
|
|
61
|
+
- Critically evaluate each field against the specific guidance above. Do not conclude 'no action is needed' or 'correctly implemented' if no violations found.
|
|
62
|
+
|
|
63
|
+
- For each issue found, provide a separate, detailed report.
|
|
64
|
+
- Keep issues concise, avoid duplicated issues or unnecessary or non-applicable problems.
|
|
65
|
+
- Assume that any imported functionality works as expected and was already analyzed.
|
|
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.
|
package/skills/experience-lwc-accessibility-validate/references/reviewers/sc-1-4-3-contrast.md
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
## SC 1.4.3 - Contrast (Minimum) (Level AA)
|
|
2
|
+
|
|
3
|
+
The visual presentation of text and images of text has a contrast ratio of at least 4.5:1, except for large text (at least 3:1), incidental text (part of inactive components, purely decorative, not visible, or part of a picture containing significant other visual content), and logotypes.
|
|
4
|
+
|
|
5
|
+
## SC: 1.4.3 - Contrast (Minimum) (Level AA)
|
|
6
|
+
|
|
7
|
+
This reviewer focuses on ensuring enough contrast between text and its background so that it can be read by people with moderately low vision (who do not use contrast-enhancing assistive technology) as well as those with color deficiencies.
|
|
8
|
+
|
|
9
|
+
### Analysis Framework (What to do):
|
|
10
|
+
|
|
11
|
+
1. Identify all visible text elements (e.g., in tags like `<h1>`, `<div>`, `<p>`, `<label>`, `<button>`, etc.).
|
|
12
|
+
2. Determine the **color** (foreground) and **background color** (background) for each text element.
|
|
13
|
+
3. Determine the **font size** and **weight** to classify the text as Standard or Large-Scale.
|
|
14
|
+
4. Compute the contrast ratio with the bundled helper — **do not calculate luminance by hand**:
|
|
15
|
+
|
|
16
|
+
```bash
|
|
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:
|
|
24
|
+
>
|
|
25
|
+
> | Gray | Ratio | Standard (4.5:1) | Large (3:1) |
|
|
26
|
+
> | --------- | ----- | ---------------- | --------------- |
|
|
27
|
+
> | `#595959` | 7.00 | pass | pass |
|
|
28
|
+
> | `#666666` | 5.74 | pass | pass |
|
|
29
|
+
> | `#767676` | 4.54 | pass (boundary) | pass |
|
|
30
|
+
> | `#777777` | 4.48 | **fail** | pass |
|
|
31
|
+
> | `#808080` | 3.95 | fail | pass |
|
|
32
|
+
> | `#959595` | 3.00 | fail | pass (boundary) |
|
|
33
|
+
> | `#999999` | 2.85 | fail | **fail** |
|
|
34
|
+
> | `#AAAAAA` | 2.32 | fail | fail |
|
|
35
|
+
> | `#BBBBBB` | 1.92 | fail | fail |
|
|
36
|
+
>
|
|
37
|
+
> Rule of thumb for grayscale on white: `#767676` is the standard-text boundary — anything **darker** (lower hex value) passes 4.5:1; `#959595` is the large-text boundary for 3:1. In particular, **`#666666` and darker pass standard-text contrast — do not flag them.** For non-grayscale colors, non-white backgrounds, gradients, or alpha compositing, compute the exact ratio; if you cannot, do not guess — only flag when you are confident the ratio is below threshold.
|
|
38
|
+
|
|
39
|
+
### Goals for Contrast Compliance:
|
|
40
|
+
|
|
41
|
+
1. **Standard Text (Ratio 4.5:1):**
|
|
42
|
+
- **Good:** Black text on a white background (Ratio 21:1).
|
|
43
|
+
- **Bad:** Light gray text on a white background (e.g., #AAAAAA on #FFFFFF, Ratio 2.32:1).
|
|
44
|
+
2. **Large-Scale Text (Ratio 3:1):**
|
|
45
|
+
- **Good:** Medium gray text on a white background (e.g., #808080 on #FFFFFF, Ratio 3.95:1 — passes large-text 3:1 but fails standard-text 4.5:1).
|
|
46
|
+
- **Bad:** Light gray text on a white background (e.g., #BBBBBB on #FFFFFF, Ratio 1.92:1).
|
|
47
|
+
3. **Focus/Hover States:** While the primary check is for the default state, flag any explicit color changes defined in CSS that might reduce contrast below the minimum thresholds during focus or hover states. _(Note: Full dynamic state checking is complex, but hard-coded poor contrast colors must be flagged.)_
|
|
48
|
+
|
|
49
|
+
### What to Look For:
|
|
50
|
+
|
|
51
|
+
- Text elements where the foreground color is too similar to the background color.
|
|
52
|
+
- Hard-coded color combinations in CSS or inline styles that fail the 4.5:1 or 3:1 ratio.
|
|
53
|
+
- Text sizes that are small (Standard Text) but have a contrast ratio less than 4.5:1.
|
|
54
|
+
- Text sizes that are large-scale but have a contrast ratio less than 3:1.
|
|
55
|
+
- Usage of transparency/opacity that negatively impacts the calculated contrast ratio.
|
|
56
|
+
|
|
57
|
+
### Common Violations for Contrast:
|
|
58
|
+
|
|
59
|
+
- **Placeholder Text:** Placeholder text should have enough contrast.
|
|
60
|
+
- **Secondary/Hint Text:** Secondary text (e.g., helper text or captions) styled with low-contrast gray colors.
|
|
61
|
+
- **Disabled/Inactive Elements:** Though exempt under strict rules, _functional_ elements styled to look inactive when they are not.
|
|
62
|
+
- **Text on Complex Backgrounds:** Text placed over gradient or patterned backgrounds where the minimum contrast requirement is not met across the entire text area.
|
|
63
|
+
|
|
64
|
+
### To fix the Contrast Violations, Use the following techniques:
|
|
65
|
+
|
|
66
|
+
• **Foreground Color (Text) Fix:**
|
|
67
|
+
|
|
68
|
+
- **Action:** Locate the style rule (inline style, CSS file, or JS variable) defining the text color.
|
|
69
|
+
- **Correction:** If the current color is a light color (e.g., #AAAAAA), change it to a darker, compliant color (e.g., #595959).
|
|
70
|
+
- **Priority:** Prioritize using standard, dark text colors (e.g., #333333 or #000000) for accessibility whenever possible.
|
|
71
|
+
|
|
72
|
+
• **Background Color Fix:**
|
|
73
|
+
|
|
74
|
+
- **Action:** Locate the style rule defining the element's background-color.
|
|
75
|
+
- **Correction:** If the current background-color is a dark color (e.g., #333333), change it to a lighter, compliant color (e.g., #CCCCCC).
|
|
76
|
+
- **Priority:** Prioritize using standard, light background colors (e.g., #FFFFFF or #F5F5F5).
|
|
77
|
+
|
|
78
|
+
• **Inline Style Correction Example:**
|
|
79
|
+
|
|
80
|
+
- **Violation:** `<div style="color: #AAAAAA; background-color: #FFFFFF;">Low Contrast Text</div>`
|
|
81
|
+
- **Fix:** `<div style="color: #444444; background-color: #FFFFFF;">Compliant Contrast Text</div>`
|
|
82
|
+
|
|
83
|
+
• **Placeholder/Secondary Text Fix:**
|
|
84
|
+
|
|
85
|
+
- **Action:** For elements like `<input placeholder="text">` or secondary helper text, find the dedicated style (often `:placeholder` or a class for secondary text).
|
|
86
|
+
- **Correction:** Ensure the foreground color of the placeholder/secondary text is adjusted to meet at least the 4.5:1 ratio against the background of the input/container.
|
|
87
|
+
|
|
88
|
+
• **Remediation Strategy:**
|
|
89
|
+
|
|
90
|
+
- **Goal:** Modify the least number of color declarations (either `color` or `background-color`) necessary to achieve the target ratio (4.5:1 for standard text, 3:1 for large text).
|
|
91
|
+
- **Method:** If foreground text is light, darken it. If foreground text is dark, lighten the background.
|
|
92
|
+
- **Context:** Only modify color values (#RRGGBB, rgb(), hsl()) found in inline styles or referenced CSS blocks identified by the analysis.
|
|
93
|
+
|
|
94
|
+
## Exemptions (DO NOT FLAG):
|
|
95
|
+
|
|
96
|
+
1. **Decorative:** Text used purely for decorative purposes, where its specific lettering is not essential to understanding the content (e.g., text used as a stylized border).
|
|
97
|
+
2. **Logotypes:** Text that is part of a logo or brand name.
|
|
98
|
+
3. **Inactive UI Components:** Text in components that are disabled (e.g., a grayed-out button).
|
|
99
|
+
|
|
100
|
+
Rules to follow:
|
|
101
|
+
|
|
102
|
+
- Focus specifically on **visible text** in HTML and JS files.
|
|
103
|
+
- Only flag when the computed ratio falls below 4.5:1 for standard text or 3:1 for large-scale text
|
|
104
|
+
- Flag color combinations that result in a contrast ratio **below 4.5:1 for Standard Text**.
|
|
105
|
+
- Flag color combinations that result in a contrast ratio **below 3:1 for Large-Scale Text**.
|
|
106
|
+
- **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 with `scripts/contrast-ratio.py` (which also handles alpha compositing), falling back to the grayscale-on-white reference table above only as a sanity check. When the resolved colors themselves are uncertain (gradients, images behind text, unknown background), do not flag.
|
|
108
|
+
- For each issue found, provide a separate, detailed report.
|
|
109
|
+
- Keep issues concise, avoid duplicated issues or unnecessary or non-applicable problems.
|
|
110
|
+
- Assume that any imported functionality works as expected and was already analyzed.
|
|
111
|
+
- 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.
|
package/skills/experience-lwc-accessibility-validate/references/reviewers/sc-2-1-1-keyboard.md
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
## SC 2.1.1 - Keyboard (Level A)
|
|
2
|
+
|
|
3
|
+
All functionality of the content is operable through a keyboard interface without requiring specific timings for individual keystrokes, except where the underlying function requires input that depends on the path of the user's movement and not just the endpoints.
|
|
4
|
+
|
|
5
|
+
## SC: 2.1.1 - Keyboard
|
|
6
|
+
|
|
7
|
+
Analyze the given file using the following framework:
|
|
8
|
+
|
|
9
|
+
Review the provided HTML and JS files for accessibility violations per WCAG 2.2 SC 2.1.1, 'Keyboard'. For all elements on the page, ensure that the element exposes all interactivity that is achievable via mouse to keyboard in order to determine if they comply with SC 2.1.1. If they don't comply with the success criterion, then flag them a violation.
|
|
10
|
+
|
|
11
|
+
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
|
+
|
|
13
|
+
Common modes of failure for this rule are:
|
|
14
|
+
|
|
15
|
+
- Custom input implementations don't have an equivalent keyboard functionality. For example, an element with click or pointer handlers, but no equivalent functionality for keypress.
|
|
16
|
+
- Elements that can't be navigated to via the keyboard but can be interacted with via the mouse. For example, an interactive element that's missing a `tabindex`, either because it doesn't have one by default or it hasn't been explicitly assigned.
|
|
17
|
+
- Tooltips that are only accessible through mouse hover. For example, an element that displays a tooltip on mouse hover, however, there is no way to access the tooltip via keyboard. The tooltip should be accessible via hover, keyboard and click.
|
|
18
|
+
- Anchor (`<a>`) elements that are used as interactive controls (e.g., with `onclick` or have an `onclick` attribute) and don't have an `href` attribute aren't focusable or operable via keyboard. This is a violation. Use a `button` element or ensure that the anchor has an `href` and is accessible via the keyboard.
|
|
19
|
+
- **Incorrect Tab Indices**: When a parent element has `tabindex="0"` but its child interactive element has `tabindex="-1"`, this creates a keyboard trap. The parent becomes focusable but the child button/link cannot be activated via keyboard. Always flag this pattern as "Incorrect Tab Indices".
|
|
20
|
+
- **Tabindex out of sequence**: When `tabindex` values are greater than 0, they disrupt the natural keyboard navigation order. Flag any `tabindex` with positive values (1, 2, 10, etc.) as violations that need to be removed.
|
|
21
|
+
- **DIV elements with event handlers**: Non-semantic elements (`div`, `span`) with click handlers must have `tabindex="0"` to be keyboard accessible. Without `tabindex`, they cannot receive focus.
|
|
22
|
+
|
|
23
|
+
Given the common modes of failure, consider:
|
|
24
|
+
|
|
25
|
+
- Is the control using semantic HTML? If the semantic HTML default behaviors aren't overridden and new mouse functions aren't added, it will work with a keyboard. Don't flag this as a violation.
|
|
26
|
+
- Is the control focusable? If the control is focusable, it can properly handle a keyboard event. Don't flag this as a violation.
|
|
27
|
+
- Does anything override the focus event? If native focus is allowed, then nothing will override the focus event and elements should receive and handle focus events correctly. If the focus is altered, elements might not receive or handle focus events correctly.
|
|
28
|
+
|
|
29
|
+
**SPECIFIC TABINDEX PATTERNS TO IDENTIFY:**
|
|
30
|
+
|
|
31
|
+
1. **Parent-Child Tabindex Conflicts**: Scan for `<li tabindex="0">` containing `<button tabindex="-1">` or similar patterns where parent is focusable but child interactive element is not.
|
|
32
|
+
2. **High Tabindex Values**: Look for any `tabindex="X"` where X > 0 (like `tabindex="10"`, `tabindex="5"`). These disrupt natural tab order.
|
|
33
|
+
3. **Semantic Elements with Unnecessary Tabindex**: Buttons, links, and form controls don't need explicit `tabindex` values.
|
|
34
|
+
|
|
35
|
+
Rules to follow:
|
|
36
|
+
|
|
37
|
+
- Find all violations of SC 2.1.1 'Keyboard' in the provided HTML and JS files.
|
|
38
|
+
- DO NOT flag issues when native HTML elements provide sufficient keyboard accessibility.
|
|
39
|
+
|
|
40
|
+
- For each issue found, provide a separate, detailed report.
|
|
41
|
+
- Keep issues concise, avoid duplicated issues or unnecessary or non-applicable problems.
|
|
42
|
+
- Assume that any imported functionality works as expected and was already analyzed.
|
|
43
|
+
- Components do not supplement or provide global functionalities.
|
|
44
|
+
- 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.
|
|
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.
|
package/skills/experience-lwc-accessibility-validate/references/reviewers/sc-2-4-4-link-purpose.md
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
## SC 2.4.4 - Link Purpose (In Context) (Level A)
|
|
2
|
+
|
|
3
|
+
The purpose of each link can be determined from the link text alone or from the link text together with its programmatically determined link context, except where the purpose of the link would be ambiguous to users in general.
|
|
4
|
+
|
|
5
|
+
## SC: 2.4.4 - Link Purpose (In Context)
|
|
6
|
+
|
|
7
|
+
Analyze the given file using the following framework:
|
|
8
|
+
|
|
9
|
+
Review the provided HTML file for accessibility violations per WCAG 2.2 SC 2.4.4, 'Link Purpose (In Context)'. For all anchor elements (`<a>`) and other interactive elements that function as links, ensure that the link text is descriptive enough to convey the purpose of the link, either on its own or with its immediate context (such as the same sentence, list item, or table cell). If the link purpose cannot be determined, flag this as a violation.
|
|
10
|
+
|
|
11
|
+
Common modes of failure for this rule are:
|
|
12
|
+
|
|
13
|
+
- Using vague link text such as 'click here', 'read more', or 'more' without sufficient context. (Type: "Vague Link Text")
|
|
14
|
+
- Relying on context that is not programmatically associated with the link (e.g., context that is visually near but not in the same sentence, list item, or table cell).
|
|
15
|
+
- Using only an icon or image as a link without accessible text or an appropriate accessible name, such as an `aria-label`. (Type: "Non-descriptive Icon Link")
|
|
16
|
+
- Multiple links using the same non-descriptive text (e.g., "Read more") but pointing to different destinations. (Type: "Duplicate Link Text")
|
|
17
|
+
|
|
18
|
+
For each violation, provide:
|
|
19
|
+
|
|
20
|
+
- The exact type as listed above.
|
|
21
|
+
- A detailed description of why it is a problem, referencing accessibility best practices.
|
|
22
|
+
- An intent analysis explaining what the developer likely intended.
|
|
23
|
+
- A suggested action, with precise recommendations (e.g., for icon links, recommend adding an `aria-label`, not just alt text).
|
|
24
|
+
- For duplicate link text, identify and report all instances, not just the first.
|
|
25
|
+
|
|
26
|
+
Rules to follow:
|
|
27
|
+
|
|
28
|
+
- Find all violations of SC 2.4.4 'Link Purpose (In Context)' in the provided HTML file.
|
|
29
|
+
- If no changes are needed, then produce an empty list.
|
|
30
|
+
- Use the exact terminology for issue types as listed above.
|
|
31
|
+
|
|
32
|
+
- For each issue found, provide a separate, detailed report.
|
|
33
|
+
- Keep issues concise, avoid duplicated issues or unnecessary or non-applicable problems.
|
|
34
|
+
- Assume that any imported functionality works as expected and was already analyzed.
|
|
35
|
+
- Components do not supplement or provide global functionalities.
|
|
36
|
+
- 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.
|
|
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.
|