Skip to content

Commit 1ad6ac9

Browse files
committed
docs: refine contents
1 parent d01aca7 commit 1ad6ac9

File tree

12 files changed

+152
-168
lines changed

12 files changed

+152
-168
lines changed

.vitepress/config/fa.mts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ export const fa = defineConfig({
4747
quote:
4848
"اما اگر جهت خود را تغییر ندهید و اگر ادامه دهید به دنبال چیزی که دنبال می‌کنید، ممکن است در نهایت به جایی که در حال رفتن به سمتش هستید، برسید.",
4949
},
50-
siteTitle: "قابلیت دسترسی (accessibility)",
50+
siteTitle: "Accessibility",
5151
},
5252
});
5353

@@ -82,6 +82,10 @@ function sidebar(): DefaultTheme.SidebarItem[] {
8282
text: "Personaهای مرتبط با accessibility",
8383
link: "/persona",
8484
},
85+
{
86+
text: "تمرین",
87+
link: "/excercise-1",
88+
},
8589
],
8690
},
8791
{
@@ -108,6 +112,10 @@ function sidebar(): DefaultTheme.SidebarItem[] {
108112
text: "چگونه یک کامپوننت UI را از نظر accessibility تست کنیم",
109113
link: "/how-to-test-components",
110114
},
115+
// {
116+
// text: "تمرین: بهبود یک کامپوننت!",
117+
// link: "/excersice-2",
118+
// },
111119
],
112120
},
113121
{

.vitepress/config/shared.mts

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
1-
import { defineConfig } from 'vitepress'
1+
import { defineConfig } from "vitepress";
22
export const shared = defineConfig({
33
rewrites: {
4-
'en/:rest*': ':rest*'
4+
"en/:rest*": ":rest*",
55
},
66
lastUpdated: true,
77
cleanUrls: true,
88
metaChunk: true,
9-
base: '/a11y',
9+
base: "/a11y",
1010

1111
themeConfig: {
12-
socialLinks: [
13-
{ icon: 'github', link: 'https://github.com/amir78729' }
14-
],
12+
editLink: {
13+
pattern: "https://github.com/code-with-amirhossein/a11y/edit/main/:path",
14+
},
15+
socialLinks: [{ icon: "github", link: "https://github.com/amir78729" }],
1516
},
16-
})
17+
});

.vitepress/theme/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import DefaultTheme from 'vitepress/theme'
22
import './fonts.css'
33
import './custom.css'
4+
import '../../components/stackBlitzEmbed'
45

56
export default DefaultTheme

api-examples.md

Lines changed: 0 additions & 49 deletions
This file was deleted.

components/stackBlitzEmbed.js

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
class StackBlitzEmbed extends HTMLElement {
2+
constructor() {
3+
super();
4+
this.attachShadow({ mode: 'open' });
5+
}
6+
7+
static get observedAttributes() {
8+
return ['name', 'height', 'view', 'open-file', 'hide-explorer', 'show-devtools'];
9+
}
10+
11+
connectedCallback() {
12+
this.render();
13+
}
14+
15+
attributeChangedCallback() {
16+
this.render();
17+
}
18+
19+
get name() {
20+
return this.getAttribute('name') || '';
21+
}
22+
23+
get height() {
24+
return this.getAttribute('height') || '600';
25+
}
26+
27+
get view() {
28+
return this.getAttribute('view') || 'preview';
29+
}
30+
31+
get openFile() {
32+
return this.getAttribute('open-file') || '';
33+
}
34+
35+
get hideExplorer() {
36+
return this.hasAttribute('hide-explorer');
37+
}
38+
39+
get showDevtools() {
40+
return this.hasAttribute('show-devtools');
41+
}
42+
43+
render() {
44+
const iframe = document.createElement('iframe');
45+
const params = new URLSearchParams({
46+
embed: '1',
47+
hideExplorer: this.hideExplorer ? '1' : '0',
48+
file: this.openFile,
49+
view: this.view,
50+
devToolsHeight: this.showDevtools ? '50' : '0',
51+
});
52+
53+
iframe.src = `https://stackblitz.com/edit/${this.name}?${params.toString()}`;
54+
iframe.height = this.height;
55+
iframe.style.width = '100%';
56+
iframe.style.border = 'none';
57+
58+
// Clear previous content
59+
this.shadowRoot.innerHTML = '';
60+
this.shadowRoot.appendChild(iframe);
61+
}
62+
}
63+
64+
customElements.define('stackblitz-embed', StackBlitzEmbed);

