@wix/agent-skills 1.16.0 → 1.16.2

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.
Files changed (94) hide show
  1. package/package.json +1 -1
  2. package/skills/wix-app/SKILL.md +72 -8
  3. package/skills/wix-app/references/CODE_QUALITY.md +0 -1
  4. package/skills/wix-app/references/DASHBOARD_MODAL.md +21 -14
  5. package/skills/wix-app/references/DASHBOARD_PAGE.md +30 -184
  6. package/skills/wix-app/references/EDITOR_REACT_COMPONENT.md +19 -3
  7. package/skills/wix-app/references/WIX_PATTERNS_DOCS.md +172 -0
  8. package/skills/wix-app/references/dashboard-page/WDS_LAYOUT.md +187 -0
  9. package/skills/wix-app/references/editor-react-component/A11Y-REVIEW.md +12 -7
  10. package/skills/wix-app/references/editor-react-component/ANIMATED-COMPONENTS.md +31 -2
  11. package/skills/wix-app/references/editor-react-component/COMPONENT-API.md +6 -1
  12. package/skills/wix-app/references/editor-react-component/COMPONENT-CONFIGURATION.md +60 -0
  13. package/skills/wix-app/references/editor-react-component/DIRECTIONALITY.md +6 -6
  14. package/skills/wix-app/references/editor-react-component/FUNCTION-HANDLERS.md +167 -0
  15. package/skills/wix-app/references/editor-react-component/REACT-GUIDELINES.md +2 -2
  16. package/skills/wix-app/references/editor-react-component/SITE-CONTEXT-HOOKS.md +187 -0
  17. package/skills/wix-app/scripts/scan-a11y-code.cjs +777 -0
  18. package/skills/wix-app/scripts/scan-a11y-eslint.cjs +201 -0
  19. package/skills/wix-base44-connector/SKILL.md +185 -0
  20. package/skills/wix-base44-connector/scripts/utils.js +212 -0
  21. package/skills/wix-design-system/SKILL.md +19 -15
  22. package/skills/wix-docs/SKILL.md +75 -1
  23. package/skills/wix-headless/references/CAPABILITIES.md +16 -3
  24. package/skills/wix-headless/references/SDK_HANDOFF.md +1 -1
  25. package/skills/wix-headless/references/SEED.md +1 -1
  26. package/skills/wix-headless/references/inline-recipes/how-to-code-forms.md +560 -102
  27. package/skills/wix-headless/references/inline-recipes/setup-forms.md +210 -143
  28. package/skills/wix-manage/SKILL.md +20 -17
  29. package/skills/wix-manage/references/accessibility/scan-site-accessibility.md +98 -0
  30. package/skills/wix-manage/references/analytics/analytics-dashboard-navigation.md +1 -2
  31. package/skills/wix-manage/references/domains/domain-search-purchase-and-connect.md +2603 -0
  32. package/skills/wix-manage/references/events/create-wix-event.md +112 -90
  33. package/skills/wix-manage/references/events/manage-wix-events.md +33 -94
  34. package/skills/wix-manage/references/sites/create-headless-site.md +1 -0
  35. package/skills/wix-manage/references/sites/manage-oauth-apps.md +154 -0
  36. package/skills/wix-manage/references/sites/read-site-context.md +125 -0
  37. package/skills/wix-manage/references/sites/site-import.md +67 -15
  38. package/skills/wix-manage/references/stores/create-product-catalog-v3.md +273 -0
  39. package/skills/wix-replatform/resources/rp-target-wix/lib/wix-writers.js +1 -1
  40. package/skills/wix-vibe-headless/SKILL.md +2 -1
  41. package/skills/wix-vibe-headless/install/deploy.cjs +63 -3
  42. package/skills/wix-vibe-headless/platforms/base44-ecom-light-seed.md +104 -0
  43. package/skills/wix-vibe-headless/platforms/base44-ecom-light.md +74 -0
  44. package/skills/wix-vibe-headless/platforms/base44.md +15 -40
  45. package/skills/wix-vibe-headless/references/blog/INSTRUCTIONS.md +7 -11
  46. package/skills/wix-vibe-headless/references/blog/seed/SEED.md +1 -1
  47. package/skills/wix-vibe-headless/references/bookings/INSTRUCTIONS.md +7 -11
  48. package/skills/wix-vibe-headless/references/bookings/seed/SEED.md +1 -1
  49. package/skills/wix-vibe-headless/references/cms/INSTRUCTIONS.md +1 -2
  50. package/skills/wix-vibe-headless/references/events/INSTRUCTIONS.md +7 -12
  51. package/skills/wix-vibe-headless/references/events/seed/SEED.md +1 -1
  52. package/skills/wix-vibe-headless/references/members/INSTRUCTIONS.md +7 -11
  53. package/skills/wix-vibe-headless/references/portfolio/INSTRUCTIONS.md +7 -11
  54. package/skills/wix-vibe-headless/references/portfolio/seed/SEED.md +1 -1
  55. package/skills/wix-vibe-headless/references/pricing-plans/INSTRUCTIONS.md +7 -11
  56. package/skills/wix-vibe-headless/references/pricing-plans/seed/SEED.md +1 -1
  57. package/skills/wix-vibe-headless/references/restaurants/INSTRUCTIONS.md +7 -11
  58. package/skills/wix-vibe-headless/references/restaurants/seed/SEED.md +1 -1
  59. package/skills/wix-vibe-headless/references/shared/app/components/WixManageBanner.jsx +1 -1
  60. package/skills/wix-vibe-headless/references/shared/app/rest/wix-config.js +5 -3
  61. package/skills/wix-vibe-headless/references/storefront/INSTRUCTIONS.md +75 -13
  62. package/skills/wix-vibe-headless/references/storefront/app/components/ProductCard.jsx +29 -86
  63. package/skills/wix-vibe-headless/references/storefront/app/components/ProductGrid.jsx +3 -8
  64. package/skills/wix-vibe-headless/references/storefront/app/components/VariantPicker.jsx +78 -105
  65. package/skills/wix-vibe-headless/references/storefront/app/hooks/useProductCard.js +92 -0
  66. package/skills/wix-vibe-headless/references/storefront/app/hooks/useVariantOptions.js +76 -0
  67. package/skills/wix-vibe-headless/references/storefront/seed/SEED.md +1 -1
  68. package/skills/wix-vibe-headless/references/storefront/seed/seed-store.js +44 -5
  69. package/skills/wix-app/references/AUTO_PATTERNS_DASHBOARD.md +0 -326
  70. package/skills/wix-app/references/auto-patterns-dashboard/action-cell.md +0 -115
  71. package/skills/wix-app/references/auto-patterns-dashboard/app-config-structure.md +0 -264
  72. package/skills/wix-app/references/auto-patterns-dashboard/app-context.md +0 -37
  73. package/skills/wix-app/references/auto-patterns-dashboard/bulk-actions.md +0 -86
  74. package/skills/wix-app/references/auto-patterns-dashboard/collection-page-actions.md +0 -119
  75. package/skills/wix-app/references/auto-patterns-dashboard/collection-page.md +0 -103
  76. package/skills/wix-app/references/auto-patterns-dashboard/custom-actions-override.md +0 -76
  77. package/skills/wix-app/references/auto-patterns-dashboard/custom-columns-override.md +0 -82
  78. package/skills/wix-app/references/auto-patterns-dashboard/custom-components-override.md +0 -89
  79. package/skills/wix-app/references/auto-patterns-dashboard/custom-header-override.md +0 -124
  80. package/skills/wix-app/references/auto-patterns-dashboard/custom-sections-override.md +0 -91
  81. package/skills/wix-app/references/auto-patterns-dashboard/custom-slots-override.md +0 -71
  82. package/skills/wix-app/references/auto-patterns-dashboard/entity-page-actions.md +0 -70
  83. package/skills/wix-app/references/auto-patterns-dashboard/entity-page-view-actions.md +0 -73
  84. package/skills/wix-app/references/auto-patterns-dashboard/entity-page.md +0 -98
  85. package/skills/wix-app/references/auto-patterns-dashboard/example-patterns.json +0 -278
  86. package/skills/wix-app/references/auto-patterns-dashboard/pages-configuration.md +0 -94
  87. package/skills/wix-app/references/auto-patterns-dashboard/resolved-action.md +0 -43
  88. package/skills/wix-app/references/auto-patterns-dashboard/sdk-utilities.md +0 -66
  89. package/skills/wix-app/references/auto-patterns-dashboard/views.md +0 -76
  90. package/skills/wix-app/scripts/generate-auto-patterns.js +0 -510
  91. package/skills/wix-manage/references/domains/domain-search-and-purchase.md +0 -437
  92. package/skills/wix-manage/references/stores/create-product-from-image.md +0 -1031
  93. package/skills/wix-manage/references/stores/create-product-with-options-catalog-v3.md +0 -623
  94. package/skills/wix-manage/references/stores/setup-online-store-catalog-v3.md +0 -106
