@salesforce/afv-skills 1.55.0 → 1.56.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/skills/agentforce-generate/SKILL.md +8 -0
- package/skills/agentforce-generate/references/actions-reference.md +2 -2
- package/skills/agentforce-generate/references/voice-modality-reference.md +51 -15
- package/skills/agentforce-generate/references/voice-telephony-cli.md +193 -0
- package/skills/agentforce-observe/SKILL.md +13 -9
- package/skills/agentforce-observe/references/ahm-alerts.md +193 -14
- package/skills/automation-sandbox-post-copy-config-generate/SKILL.md +24 -15
- package/skills/automation-sandbox-post-copy-config-generate/assets/config_template.json +11 -0
- package/skills/automation-sandbox-post-copy-config-generate/assets/json_schema.json +33 -1
- package/skills/automation-sandbox-post-copy-config-generate/references/configuration_catalog.md +32 -1
- package/skills/automation-sandbox-post-copy-configure/SKILL.md +75 -71
- package/skills/automation-sandbox-post-copy-configure/assets/scheduled_apex_template.apex +13 -0
- package/skills/automation-sandbox-post-copy-configure/examples/sample_scheduled_apex_config.json +13 -0
- package/skills/automation-sandbox-post-copy-configure/references/scheduled_apex_path.md +155 -0
- package/skills/automation-sandbox-post-copy-configure/scripts/build-scheduled-apex.mjs +62 -0
- package/skills/automation-sandbox-post-copy-configure/scripts/soql-escape-job-name.mjs +28 -0
- package/skills/consumer-goods-accruals-datakit-deploy/SKILL.md +383 -0
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/setup.js +324 -0
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/00-check-prerequisites.js +63 -0
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/01-download-static-resource.js +100 -0
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/02-replace-org-id.js +46 -0
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/03-deploy-metadata.js +46 -0
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/04-deploy-engine.js +198 -0
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/05-deploy-tpm-accruals.js +231 -0
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/06-create-dataspace.js +82 -0
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/07-deploy-accruals-reports.js +517 -0
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/08-deploy-ui.js +416 -0
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/09-completion.js +44 -0
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/utils.js +514 -0
- package/skills/consumer-goods-sync-management-configure/SKILL.md +137 -0
- package/skills/consumer-goods-sync-management-configure/examples/scenarios.md +294 -0
- package/skills/consumer-goods-sync-management-configure/references/act1-setup-sync.md +333 -0
- package/skills/consumer-goods-sync-management-configure/references/act2-assign-users.md +324 -0
- package/skills/consumer-goods-sync-management-configure/references/act3-plan-verify.md +113 -0
- package/skills/consumer-goods-sync-management-configure/references/readiness-and-enablement.md +164 -0
- package/skills/consumer-goods-sync-management-configure/references/sync-management-app-install-backbone.md +159 -0
- package/skills/consumer-goods-sync-management-configure/references/transports-and-namespace.md +220 -0
- package/skills/consumer-goods-sync-management-configure/references/verify-and-smoke.md +175 -0
- package/skills/dx-org-analyze/SKILL.md +0 -1
- package/skills/dx-org-analyze/scripts/collect_org_data.py +2 -2
- package/skills/dx-org-analyze/scripts/compute_diff.py +2 -4
- package/skills/dx-org-analyze/scripts/introspect_org.py +4 -40
- package/skills/dx-org-manage/SKILL.md +6 -50
- package/skills/dx-org-manage/examples/README.md +10 -16
- package/skills/dx-org-manage/references/scratch-org-create.md +1 -1
- package/skills/dx-org-manage/references/scratch-org-operations.md +1 -1
- package/skills/dx-org-shape-manage/SKILL.md +4 -3
- package/skills/education-cloud-domain-configure/references/gotchas-extended.md +1 -0
- package/skills/experience-accessibility-validate/SKILL.md +8 -5
- package/skills/experience-accessibility-validate/references/reviewers/sc-1-1-1-non-text-content.md +1 -4
- package/skills/experience-accessibility-validate/references/reviewers/sc-1-3-1-i-lists.md +0 -4
- package/skills/experience-accessibility-validate/references/reviewers/sc-1-3-1-ii-tables.md +20 -85
- package/skills/experience-accessibility-validate/references/reviewers/sc-1-3-1-iii-form-labels.md +4 -4
- package/skills/experience-accessibility-validate/references/reviewers/sc-1-3-1-iv-regions.md +0 -4
- package/skills/experience-accessibility-validate/references/reviewers/sc-1-3-1-v-groups.md +2 -4
- package/skills/experience-accessibility-validate/references/reviewers/sc-1-3-5-identify-input.md +0 -4
- package/skills/experience-accessibility-validate/references/reviewers/sc-1-4-3-contrast.md +4 -14
- package/skills/experience-accessibility-validate/references/reviewers/sc-2-1-1-keyboard.md +9 -5
- package/skills/experience-accessibility-validate/references/reviewers/sc-2-4-4-link-purpose.md +1 -4
- package/skills/experience-accessibility-validate/references/reviewers/sc-2-4-6-headings-labels.md +0 -4
- package/skills/experience-accessibility-validate/references/reviewers/sc-2-5-1-pointer-gestures.md +0 -4
- package/skills/experience-accessibility-validate/references/reviewers/sc-2-5-2-pointer-cancellation.md +0 -4
- package/skills/experience-accessibility-validate/references/reviewers/sc-2-5-3-label-in-name.md +0 -4
- package/skills/experience-accessibility-validate/references/reviewers/sc-2-5-7-dragging-movement.md +0 -4
- package/skills/experience-accessibility-validate/references/reviewers/sc-3-2-1-on-focus.md +0 -4
- package/skills/experience-accessibility-validate/references/reviewers/sc-3-2-2-on-input.md +1 -4
- package/skills/experience-accessibility-validate/references/reviewers/sc-3-3-1-error-identification.md +1 -4
- package/skills/experience-accessibility-validate/references/reviewers/sc-3-3-2-labels-instructions.md +1 -4
- package/skills/experience-accessibility-validate/references/reviewers/sc-3-3-3-error-suggestion.md +1 -4
- package/skills/experience-accessibility-validate/references/reviewers/sc-4-1-2-i-name.md +4 -5
- package/skills/experience-accessibility-validate/references/reviewers/sc-4-1-2-ii-role.md +1 -4
- package/skills/experience-accessibility-validate/references/reviewers/sc-4-1-2-iii-value.md +0 -4
- package/skills/experience-lwc-accessibility-jest-run/SKILL.md +104 -25
- package/skills/experience-lwc-accessibility-jest-run/assets/jest.config.js +4 -0
- package/skills/experience-lwc-accessibility-jest-run/assets/sa11y-jest-setup.js +5 -0
- package/skills/experience-ui-bundle-app-coordinate/SKILL.md +5 -5
- package/skills/experience-ui-bundle-features-generate/SKILL.md +65 -36
- package/skills/experience-ui-bundle-features-generate/references/angular/features.md +74 -0
- package/skills/experience-ui-bundle-features-generate/references/react/features.md +59 -0
- package/skills/experience-ui-bundle-features-generate/scripts/detect-framework.sh +73 -0
- package/skills/experience-ui-bundle-frontend-generate/SKILL.md +2 -2
- package/skills/experience-ui-bundle-metadata-generate/SKILL.md +26 -14
- package/skills/experience-ui-bundle-metadata-generate/references/angular-metadata-generate.md +37 -0
- package/skills/experience-ui-bundle-metadata-generate/references/react-metadata-generate.md +32 -0
- package/skills/experience-ui-bundle-metadata-generate/scripts/detect-framework.sh +73 -0
- package/skills/experience-ui-bundle-metadata-generate/scripts/verify-bundle-location.sh +30 -8
- package/skills/field-service-data-capture-migrate/SKILL.md +391 -0
- package/skills/field-service-data-capture-migrate/assets/sample-legacy-flow.flow-meta.xml +163 -0
- package/skills/field-service-data-capture-migrate/references/architecture-notes.md +40 -0
- package/skills/field-service-data-capture-migrate/references/component-mapping.md +278 -0
- package/skills/field-service-data-capture-migrate/references/converter-builder-contract.md +183 -0
- package/skills/field-service-data-capture-migrate/references/dc-platform-rules.md +130 -0
- package/skills/field-service-data-capture-migrate/references/fsm-dc-capability-catalog.md +215 -0
- package/skills/field-service-data-capture-migrate/references/known-deploy-errors.md +36 -0
- package/skills/field-service-data-capture-migrate/references/migration-checklist.md +121 -0
- package/skills/field-service-data-capture-migrate/references/transformer-rules.md +132 -0
- package/skills/field-service-data-capture-migrate/scripts/analyze_flow.py +277 -0
- package/skills/field-service-data-capture-migrate/scripts/convert_to_dc_spec.py +1311 -0
- package/skills/field-service-data-capture-migrate/scripts/cud_analysis.py +402 -0
- package/skills/field-service-data-capture-migrate/scripts/deploy_flow.sh +230 -0
- package/skills/field-service-data-capture-migrate/scripts/discover_subflow_tree.py +230 -0
- package/skills/field-service-data-capture-migrate/scripts/flow_input.py +186 -0
- package/skills/field-service-data-capture-migrate/scripts/flow_xml_utils.py +39 -0
- package/skills/field-service-data-capture-migrate/scripts/fsm_dc_catalog.py +413 -0
- package/skills/field-service-data-capture-migrate/scripts/generate_summary.py +199 -0
- package/skills/field-service-data-capture-migrate/scripts/json_to_flow_xml.py +146 -0
- package/skills/field-service-data-capture-migrate/scripts/manual_review_flags.py +42 -0
- package/skills/field-service-data-capture-migrate/scripts/retrieve_flow_rest.sh +155 -0
- package/skills/field-service-data-capture-migrate/scripts/subflow_names.py +49 -0
- package/skills/field-service-data-capture-migrate/scripts/transform_flow.py +1661 -0
- package/skills/field-service-data-capture-migrate/scripts/validate_flow.sh +147 -0
- package/skills/field-service-data-capture-migrate/scripts/vendor/build_flow.py +1258 -0
- package/skills/life-sciences-fieldsalesrep-coordinate/SKILL.md +1 -1
- package/skills/life-sciences-fieldsalesrep-coordinate/references/orchestration-flow.md +1 -1
- package/skills/life-sciences-kam-coordinate/references/stage-5-data-and-plan-templates-overview.md +14 -1
- package/skills/mobile-apps-create/SKILL.md +1 -1
- package/skills/{platform-agentsetup-categories-fetch → platform-agenticsetup-categories-get}/SKILL.md +7 -7
- package/skills/platform-sandbox-configure/SKILL.md +108 -133
- package/skills/platform-sandbox-configure/references/api-response-shapes.md +39 -0
- package/skills/platform-sandbox-configure/references/definition-file-approach.md +73 -0
- package/skills/platform-widget-generate/SKILL.md +26 -18
- package/skills/platform-widget-generate/examples/formulas.json +191 -0
- package/skills/platform-widget-generate/references/widget-formulas.md +123 -0
- package/skills/platform-widget-generate/references/widget-meta-directives.md +4 -4
- package/skills/sales-call-scoring-configure/SKILL.md +318 -0
- package/skills/sales-call-scoring-configure/assets/best-practice-competencies.json +67 -0
- package/skills/sales-call-scoring-configure/assets/ootb-competencies.json +58 -0
- package/skills/sales-call-scoring-configure/references/admin-communication.md +79 -0
- package/skills/sales-call-scoring-configure/references/competency-crud.md +130 -0
- package/skills/sales-call-scoring-configure/scripts/create-competency.sh +166 -0
- package/skills/sales-call-scoring-configure/scripts/create-custom-competency.sh +166 -0
- package/skills/sales-call-scoring-configure/scripts/edit-competency.sh +185 -0
- package/skills/sales-call-scoring-configure/scripts/edit-custom-competency.sh +190 -0
- package/skills/sales-call-scoring-configure/scripts/enable-call-scoring.sh +436 -0
- package/skills/sales-call-scoring-configure/scripts/get-competency.sh +72 -0
- package/skills/sales-call-scoring-configure/scripts/get-custom-competency.sh +78 -0
- package/skills/sales-call-scoring-configure/scripts/install-best-practice-competencies.sh +223 -0
- package/skills/sales-call-scoring-configure/scripts/install-ootb-competencies.sh +237 -0
- package/skills/sales-call-scoring-configure/scripts/list-competencies.sh +99 -0
- package/skills/sales-call-scoring-configure/scripts/shared/auth.sh +116 -0
- package/skills/sales-call-scoring-configure/scripts/shared/cap.sh +86 -0
- package/skills/sales-call-scoring-configure/scripts/shared/soap.sh +267 -0
- package/skills/sales-call-scoring-configure/scripts/shared/soql.sh +25 -0
- package/skills/sales-call-scoring-configure/scripts/toggle-competency.sh +112 -0
- package/skills/sales-call-scoring-configure/scripts/toggle-custom-competency.sh +125 -0
- package/skills/sales-call-scoring-configure/scripts/verify-ootb-competencies.sh +116 -0
- package/skills/service-concierge-portal-generate/references/portal-deploy-runbook.md +1 -0
- package/skills/service-de-channel-activate/SKILL.md +6 -5
- package/skills/service-de-channel-create/SKILL.md +3 -3
- package/skills/service-de-channel-routing-configure/SKILL.md +3 -3
- package/skills/service-de-channel-settings-configure/SKILL.md +195 -0
- package/skills/service-de-channel-settings-configure/references/channel-settings-facets.md +152 -0
- package/skills/{service-de-channel-consent-configure → service-de-channel-settings-configure}/references/gotchas.md +3 -3
- package/skills/{service-de-channel-consent-configure → service-de-channel-settings-configure}/references/language-keywords.md +4 -4
- package/skills/{service-de-channel-consent-configure → service-de-channel-settings-configure}/references/worked-examples.md +14 -14
- package/skills/service-de-headless-channel-configure/SKILL.md +6 -6
- package/skills/service-de-headless-channel-configure/references/worked-examples.md +1 -1
- package/skills/service-helpagent-coordinate/SKILL.md +3 -2
- package/skills/service-helpagent-coordinate/references/channel-voice.md +15 -4
- package/skills/service-itsm-agentic-setup-agentforce-coordinate/SKILL.md +49 -31
- package/skills/service-itsm-agentic-setup-agentforce-coordinate/examples/output-templates.md +71 -6
- package/skills/service-itsm-agentic-setup-agentforce-coordinate/scripts/verify-child-verdict.mjs +26 -4
- package/skills/service-itsm-agentic-setup-cmdb-access-assign/SKILL.md +35 -10
- package/skills/service-itsm-agentic-setup-cmdb-access-assign/references/mcp-invocation.md +25 -5
- package/skills/service-itsm-agentic-setup-cmdb-bundle-deploy/SKILL.md +1 -1
- package/skills/service-itsm-agentic-setup-cmdb-configure/SKILL.md +5 -5
- package/skills/service-itsm-agentic-setup-cmdb-configure/references/mcp-invocation.md +1 -1
- package/skills/service-itsm-agentic-setup-cmdb-coordinate/SKILL.md +2 -2
- package/skills/service-itsm-agentic-setup-cmdb-coordinate/examples/output-templates.md +1 -1
- package/skills/service-itsm-agentic-setup-cmdb-discovery-configure/SKILL.md +25 -15
- package/skills/service-itsm-agentic-setup-employee-agent-configure/SKILL.md +8 -5
- package/skills/service-itsm-agentic-setup-employee-agent-configure/references/report-format.md +4 -2
- package/skills/service-itsm-agentic-setup-employee-agent-configure/references/workflow-detail.md +1 -1
- package/skills/service-itsm-agentic-setup-employee-agent-configure/scripts/render-report.mjs +29 -16
- package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/SKILL.md +8 -5
- package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/references/report-format.md +4 -2
- package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/references/workflow-detail.md +1 -1
- package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/scripts/render-report.mjs +29 -16
- package/skills/service-itsm-agentic-setup-incident-management/SKILL.md +138 -68
- package/skills/service-itsm-agentic-setup-incident-management/examples/output-templates.md +31 -15
- package/skills/service-itsm-agentic-setup-incident-management/references/incident-persona-psg.md +156 -0
- package/skills/service-itsm-agentic-setup-incident-management/references/incident-preferences.md +148 -0
- package/skills/service-itsm-agentic-setup-incident-management/references/major-incident-management.md +162 -0
- package/skills/service-itsm-agentic-setup-incident-management/references/service-mgmt-privilege.md +149 -0
- package/skills/service-itsm-agentic-setup-incident-sla-configure/SKILL.md +103 -89
- package/skills/service-itsm-agentic-setup-incident-sla-configure/assets/attach-milestone.json +2 -2
- package/skills/service-itsm-agentic-setup-incident-sla-configure/assets/predefined-incident-policy.json +21 -39
- package/skills/service-itsm-agentic-setup-incident-sla-configure/examples/milestone-patterns.md +3 -3
- package/skills/service-itsm-agentic-setup-incident-sla-configure/examples/output-templates.md +18 -1
- package/skills/service-itsm-agentic-setup-incident-sla-configure/references/mcp-invocation.md +63 -37
- package/skills/service-omni-attribute-routing-configure/SKILL.md +53 -0
- package/skills/service-omni-attribute-routing-configure/references/api-notes.md +7 -0
- package/skills/service-omni-attribute-routing-configure/scripts/configure-and-report.sh +224 -0
- package/skills/service-omni-attribute-routing-configure/scripts/tests/test_attribute_routing_contracts.py +137 -0
- package/skills/service-omni-channel-inventory-analyze/SKILL.md +96 -0
- package/skills/service-omni-channel-inventory-analyze/references/api-notes.md +52 -0
- package/skills/service-omni-channel-inventory-analyze/scripts/analyze.sh +185 -0
- package/skills/service-omni-channel-inventory-analyze/scripts/tests/_bootstrap.py +84 -0
- package/skills/service-omni-channel-inventory-analyze/scripts/tests/test_inventory_analyze_contracts.py +141 -0
- package/skills/service-omni-channel-limits-analyze/SKILL.md +70 -0
- package/skills/service-omni-channel-limits-analyze/references/api-notes.md +22 -0
- package/skills/service-omni-channel-limits-analyze/scripts/analyze.sh +159 -0
- package/skills/service-omni-channel-limits-analyze/scripts/tests/_bootstrap.py +87 -0
- package/skills/service-omni-channel-limits-analyze/scripts/tests/test_limits_analyze_contracts.py +99 -0
- package/skills/service-omni-channel-setup-coordinate/SKILL.md +12 -20
- package/skills/service-omni-channel-setup-coordinate/scripts/integration-driver.sh +55 -5
- package/skills/service-omni-channel-setup-coordinate/scripts/tests/test_omni_contracts.py +38 -0
- package/skills/service-omni-command-center-analyze/SKILL.md +2 -2
- package/skills/service-omni-command-center-analyze/scripts/analyze.sh +3 -3
- package/skills/dx-org-manage/examples/snapshots/error_output.json +0 -9
- package/skills/dx-org-manage/examples/snapshots/success_output.json +0 -15
- package/skills/dx-org-manage/references/cli_flags.md +0 -67
- package/skills/dx-org-manage/references/creating-snapshot.md +0 -103
- package/skills/dx-org-manage/references/snapshot_usage.md +0 -74
- package/skills/experience-accessibility-validate/scripts/contrast-ratio.py +0 -153
- package/skills/experience-lwc-accessibility-jest-run/references/running-sa11y-jest-tests.md +0 -205
- package/skills/experience-ui-bundle-features-generate/scripts/verify-react-bundle.sh +0 -14
- /package/skills/experience-ui-bundle-features-generate/references/{conflict-resolution-schema.json → common/conflict-resolution-schema.json} +0 -0
- /package/skills/{platform-agentsetup-categories-fetch → platform-agenticsetup-categories-get}/references/api-response-schema.md +0 -0
|
@@ -11,16 +11,10 @@ This reviewer focuses on ensuring enough contrast between text and its backgroun
|
|
|
11
11
|
1. Identify all visible text elements (e.g., in tags like `<h1>`, `<div>`, `<p>`, `<label>`, `<button>`, etc.).
|
|
12
12
|
2. Determine the **color** (foreground) and **background color** (background) for each text element.
|
|
13
13
|
3. Determine the **font size** and **weight** to classify the text as Standard or Large-Scale.
|
|
14
|
-
4.
|
|
14
|
+
4. Calculate the contrast ratio using the WCAG formula: $(L1 + 0.05) / (L2 + 0.05)$, where L1 is the relative luminance of the lighter color, and L2 is the relative luminance of the darker color.
|
|
15
|
+
5. Check if the calculated ratio meets the required threshold (4.5:1 or 3:1).
|
|
15
16
|
|
|
16
|
-
|
|
17
|
-
python3 scripts/contrast-ratio.py FOREGROUND BACKGROUND [--large]
|
|
18
|
-
```
|
|
19
|
-
|
|
20
|
-
Pass the resolved foreground and background colors (`#RGB`, `#RRGGBB`, `rgb()`, or `rgba()`); add `--large` when the text is large-scale (≥24px, or ≥18.66px bold). The script alpha-composites a translucent *foreground* over the background, applies the exact WCAG formula $(L1 + 0.05) / (L2 + 0.05)$, and prints the ratio plus a `PASS`/`FAIL` verdict for both thresholds (exit code `0` = meets the applicable threshold, `1` = below it, `2` = parse error). The **background must be opaque** — a translucent `rgba()` background is rejected (exit code `2`) because its rendered color depends on the unknown layer beneath it; resolve the effective opaque background first and pass that. Use `--json` for a machine-readable object. The script's verdict is authoritative; use it rather than an estimate.
|
|
21
|
-
5. Treat the script's verdict against the required threshold (4.5:1 standard, 3:1 large) as the check result.
|
|
22
|
-
|
|
23
|
-
> **Do not estimate luminance by hand.** Mentally approximating relative luminance is unreliable — it has produced false positives and even different ratios for the _same_ color. Run `scripts/contrast-ratio.py` for the exact value. The verified reference below (sRGB gray `#NNNNNN` on `#FFFFFF`) is a quick sanity check for the common grayscale-text-on-white case, not a substitute for the script:
|
|
17
|
+
> **Do not estimate luminance by hand.** Mentally approximating relative luminance is unreliable — it has produced false positives and even different ratios for the _same_ color. Compute the WCAG formula exactly, or for the common grayscale-text-on-white case use this verified reference (sRGB gray `#NNNNNN` on `#FFFFFF`):
|
|
24
18
|
>
|
|
25
19
|
> | Gray | Ratio | Standard (4.5:1) | Large (3:1) |
|
|
26
20
|
> | --------- | ----- | ---------------- | --------------- |
|
|
@@ -104,12 +98,8 @@ Rules to follow:
|
|
|
104
98
|
- Flag color combinations that result in a contrast ratio **below 4.5:1 for Standard Text**.
|
|
105
99
|
- Flag color combinations that result in a contrast ratio **below 3:1 for Large-Scale Text**.
|
|
106
100
|
- **Ignore** text clearly marked as decorative, part of a logo, or permanently disabled/inactive components.
|
|
107
|
-
- Do not assume or estimate the contrast ratio — compute it
|
|
101
|
+
- Do not assume or estimate the contrast ratio — compute it exactly, or use the grayscale-on-white reference table above. When the exact ratio is uncertain (gradients, alpha compositing, images behind text, unknown background), do not flag.
|
|
108
102
|
- For each issue found, provide a separate, detailed report.
|
|
109
103
|
- Keep issues concise, avoid duplicated issues or unnecessary or non-applicable problems.
|
|
110
104
|
- Assume that any imported functionality works as expected and was already analyzed.
|
|
111
105
|
- Components do not supplement or provide global functionalities.
|
|
112
|
-
- Lightning base components (`lightning-input`, `lightning-combobox`, `lightning-textarea`, `lightning-icon`, etc.) provide their own accessible labeling, ARIA, and error handling in shadow DOM via their dedicated attributes (`label`, `alternative-text`, field-level validation). When such a component is given a `label` attribute it is already programmatically labeled — even with `variant="label-hidden"`, which hides the label visually but keeps it for assistive technology. Do **not** flag a sibling/wrapper `<label>` or `<span>` for a missing `for`/`id` when the actual control is a self-labeling Lightning component, and do not treat a visible heading as if it were the control's only label. This also covers navigation and icon base components (`lightning-vertical-navigation-item`, `lightning-vertical-navigation-item-icon`, `lightning-button-icon`, etc.): when a `label` (or `alternative-text`) attribute is supplied, the base component renders it as the visible link/control text **and** exposes it as the accessible name, and any `icon-name` is decorative — do not emit a 4.1.2 "verify the label is associated with the icon" warning, even a hedged one. The presence of the `label` attribute is the association.
|
|
113
|
-
- Resolve template bindings before judging them. A template expression like `{someValue}` refers to a property or getter on the component's controller (`.js`/`.ts`) — including `@api` properties and `get someValue()` getters — not to a module-level imported constant (which LWC templates cannot bind to). Check the controller for the binding's definition before concluding a value is undefined, empty, or missing. When reviewing a diff, verify which side is the corrected code; do not assume the change introduced the problem.
|
|
114
|
-
- Prefer a real `<button>` for actions; for a link, `href="#"` with `event.preventDefault()` (the canonical SLDS pattern). Don't recommend `href="javascript:void(0)"` as a first-line remediation — it's a no-op-anchor anti-pattern. It is acceptable only as a last resort when moving `<a>` → `<button>` is genuinely impossible, and even then only when paired with the full set of attributes that make the anchor behave as an accessible button (`role="button"`, keyboard activation, etc.) — `void(0)` on its own is an incomplete fix. Don't flag existing `javascript:void(0)` as a violation.
|
|
115
|
-
- ARIA attribute spelling depends on the element type. On a **plain HTML element** (`div`, `span`, `button`, `input`, `a`, `img`, `iframe`, …) the only valid spelling is the W3C form `aria-labelledby` / `aria-describedby`; the hyphen-split `aria-labelled-by` / `aria-described-by` there **is** a real bug — keep flagging it. But on an **LWC component tag** (`lightning-*` or a custom `ns-name` element), the hyphen-split form is the kebab-case binding of the component's `@api ariaLabelledBy` / `ariaDescribedBy` property (each capital letter maps to `-` + lowercase), and LWC reflects it to the spec-correct `aria-labelledby` in the rendered DOM. Do **not** flag `aria-labelled-by` on a component tag as a misspelling, and do not claim it "breaks the accessible name computation" — you cannot determine that from the attribute name alone, because both `aria-labelled-by` (via `@api` property kebab-casing) and `aria-labelledby` (via LWC's ARIA reflection) can wire to the same property depending on the component. Treat a hyphen-split ARIA attribute on a component tag as a valid binding, not a violation.
|
|
@@ -6,7 +6,14 @@ All functionality of the content is operable through a keyboard interface withou
|
|
|
6
6
|
|
|
7
7
|
Analyze the given file using the following framework:
|
|
8
8
|
|
|
9
|
-
Review the provided HTML and JS files for accessibility violations per WCAG 2.2 SC 2.1.1, 'Keyboard'.
|
|
9
|
+
Review the provided HTML and JS files for accessibility violations per WCAG 2.2 SC 2.1.1, 'Keyboard'.
|
|
10
|
+
|
|
11
|
+
**Scope — this criterion applies to _interactive_ elements only; native controls pass.** A violation requires an element that is operable by mouse/pointer (a click/pointer/mouse handler, or a custom control role) but is **not** equivalently operable by keyboard. Before flagging anything, apply these two gates — an element that clears them **passes** and must not be flagged:
|
|
12
|
+
|
|
13
|
+
- **Native interactive HTML is keyboard-operable for free.** `<a href>`, `<button>`, `<input>` (including `type="checkbox"`, `type="radio"`, `type="submit"`, etc.), `<select>`, `<textarea>`, and `<summary>` receive focus and handle keyboard activation by default. Do **not** flag a native control for a missing `tabindex`, missing keyboard handler, or keyboard inoperability unless its native behavior has been explicitly overridden or suppressed.
|
|
14
|
+
- **Non-interactive elements are out of scope.** A `<div>`, `<span>`, `<li>`, `<p>`, etc. that has **no** click/pointer/key handler and no interactive role is not a control — it does not need `tabindex` and must not be flagged. Only a non-semantic element that _carries a click/pointer handler_ (making it a de-facto control) needs `tabindex="0"` plus a keyboard handler.
|
|
15
|
+
|
|
16
|
+
For an element that is in scope (an interactive control), ensure it exposes via keyboard all interactivity achievable via mouse; if it does not, flag it as a violation. The exception is when the underlying functionality requires path-based movement.
|
|
10
17
|
|
|
11
18
|
Interactive controls must be accessible when using the keyboard alone, and when using a keyboard along with assistive technology, such as a screen reader, without requiring specific timings for keystrokes. The exception to this is when the underlying functionality requires path-based movement.
|
|
12
19
|
|
|
@@ -41,7 +48,4 @@ Rules to follow:
|
|
|
41
48
|
- Keep issues concise, avoid duplicated issues or unnecessary or non-applicable problems.
|
|
42
49
|
- Assume that any imported functionality works as expected and was already analyzed.
|
|
43
50
|
- Components do not supplement or provide global functionalities.
|
|
44
|
-
-
|
|
45
|
-
- Resolve template bindings before judging them. A template expression like `{someValue}` refers to a property or getter on the component's controller (`.js`/`.ts`) — including `@api` properties and `get someValue()` getters — not to a module-level imported constant (which LWC templates cannot bind to). Check the controller for the binding's definition before concluding a value is undefined, empty, or missing. When reviewing a diff, verify which side is the corrected code; do not assume the change introduced the problem.
|
|
46
|
-
- Prefer a real `<button>` for actions; for a link, `href="#"` with `event.preventDefault()` (the canonical SLDS pattern). Don't recommend `href="javascript:void(0)"` as a first-line remediation — it's a no-op-anchor anti-pattern. It is acceptable only as a last resort when moving `<a>` → `<button>` is genuinely impossible, and even then only when paired with the full set of attributes that make the anchor behave as an accessible button (`role="button"`, keyboard activation, etc.) — `void(0)` on its own is an incomplete fix. Don't flag existing `javascript:void(0)` as a violation.
|
|
47
|
-
- ARIA attribute spelling depends on the element type. On a **plain HTML element** (`div`, `span`, `button`, `input`, `a`, `img`, `iframe`, …) the only valid spelling is the W3C form `aria-labelledby` / `aria-describedby`; the hyphen-split `aria-labelled-by` / `aria-described-by` there **is** a real bug — keep flagging it. But on an **LWC component tag** (`lightning-*` or a custom `ns-name` element), the hyphen-split form is the kebab-case binding of the component's `@api ariaLabelledBy` / `ariaDescribedBy` property (each capital letter maps to `-` + lowercase), and LWC reflects it to the spec-correct `aria-labelledby` in the rendered DOM. Do **not** flag `aria-labelled-by` on a component tag as a misspelling, and do not claim it "breaks the accessible name computation" — you cannot determine that from the attribute name alone, because both `aria-labelled-by` (via `@api` property kebab-casing) and `aria-labelledby` (via LWC's ARIA reflection) can wire to the same property depending on the component. Treat a hyphen-split ARIA attribute on a component tag as a valid binding, not a violation.
|
|
51
|
+
- Prefer a real `<button>` for actions. If an anchor must act as a control, use the canonical SLDS `href="#"` plus `event.preventDefault()` pattern and supply the complete button-like semantics and keyboard behavior. Do not recommend `href="javascript:void(0)"` as a first-line fix, and do not flag that value alone as a keyboard violation.
|
package/skills/experience-accessibility-validate/references/reviewers/sc-2-4-4-link-purpose.md
CHANGED
|
@@ -33,7 +33,4 @@ Rules to follow:
|
|
|
33
33
|
- Keep issues concise, avoid duplicated issues or unnecessary or non-applicable problems.
|
|
34
34
|
- Assume that any imported functionality works as expected and was already analyzed.
|
|
35
35
|
- Components do not supplement or provide global functionalities.
|
|
36
|
-
-
|
|
37
|
-
- Resolve template bindings before judging them. A template expression like `{someValue}` refers to a property or getter on the component's controller (`.js`/`.ts`) — including `@api` properties and `get someValue()` getters — not to a module-level imported constant (which LWC templates cannot bind to). Check the controller for the binding's definition before concluding a value is undefined, empty, or missing. When reviewing a diff, verify which side is the corrected code; do not assume the change introduced the problem.
|
|
38
|
-
- Prefer a real `<button>` for actions; for a link, `href="#"` with `event.preventDefault()` (the canonical SLDS pattern). Don't recommend `href="javascript:void(0)"` as a first-line remediation — it's a no-op-anchor anti-pattern. It is acceptable only as a last resort when moving `<a>` → `<button>` is genuinely impossible, and even then only when paired with the full set of attributes that make the anchor behave as an accessible button (`role="button"`, keyboard activation, etc.) — `void(0)` on its own is an incomplete fix. Don't flag existing `javascript:void(0)` as a violation.
|
|
39
|
-
- ARIA attribute spelling depends on the element type. On a **plain HTML element** (`div`, `span`, `button`, `input`, `a`, `img`, `iframe`, …) the only valid spelling is the W3C form `aria-labelledby` / `aria-describedby`; the hyphen-split `aria-labelled-by` / `aria-described-by` there **is** a real bug — keep flagging it. But on an **LWC component tag** (`lightning-*` or a custom `ns-name` element), the hyphen-split form is the kebab-case binding of the component's `@api ariaLabelledBy` / `ariaDescribedBy` property (each capital letter maps to `-` + lowercase), and LWC reflects it to the spec-correct `aria-labelledby` in the rendered DOM. Do **not** flag `aria-labelled-by` on a component tag as a misspelling, and do not claim it "breaks the accessible name computation" — you cannot determine that from the attribute name alone, because both `aria-labelled-by` (via `@api` property kebab-casing) and `aria-labelledby` (via LWC's ARIA reflection) can wire to the same property depending on the component. Treat a hyphen-split ARIA attribute on a component tag as a valid binding, not a violation.
|
|
36
|
+
- Judge whether link text describes its destination, not whether the destination opens in a new window. `target="_blank"` and click handlers that call `window.open(...)` are not SC 2.4.4 failures. If new-tab behavior is mentioned, describe indicating it as an optional enhancement rather than a warning or violation.
|
package/skills/experience-accessibility-validate/references/reviewers/sc-2-4-6-headings-labels.md
CHANGED
|
@@ -44,7 +44,3 @@ Rules to follow:
|
|
|
44
44
|
- Keep issues concise, avoid duplicated issues or unnecessary or non-applicable problems.
|
|
45
45
|
- Assume that any imported functionality works as expected and was already analyzed.
|
|
46
46
|
- Components do not supplement or provide global functionalities.
|
|
47
|
-
- Lightning base components (`lightning-input`, `lightning-combobox`, `lightning-textarea`, `lightning-icon`, etc.) provide their own accessible labeling, ARIA, and error handling in shadow DOM via their dedicated attributes (`label`, `alternative-text`, field-level validation). When such a component is given a `label` attribute it is already programmatically labeled — even with `variant="label-hidden"`, which hides the label visually but keeps it for assistive technology. Do **not** flag a sibling/wrapper `<label>` or `<span>` for a missing `for`/`id` when the actual control is a self-labeling Lightning component, and do not treat a visible heading as if it were the control's only label. This also covers navigation and icon base components (`lightning-vertical-navigation-item`, `lightning-vertical-navigation-item-icon`, `lightning-button-icon`, etc.): when a `label` (or `alternative-text`) attribute is supplied, the base component renders it as the visible link/control text **and** exposes it as the accessible name, and any `icon-name` is decorative — do not emit a 4.1.2 "verify the label is associated with the icon" warning, even a hedged one. The presence of the `label` attribute is the association.
|
|
48
|
-
- Resolve template bindings before judging them. A template expression like `{someValue}` refers to a property or getter on the component's controller (`.js`/`.ts`) — including `@api` properties and `get someValue()` getters — not to a module-level imported constant (which LWC templates cannot bind to). Check the controller for the binding's definition before concluding a value is undefined, empty, or missing. When reviewing a diff, verify which side is the corrected code; do not assume the change introduced the problem.
|
|
49
|
-
- Prefer a real `<button>` for actions; for a link, `href="#"` with `event.preventDefault()` (the canonical SLDS pattern). Don't recommend `href="javascript:void(0)"` as a first-line remediation — it's a no-op-anchor anti-pattern. It is acceptable only as a last resort when moving `<a>` → `<button>` is genuinely impossible, and even then only when paired with the full set of attributes that make the anchor behave as an accessible button (`role="button"`, keyboard activation, etc.) — `void(0)` on its own is an incomplete fix. Don't flag existing `javascript:void(0)` as a violation.
|
|
50
|
-
- ARIA attribute spelling depends on the element type. On a **plain HTML element** (`div`, `span`, `button`, `input`, `a`, `img`, `iframe`, …) the only valid spelling is the W3C form `aria-labelledby` / `aria-describedby`; the hyphen-split `aria-labelled-by` / `aria-described-by` there **is** a real bug — keep flagging it. But on an **LWC component tag** (`lightning-*` or a custom `ns-name` element), the hyphen-split form is the kebab-case binding of the component's `@api ariaLabelledBy` / `ariaDescribedBy` property (each capital letter maps to `-` + lowercase), and LWC reflects it to the spec-correct `aria-labelledby` in the rendered DOM. Do **not** flag `aria-labelled-by` on a component tag as a misspelling, and do not claim it "breaks the accessible name computation" — you cannot determine that from the attribute name alone, because both `aria-labelled-by` (via `@api` property kebab-casing) and `aria-labelledby` (via LWC's ARIA reflection) can wire to the same property depending on the component. Treat a hyphen-split ARIA attribute on a component tag as a valid binding, not a violation.
|
package/skills/experience-accessibility-validate/references/reviewers/sc-2-5-1-pointer-gestures.md
CHANGED
|
@@ -48,7 +48,3 @@ Rules to follow:
|
|
|
48
48
|
- Keep issues concise, avoid duplicated issues or unnecessary or non-applicable problems.
|
|
49
49
|
- Assume that any imported functionality works as expected and was already analyzed.
|
|
50
50
|
- Components do not supplement or provide global functionalities.
|
|
51
|
-
- Lightning base components (`lightning-input`, `lightning-combobox`, `lightning-textarea`, `lightning-icon`, etc.) provide their own accessible labeling, ARIA, and error handling in shadow DOM via their dedicated attributes (`label`, `alternative-text`, field-level validation). When such a component is given a `label` attribute it is already programmatically labeled — even with `variant="label-hidden"`, which hides the label visually but keeps it for assistive technology. Do **not** flag a sibling/wrapper `<label>` or `<span>` for a missing `for`/`id` when the actual control is a self-labeling Lightning component, and do not treat a visible heading as if it were the control's only label. This also covers navigation and icon base components (`lightning-vertical-navigation-item`, `lightning-vertical-navigation-item-icon`, `lightning-button-icon`, etc.): when a `label` (or `alternative-text`) attribute is supplied, the base component renders it as the visible link/control text **and** exposes it as the accessible name, and any `icon-name` is decorative — do not emit a 4.1.2 "verify the label is associated with the icon" warning, even a hedged one. The presence of the `label` attribute is the association.
|
|
52
|
-
- Resolve template bindings before judging them. A template expression like `{someValue}` refers to a property or getter on the component's controller (`.js`/`.ts`) — including `@api` properties and `get someValue()` getters — not to a module-level imported constant (which LWC templates cannot bind to). Check the controller for the binding's definition before concluding a value is undefined, empty, or missing. When reviewing a diff, verify which side is the corrected code; do not assume the change introduced the problem.
|
|
53
|
-
- Prefer a real `<button>` for actions; for a link, `href="#"` with `event.preventDefault()` (the canonical SLDS pattern). Don't recommend `href="javascript:void(0)"` as a first-line remediation — it's a no-op-anchor anti-pattern. It is acceptable only as a last resort when moving `<a>` → `<button>` is genuinely impossible, and even then only when paired with the full set of attributes that make the anchor behave as an accessible button (`role="button"`, keyboard activation, etc.) — `void(0)` on its own is an incomplete fix. Don't flag existing `javascript:void(0)` as a violation.
|
|
54
|
-
- ARIA attribute spelling depends on the element type. On a **plain HTML element** (`div`, `span`, `button`, `input`, `a`, `img`, `iframe`, …) the only valid spelling is the W3C form `aria-labelledby` / `aria-describedby`; the hyphen-split `aria-labelled-by` / `aria-described-by` there **is** a real bug — keep flagging it. But on an **LWC component tag** (`lightning-*` or a custom `ns-name` element), the hyphen-split form is the kebab-case binding of the component's `@api ariaLabelledBy` / `ariaDescribedBy` property (each capital letter maps to `-` + lowercase), and LWC reflects it to the spec-correct `aria-labelledby` in the rendered DOM. Do **not** flag `aria-labelled-by` on a component tag as a misspelling, and do not claim it "breaks the accessible name computation" — you cannot determine that from the attribute name alone, because both `aria-labelled-by` (via `@api` property kebab-casing) and `aria-labelledby` (via LWC's ARIA reflection) can wire to the same property depending on the component. Treat a hyphen-split ARIA attribute on a component tag as a valid binding, not a violation.
|
|
@@ -43,7 +43,3 @@ Rules to follow:
|
|
|
43
43
|
- Keep issues concise, avoid duplicated issues or unnecessary or non-applicable problems.
|
|
44
44
|
- Assume that any imported functionality works as expected and was already analyzed.
|
|
45
45
|
- Components do not supplement or provide global functionalities.
|
|
46
|
-
- Lightning base components (`lightning-input`, `lightning-combobox`, `lightning-textarea`, `lightning-icon`, etc.) provide their own accessible labeling, ARIA, and error handling in shadow DOM via their dedicated attributes (`label`, `alternative-text`, field-level validation). When such a component is given a `label` attribute it is already programmatically labeled — even with `variant="label-hidden"`, which hides the label visually but keeps it for assistive technology. Do **not** flag a sibling/wrapper `<label>` or `<span>` for a missing `for`/`id` when the actual control is a self-labeling Lightning component, and do not treat a visible heading as if it were the control's only label. This also covers navigation and icon base components (`lightning-vertical-navigation-item`, `lightning-vertical-navigation-item-icon`, `lightning-button-icon`, etc.): when a `label` (or `alternative-text`) attribute is supplied, the base component renders it as the visible link/control text **and** exposes it as the accessible name, and any `icon-name` is decorative — do not emit a 4.1.2 "verify the label is associated with the icon" warning, even a hedged one. The presence of the `label` attribute is the association.
|
|
47
|
-
- Resolve template bindings before judging them. A template expression like `{someValue}` refers to a property or getter on the component's controller (`.js`/`.ts`) — including `@api` properties and `get someValue()` getters — not to a module-level imported constant (which LWC templates cannot bind to). Check the controller for the binding's definition before concluding a value is undefined, empty, or missing. When reviewing a diff, verify which side is the corrected code; do not assume the change introduced the problem.
|
|
48
|
-
- Prefer a real `<button>` for actions; for a link, `href="#"` with `event.preventDefault()` (the canonical SLDS pattern). Don't recommend `href="javascript:void(0)"` as a first-line remediation — it's a no-op-anchor anti-pattern. It is acceptable only as a last resort when moving `<a>` → `<button>` is genuinely impossible, and even then only when paired with the full set of attributes that make the anchor behave as an accessible button (`role="button"`, keyboard activation, etc.) — `void(0)` on its own is an incomplete fix. Don't flag existing `javascript:void(0)` as a violation.
|
|
49
|
-
- ARIA attribute spelling depends on the element type. On a **plain HTML element** (`div`, `span`, `button`, `input`, `a`, `img`, `iframe`, …) the only valid spelling is the W3C form `aria-labelledby` / `aria-describedby`; the hyphen-split `aria-labelled-by` / `aria-described-by` there **is** a real bug — keep flagging it. But on an **LWC component tag** (`lightning-*` or a custom `ns-name` element), the hyphen-split form is the kebab-case binding of the component's `@api ariaLabelledBy` / `ariaDescribedBy` property (each capital letter maps to `-` + lowercase), and LWC reflects it to the spec-correct `aria-labelledby` in the rendered DOM. Do **not** flag `aria-labelled-by` on a component tag as a misspelling, and do not claim it "breaks the accessible name computation" — you cannot determine that from the attribute name alone, because both `aria-labelled-by` (via `@api` property kebab-casing) and `aria-labelledby` (via LWC's ARIA reflection) can wire to the same property depending on the component. Treat a hyphen-split ARIA attribute on a component tag as a valid binding, not a violation.
|
package/skills/experience-accessibility-validate/references/reviewers/sc-2-5-3-label-in-name.md
CHANGED
|
@@ -71,7 +71,3 @@ Rules to follow:
|
|
|
71
71
|
- Keep issues concise, avoid duplicated issues or unnecessary or non-applicable problems.
|
|
72
72
|
- Assume that any imported functionality works as expected and was already analyzed.
|
|
73
73
|
- Components do not supplement or provide global functionalities.
|
|
74
|
-
- Lightning base components (`lightning-input`, `lightning-combobox`, `lightning-textarea`, `lightning-icon`, etc.) provide their own accessible labeling, ARIA, and error handling in shadow DOM via their dedicated attributes (`label`, `alternative-text`, field-level validation). When such a component is given a `label` attribute it is already programmatically labeled — even with `variant="label-hidden"`, which hides the label visually but keeps it for assistive technology. Do **not** flag a sibling/wrapper `<label>` or `<span>` for a missing `for`/`id` when the actual control is a self-labeling Lightning component, and do not treat a visible heading as if it were the control's only label. This also covers navigation and icon base components (`lightning-vertical-navigation-item`, `lightning-vertical-navigation-item-icon`, `lightning-button-icon`, etc.): when a `label` (or `alternative-text`) attribute is supplied, the base component renders it as the visible link/control text **and** exposes it as the accessible name, and any `icon-name` is decorative — do not emit a 4.1.2 "verify the label is associated with the icon" warning, even a hedged one. The presence of the `label` attribute is the association.
|
|
75
|
-
- Resolve template bindings before judging them. A template expression like `{someValue}` refers to a property or getter on the component's controller (`.js`/`.ts`) — including `@api` properties and `get someValue()` getters — not to a module-level imported constant (which LWC templates cannot bind to). Check the controller for the binding's definition before concluding a value is undefined, empty, or missing. When reviewing a diff, verify which side is the corrected code; do not assume the change introduced the problem.
|
|
76
|
-
- Prefer a real `<button>` for actions; for a link, `href="#"` with `event.preventDefault()` (the canonical SLDS pattern). Don't recommend `href="javascript:void(0)"` as a first-line remediation — it's a no-op-anchor anti-pattern. It is acceptable only as a last resort when moving `<a>` → `<button>` is genuinely impossible, and even then only when paired with the full set of attributes that make the anchor behave as an accessible button (`role="button"`, keyboard activation, etc.) — `void(0)` on its own is an incomplete fix. Don't flag existing `javascript:void(0)` as a violation.
|
|
77
|
-
- ARIA attribute spelling depends on the element type. On a **plain HTML element** (`div`, `span`, `button`, `input`, `a`, `img`, `iframe`, …) the only valid spelling is the W3C form `aria-labelledby` / `aria-describedby`; the hyphen-split `aria-labelled-by` / `aria-described-by` there **is** a real bug — keep flagging it. But on an **LWC component tag** (`lightning-*` or a custom `ns-name` element), the hyphen-split form is the kebab-case binding of the component's `@api ariaLabelledBy` / `ariaDescribedBy` property (each capital letter maps to `-` + lowercase), and LWC reflects it to the spec-correct `aria-labelledby` in the rendered DOM. Do **not** flag `aria-labelled-by` on a component tag as a misspelling, and do not claim it "breaks the accessible name computation" — you cannot determine that from the attribute name alone, because both `aria-labelled-by` (via `@api` property kebab-casing) and `aria-labelledby` (via LWC's ARIA reflection) can wire to the same property depending on the component. Treat a hyphen-split ARIA attribute on a component tag as a valid binding, not a violation.
|
package/skills/experience-accessibility-validate/references/reviewers/sc-2-5-7-dragging-movement.md
CHANGED
|
@@ -39,7 +39,3 @@ _Rules to follow_:
|
|
|
39
39
|
- Keep issues concise, avoid duplicated issues or unnecessary or non-applicable problems.
|
|
40
40
|
- Assume that any imported functionality works as expected and was already analyzed.
|
|
41
41
|
- Components do not supplement or provide global functionalities.
|
|
42
|
-
- Lightning base components (`lightning-input`, `lightning-combobox`, `lightning-textarea`, `lightning-icon`, etc.) provide their own accessible labeling, ARIA, and error handling in shadow DOM via their dedicated attributes (`label`, `alternative-text`, field-level validation). When such a component is given a `label` attribute it is already programmatically labeled — even with `variant="label-hidden"`, which hides the label visually but keeps it for assistive technology. Do **not** flag a sibling/wrapper `<label>` or `<span>` for a missing `for`/`id` when the actual control is a self-labeling Lightning component, and do not treat a visible heading as if it were the control's only label. This also covers navigation and icon base components (`lightning-vertical-navigation-item`, `lightning-vertical-navigation-item-icon`, `lightning-button-icon`, etc.): when a `label` (or `alternative-text`) attribute is supplied, the base component renders it as the visible link/control text **and** exposes it as the accessible name, and any `icon-name` is decorative — do not emit a 4.1.2 "verify the label is associated with the icon" warning, even a hedged one. The presence of the `label` attribute is the association.
|
|
43
|
-
- Resolve template bindings before judging them. A template expression like `{someValue}` refers to a property or getter on the component's controller (`.js`/`.ts`) — including `@api` properties and `get someValue()` getters — not to a module-level imported constant (which LWC templates cannot bind to). Check the controller for the binding's definition before concluding a value is undefined, empty, or missing. When reviewing a diff, verify which side is the corrected code; do not assume the change introduced the problem.
|
|
44
|
-
- Prefer a real `<button>` for actions; for a link, `href="#"` with `event.preventDefault()` (the canonical SLDS pattern). Don't recommend `href="javascript:void(0)"` as a first-line remediation — it's a no-op-anchor anti-pattern. It is acceptable only as a last resort when moving `<a>` → `<button>` is genuinely impossible, and even then only when paired with the full set of attributes that make the anchor behave as an accessible button (`role="button"`, keyboard activation, etc.) — `void(0)` on its own is an incomplete fix. Don't flag existing `javascript:void(0)` as a violation.
|
|
45
|
-
- ARIA attribute spelling depends on the element type. On a **plain HTML element** (`div`, `span`, `button`, `input`, `a`, `img`, `iframe`, …) the only valid spelling is the W3C form `aria-labelledby` / `aria-describedby`; the hyphen-split `aria-labelled-by` / `aria-described-by` there **is** a real bug — keep flagging it. But on an **LWC component tag** (`lightning-*` or a custom `ns-name` element), the hyphen-split form is the kebab-case binding of the component's `@api ariaLabelledBy` / `ariaDescribedBy` property (each capital letter maps to `-` + lowercase), and LWC reflects it to the spec-correct `aria-labelledby` in the rendered DOM. Do **not** flag `aria-labelled-by` on a component tag as a misspelling, and do not claim it "breaks the accessible name computation" — you cannot determine that from the attribute name alone, because both `aria-labelled-by` (via `@api` property kebab-casing) and `aria-labelledby` (via LWC's ARIA reflection) can wire to the same property depending on the component. Treat a hyphen-split ARIA attribute on a component tag as a valid binding, not a violation.
|
|
@@ -49,7 +49,3 @@ _Rules to follow_:
|
|
|
49
49
|
- Keep issues concise, avoid duplicated issues or unnecessary or non-applicable problems.
|
|
50
50
|
- Assume that any imported functionality works as expected and was already analyzed.
|
|
51
51
|
- Components do not supplement or provide global functionalities.
|
|
52
|
-
- Lightning base components (`lightning-input`, `lightning-combobox`, `lightning-textarea`, `lightning-icon`, etc.) provide their own accessible labeling, ARIA, and error handling in shadow DOM via their dedicated attributes (`label`, `alternative-text`, field-level validation). When such a component is given a `label` attribute it is already programmatically labeled — even with `variant="label-hidden"`, which hides the label visually but keeps it for assistive technology. Do **not** flag a sibling/wrapper `<label>` or `<span>` for a missing `for`/`id` when the actual control is a self-labeling Lightning component, and do not treat a visible heading as if it were the control's only label. This also covers navigation and icon base components (`lightning-vertical-navigation-item`, `lightning-vertical-navigation-item-icon`, `lightning-button-icon`, etc.): when a `label` (or `alternative-text`) attribute is supplied, the base component renders it as the visible link/control text **and** exposes it as the accessible name, and any `icon-name` is decorative — do not emit a 4.1.2 "verify the label is associated with the icon" warning, even a hedged one. The presence of the `label` attribute is the association.
|
|
53
|
-
- Resolve template bindings before judging them. A template expression like `{someValue}` refers to a property or getter on the component's controller (`.js`/`.ts`) — including `@api` properties and `get someValue()` getters — not to a module-level imported constant (which LWC templates cannot bind to). Check the controller for the binding's definition before concluding a value is undefined, empty, or missing. When reviewing a diff, verify which side is the corrected code; do not assume the change introduced the problem.
|
|
54
|
-
- Prefer a real `<button>` for actions; for a link, `href="#"` with `event.preventDefault()` (the canonical SLDS pattern). Don't recommend `href="javascript:void(0)"` as a first-line remediation — it's a no-op-anchor anti-pattern. It is acceptable only as a last resort when moving `<a>` → `<button>` is genuinely impossible, and even then only when paired with the full set of attributes that make the anchor behave as an accessible button (`role="button"`, keyboard activation, etc.) — `void(0)` on its own is an incomplete fix. Don't flag existing `javascript:void(0)` as a violation.
|
|
55
|
-
- ARIA attribute spelling depends on the element type. On a **plain HTML element** (`div`, `span`, `button`, `input`, `a`, `img`, `iframe`, …) the only valid spelling is the W3C form `aria-labelledby` / `aria-describedby`; the hyphen-split `aria-labelled-by` / `aria-described-by` there **is** a real bug — keep flagging it. But on an **LWC component tag** (`lightning-*` or a custom `ns-name` element), the hyphen-split form is the kebab-case binding of the component's `@api ariaLabelledBy` / `ariaDescribedBy` property (each capital letter maps to `-` + lowercase), and LWC reflects it to the spec-correct `aria-labelledby` in the rendered DOM. Do **not** flag `aria-labelled-by` on a component tag as a misspelling, and do not claim it "breaks the accessible name computation" — you cannot determine that from the attribute name alone, because both `aria-labelled-by` (via `@api` property kebab-casing) and `aria-labelledby` (via LWC's ARIA reflection) can wire to the same property depending on the component. Treat a hyphen-split ARIA attribute on a component tag as a valid binding, not a violation.
|
|
@@ -45,7 +45,4 @@ _Rules to follow_ :
|
|
|
45
45
|
- Keep issues concise, avoid duplicated issues or unnecessary or non-applicable problems.
|
|
46
46
|
- Assume that any imported functionality works as expected and was already analyzed.
|
|
47
47
|
- Components do not supplement or provide global functionalities.
|
|
48
|
-
-
|
|
49
|
-
- Resolve template bindings before judging them. A template expression like `{someValue}` refers to a property or getter on the component's controller (`.js`/`.ts`) — including `@api` properties and `get someValue()` getters — not to a module-level imported constant (which LWC templates cannot bind to). Check the controller for the binding's definition before concluding a value is undefined, empty, or missing. When reviewing a diff, verify which side is the corrected code; do not assume the change introduced the problem.
|
|
50
|
-
- Prefer a real `<button>` for actions; for a link, `href="#"` with `event.preventDefault()` (the canonical SLDS pattern). Don't recommend `href="javascript:void(0)"` as a first-line remediation — it's a no-op-anchor anti-pattern. It is acceptable only as a last resort when moving `<a>` → `<button>` is genuinely impossible, and even then only when paired with the full set of attributes that make the anchor behave as an accessible button (`role="button"`, keyboard activation, etc.) — `void(0)` on its own is an incomplete fix. Don't flag existing `javascript:void(0)` as a violation.
|
|
51
|
-
- ARIA attribute spelling depends on the element type. On a **plain HTML element** (`div`, `span`, `button`, `input`, `a`, `img`, `iframe`, …) the only valid spelling is the W3C form `aria-labelledby` / `aria-describedby`; the hyphen-split `aria-labelled-by` / `aria-described-by` there **is** a real bug — keep flagging it. But on an **LWC component tag** (`lightning-*` or a custom `ns-name` element), the hyphen-split form is the kebab-case binding of the component's `@api ariaLabelledBy` / `ariaDescribedBy` property (each capital letter maps to `-` + lowercase), and LWC reflects it to the spec-correct `aria-labelledby` in the rendered DOM. Do **not** flag `aria-labelled-by` on a component tag as a misspelling, and do not claim it "breaks the accessible name computation" — you cannot determine that from the attribute name alone, because both `aria-labelled-by` (via `@api` property kebab-casing) and `aria-labelledby` (via LWC's ARIA reflection) can wire to the same property depending on the component. Treat a hyphen-split ARIA attribute on a component tag as a valid binding, not a violation.
|
|
48
|
+
- Opening a link or button target in a new browser tab or window (`target="_blank"` or a click handler that calls `window.open(...)`) is not an SC 3.2.2 violation. This criterion concerns unexpected context changes caused by changing a form control's value or state, not the expected result of deliberately activating a link or button. Treat indicating new-tab behavior as optional advisory guidance, never as a Level A or AA failure.
|
|
@@ -78,7 +78,4 @@ Rules to follow:
|
|
|
78
78
|
- Keep issues concise, avoid duplicated issues or unnecessary or non-applicable problems.
|
|
79
79
|
- Assume that any imported functionality works as expected and was already analyzed.
|
|
80
80
|
- Components do not supplement or provide global functionalities.
|
|
81
|
-
-
|
|
82
|
-
- Resolve template bindings before judging them. A template expression like `{someValue}` refers to a property or getter on the component's controller (`.js`/`.ts`) — including `@api` properties and `get someValue()` getters — not to a module-level imported constant (which LWC templates cannot bind to). Check the controller for the binding's definition before concluding a value is undefined, empty, or missing. When reviewing a diff, verify which side is the corrected code; do not assume the change introduced the problem.
|
|
83
|
-
- Prefer a real `<button>` for actions; for a link, `href="#"` with `event.preventDefault()` (the canonical SLDS pattern). Don't recommend `href="javascript:void(0)"` as a first-line remediation — it's a no-op-anchor anti-pattern. It is acceptable only as a last resort when moving `<a>` → `<button>` is genuinely impossible, and even then only when paired with the full set of attributes that make the anchor behave as an accessible button (`role="button"`, keyboard activation, etc.) — `void(0)` on its own is an incomplete fix. Don't flag existing `javascript:void(0)` as a violation.
|
|
84
|
-
- ARIA attribute spelling depends on the element type. On a **plain HTML element** (`div`, `span`, `button`, `input`, `a`, `img`, `iframe`, …) the only valid spelling is the W3C form `aria-labelledby` / `aria-describedby`; the hyphen-split `aria-labelled-by` / `aria-described-by` there **is** a real bug — keep flagging it. But on an **LWC component tag** (`lightning-*` or a custom `ns-name` element), the hyphen-split form is the kebab-case binding of the component's `@api ariaLabelledBy` / `ariaDescribedBy` property (each capital letter maps to `-` + lowercase), and LWC reflects it to the spec-correct `aria-labelledby` in the rendered DOM. Do **not** flag `aria-labelled-by` on a component tag as a misspelling, and do not claim it "breaks the accessible name computation" — you cannot determine that from the attribute name alone, because both `aria-labelled-by` (via `@api` property kebab-casing) and `aria-labelledby` (via LWC's ARIA reflection) can wire to the same property depending on the component. Treat a hyphen-split ARIA attribute on a component tag as a valid binding, not a violation.
|
|
81
|
+
- Associate error text with the actual focusable control. An `aria-describedby` or `aria-errormessage` on a non-focusable wrapper does not reach a composite editor's internal control unless the wrapper forwards it. A disabled control cannot receive focus, so attaching the only error explanation to it also cannot make that explanation available on focus. Use an adjacent visible message, a live region where appropriate, or the control's supported error-association API.
|
|
@@ -44,7 +44,4 @@ Rules to follow:
|
|
|
44
44
|
- Keep issues concise, avoid duplicated issues or unnecessary or non-applicable problems.
|
|
45
45
|
- Assume that any imported functionality works as expected and was already analyzed.
|
|
46
46
|
- Components do not supplement or provide global functionalities.
|
|
47
|
-
-
|
|
48
|
-
- Resolve template bindings before judging them. A template expression like `{someValue}` refers to a property or getter on the component's controller (`.js`/`.ts`) — including `@api` properties and `get someValue()` getters — not to a module-level imported constant (which LWC templates cannot bind to). Check the controller for the binding's definition before concluding a value is undefined, empty, or missing. When reviewing a diff, verify which side is the corrected code; do not assume the change introduced the problem.
|
|
49
|
-
- Prefer a real `<button>` for actions; for a link, `href="#"` with `event.preventDefault()` (the canonical SLDS pattern). Don't recommend `href="javascript:void(0)"` as a first-line remediation — it's a no-op-anchor anti-pattern. It is acceptable only as a last resort when moving `<a>` → `<button>` is genuinely impossible, and even then only when paired with the full set of attributes that make the anchor behave as an accessible button (`role="button"`, keyboard activation, etc.) — `void(0)` on its own is an incomplete fix. Don't flag existing `javascript:void(0)` as a violation.
|
|
50
|
-
- ARIA attribute spelling depends on the element type. On a **plain HTML element** (`div`, `span`, `button`, `input`, `a`, `img`, `iframe`, …) the only valid spelling is the W3C form `aria-labelledby` / `aria-describedby`; the hyphen-split `aria-labelled-by` / `aria-described-by` there **is** a real bug — keep flagging it. But on an **LWC component tag** (`lightning-*` or a custom `ns-name` element), the hyphen-split form is the kebab-case binding of the component's `@api ariaLabelledBy` / `ariaDescribedBy` property (each capital letter maps to `-` + lowercase), and LWC reflects it to the spec-correct `aria-labelledby` in the rendered DOM. Do **not** flag `aria-labelled-by` on a component tag as a misspelling, and do not claim it "breaks the accessible name computation" — you cannot determine that from the attribute name alone, because both `aria-labelled-by` (via `@api` property kebab-casing) and `aria-labelledby` (via LWC's ARIA reflection) can wire to the same property depending on the component. Treat a hyphen-split ARIA attribute on a component tag as a valid binding, not a violation.
|
|
47
|
+
- Attach instructions to the actual focusable control. An `aria-describedby` on a disabled control cannot expose the instructions on focus, and an association on a non-focusable wrapper does not reach a composite editor's internal control unless the wrapper forwards it. Use adjacent visible instructions or the control's supported association API instead.
|
package/skills/experience-accessibility-validate/references/reviewers/sc-3-3-3-error-suggestion.md
CHANGED
|
@@ -58,7 +58,4 @@ Rules to follow:
|
|
|
58
58
|
- Keep issues concise, avoid duplicated issues or unnecessary or non-applicable problems.
|
|
59
59
|
- Assume that any imported functionality works as expected and was already analyzed.
|
|
60
60
|
- Components do not supplement or provide global functionalities.
|
|
61
|
-
-
|
|
62
|
-
- Resolve template bindings before judging them. A template expression like `{someValue}` refers to a property or getter on the component's controller (`.js`/`.ts`) — including `@api` properties and `get someValue()` getters — not to a module-level imported constant (which LWC templates cannot bind to). Check the controller for the binding's definition before concluding a value is undefined, empty, or missing. When reviewing a diff, verify which side is the corrected code; do not assume the change introduced the problem.
|
|
63
|
-
- Prefer a real `<button>` for actions; for a link, `href="#"` with `event.preventDefault()` (the canonical SLDS pattern). Don't recommend `href="javascript:void(0)"` as a first-line remediation — it's a no-op-anchor anti-pattern. It is acceptable only as a last resort when moving `<a>` → `<button>` is genuinely impossible, and even then only when paired with the full set of attributes that make the anchor behave as an accessible button (`role="button"`, keyboard activation, etc.) — `void(0)` on its own is an incomplete fix. Don't flag existing `javascript:void(0)` as a violation.
|
|
64
|
-
- ARIA attribute spelling depends on the element type. On a **plain HTML element** (`div`, `span`, `button`, `input`, `a`, `img`, `iframe`, …) the only valid spelling is the W3C form `aria-labelledby` / `aria-describedby`; the hyphen-split `aria-labelled-by` / `aria-described-by` there **is** a real bug — keep flagging it. But on an **LWC component tag** (`lightning-*` or a custom `ns-name` element), the hyphen-split form is the kebab-case binding of the component's `@api ariaLabelledBy` / `ariaDescribedBy` property (each capital letter maps to `-` + lowercase), and LWC reflects it to the spec-correct `aria-labelledby` in the rendered DOM. Do **not** flag `aria-labelled-by` on a component tag as a misspelling, and do not claim it "breaks the accessible name computation" — you cannot determine that from the attribute name alone, because both `aria-labelled-by` (via `@api` property kebab-casing) and `aria-labelledby` (via LWC's ARIA reflection) can wire to the same property depending on the component. Treat a hyphen-split ARIA attribute on a component tag as a valid binding, not a violation.
|
|
61
|
+
- Associate an error suggestion with the actual focusable control. An `aria-describedby` or `aria-errormessage` on a non-focusable wrapper does not reach a composite editor's internal control unless the wrapper forwards it. A disabled control cannot expose described text on focus. Use adjacent visible guidance, a live region where appropriate, or the control's supported error-association API.
|
|
@@ -73,16 +73,13 @@ Following are some preferred sufficient techniques that can help satisfy name-on
|
|
|
73
73
|
- Keep issues concise, avoid duplicated issues or unnecessary or non-applicable problems.
|
|
74
74
|
- Assume that any imported functionality works as expected and was already analyzed.
|
|
75
75
|
- Components do not supplement or provide global functionalities.
|
|
76
|
-
- 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.
|
|
77
|
-
- 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.
|
|
78
|
-
- 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.
|
|
79
|
-
- 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.
|
|
80
76
|
|
|
81
77
|
**ABSOLUTE AND STRICT EXCLUSION RULES FOR SC 4.1.2 'NAME' ANALYSIS (AND WHEN NOT TO FLAG):**
|
|
82
78
|
|
|
83
79
|
- **PRIMARY RULE:** A user interface component **PASSES** the 'Name' criterion if it has _any_ programmatically determinable accessible name, whether visible or invisible, provided through valid HTML or ARIA.
|
|
80
|
+
- **DETERMINE HOW THE ACCESSIBLE NAME IS SUPPLIED IN THE PROVIDED MARKUP BEFORE CONCLUDING A NAME IS MISSING.** Before flagging an element for a missing name, determine its role and applicable accessible-name sources. Check for text content only when the role or host-language semantics support naming from content; otherwise look for a native labeling mechanism, `aria-label`, `aria-labelledby`, or a valid `<label>` association. Proximity alone is not a naming relationship: an adjacent `<label>`, heading, or text node names a control only when the markup explicitly associates them. A named `<fieldset>`, `<section>`, `role="group"`, or `role="radiogroup"` provides group context but does **not** supply an accessible name to each descendant control; every descendant input, button, or other control still needs its own valid name. Evaluate the group container separately: a `<legend>` names its containing `<fieldset>`, while `aria-label` or `aria-labelledby` names the group element on which it appears. Also do not flag an icon or `<svg>` marked `aria-hidden="true"` or `role="presentation"` for a missing name: it is intentionally removed from the accessibility tree, while the interactive parent must provide its own name.
|
|
84
81
|
- **DO NOT FLAG:** If an element already has a programmatically determinable name via:
|
|
85
|
-
- Its text content (e.g., button text, heading text, link text).
|
|
82
|
+
- Its text content when its role or host-language semantics support naming from content (e.g., button text, heading text, link text).
|
|
86
83
|
- An associated `<label>` element.
|
|
87
84
|
- An `aria-label` attribute.
|
|
88
85
|
- An `aria-labelledby` attribute (and the referenced ID exists within the provided code).
|
|
@@ -103,3 +100,5 @@ Following are some preferred sufficient techniques that can help satisfy name-on
|
|
|
103
100
|
- **For `spinbutton` and similar roles (e.g., `slider`, `progressbar`)**: Ensure `aria-valuemin`, `aria-valuemax`, and `aria-valuenow` use **numeric** values. Flag as an error if non-numeric values are used.
|
|
104
101
|
- **Focus strictly on identifying where a user interface component's _accessible name_ cannot be programmatically determined, or where an explicit ARIA naming attribute (if used) is invalid or misleading (e.g., empty `aria-label`, `aria-labelledby` referencing non-existent ID).**
|
|
105
102
|
- **DO NOT flag Salesforce Lightning Base Components (e.g., `lightning-card`, `lightning-record-edit-form`, `lightning-input-field`, `lightning-button`). Assume these components **automatically pass** the 'Name' criterion because Salesforce ensures their accessible names are handled implicitly and correctly.** Only flag if a custom override _explicitly breaks_ their inherent name determination, which is highly unlikely in standard usage.
|
|
103
|
+
- **ARIA SPELLING IS ELEMENT-SPECIFIC:** Plain HTML elements use `aria-labelledby` and `aria-describedby`; the hyphen-split `aria-labelled-by` or `aria-described-by` spelling is invalid there. On an LWC component tag, however, the hyphen-split spelling can be the kebab-case binding for an `@api ariaLabelledBy` or `ariaDescribedBy` property. Do not conclude that the component lacks a name from the spelling alone.
|
|
104
|
+
- **ASSOCIATE THE ACTUAL CONTROL:** An accessible name attached to a non-focusable wrapper around a composite editor does not name the editor's internal control unless the wrapper forwards it. Recommend extending the control to accept or forward the naming relationship, or using its supported labeling prop.
|
|
@@ -93,7 +93,4 @@ Rules to follow:
|
|
|
93
93
|
- Keep issues concise, avoid duplicated issues or unnecessary or non-applicable problems.
|
|
94
94
|
- Assume that any imported functionality works as expected and was already analyzed.
|
|
95
95
|
- Components do not supplement or provide global functionalities.
|
|
96
|
-
-
|
|
97
|
-
- 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.
|
|
98
|
-
- 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.
|
|
99
|
-
- 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.
|
|
96
|
+
- Prefer a real `<button>` for actions. Do not recommend `href="javascript:void(0)"` as a role fix: that value alone does not give an anchor button semantics. If converting the anchor is impossible, any anchor-based remediation must provide the complete role and keyboard behavior needed for an accessible button. Do not flag an existing `javascript:void(0)` value by itself as a role violation.
|
|
@@ -91,7 +91,3 @@ _Rules to follow_:
|
|
|
91
91
|
- Keep issues concise, avoid duplicated issues or unnecessary or non-applicable problems.
|
|
92
92
|
- Assume that any imported functionality works as expected and was already analyzed.
|
|
93
93
|
- Components do not supplement or provide global functionalities.
|
|
94
|
-
- 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.
|
|
95
|
-
- 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.
|
|
96
|
-
- 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.
|
|
97
|
-
- 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.
|
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: experience-lwc-accessibility-jest-run
|
|
3
|
-
description: "Use ALWAYS when running Sa11y accessibility Jest tests for
|
|
3
|
+
description: "Use ALWAYS when running Sa11y accessibility Jest tests for an LWC — locally before pushing, producing the command(s), running one file vs a suite, selecting tests by naming convention, saving Sa11y-rendered HTML, or reproducing a Sa11y/A11yBug failure. Covers core (Bazel; `bazel test //<module>:<target>`) and standalone `npx jest` (`.accessibility.test.js`, `@sa11y/jest`). REQUIRED for a `run-plan.md`, a failing a11y test's exit code, or `SA11Y_*`/`A11yBug`/core-Bazel test paths. DO NOT TRIGGER for functional Jest tests, a11y review without running tests (use experience-accessibility-validate), or Selenium-based a11y tests."
|
|
4
4
|
metadata:
|
|
5
5
|
version: "1.0"
|
|
6
6
|
domains: ["Experience"]
|
|
7
|
+
relatedSkills:
|
|
8
|
+
- "experience-accessibility-validate"
|
|
7
9
|
cliTools:
|
|
10
|
+
- tool: ["node"]
|
|
11
|
+
semver: ">=18.0.0"
|
|
8
12
|
- tool: ["npm"]
|
|
9
13
|
semver: ">=8.0"
|
|
10
14
|
---
|
|
11
|
-
<!--
|
|
15
|
+
<!-- a11y-expert-managed-skill -->
|
|
12
16
|
|
|
13
17
|
# Running LWC Accessibility Jest Tests
|
|
14
18
|
|
|
@@ -19,7 +23,7 @@ Run Sa11y accessibility unit tests on Lightning Web Components in either:
|
|
|
19
23
|
|
|
20
24
|
Selenium-level reproductions, GUS A11yBug ingestion, and other internal
|
|
21
25
|
Salesforce-only flows are out of scope for this skill. For source-code-level
|
|
22
|
-
WCAG review without running tests, see `experience-
|
|
26
|
+
WCAG review without running tests, see `experience-accessibility-validate`.
|
|
23
27
|
|
|
24
28
|
## When to Use This Skill
|
|
25
29
|
|
|
@@ -39,28 +43,101 @@ WCAG review without running tests, see `experience-lwc-accessibility-validate`.
|
|
|
39
43
|
|
|
40
44
|
## Workflow
|
|
41
45
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
46
|
+
Choose the approach based on the environment. If this is not a Salesforce core
|
|
47
|
+
build environment, do not mention the Core workflow.
|
|
48
|
+
|
|
49
|
+
### Core (Bazel)
|
|
50
|
+
|
|
51
|
+
Use this mode when a `WORKSPACE` file is present. The base command is:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
{coreRootPath}/tools/bazel test [TARGET] --test_output=streamed --test_env=SA11Y_AUTO=1 --test_env=SA11Y_ENABLE_DOM_MUTATION_OBSERVER=1
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Replace `{coreRootPath}` with the Core repository root, `{moduleName}` with the
|
|
58
|
+
module name, and `{relativePath}` with the test file path without the `.test.js`
|
|
59
|
+
extension.
|
|
60
|
+
|
|
61
|
+
To discover targets and paths:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
find {coreRootPath}/{moduleName} -name "*.test.js" -type f
|
|
65
|
+
{coreRootPath}/tools/bazel query "tests(//{moduleName}:*)"
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Component tests typically live under
|
|
69
|
+
`modules/{componentDir}/{componentName}/__tests__/`.
|
|
70
|
+
|
|
71
|
+
Prefer a single-file target when the failing test path is known:
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
{coreRootPath}/tools/bazel test //{moduleName}:{relativePath} --test_output=streamed --test_env=SA11Y_AUTO=1 --test_env=SA11Y_ENABLE_DOM_MUTATION_OBSERVER=1
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Run all Sa11y Jest tests in a module when a specific test is not known:
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
{coreRootPath}/tools/bazel test //{moduleName}:sa11y_jest_test --test_output=streamed --test_env=SA11Y_AUTO=1 --test_env=SA11Y_ENABLE_DOM_MUTATION_OBSERVER=1
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Multiple module targets can be passed to the same command. To filter tests
|
|
84
|
+
within a module, add `--test_arg=--testMatch="**/{modulePath}/**"`.
|
|
85
|
+
|
|
86
|
+
Useful options:
|
|
87
|
+
|
|
88
|
+
- Update snapshots: `--test_arg="--updateSnapshot"`
|
|
89
|
+
- Disable cached test results: `--cache_test_results=no`
|
|
90
|
+
- Save rendered HTML:
|
|
91
|
+
`--test_env=SA11Y_ENABLE_RENDERED_DOM_SAVE=1 --test_env=SA11Y_RENDERED_DOM_SAVE_PATH=sfdc-test/unit/javascript/htdocs/sa11y/jest`
|
|
92
|
+
|
|
93
|
+
Use `sfdc-test/unit/javascript/htdocs/sa11y/jest` as the rendered DOM save path
|
|
94
|
+
to avoid EPERM errors.
|
|
95
|
+
|
|
96
|
+
### Standalone (Jest)
|
|
97
|
+
|
|
98
|
+
Use this mode when no `WORKSPACE` file is present. Run all accessibility tests:
|
|
99
|
+
|
|
100
|
+
Do **not** prepend `SA11Y_*` environment variables in standalone mode;
|
|
101
|
+
`@sa11y/jest` is activated through the project's Jest setup.
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
npm test -- --testMatch="**/*.accessibility.test.js"
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Or target a specific file:
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
npm test -- src/components/MyComponent/__tests__/MyComponent.accessibility.test.js
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Use the filename or path supplied by the user. When the named test is in the
|
|
114
|
+
current directory, keep a bare filename bare instead of inventing a path.
|
|
115
|
+
|
|
116
|
+
Other useful options are `--coverage`, `--updateSnapshot`, `--watch`, and
|
|
117
|
+
`--verbose`. To target a named test, use
|
|
118
|
+
`npm test -- --testNamePattern="MyComponent accessibility"`.
|
|
119
|
+
|
|
120
|
+
Ensure Jest uses a `jsdom` environment and loads the project's `@sa11y/jest`
|
|
121
|
+
setup file. Copy or adapt the bundled `assets/jest.config.js` template into
|
|
122
|
+
the project's Jest configuration, and copy `assets/sa11y-jest-setup.js` to
|
|
123
|
+
`test/setup/sa11y-setup.js`. If the project already has a Jest configuration,
|
|
124
|
+
merge the relevant settings instead of overwriting unrelated configuration.
|
|
125
|
+
|
|
126
|
+
The `SA11Y_*` variables shown above are for Core/Bazel only; the Bazel commands
|
|
127
|
+
already include them.
|
|
128
|
+
|
|
129
|
+
## Response Scope
|
|
130
|
+
|
|
131
|
+
Answer only what the user asked. Emit the requested command or commands plus
|
|
132
|
+
the relevant exit-code meaning. Do not add watch, coverage, snapshot-update,
|
|
133
|
+
HTML-save, or other variants unless the user requests them.
|
|
134
|
+
|
|
135
|
+
## Expected Exit Codes
|
|
136
|
+
|
|
137
|
+
- Bazel: `0` means all tests passed, `3` means tests failed, and `1` means the
|
|
138
|
+
build or command failed.
|
|
139
|
+
- Jest: `0` means all tests passed and `1` means tests failed or an error
|
|
140
|
+
occurred.
|
|
64
141
|
|
|
65
142
|
|
|
66
143
|
## Verification Checklist
|
|
@@ -77,3 +154,5 @@ explicitly asks for them.
|
|
|
77
154
|
`.test.js` extension in `{relativePath}`.
|
|
78
155
|
- **HTML saving fails with EPERM** — use the prescribed save path
|
|
79
156
|
`sfdc-test/unit/javascript/htdocs/sa11y/jest`.
|
|
157
|
+
- **Standalone tests do not run** — verify the test naming pattern, Jest
|
|
158
|
+
configuration, `@sa11y/jest` dependency, and `jsdom` environment.
|
|
@@ -163,16 +163,16 @@ Search project code (src/) for existing implementations
|
|
|
163
163
|
v
|
|
164
164
|
Install dependencies (npm install)
|
|
165
165
|
v
|
|
166
|
-
Search, describe, and
|
|
166
|
+
Search, describe, and adopt features (auth, shadcn, search, navigation, GraphQL)
|
|
167
167
|
v
|
|
168
168
|
Resolve conflicts (two-pass: --on-conflict error, then --conflict-resolution)
|
|
169
169
|
v
|
|
170
170
|
Integrate __examples__ files into target files (verify build succeeds), then delete them
|
|
171
171
|
```
|
|
172
172
|
|
|
173
|
-
|
|
173
|
+
Loads the feature skill to install pre-built packages, or adopt ones the template already shipped — never build your own version of a catalog feature. See "Prompt Classification Keywords" for triggers and negative-phrasing handling.
|
|
174
174
|
|
|
175
|
-
|
|
175
|
+
Skip only for a minimal "hello world" with no interactive features; pre-shipped features still require this phase.
|
|
176
176
|
|
|
177
177
|
### Phase 2.5: Custom Objects (Required if the prompt requires a new custom Salesforce object the org doesn't have)
|
|
178
178
|
|
|
@@ -378,14 +378,14 @@ Execute each phase sequentially following the standard pattern in `references/ph
|
|
|
378
378
|
---
|
|
379
379
|
|
|
380
380
|
**Phase 0 -- Template Offer & Bootstrap**
|
|
381
|
-
- Load `experience-ui-bundle-project-generate`, offer templates. If chosen: skip Phase 1, continue at Phase
|
|
381
|
+
- Load `experience-ui-bundle-project-generate`, offer templates. If chosen: skip Phase 1, continue at Phase 2. If declined: run `scripts/check-sfdx-project.sh`, create project if missing.
|
|
382
382
|
|
|
383
383
|
**Phase 1 -- Scaffolding** (skip if template used in Phase 0)
|
|
384
384
|
- **Precondition**: `scripts/check-sfdx-project.sh` passes
|
|
385
385
|
- Load `experience-ui-bundle-metadata-generate`. Determine hosting target FIRST. Run `sf template generate ui-bundle --template reactbasic`, configure meta XML with `<target>`.
|
|
386
386
|
- **Post-verification**: `scripts/check-phase-1-complete.sh` passes
|
|
387
387
|
|
|
388
|
-
**Phase 2 -- Features** (
|
|
388
|
+
**Phase 2 -- Features** (run on any feature keyword, even if pre-installed — see "Prompt Classification Keywords")
|
|
389
389
|
- Load `experience-ui-bundle-features-generate`. Install features, integrate examples. Verify with `npm run build`.
|
|
390
390
|
|
|
391
391
|
**Phase 2.5 -- Custom Objects** (skip if org has all needed objects)
|