diff --git a/.gitignore b/.gitignore index 1ed7758f7..4b96337cc 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,5 @@ .DS_Store dist *.sw[op] +# docker +compose-dev.yaml \ No newline at end of file diff --git a/content/fa/404.md b/content/fa/404.md new file mode 100644 index 000000000..61d1698be --- /dev/null +++ b/content/fa/404.md @@ -0,0 +1,5 @@ +# مشکل + +به نظر میرسید که این صفحه ناپدید شده. + +بهتره برگردیم به [خانه](/). \ No newline at end of file diff --git a/content/fa/blog.md b/content/fa/blog.md new file mode 100644 index 000000000..0d3143d26 --- /dev/null +++ b/content/fa/blog.md @@ -0,0 +1,14 @@ +درباره پروژه هایی که تیم Preact روی آن کار می کنند بیشتر بدانید. + +
+ +
+
+

از چیزی که می بینید خوشتان می آید؟

+

+ استفاده از Preact رایگان است تا همه بتوانند در ساختن پروژه های وب شرکت کنند. + با تشکر از همه اسپانسرها که کار کردن بر روی Preact را ممکن می کنند. + اگر می خواهید یکی از آنها شوید: + کمک مالی را در نظر بگیرید. +

+
diff --git a/content/fa/index.md b/content/fa/index.md new file mode 100644 index 000000000..dc07b181b --- /dev/null +++ b/content/fa/index.md @@ -0,0 +1,231 @@ +--- +layout: home +title: Preact +show_title: false +toc: false +description: 'جایگزین 3kb برای React با همان API مدرن' +--- + + +

+ Preact +

+

جایگزین 3kb برای React با همان API مدرن

+

+ شروع + عوض کرن به Preact +

+
+ +```jsx +function Counter() { + const [value, setValue] = useState(0); + + return ( + <> +
Counter: {value}
+ + + + ) +} +``` + +
+

با افتخار حمایت شده توسط:

+ +
+ +
+

یک کتابخانه کاملا متفاوت

+
+ +
+ metal + +
+

نزدیک تر به DOM

+

+ Preact نازک ترین انتزاع مجازی DOM ممکن را در بالای DOM ارائه می دهد. + این برنامه بر روی ویژگی‌های پلتفرم پایدار ساخته می‌شود، کنترل‌کننده‌های event واقعی را ثبت می‌کند و به خوبی با کتابخانه‌های دیگر سازگار است. +

+

+ Preact را می توان مستقیماً در مرورگر بدون هیچ مرحله کامپایل کردن استفاده کرد. +

+
+
+ +
+ size + +
+

حجم کم

+

+ اکثر فریم ورک‌های رابط کاربری به اندازه‌ای حجیم هستند که شامل اکثریت اندازه جاوا اسکریپت یک برنامه می شوند. + Preact متفاوت است: به اندازه ای کوچک است که کد شما بزرگترین بخش برنامه هست. +

+

+ این یعنی جاوا اسکریپت کمتری برای دانلود، parse و execute - زمان بیشتری برای کد شما باقی می‌ماند، بنابراین می‌توانید تجربه‌ای بسازید که بدون دردسر فریم ورک را تحت کنترل داشته باشید. +

+
+
+ +
+ performance + +
+

عملکرد بیشتر

+

+ Preact سریع است و نه فقط به دلیل اندازه آن. این یکی از سریع‌ترین کتابخانه‌های DOM مجازی است که به لطف اجرای تفاوت ساده و قابل پیش‌بینی بودن.. +

+

+ ما به‌طور خودکار به‌روزرسانی‌های Preact را منتشر و در مورد عملکرد را تا حد زیادی تنظیم می‌کنیم. ما از نزدیک با مهندسان مرورگر کار می کنیم تا حداکثر عملکرد ممکن را از Preact بدست آوریم. +

+
+
+ +
+ portable + +
+

قابل حمل و نشاندن

+

+ ردپای کوچک Preact به این معنی است که می‌توانید پارادایم قدرتمند کامپوننت های DOM مجازی را به مکان‌های جدیدی ببرید که در غیر این صورت نمی‌توانست بروید. +

+