@@ -0,0 +1,167 @@
1
+ # Function Event Handlers
2
+
3
+ Rules and patterns for adding function event handler props to an Editor React component's TypeScript interface, wiring them to DOM events, and declaring custom callbacks.
4
+
5
+ ---
6
+
7
+ ## Rules
8
+
9
+ ### Standard SDK Event Handlers
10
+
11
+ These are the standard event handler props the editor SDK exposes to site owners. Use the exact prop names — ZeroConfig and the manifest system recognize them.
12
+
13
+ | Prop name | React DOM event | Type |
14
+ | ------------ | --------------- | ------------------------------------------------ |
15
+ | `onClick` | `onClick` | `(event: React.MouseEvent) => void` |
16
+ | `onDblClick` | `onDoubleClick` | `(event: React.MouseEvent) => void` |
17
+ | `onChange` | `onChange` | `(event: React.ChangeEvent<HTMLElement>) => void` |
18
+ | `onFocus` | `onFocus` | `(event: React.FocusEvent) => void` |
19
+ | `onBlur` | `onBlur` | `(event: React.FocusEvent) => void` |
20
+ | `onMouseIn` | `onMouseEnter` | `(event: React.MouseEvent) => void` |
21
+ | `onMouseOut` | `onMouseLeave` | `(event: React.MouseEvent) => void` |
22
+
23
+ Three props have a **name mismatch** between the SDK prop and the DOM event: `onDblClick` → `onDoubleClick`, `onMouseIn` → `onMouseEnter`, `onMouseOut` → `onMouseLeave`.
24
+
25
+ ### Declaring Standard Handler Props
26
+
27
+ Declare standard handlers inline with the exact SDK prop names and React event types:
28
+
29
+ ```typescript
30
+ interface MyComponentProps {
31
+ label?: string;
32
+ onClick?: (event: React.MouseEvent) => void;
33
+ onDblClick?: (event: React.MouseEvent) => void;
34
+ onChange?: (event: React.ChangeEvent<HTMLElement>) => void;
35
+ onFocus?: (event: React.FocusEvent) => void;
36
+ onBlur?: (event: React.FocusEvent) => void;
37
+ onMouseIn?: (event: React.MouseEvent) => void;
38
+ onMouseOut?: (event: React.MouseEvent) => void;
39
+ }
40
+ ```
41
+
42
+ Only declare handlers the component actually exposes. Do not add all seven if the component only handles two.
43
+
44
+ ### Wiring Standard Handlers to DOM Events
45
+
46
+ Destructure the props and pass them to the correct DOM event — applying the name mappings:
47
+
48
+ ```typescript
49
+ export const MyComponent = (props: MyComponentProps) => {
50
+ const { onClick, onDblClick, onFocus, onBlur, onMouseIn, onMouseOut } = props;
51
+ return (
52
+ <div
53
+ onClick={onClick}
54
+ onDoubleClick={onDblClick}
55
+ onFocus={onFocus}
56
+ onBlur={onBlur}
57
+ onMouseEnter={onMouseIn}
58
+ onMouseLeave={onMouseOut}
59
+ >
60
+ {/* ... */}
61
+ </div>
62
+ );
63
+ };
64
+ ```
65
+
66
+ ### Custom Callbacks
67
+
68
+ Component-specific callbacks that do not correspond to a DOM event (e.g., `onPlay`, `onPause`, `onEnded`, `onTimeupdate`) are **not** standard SDK event handlers. Type them as `() => void` — no React event parameter:
69
+
70
+ ```typescript
71
+ interface VideoPlayerProps {
72
+ onPlay?: () => void;
73
+ onPause?: () => void;
74
+ onEnded?: () => void;
75
+ }
76
+ ```
77
+
78
+ Pass them directly to the underlying element — no name remapping needed:
79
+
80
+ ```typescript
81
+ export const VideoPlayer = (props: VideoPlayerProps) => {
82
+ const { onPlay, onPause, onEnded } = props;
83
+ return <video onPlay={onPlay} onPause={onPause} onEnded={onEnded} />;
84
+ };
85
+ ```
86
+
87
+ ---
88
+
89
+ ## Common Mistakes
90
+
91
+ ### Passing SDK prop name directly to DOM instead of remapping
92
+
93
+ **❌ Wrong:**
94
+
95
+ ```typescript
96
+ export const MyComponent = (props: MyComponentProps) => {
97
+ const { onMouseIn, onMouseOut, onDblClick } = props;
98
+ return (
99
+ <div
100
+ onMouseIn={onMouseIn} // ❌ not a valid React DOM prop
101
+ onMouseOut={onMouseOut} // ❌ not a valid React DOM prop
102
+ onDblClick={onDblClick} // ❌ not a valid React DOM prop
103
+ />
104
+ );
105
+ };
106
+ ```
107
+
108
+ **✅ Correct:**
109
+
110
+ ```typescript
111
+ export const MyComponent = (props: MyComponentProps) => {
112
+ const { onMouseIn, onMouseOut, onDblClick } = props;
113
+ return (
114
+ <div
115
+ onMouseEnter={onMouseIn} // ✅ onMouseIn → onMouseEnter
116
+ onMouseLeave={onMouseOut} // ✅ onMouseOut → onMouseLeave
117
+ onDoubleClick={onDblClick} // ✅ onDblClick → onDoubleClick
118
+ />
119
+ );
120
+ };
121
+ ```
122
+
123
+ ### Adding a React event parameter to custom callbacks
124
+
125
+ **❌ Wrong:**
126
+
127
+ ```typescript
128
+ interface VideoPlayerProps {
129
+ onPlay?: (event: React.SyntheticEvent) => void; // ❌ event param on custom callback
130
+ onEnded?: (event: React.SyntheticEvent) => void; // ❌ event param on custom callback
131
+ }
132
+ ```
133
+
134
+ **✅ Correct:**
135
+
136
+ ```typescript
137
+ interface VideoPlayerProps {
138
+ onPlay?: () => void; // ✅ no event param
139
+ onEnded?: () => void; // ✅ no event param
140
+ }
141
+ ```
142
+
143
+ **Why:** Custom callbacks are component-level notifications to the site owner, not DOM event forwarders. They carry no event object — the SDK passes no event to them.
144
+
145
+ ### Using the DOM event name as the SDK prop name
146
+
147
+ **❌ Wrong:**
148
+
149
+ ```typescript
150
+ interface MyComponentProps {
151
+ onDoubleClick?: (event: React.MouseEvent) => void; // ❌ DOM name, not SDK name
152
+ onMouseEnter?: (event: React.MouseEvent) => void; // ❌ DOM name, not SDK name
153
+ onMouseLeave?: (event: React.MouseEvent) => void; // ❌ DOM name, not SDK name
154
+ }
155
+ ```
156
+
157
+ **✅ Correct:**
158
+
159
+ ```typescript
160
+ interface MyComponentProps {
161
+ onDblClick?: (event: React.MouseEvent) => void; // ✅ SDK prop name
162
+ onMouseIn?: (event: React.MouseEvent) => void; // ✅ SDK prop name
163
+ onMouseOut?: (event: React.MouseEvent) => void; // ✅ SDK prop name
164
+ }
165
+ ```
166
+
167
+ **Why:** The SDK prop names (`onDblClick`, `onMouseIn`, `onMouseOut`) are what ZeroConfig and the manifest system register. Using DOM names breaks the editor's event wiring.
@@ -9,6 +9,7 @@ This guide defines rules and guidance on **how to implement** production-quality
9
9
  - [`DIRECTIONALITY.md`](DIRECTIONALITY.md) — RTL/LTR rules and patterns
