Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Frontend code review guidance from the Dify LLM application development platform repository.
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
references/accessibility-ui.md
1# Accessibility And UI Rules23Accessibility findings are first-class review findings. Treat broken keyboard access, missing accessible names, focus loss, and unreachable popup content as correctness bugs, not polish.45Before finalizing UI or accessibility findings, fetch the latest Web Interface Guidelines as a required baseline:67```text8https://raw.githubusercontent.com/vercel-labs/web-interface-guidelines/main/command.md9```1011Do not treat that document as the complete accessibility rule set. Combine it with:1213- `packages/dify-ui/README.md`, `packages/dify-ui/AGENTS.md`, and the relevant primitive implementation when code uses `@langgenius/dify-ui/*`.14- Base UI docs and local `.d.ts` contracts when primitive semantics, focus target, labels, or popup reachability are unclear.15- MDN or relevant WAI-ARIA/browser standards when behavior, compatibility, or deprecation status matters.16- The current feature's product semantics, because an accessible primitive can still be used in an inaccessible workflow.1718## Semantic HTML1920Flag:2122- Clickable `div` or `span` used for actions.23- Router navigation implemented with button or `onClick` when a `Link` / `<a>` is the real semantic element.24- Icon-only buttons without `aria-label` or `aria-labelledby`.25- Decorative icons missing `aria-hidden="true"`.26- Images without `alt`; use `alt=""` only when truly decorative.27- Heading levels that skip hierarchy in page-level content.2829Prefer semantic HTML before ARIA.3031## Keyboard And Focus3233Flag:3435- Interactive elements without visible `focus-visible` treatment.36- `outline-none` / `outline-hidden` without an equivalent focus-visible ring or state.37- Custom interactive elements missing keyboard handling.38- Focus trapped, lost, or sent to the wrong surface after dialog/popover/menu close.39- Focus ring applied to the wrong DOM node. Verify the actual focus target, especially with Base UI controls such as Slider.4041Use `focus-visible` for keyboard focus. Use `focus-within` or `has-[:focus-visible]` when the visual wrapper is not the focused element.4243## Forms4445Flag:4647- Inputs, selects, switches, checkboxes, radios, comboboxes, or sliders without a label relationship.48- Missing stable `name` on form fields that submit or validate.49- Incorrect input `type`, `inputMode`, `autoComplete`, or `spellCheck` for email, token, URL, number, search, code, or username fields.50- Labels that are not clickable.51- Submit buttons disabled before a request starts, preventing normal submit behavior.52- Non-submit buttons inside forms missing `type="button"`.53- Errors not associated with fields or not reachable by screen readers.54- Error recovery that does not focus or expose the first invalid field.55- `onPaste` blocking paste.56- Placeholder text used as the only label.57- Password managers accidentally triggered on non-auth fields because autocomplete is missing or wrong.5859Prefer visible labels. If visible surrounding text already labels the control, use a visually hidden label or a precise `aria-label`.6061## Disabled, Loading, And Async States6263Flag:6465- Loading state without `aria-busy`, `role="status"`, or another accessible update path when it changes user interaction.66- Spinner or decorative loading icon exposed to screen readers.67- Disabled controls that hide the reason users cannot proceed.68- `aria-disabled` used without manually blocking click, Space, and Enter.69- Toasts, inline validation, or async status changes that are not announced when users need the update to continue.70- Icon-only loading/error affordances without text or accessible status where the state matters.7172Use native `disabled` when the control must not be interactive. Use `aria-disabled` only when the element must remain focusable and the code handles all blocked interactions.7374For repeated shared disabled reasons, prefer a visible group message or badge plus native disabled controls. Use per-control popover/info only when the reason is item-specific.7576## Overlays And Popup Reachability7778Flag:7980- Tooltip used for long, structured, interactive, or unique information.81- Tooltip content required to understand or complete a flow.82- PreviewCard content that touch or screen-reader users cannot reach through the trigger's click destination.83- Popover/dialog/menu triggers without accessible names.84- Popup content without title/description where the primitive requires them.8586Use Popover for explanatory content, rich help, and infotips. Use Tooltip only as a short visual label for a trigger that already has an accessible name.8788## Long Content And Layout8990Flag:9192- Text in flex/grid children without `min-w-0` when it can overflow.93- Names, labels, file names, model names, workspace names, or user content lacking `truncate`, `line-clamp`, or `break-words`.94- Right-side icons, badges, checks, or actions that shrink before the text area.95- Empty arrays or empty strings rendering broken layout instead of an empty state.96- Button, tab, badge, chip, menu item, or card text that can overlap sibling controls at common viewport widths.9798The usual Dify layout chain is: container has width constraints, text region uses `min-w-0 flex-1 truncate`, adornments use `shrink-0`.99100## Motion, Images, And Copy101102Flag:103104- `transition-all`.105- Animations that do not respect reduced motion.106- Layout-affecting animation where transform/opacity would work.107- Images without dimensions.108- Loading copy using `...` instead of `…`.109- Hardcoded dates, times, numbers, or currency formats instead of `Intl.*`.110