مزایای استفاده از ویژگی های سفارشی در سیستم های طراحی و کتابخانه های مؤلفه.
من دیو هستم و یک برنامه نویس ارشد Front-end در Nordhealth هستم. من روی طراحی و توسعه سیستم طراحی خود Nord کار می کنم که شامل ساخت اجزای وب برای کتابخانه اجزای ما است. من میخواستم به اشتراک بگذارم که چگونه مشکلات مربوط به استایلسازی اجزای وب را با استفاده از ویژگیهای سفارشی CSS و برخی از مزایای دیگر استفاده از ویژگیهای سفارشی در سیستمهای طراحی و کتابخانههای مؤلفه حل کردیم.
چگونه کامپوننت های وب را می سازیم
برای ساخت اجزای وب خود از Lit استفاده میکنیم، کتابخانهای که کدهای دیگ بخار زیادی مانند حالت، سبکهای محدوده، قالببندی و موارد دیگر را ارائه میکند. Lit نه تنها سبک وزن است، بلکه بر روی API های بومی جاوا اسکریپت نیز ساخته شده است، به این معنی که می توانیم یک بسته نرم افزاری ناب از کد ارائه دهیم که از ویژگی هایی که مرورگر قبلاً دارد بهره می برد.
اما جذابترین چیز در مورد کامپوننتهای وب این است که تقریباً با هر چارچوب جاوا اسکریپت موجود یا حتی بدون هیچ چارچوبی کار میکنند. هنگامی که بسته اصلی جاوا اسکریپت در صفحه ارجاع داده می شود، استفاده از یک کامپوننت وب بسیار شبیه به استفاده از یک عنصر HTML بومی است. تنها نشانه واقعی که نشان میدهد یک عنصر بومی HTML نیست، خط فاصله درون تگها است، که استانداردی برای نشان دادن این موضوع به مرورگر است که این یک مؤلفه وب است.
کپسوله سازی به سبک Shadow DOM
به همان شکلی که عناصر بومی HTML دارای Shadow DOM هستند. Shadow DOM یک درخت پنهان از گره ها در یک عنصر است. بهترین راه برای تجسم این موضوع این است که بازرس وب خود را باز کنید و گزینه "Show Shadow DOM tree" را روشن کنید. هنگامی که این کار را انجام دادید، سعی کنید به یک عنصر ورودی بومی در بازرس نگاه کنید—اکنون این گزینه را خواهید داشت که آن ورودی را باز کنید و همه عناصر درون آن را ببینید. حتی میتوانید این کار را با یکی از مؤلفههای وب ما امتحان کنید - سعی کنید مؤلفه ورودی سفارشی ما را بررسی کنید تا Shadow DOM آن را ببینید.
یکی از مزایا (یا معایب، بسته به دیدگاه شما) Shadow DOM کپسوله کردن سبک است. اگر CSS را در کامپوننت وب خود بنویسید، آن سبک ها نمی توانند به بیرون درز کنند و بر صفحه اصلی یا سایر عناصر تأثیر بگذارند. آنها به طور کامل در داخل جزء موجود هستند. علاوه بر این، CSS نوشته شده برای صفحه اصلی یا یک مؤلفه وب مادر نمی تواند به مؤلفه وب شما نشت کند.
این کپسولهسازی سبکها یک مزیت در کتابخانه مؤلفه ما است. این به ما تضمین بیشتری میدهد که وقتی شخصی از یکی از مؤلفههای ما استفاده میکند، بدون توجه به سبکهای اعمال شده در صفحه اصلی، همانطور که در نظر داشتیم به نظر میرسد. و برای اطمینان بیشتر، all: unset;
به ریشه یا "میزبان" همه اجزای وب ما.
با این حال، اگر شخصی که از کامپوننت وب شما استفاده می کند دلیل موجهی برای تغییر سبک های خاص داشته باشد، چه؟ شاید خطی از متن وجود داشته باشد که به دلیل زمینهاش به کنتراست بیشتری نیاز دارد یا حاشیه باید ضخیمتر باشد؟ اگر هیچ سبکی نمی تواند وارد مؤلفه شما شود، چگونه می توانید قفل آن گزینه های استایل را باز کنید؟
اینجاست که CSS Custom Properties وارد می شود.
ویژگی های سفارشی CSS
ویژگی های سفارشی بسیار مناسب نام گذاری شده اند - آنها ویژگی های CSS هستند که شما می توانید به طور کامل نام خود را بنویسید و هر مقداری را که لازم است اعمال کنید. تنها شرط لازم این است که آنها را با دو خط فاصله قرار دهید. هنگامی که ویژگی سفارشی خود را اعلام کردید، مقدار را می توان در CSS با استفاده از تابع var()
استفاده کرد.
وقتی صحبت از وراثت میشود، تمام ویژگیهای سفارشی به ارث میرسد که از رفتار معمولی خواص و مقادیر CSS معمولی پیروی میکند. هر خاصیت سفارشی که برای یک عنصر والد یا خود عنصر اعمال می شود، می تواند به عنوان یک مقدار در ویژگی های دیگر استفاده شود. ما از ویژگیهای سفارشی برای توکنهای طراحی خود با اعمال آنها بر روی عنصر ریشه از طریق چارچوب CSS خود استفاده زیادی میکنیم، به این معنی که همه عناصر موجود در صفحه میتوانند از این مقادیر نشانه استفاده کنند، خواه یک Web Component، کلاس کمکی CSS یا یک توسعهدهندهای که میخواهد مقداری را از لیست توکنهای ما حذف کند.
این توانایی به ارث بردن ویژگیهای سفارشی، با استفاده از تابع var()
است که چگونه در Shadow DOM اجزای وب خود نفوذ میکنیم و به توسعهدهندگان اجازه میدهیم هنگام استایلسازی اجزای ما، کنترل دقیقتری داشته باشند.
ویژگی های سفارشی در یک مؤلفه وب Nord
هر زمان که ما در حال توسعه یک مؤلفه برای سیستم طراحی خود هستیم، یک رویکرد متفکرانه به CSS آن در پیش می گیریم - ما دوست داریم کد ناب اما بسیار قابل نگهداری را هدف قرار دهیم. توکن های طراحی ما به عنوان ویژگی های سفارشی در چارچوب اصلی CSS ما در عنصر ریشه تعریف می شوند.
سپس این مقادیر نشانه در اجزای ما ارجاع داده می شوند. در برخی موارد، مقدار را مستقیماً روی ویژگی CSS اعمال میکنیم، اما برای برخی دیگر، در واقع یک ویژگی سفارشی متنی جدید تعریف میکنیم و مقدار را به آن اعمال میکنیم.
ما همچنین مقادیری را که مختص مولفه هستند اما در توکنهای ما نیستند، انتزاع میکنیم و آنها را به یک ویژگی سفارشی متنی تبدیل میکنیم. ویژگی های سفارشی که در زمینه کامپوننت هستند، دو مزیت کلیدی را به ما ارائه می دهند. اول، به این معنی است که ما میتوانیم با CSS خود «خشکتر» باشیم، زیرا این مقدار میتواند به چندین ویژگی داخل مؤلفه اعمال شود.
و ثانیاً، باعث میشود تغییرات وضعیت و تغییرات کامپوننت واقعاً تمیز باشد - فقط ویژگی سفارشی است که باید تغییر کند تا همه آن ویژگیها را بهروزرسانی کنید، مثلاً زمانی که یک حالت شناور یا حالت فعال یا، در این مورد، یک تغییر را طراحی میکنید.
اما قویترین مزیت این است که وقتی این ویژگیهای سفارشی متنی را بر روی یک مؤلفه تعریف میکنیم، نوعی CSS API سفارشی برای هر یک از مؤلفههای خود ایجاد میکنیم که میتواند توسط کاربر آن مؤلفه مورد استفاده قرار گیرد.
مثال قبلی یکی از اجزای وب ما را با یک ویژگی سفارشی متنی که از طریق یک انتخابگر تغییر کرده است نشان می دهد. نتیجه کل این رویکرد مؤلفهای است که انعطافپذیری ظاهری کافی را برای کاربر فراهم میکند و در عین حال اکثر سبکهای واقعی را کنترل میکند. به علاوه، به عنوان یک امتیاز، ما به عنوان توسعه دهندگان کامپوننت توانایی رهگیری آن سبک های اعمال شده توسط کاربر را داریم. اگر بخواهیم یکی از آن ویژگیها را تنظیم یا گسترش دهیم، میتوانیم بدون اینکه کاربر نیازی به تغییر کد خود داشته باشد.
ما این رویکرد را بسیار قدرتمند میدانیم، نه تنها برای ما بهعنوان خالق اجزای سیستم طراحیمان، بلکه برای تیم توسعهمان نیز زمانی که از این اجزا در محصولات ما استفاده میکنند.
استفاده بیشتر از ویژگی های سفارشی
در زمان نگارش، ما در واقع این ویژگی های سفارشی متنی را در اسناد خود آشکار نمی کنیم. با این حال، ما برنامهریزی میکنیم تا تیم توسعه گستردهتر ما بتواند این ویژگیها را درک کرده و از آنها استفاده کند. اجزای ما در npm با یک فایل مانیفست بسته بندی می شوند که حاوی هر چیزی است که درباره آنها باید بدانید. سپس فایل مانیفست را بهعنوان داده مصرف میکنیم وقتی که سایت مستندسازی ما مستقر میشود، که با استفاده از Eleventy و ویژگی Global Data آن انجام میشود. ما قصد داریم این ویژگی های سفارشی متنی را در این فایل داده مانیفست لحاظ کنیم.
حوزه دیگری که ما می خواهیم در آن بهبود ببخشیم این است که چگونه این ویژگی های سفارشی متنی مقادیر را به ارث می برند. در حال حاضر، برای مثال، اگر میخواهید رنگ دو مؤلفه تقسیمکننده را تنظیم کنید، باید هر دوی آن مؤلفهها را بهطور خاص با انتخابگرها هدف قرار دهید یا ویژگی سفارشی را مستقیماً روی عنصر با ویژگی style اعمال کنید. این ممکن است خوب به نظر برسد، اما اگر توسعهدهنده بتواند آن سبکها را در یک عنصر حاوی یا حتی در سطح ریشه تعریف کند، مفیدتر خواهد بود.
دلیل اینکه شما باید مقدار Custom Property را مستقیماً روی کامپوننت تنظیم کنید این است که ما آنها را روی همان عنصر از طریق انتخابگر میزبان کامپوننت تعریف می کنیم. توکنهای طراحی جهانی که مستقیماً در کامپوننت استفاده میکنیم، مستقیماً بدون تأثیر این موضوع از بین میروند و حتی میتوانند روی عناصر والد رهگیری شوند. چگونه می توانیم بهترین های هر دو دنیا را بدست آوریم؟
خصوصیات سفارشی خصوصی و عمومی
خصوصیات سفارشی خصوصی چیزی است که توسط Lea Verou گردآوری شده است ، که یک ویژگی سفارشی "خصوصی" متنی بر روی خود مؤلفه است، اما به یک ویژگی سفارشی "عمومی" با یک بازگشت مجدد تنظیم شده است.
تعریف ویژگیهای سفارشی متنی خود به این روش به این معنی است که ما هنوز هم میتوانیم همه کارهایی را که قبلا انجام میدادیم، مانند ارث بردن مقادیر توکن جهانی و استفاده مجدد از مقادیر در سراسر کد مؤلفه خود انجام دهیم. اما مؤلفه همچنین تعاریف جدیدی از آن ویژگی را بر روی خود یا هر عنصر والد به ارث خواهد برد.
اگرچه ممکن است استدلال شود که این روش واقعاً "خصوصی" نیست، اما هنوز فکر می کنیم که این یک راه حل نسبتاً ظریف برای مشکلی است که ما نگران آن بودیم. زمانی که فرصت داشته باشیم، این موضوع را در اجزای خود حل خواهیم کرد تا تیم توسعه ما کنترل بیشتری بر استفاده از قطعات داشته باشد در حالی که همچنان از نردههای محافظی که در اختیار داریم بهره میبرد.
امیدوارم این بینش در مورد نحوه استفاده ما از اجزای وب با ویژگی های سفارشی CSS مفید بوده باشد. نظر خود را با ما در میان بگذارید و اگر تصمیم دارید از هر یک از این روش ها در کار خود استفاده کنید، می توانید من را در توییتر @DavidDarnes پیدا کنید. همچنین میتوانید Nordhealth @NordhealthHQ را در توییتر بیابید، و همچنین بقیه اعضای تیم من، که برای گردآوری این سیستم طراحی و اجرای ویژگیهای ذکر شده در این مقاله سخت کار کردهاند: @Viljamis ، @WickyNilliams و @eric_habich .
تصویر قهرمان توسط دن کریستین پادورت
،مزایای استفاده از ویژگی های سفارشی در سیستم های طراحی و کتابخانه های مؤلفه.
من دیو هستم و یک برنامه نویس ارشد Front-end در Nordhealth هستم. من روی طراحی و توسعه سیستم طراحی خود Nord کار می کنم که شامل ساخت اجزای وب برای کتابخانه اجزای ما است. من میخواستم به اشتراک بگذارم که چگونه مشکلات مربوط به استایلسازی اجزای وب را با استفاده از ویژگیهای سفارشی CSS و برخی از مزایای دیگر استفاده از ویژگیهای سفارشی در سیستمهای طراحی و کتابخانههای مؤلفه حل کردیم.
چگونه کامپوننت های وب را می سازیم
برای ساخت اجزای وب خود از Lit استفاده میکنیم، کتابخانهای که کدهای دیگ بخار زیادی مانند حالت، سبکهای محدوده، قالببندی و موارد دیگر را ارائه میکند. Lit نه تنها سبک وزن است، بلکه بر روی API های بومی جاوا اسکریپت نیز ساخته شده است، به این معنی که می توانیم یک بسته نرم افزاری ناب از کد ارائه دهیم که از ویژگی هایی که مرورگر قبلاً دارد بهره می برد.
اما جذابترین چیز در مورد کامپوننتهای وب این است که تقریباً با هر چارچوب جاوا اسکریپت موجود یا حتی بدون هیچ چارچوبی کار میکنند. هنگامی که بسته اصلی جاوا اسکریپت در صفحه ارجاع داده می شود، استفاده از یک کامپوننت وب بسیار شبیه به استفاده از یک عنصر HTML بومی است. تنها نشانه واقعی که نشان میدهد یک عنصر بومی HTML نیست، خط فاصله درون تگها است، که استانداردی برای نشان دادن این موضوع به مرورگر است که این یک مؤلفه وب است.
کپسوله سازی به سبک Shadow DOM
به همان شکلی که عناصر بومی HTML دارای Shadow DOM هستند. Shadow DOM یک درخت پنهان از گره ها در یک عنصر است. بهترین راه برای تجسم این موضوع این است که بازرس وب خود را باز کنید و گزینه "Show Shadow DOM tree" را روشن کنید. هنگامی که این کار را انجام دادید، سعی کنید به یک عنصر ورودی بومی در بازرس نگاه کنید—اکنون این گزینه را خواهید داشت که آن ورودی را باز کنید و همه عناصر درون آن را ببینید. حتی میتوانید این کار را با یکی از مؤلفههای وب ما امتحان کنید - سعی کنید مؤلفه ورودی سفارشی ما را بررسی کنید تا Shadow DOM آن را ببینید.
یکی از مزایا (یا معایب، بسته به دیدگاه شما) Shadow DOM کپسوله کردن سبک است. اگر CSS را در کامپوننت وب خود بنویسید، آن سبک ها نمی توانند به بیرون درز کنند و بر صفحه اصلی یا سایر عناصر تأثیر بگذارند. آنها به طور کامل در داخل جزء موجود هستند. علاوه بر این، CSS نوشته شده برای صفحه اصلی یا یک مؤلفه وب مادر نمی تواند به مؤلفه وب شما نشت کند.
این کپسولهسازی سبکها یک مزیت در کتابخانه مؤلفه ما است. این به ما تضمین بیشتری میدهد که وقتی شخصی از یکی از مؤلفههای ما استفاده میکند، بدون توجه به سبکهای اعمال شده در صفحه اصلی، همانطور که در نظر داشتیم به نظر میرسد. و برای اطمینان بیشتر، all: unset;
به ریشه یا "میزبان" همه اجزای وب ما.
با این حال، اگر شخصی که از کامپوننت وب شما استفاده می کند دلیل موجهی برای تغییر سبک های خاص داشته باشد، چه؟ شاید خطی از متن وجود داشته باشد که به دلیل زمینهاش به کنتراست بیشتری نیاز دارد یا حاشیه باید ضخیمتر باشد؟ اگر هیچ سبکی نمی تواند وارد مؤلفه شما شود، چگونه می توانید قفل آن گزینه های استایل را باز کنید؟
اینجاست که CSS Custom Properties وارد می شود.
ویژگی های سفارشی CSS
ویژگی های سفارشی بسیار مناسب نام گذاری شده اند - آنها ویژگی های CSS هستند که شما می توانید به طور کامل نام خود را بنویسید و هر مقداری را که لازم است اعمال کنید. تنها شرط لازم این است که آنها را با دو خط فاصله قرار دهید. هنگامی که ویژگی سفارشی خود را اعلام کردید، مقدار را می توان در CSS با استفاده از تابع var()
استفاده کرد.
وقتی صحبت از وراثت میشود، تمام ویژگیهای سفارشی به ارث میرسد که از رفتار معمولی خواص و مقادیر CSS معمولی پیروی میکند. هر خاصیت سفارشی که برای یک عنصر والد یا خود عنصر اعمال می شود، می تواند به عنوان یک مقدار در ویژگی های دیگر استفاده شود. ما از ویژگیهای سفارشی برای توکنهای طراحی خود با اعمال آنها بر روی عنصر ریشه از طریق چارچوب CSS خود استفاده زیادی میکنیم، به این معنی که همه عناصر موجود در صفحه میتوانند از این مقادیر نشانه استفاده کنند، خواه یک Web Component، کلاس کمکی CSS یا یک توسعهدهندهای که میخواهد مقداری را از لیست توکنهای ما حذف کند.
این توانایی به ارث بردن ویژگیهای سفارشی، با استفاده از تابع var()
است که چگونه در Shadow DOM اجزای وب خود نفوذ میکنیم و به توسعهدهندگان اجازه میدهیم هنگام استایلسازی اجزای ما، کنترل دقیقتری داشته باشند.
ویژگی های سفارشی در یک مؤلفه وب Nord
هر زمان که ما در حال توسعه یک مؤلفه برای سیستم طراحی خود هستیم، یک رویکرد متفکرانه به CSS آن در پیش می گیریم - ما دوست داریم کد ناب اما بسیار قابل نگهداری را هدف قرار دهیم. توکن های طراحی ما به عنوان ویژگی های سفارشی در چارچوب اصلی CSS ما در عنصر ریشه تعریف می شوند.
سپس این مقادیر نشانه در اجزای ما ارجاع داده می شوند. در برخی موارد، مقدار را مستقیماً روی ویژگی CSS اعمال میکنیم، اما برای برخی دیگر، در واقع یک ویژگی سفارشی متنی جدید تعریف میکنیم و مقدار را به آن اعمال میکنیم.
ما همچنین مقادیری را که مختص مولفه هستند اما در توکنهای ما نیستند، انتزاع میکنیم و آنها را به یک ویژگی سفارشی متنی تبدیل میکنیم. ویژگی های سفارشی که در زمینه کامپوننت هستند، دو مزیت کلیدی را به ما ارائه می دهند. اول، به این معنی است که ما میتوانیم با CSS خود «خشکتر» باشیم، زیرا این مقدار میتواند به چندین ویژگی داخل مؤلفه اعمال شود.
و ثانیاً، باعث میشود تغییرات وضعیت و تغییرات کامپوننت واقعاً تمیز باشد - فقط ویژگی سفارشی است که باید تغییر کند تا همه آن ویژگیها را بهروزرسانی کنید، مثلاً زمانی که یک حالت شناور یا حالت فعال یا، در این مورد، یک تغییر را طراحی میکنید.
اما قویترین مزیت این است که وقتی این ویژگیهای سفارشی متنی را بر روی یک مؤلفه تعریف میکنیم، نوعی CSS API سفارشی برای هر یک از مؤلفههای خود ایجاد میکنیم که میتواند توسط کاربر آن مؤلفه مورد استفاده قرار گیرد.
مثال قبلی یکی از اجزای وب ما را با یک ویژگی سفارشی متنی که از طریق یک انتخابگر تغییر کرده است نشان می دهد. نتیجه کل این رویکرد مؤلفهای است که انعطافپذیری ظاهری کافی را برای کاربر فراهم میکند و در عین حال اکثر سبکهای واقعی را کنترل میکند. به علاوه، به عنوان یک امتیاز، ما به عنوان توسعه دهندگان کامپوننت توانایی رهگیری آن سبک های اعمال شده توسط کاربر را داریم. اگر بخواهیم یکی از آن ویژگیها را تنظیم یا گسترش دهیم، میتوانیم بدون اینکه کاربر نیازی به تغییر کد خود داشته باشد.
ما این رویکرد را بسیار قدرتمند میدانیم، نه تنها برای ما بهعنوان خالق اجزای سیستم طراحیمان، بلکه برای تیم توسعهمان نیز زمانی که از این اجزا در محصولات ما استفاده میکنند.
استفاده بیشتر از ویژگی های سفارشی
در زمان نگارش، ما در واقع این ویژگی های سفارشی متنی را در اسناد خود آشکار نمی کنیم. با این حال، ما برنامهریزی میکنیم تا تیم توسعه گستردهتر ما بتواند این ویژگیها را درک کرده و از آنها استفاده کند. اجزای ما در npm با یک فایل مانیفست بسته بندی می شوند که حاوی هر چیزی است که درباره آنها باید بدانید. سپس فایل مانیفست را بهعنوان داده مصرف میکنیم وقتی که سایت مستندسازی ما مستقر میشود، که با استفاده از Eleventy و ویژگی Global Data آن انجام میشود. ما قصد داریم این ویژگی های سفارشی متنی را در این فایل داده مانیفست لحاظ کنیم.
حوزه دیگری که ما می خواهیم در آن بهبود ببخشیم این است که چگونه این ویژگی های سفارشی متنی مقادیر را به ارث می برند. در حال حاضر، برای مثال، اگر میخواهید رنگ دو مؤلفه تقسیمکننده را تنظیم کنید، باید هر دوی آن مؤلفهها را بهطور خاص با انتخابگرها هدف قرار دهید یا ویژگی سفارشی را مستقیماً روی عنصر با ویژگی style اعمال کنید. این ممکن است خوب به نظر برسد، اما اگر توسعهدهنده بتواند آن سبکها را در یک عنصر حاوی یا حتی در سطح ریشه تعریف کند، مفیدتر خواهد بود.
دلیل اینکه شما باید مقدار Custom Property را مستقیماً روی کامپوننت تنظیم کنید این است که ما آنها را روی همان عنصر از طریق انتخابگر میزبان کامپوننت تعریف می کنیم. توکنهای طراحی جهانی که مستقیماً در کامپوننت استفاده میکنیم، مستقیماً بدون تأثیر این موضوع از بین میروند و حتی میتوانند روی عناصر والد رهگیری شوند. چگونه می توانیم بهترین های هر دو دنیا را بدست آوریم؟
خصوصیات سفارشی خصوصی و عمومی
خصوصیات سفارشی خصوصی چیزی است که توسط Lea Verou گردآوری شده است ، که یک ویژگی سفارشی "خصوصی" متنی بر روی خود مؤلفه است، اما به یک ویژگی سفارشی "عمومی" با یک بازگشت مجدد تنظیم شده است.
تعریف ویژگیهای سفارشی متنی خود به این روش به این معنی است که ما هنوز هم میتوانیم همه کارهایی را که قبلا انجام میدادیم، مانند ارث بردن مقادیر توکن جهانی و استفاده مجدد از مقادیر در سراسر کد مؤلفه خود انجام دهیم. اما مؤلفه همچنین تعاریف جدیدی از آن ویژگی را بر روی خود یا هر عنصر والد به ارث خواهد برد.
اگرچه ممکن است استدلال شود که این روش واقعاً "خصوصی" نیست، اما هنوز فکر می کنیم که این یک راه حل نسبتاً ظریف برای مشکلی است که ما نگران آن بودیم. زمانی که فرصت داشته باشیم، این موضوع را در اجزای خود حل خواهیم کرد تا تیم توسعه ما کنترل بیشتری بر استفاده از قطعات داشته باشد در حالی که همچنان از نردههای محافظی که در اختیار داریم بهره میبرد.
امیدوارم این بینش در مورد نحوه استفاده ما از اجزای وب با ویژگی های سفارشی CSS مفید بوده باشد. نظر خود را با ما در میان بگذارید و اگر تصمیم دارید از هر یک از این روش ها در کار خود استفاده کنید، می توانید من را در توییتر @DavidDarnes پیدا کنید. همچنین میتوانید Nordhealth @NordhealthHQ را در توییتر بیابید، و همچنین بقیه اعضای تیم من، که برای گردآوری این سیستم طراحی و اجرای ویژگیهای ذکر شده در این مقاله سخت کار کردهاند: @Viljamis ، @WickyNilliams و @eric_habich .
تصویر قهرمان توسط دن کریستین پادورت