10
10
  - [`PROPS-VS-CSS.md`](PROPS-VS-CSS.md) — What should be a React prop vs CSS
11
11
  - [`COMPONENT-API.md`](COMPONENT-API.md) — Props structure, elementProps, data types, file splitting, containers, array props
12
+ - [`FUNCTION-HANDLERS.md`](FUNCTION-HANDLERS.md) — Standard SDK event handler props, DOM wiring, custom callbacks
12
13
  - [`ANIMATED-COMPONENTS.md`](ANIMATED-COMPONENTS.md) — Play/pause control and autoplay for animated/playable components
13
14
  - [`REACT-PATTERNS.md`](REACT-PATTERNS.md) — SSR-safe patterns, CSS rules, common mistakes
14
15
 
@@ -110,7 +111,7 @@ Unless explicitly specified as a component capability/API in the specification,
110
111
  **External handlers (only when specified):**
111
112
 
112
113
  - Only expose handlers that are explicitly listed as component capabilities
113
- - Example: If specification says "onClick callback for external control", then add `onClick?: () => void` to props
114
+ - Use the standard SDK prop names and DOM wiring rules from [`FUNCTION-HANDLERS.md`](FUNCTION-HANDLERS.md)
114
115
 
115
116
  **Child component handlers:**
116
117
 