+ از Preact برای ساخت بخش هایی از یک برنامه بدون یکپارچگی پیچیده استفاده کنید. Preact را در یک ویجت جاسازی کنید و از همان ابزارها و تکنیک هایی استفاده کنید که برای ساختن یک برنامه کامل استفاده می کنید. +

+
+
+ +
+ productive + +
+

پروداکتیو بیشتر

+

+ کم حجم بودن بسیار سرگرم کننده تر است وقتی که لازم نیست پروداکتیویتی را برای رسیدن به آن فدا کنید. Preact فوراً شما را ‍پروداکتیو می کند. حتی دارای چند ویژگی عالی هم است: +

+ +
+
+ +
+ compatible + +
+

اکوسیستم سازگار

+

+ کامپوننت های DOM مجازی اشتراک گذاری چیزهای قابل استفاده مجدد را آسان می کند - همه چیز از دکمه ها گرفته تا ارائه دهندگان داده(providers). +طراحی Preact به این معنی است که شما می توانید به طور یکپارچه از هزاران کامپوننت موجود در اکوسیستم React استفاده کنید. +

+

+ افزودن یک alias ساده preact/compat به bundler یک لایه سازگاری را فراهم می‌کند که حتی اکثر کامپوننت های پیچیده React را برای استفاده در برنامه شما فعال می‌کند. +

+
+
+ +
+

امتحان کنید و ببینید!

+
+ +
+
+

Todo List

+

+export default class TodoList extends Component {
+    state = { todos: [], text: '' };
+    setText = e => {
+        this.setState({ text: e.target.value });
+    };
+    addTodo = () => {
+        let { todos, text } = this.state;
+        todos = todos.concat({ text });
+        this.setState({ todos, text: '' });
+    };
+    render({ }, { todos, text }) {
+        return (
+            <form onSubmit={this.addTodo} action="javascript:">
+                <label>
+                  <span>Add Todo</span>
+                  <input value={text} onInput={this.setText} />
+                </label>
+                <button type="submit">Add</button>
+                <ul>
+                    { todos.map( todo => (
+                        <li>{todo.text}</li>
+                    )) }
+                </ul>
+            </form>
+        );
+    }
+}
+        
+
+
+

نمونه زنده

+

+import TodoList from './todo-list';
+
+render(<TodoList />, document.body);
+        
+
+ +
+
+
+ +
+
+

Fetch GitHub Stars

+

+export default class Stars extends Component {
+    async componentDidMount() {
+        let stars = await githubStars(this.props.repo);
+        this.setState({ stars });
+    }
+    render({ repo }, { stars=0 }) {
+        let url = `https://github.com/${repo}`;
+        return (
+            <a href={url} class="stars">
+                ⭐️ {stars} Stars
+            </a>
+        );
+    }
+}
+        
+
+
+

نمونه زنده

+

+import Stars from './stars';
+
+render(
+    <Stars repo="preactjs/preact" />,
+    document.body
+);
+        
+
+ +
+
+
+ +
+

آماده اید که شروع کنید؟

+
+ +
+

+ ما برای افرادی که تجربه ای با React دارند یا نه راهنما های متفاوتی داریم. +
+ راهنمایی که مناسب خودت هست رو انتخاب کن! +

+

+ شروع + عوض کردن به Preact +