markdown-examples.md

Lines changed: 0 additions & 85 deletions
This file was deleted.

public/typeahead.png

389 KB
Loading

topics/mvp/excercise-1.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# تمرین بحث گروهی
2+
3+
در اولین تمرین، یک مشخصه برای قابلیت جدید بررسی می‌شود — با در نظر گرفتن accessibility. چه سؤالاتی باید از ابتدا مطرح کنیم تا مطمئن شویم این قابلیت در زمان انتشار، accessible خواهد بود؟
4+
5+
## قابلیت: کامپوننت Typeahead برای جستجو
6+
7+
<figure className="my-6">
8+
<img src="/typeahead.png" alt="A screenshot of the Amazon search box, with toddler results" className="max-w-[560px]" />
9+
</figure>
10+
11+
## مواردی برای بحث
12+
13+
- الزامات accessibility برای این قابلیت چیستند؟
14+
- برای رعایت Deadlineها، چه چیزهایی را می‌توان حذف کرد، بدون اینکه به accessibility آسیب برسد؟
15+
- چگونه می‌توان این قابلیت را به‌صورت مرحله‌ای توسعه داد؟

topics/mvp/shift-left.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<img src="/SDLC.png" alt="The Software Development Lifecycle" style="border-radius: 50%; padding: 64px 10%;" />
55
</figure>
66

7-
زمانی که در مراحل برنامه‌ریزی، طراحی یا مهندسی به accessibility توجه نمی‌شود، اعمال تغییرات و اصلاحات بعدی می‌تواند دشوار و پرهزینه باشد — به‌ویژه اگر تصمیمات گرفته‌شده به بخش اساسی هویت محصول تبدیل شده باشند، مانند رنگ برند یا پیاده‌سازی کامل برنامه با HTML5 Canvas.
7+
زمانی که در مراحل برنامه‌ریزی، طراحی یا مهندسی به accessibility توجه نمی‌شود، اعمال تغییرات و اصلاحات بعدی می‌تواند دشوار و پرهزینه باشد — به‌ویژه اگر تصمیمات گرفته‌شده به بخش اساسی هویت محصول تبدیل شده باشند، مانند رنگ برند یا پیاده‌سازی کامل برنامه با HTML5 Canvas (مثل Figma).
88

99
بیشترین موفقیت زمانی حاصل می‌شود که accessibility در چرخه عمر توسعه نرم‌افزار (SDLC) به مراحل ابتدایی‌تر منتقل شود؛ از مرحله پیاده‌سازی (مهندسی) به طراحی و از طراحی به برنامه‌ریزی.
1010

topics/ui/dont-be-a-div-button-creator.md

Lines changed: 21 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -7,47 +7,44 @@
77
<figure className="grid grid-cols-2 gap-6 py-2 item-start">
88

99
```tsx
10-
1110
const Submit = () => {
12-
const handleKeyDown = (event) => {
13-
if (event.code === 'Space' || event.code === 'Enter') {
14-
// do click stuff
15-
}
16-
};
17-
18-
return (
19-
<div
20-
onClick={handleClick}
21-
onKeyDown={handleKeyDown}
22-
role="button"
23-
tabIndex="0"
24-
>
25-
Submit
26-
</div>
27-
)
28-
}
29-
11+
const handleKeyDown = (event) => {
12+
if (event.code === "Space" || event.code === "Enter") {
13+
// do click stuff
14+
}
15+
};
16+
17+
return (
18+
<div
19+
onClick={handleClick}
20+
onKeyDown={handleKeyDown} // Add functionality for keyboard users // [!code highlight]
21+
role="button" // Tell the screen readers that it's a button (it's NOT!) // [!code highlight]
22+
tabIndex="0" // Make it focusable! // [!code highlight]
23+
>
24+
Submit
25+
</div>
26+
);
27+
};
3028
```
3129