@@ -170,4 +171,3 @@ See [`PROPS-VS-CSS.md`](PROPS-VS-CSS.md) and [`COMPONENT-API.md`](COMPONENT-API.
170
171
  **Phase 2: Component File** — Apply all §1.1 mandatory features and §1.2 implementation standards; toggle custom-state classes from data ([`DESIGN-STATES.md`](DESIGN-STATES.md))
171
172
 
172
173
  **Phase 3: Styles** — Apply Part 2 SCSS rules, including state styles ([`DESIGN-STATES.md`](DESIGN-STATES.md)). If the request uses the words **branded**, **themed**, or **brand-aware**, also apply [`BRANDED-COMPONENTS.md`](BRANDED-COMPONENTS.md) before writing CSS.
173
-
@@ -0,0 +1,187 @@
1
+ # Site Context Hooks
2
+
3
+ Rules and patterns for reading **runtime site context** in Editor React
4
+ components — the site's page tree, the current URL, the language direction, and
5
+ editor mode. None of these can be carried by a prop.
6
+
7
+ All of them come from hooks in `@wix/react-component-utils`, already a base
8
+ dependency. No additional install is needed, but the hooks require
9
+ `@wix/react-component-utils` ≥ 1.12.0.
10
+
11
+ ---
12
+
13
+ ## When this applies
14
+
15
+ Apply only when the component genuinely needs live site context:
16
+
17
+ - **The component reflects where the visitor is in the site** — breadcrumbs,
18
+ "you are here" indicators. Not navigation menus: the site owner authors those,
19
+ and their items need not necessarily be site pages, so they take a
20
+ `MenuItems` prop
21
+ - **The component needs the page's own URL** — share buttons, copy-link,
22
+ canonical links, QR codes
23
+ - **Language direction drives JavaScript** — keyboard navigation, transform or
24
+ animation math, conditional rendering
25
+ - **Behavior must differ inside the editor** — suppressing autoplay, network
26
+ calls, or timers while the site owner is designing
27
+
28
+ The test is whether the site owner **authors** the data. A hook reports state the
29
+ owner cannot write — which page is being rendered, what the site's URL is. Data
30
+ the owner chooses belongs in props, even when it happens to point at site
31
+ pages — see [`PROPS-VS-CSS.md`](PROPS-VS-CSS.md) and
32
+ [`COMPONENT-API.md`](COMPONENT-API.md). Purely visual RTL needs no hook
33
+ either — use logical CSS properties, see
34
+ [`DIRECTIONALITY.md`](DIRECTIONALITY.md).
35
+
36
+ ---
37
+
38
+ ## Rules
39
+
40
+ ### The Available Hooks
41
+
42
+ | Hook | Returns | Use for |
43
+ | --- | --- | --- |
44
+ | `usePages()` | `Readonly<Record<string, PageConfig>>` | Every page on the site, keyed by page id |
45
+ | `useCurrentPageId()` | `string` | Id of the page being rendered |
46
+ | `useMainPageId()` | `string` | Id of the site's homepage |
47
+ | `useSiteUrl()` | `string` | The site's public base URL |
48
+ | `useCurrentUrl()` | `string` | Full URL of the page being rendered |
49
+ | `useLanguageDirection()` | `'ltr' \| 'rtl'` | The site's language direction |
50
+ | `useIsEditMode()` | `boolean` | `true` in editor design mode — see [`COMPONENT-PREVIEW.md`](COMPONENT-PREVIEW.md) |
51
+ | `useReducedMotion()` | `boolean` | `true` when the OS requests reduced motion — see [`ANIMATED-COMPONENTS.md`](ANIMATED-COMPONENTS.md) |
52
+
53
+ All import from the same place:
54
+
55
+ ```typescript
56
+ import { usePages, useCurrentPageId, useSiteUrl } from '@wix/react-component-utils';
57
+ ```
58
+
59
+ Each returns a plain value, so there is nothing to unwrap or guard. They are
60
+ React hooks — call them at the top of the component or hook body, never at module
61
+ scope, inside a callback, or conditionally.
62
+
63
+ ### Read Values During Render
64
+
65
+ Hook values are read on the server too, so their results are part of the server
66
+ markup — see [`SSR.md`](SSR.md). Use the value directly.
67
+
68
+ **✅ Correct:**
69
+
70
+ ```tsx
71
+ const siteUrl = useSiteUrl();
72
+ ```
73
+
74
+ **❌ Wrong — empty on the server, then a hydration mismatch:**
75
+
76
+ ```tsx
77
+ const resolvedUrl = useSiteUrl();
78
+ const [siteUrl, setSiteUrl] = useState('');
79
+ useEffect(() => setSiteUrl(resolvedUrl), []);
80
+ ```
81
+
82
+ ---
83
+
84
+ ## Patterns
85
+
86
+ ### Walking the Page Tree
87
+
88
+ `usePages()` returns a map keyed by page id. Three things to get right:
89
+
90
+ - **The map key is the page id** — the values carry no `id` field.
91
+ - **`parentPageId` is absent for top-level pages** — treat those as children of
92
+ `useMainPageId()` when walking upward.
93
+ - **`popup: true` pages are lightboxes**, not navigable pages. Filter them out of
94
+ breadcrumbs, menus, and page pickers.
95
+
96
+ ```tsx
97
+ import { usePages, useCurrentPageId, useMainPageId } from '@wix/react-component-utils';
98
+
99
+ export const useBreadcrumbTrail = (): Array<{ id: string; label: string }> => {
100
+ const pages = usePages();
101
+ const currentPageId = useCurrentPageId();
102
+ const mainPageId = useMainPageId();
103
+
104
+ const trail: Array<{ id: string; label: string }> = [];
105
+ const visited = new Set<string>();
106
+ let pageId: string | undefined = currentPageId;
107
+
108
+ while (pageId && !visited.has(pageId) && pages[pageId]) {
109
+ visited.add(pageId);
110
+ const page = pages[pageId]!;
111
+ if (!page.popup) {
112
+ trail.push({ id: pageId, label: page.title });
113
+ }
114
+ // Pages without parentPageId are top-level children of the homepage.
115
+ pageId = pageId === mainPageId ? undefined : (page.parentPageId ?? mainPageId);
116
+ }
117
+
118
+ return trail.reverse();
119
+ };
120
+ ```
121
+
122
+ The `visited` set is not optional — a misconfigured site can produce a parent
123
+ cycle, and an unguarded walk hangs the render.
124
+
125
+ ### Building a Link to a Page
126
+
127
+ Join a page's `path` onto `useSiteUrl()`. The base URL may or may not carry a
128
+ trailing slash, so normalize before joining:
129
+
130
+ ```typescript
131
+ const buildPageUrl = (path: string, siteUrl: string): string => {
132
+ const base = siteUrl.replace(/\/$/, '');
133
+ return path ? `${base}/${path}` : base;
134
+ };
135
+ ```
136
+
137
+ ### Direction-Dependent Logic
138
+
139
+ Resolve the component's own `direction` prop first, then fall back to the site:
140
+
141
+ ```typescript
142
+ import type { Direction } from '@wix/editor-react-types';
143
+ import { useLanguageDirection } from '@wix/react-component-utils';
144
+
145
+ export const useResolvedDirection = (direction?: Direction): Direction => {
146
+ // Call unconditionally — `direction ?? useLanguageDirection()` would
147
+ // short-circuit and skip the hook whenever the prop is set.
148
+ const siteDirection = useLanguageDirection() as Direction;
149
+ return direction ?? siteDirection;
150
+ };
151
+ ```
152
+
153
+ Use the resolved value for **logic only** — arrow-key handling, transform sign,
154
+ scroll direction:
155
+
156
+ ```tsx
157
+ const isRTL = useResolvedDirection(direction) === 'rtl';
158
+
159
+ const onKeyDown = (event: React.KeyboardEvent) => {
160
+ const forward = isRTL ? 'ArrowLeft' : 'ArrowRight';
161
+ if (event.key === forward) {
162
+ focusNext();
163
+ }
164
+ };
165
+ ```
166
+
167
+ ---
168
+
169
+ ## Common Mistake: Direction Logic Instead of Logical CSS
170
+
171
+ Calling `useLanguageDirection()` to pick between physical CSS properties.
172
+
173
+ **❌ Wrong:**
174
+
175
+ ```tsx
176
+ const isRTL = useLanguageDirection() === 'rtl';
177
+
178
+ <div style={{ paddingLeft: isRTL ? 0 : 8, paddingRight: isRTL ? 8 : 0 }} />
179
+ ```
180
+
181
+ **✅ Correct:**
182
+
183
+ ```scss
184
+ .element {
185
+ padding-inline-start: 8px; // Auto RTL/LTR, no hook needed
186
+ }
187
+ ```