+
diff --git a/package-lock.json b/package-lock.json index cd1bdbce6..f2d7832ce 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,6 +5,7 @@ "requires": true, "packages": { "": { + "name": "preact-www", "license": "MIT", "dependencies": { "@preact/signals": "^1.0.0", diff --git a/src/components/content-region.js b/src/components/content-region.js index b0f4297cd..6e6e342ca 100644 --- a/src/components/content-region.js +++ b/src/components/content-region.js @@ -47,6 +47,9 @@ function SiblingNav({ route, lang, start }) { export default function ContentRegion({ content, components, ...props }) { const hasNav = !!(props.next || props.prev); components = Object.assign({}, COMPONENTS, components); + + // TODO: Add props.name + '-rtl' class if lang is RTL + return ( {content && ( diff --git a/src/components/header/index.js b/src/components/header/index.js index bbecb6faa..6a2119bc8 100644 --- a/src/components/header/index.js +++ b/src/components/header/index.js @@ -21,12 +21,23 @@ export default function Header() { const [open, setOpen] = useOverlayToggle(false); const toggle = useCallback(() => setOpen(!open), [open]); + // change to RTL based on language + const { lang } = useStore(['lang']).state; + useEffect(() => { if (open) setOpen(false); }, [url]); return ( -
+ // Adding rtl directtion if persian + // TODO: Auto RTL language detection +
We stand with Ukraine. Show your support 🇺🇦 diff --git a/src/components/header/style.module.less b/src/components/header/style.module.less index 47bfe3c04..621050843 100644 --- a/src/components/header/style.module.less +++ b/src/components/header/style.module.less @@ -1,3 +1,6 @@ +// TODO: Mobile nav RTL styling +// TODO: Search box RTL settings + @import '~style/helpers'; .banner { @@ -187,6 +190,7 @@ content: '▼'; position: relative; left: 7px; + right: 7px; top: -1px; font-size: 60%; vertical-align: middle; diff --git a/src/config.json b/src/config.json index 7eae58fb9..14c6a3c79 100644 --- a/src/config.json +++ b/src/config.json @@ -11,7 +11,8 @@ "pt-br": "Brazilian Portuguese", "de": "German", "it": "Italian", - "kr": "Korean" + "kr": "Korean", + "fa": "Persian" }, "repo": "preact", "docsearch": { @@ -29,7 +30,8 @@ "it": "Pagina Successiva", "pt-br": "Próxima Página", "zh": "下一页", - "kr": "다음" + "kr": "다음", + "fa": "صفحه بعدی" }, "previous": { "en": "Previous Page", @@ -41,12 +43,14 @@ "it": "Pagina Precedente", "pt-br": "Página Anterior", "zh": "上一页", - "kr": "이전" + "kr": "이전", + "fa": "صفحه قبلی" }, "continueReading": { "en": "Continue reading", "de": "Weiter lesen", - "zh": "继续阅读" + "zh": "继续阅读", + "fa": "ادامه خواندن" } }, "nav": [ @@ -69,7 +73,8 @@ "first": "index", "name": { "en": "Tutorial", - "zh": "教程" + "zh": "教程", + "fa": "آموزش" }, "controller": "Tutorial" }, @@ -80,7 +85,8 @@ "pt-br": "Guia", "ja": "ガイド", "es": "Guía", - "zh": "指南" + "zh": "指南", + "fa": "راهنما" }, "content": "guide", "path": "/guide/:version?/:page?", @@ -93,7 +99,8 @@ "pt-br": "Sobre", "ja": "Preactについて", "es": "Sobre", - "zh": "关于" + "zh": "关于", + "fa": "درباره ما" }, "content": "about", "routes": [ @@ -105,7 +112,8 @@ "pt-br": "Empresas que usam Preact", "ja": "Preactを使っている企業", "es": "Empresas que usan Preact", - "zh": "使用 Preact 的企业" + "zh": "使用 Preact 的企业", + "fa": "شرکت های استفاده کننده Preact" } }, { @@ -116,7 +124,8 @@ "pt-br": "Bibliotecas e Complementos", "ja": "ライブラリとアドオン", "es": "Librerías y complementos", - "zh": "第三方库和附加组件" + "zh": "第三方库和附加组件", + "fa": "کتابخانه ها و افزونه ها" } }, { @@ -127,7 +136,8 @@ "pt-br": "Demonstrações e exemplos", "ja": "デモと例", "es": "Demostraciones y ejemplos", - "zh": "示例" + "zh": "示例", + "fa": "دمو و نمونه ها" } }, { @@ -138,7 +148,8 @@ "pt-br": "Objetivos do Projeto", "ja": "Preactの目的", "es": "Objetivos del proyecto", - "zh": "项目目标" + "zh": "项目目标", + "fa": "اهداف پر‍وژه" } }, { @@ -149,7 +160,8 @@ "pt-br": "Suporte do navegador", "ja": "ブラウザのサポート", "es": "Soporte de navegadores", - "zh": "浏览器支持" + "zh": "浏览器支持", + "fa": "پشتیبانی مرورگر" } } ] @@ -158,7 +170,8 @@ "path": "/blog", "name": { "en": "Blog", - "zh": "博客" + "zh": "博客", + "fa": "بلاگ" }, "first": "index", "content": "blog", @@ -180,7 +193,8 @@ "en": "Getting Started", "pt-br": "Começando", "de": "Los geht's", - "zh": "开始上手" + "zh": "开始上手", + "fa": "شروع" } }, { @@ -189,7 +203,8 @@ "en": "Differences to React", "pt-br": "Diferenças do React", "de": "Unterschiede zu React", - "zh": "与 React 的区别" + "zh": "与 React 的区别", + "fa": "تفاوت ها با React" } }, { @@ -198,7 +213,8 @@ "en": "Switching to Preact", "pt-br": "Mudando para Preact", "de": "Wechsel zu Preact", - "zh": "从 React 转到 Preact" + "zh": "从 React 转到 Preact", + "fa": "عوض کردن به Preact" } }, { @@ -207,7 +223,8 @@ "en": "Types of Components", "pt-br": "Tipos de Componentes", "de": "Komponenten-Typen", - "zh": "组件类型" + "zh": "组件类型", + "fa": "انواع کام‍پوننت ها" } }, { @@ -216,7 +233,8 @@ "en": "API Reference", "pt-br": "Referência da API", "de": "API Referenz", - "zh": "API 参考" + "zh": "API 参考", + "fa": "مرجع API" } }, { diff --git a/src/style/helpers.less b/src/style/helpers.less index 25b4cad46..064ed23e0 100644 --- a/src/style/helpers.less +++ b/src/style/helpers.less @@ -1,2 +1,3 @@ @import 'variables'; @import 'mixins'; +@import 'rtl'; diff --git a/src/style/index.less b/src/style/index.less index 2e4a1ca00..085df16c2 100755 --- a/src/style/index.less +++ b/src/style/index.less @@ -149,6 +149,24 @@ main .markup { } } + // RTL version + .home-top-rtl { + direction: rtl; + margin: 60px auto; + max-width: 984px; + + h1 { + font-size: 7.3vw; + text-align: center; + font-weight: lighter; + letter-spacing: 0.02em; + + @media (min-width: 1024px) { + font-size: 400%; + } + } + } + .intro-buttons { display: flex; flex-direction: column; @@ -311,3 +329,72 @@ main .markup { } } } + +// RTL home-section +.home-section-rtl { + direction: rtl; + display: flex; + flex-direction: column; + max-width: @home-width !important; // TODO: Fix markup page styles + + @media @break-s { + flex-direction: row; + } + + & + .home-section { + margin: 1.6rem 0; + + @media @break-s { + margin: 3.75rem 0; + } + } + + // The following nodes are created inside the markdown files. + // To make the authoring experience easier we select and style them + // based on the type instead of forcing content creators to add classes. + h2 { + font-size: 220%; + letter-spacing: 0.01em; + font-weight: 300; + text-align: center; + line-height: 1.2; + margin-bottom: 0.5em; + + @media @break-s { + margin-top: 0; + text-align: right; + } + } + + // TODO: Inline SVGs instead of using images to allow more styling options + // via CSS. We could play with subtle gradients for the stroke-color, etc. + img { + display: block; + width: 25%; + align-self: center; + height: auto; // override intrinsic size + max-height: 13rem; // IE11 fix + + @media @break-s { + width: 100%; + flex: 22% 0 0; + margin-left: 4%; + } + } + + code { + direction: ltr; + } + + @media @break-s { + // Variant: Right aligned image + &:nth-of-type(2n + 1) { + flex-direction: row-reverse; + + img { + margin-left: 0; + margin-right: 4%; + } + } + } +} diff --git a/src/style/rtl.less b/src/style/rtl.less new file mode 100644 index 000000000..5479aafa3 --- /dev/null +++ b/src/style/rtl.less @@ -0,0 +1,14 @@ +.dir-rtl { + direction: rtl; +} +.force-rtl-align { + text-align: right !important; +} + +.blog-rtl { + direction: rtl; + + .btn-small { + direction: ltr; + } +}