32-
3330
</figure>
3431

3532
در key handler باید به‌طور شرطی منطق مورد نظر را هنگام فشردن کلید Space یا Enter اجرا کنید. و اگر دکمه‌ شما آیکونی است یا محتوای متنی ندارد، فراموش نکنید که یک نام قابل دسترس (احتمالاً با `aria-label`) به آن اختصاص دهید.
3633

37-
استفاده از عنصر `button` بسیار ساده‌تر است. برای رسیدن به همان عملکرد و سطح دسترسی، تنها کافی است:
34+
استفاده از عنصر `button` بسیار ساده‌تر است. برای رسیدن به همان عملکرد و سطح دسترسی، تنها کافی است بگوییم:
3835

3936
```javascript
4037
<button onClick={handleClick}>Submit</button>
4138
```
4239

43-
همین. نیازی به تعیین role صریح، `tabIndex`، یا key handler ندارید (چون دکمه‌ها به‌صورت پیش‌فرض از طریق کیبورد فعال می‌شوند، بر خلاف DIVها).
40+
همین! نیازی به تعیین role صریح، `tabIndex`، یا key handler نداریم (چون دکمه‌ها به‌صورت پیش‌فرض از طریق کیبورد فعال می‌شوند، بر خلاف DIVها).
4441

4542
## مراقب دکمه‌های DIV باشید
4643

4744
این یکی از ساده‌ترین مشکلاتی است که می‌توان در بازبینی کدها شناسایی کرد: رویداد کلیک روی یک DIV (یا listitem یا سایر عناصر غیرتعاملی). معمولاً اعضای تیم تلاش خود را می‌کنند و role و tabIndex را اضافه می‌کنند، اما اغلب key handler را فراموش می‌کنند، چون تست با کیبورد بخشی از فرآیند کاری روزمره‌ آن‌ها نیست.
4845

4946
تست با کیبورد را به بخشی از جریان کاری منظم خود تبدیل کنید و از دکمه‌های HTML استفاده کنید! مشکل به‌سادگی حل خواهد شد.
5047

51-
## نکته‌ای درباره هوش مصنوعی
48+
<!-- ## نکته‌ای درباره هوش مصنوعی
5249
53-
ما باید این مسئله (و سایر بخش‌های مرتبط با accessibility) را در مرحله توسعه، یعنی همان authoring، به‌طور جدی مدنظر قرار دهیم. نباید انتظار داشته باشیم Assistive Tech یا هوش مصنوعی این مشکلات را به‌جای ما حل کنند. چنین دیدگاهی بسیار خاص و وابسته به امکانات لوکس است، در حالی که بسیاری از افراد در سراسر جهان توانایی استفاده از فناوری‌های پیشرفته را ندارند. در عوض، می‌توانیم همین حالا UIهایی بسازیم که از نظر پایه‌ای accessible باشند — هم برای امروز و هم برای آینده.
50+
ما باید این مسئله (و سایر بخش‌های مرتبط با accessibility) را در مرحله توسعه، یعنی همان authoring، به‌طور جدی مدنظر قرار دهیم. نباید انتظار داشته باشیم Assistive Tech یا هوش مصنوعی این مشکلات را به‌جای ما حل کنند. چنین دیدگاهی بسیار خاص و وابسته به امکانات لوکس است، در حالی که بسیاری از افراد در سراسر جهان توانایی استفاده از فناوری‌های پیشرفته را ندارند. در عوض، می‌توانیم همین حالا UIهایی بسازیم که از نظر پایه‌ای accessible باشند — هم برای امروز و هم برای آینده. -->

0 commit comments

Comments
 (0)