<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Neema Adam</title>
    <description>The latest articles on Forem by Neema Adam (@neicore).</description>
    <link>https://forem.com/neicore</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F613265%2F24a7f683-6c49-4500-aa57-14b0a787a45b.jpeg</url>
      <title>Forem: Neema Adam</title>
      <link>https://forem.com/neicore</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/neicore"/>
    <language>en</language>
    <item>
      <title>Reflective — AI journaling companion built with Notion MCP and Claude</title>
      <dc:creator>Neema Adam</dc:creator>
      <pubDate>Sun, 29 Mar 2026 23:11:43 +0000</pubDate>
      <link>https://forem.com/neicore/reflective-ai-journaling-companion-built-with-notion-mcp-and-claude-4l70</link>
      <guid>https://forem.com/neicore/reflective-ai-journaling-companion-built-with-notion-mcp-and-claude-4l70</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/notion-2026-03-04"&gt;Notion MCP Challenge&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Reflective&lt;/strong&gt; is a Chrome extension + Node.js backend that adds an AI journaling companion to your browser sidebar while you write in Notion.&lt;/p&gt;

&lt;p&gt;Most journaling tools are write-only. You pour thoughts in, they sit there. Reflective makes your Notion journal a two-way conversation — without leaving the page.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How it works:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;You write in Notion
       ↓
Click "Analyze this entry" in the sidebar
       ↓
Claude reads your entry + your journal history from Notion
       ↓
Opens a conversation grounded in what you actually wrote
       ↓
Click "Mark session complete"
       ↓
Mood score, tags, themes, and AI summary written back to Notion
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Key behaviors:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sits in the Chrome side panel alongside Notion — no new tabs&lt;/li&gt;
&lt;li&gt;Context-aware: on a database view it loads your last 50 entries; on a single entry it reads just that page&lt;/li&gt;
&lt;li&gt;Temporal awareness: if you're reading an old entry, Claude knows — it frames responses as looking back, not as if it's today&lt;/li&gt;
&lt;li&gt;One conversation across the whole session — navigating to a new entry appends to the chat with a &lt;code&gt;— now reading: [title] —&lt;/code&gt; divider&lt;/li&gt;
&lt;li&gt;Analysis is always user-initiated. The extension makes zero API calls on navigation.&lt;/li&gt;
&lt;li&gt;Mood sparkline shows your last 14 days, pulled live from a Notion database&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;One-click workspace setup.&lt;/strong&gt; On first launch, it creates a Journal Entries database, Mood Log, Weekly Summaries database, a seeded starter entry, and a dashboard page — all via the Notion API. You paste your integration token, it does the rest in ~10 seconds.&lt;/p&gt;




&lt;h2&gt;
  
  
  Video Demo
&lt;/h2&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/CQgKAd8S9xQ"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;




&lt;h2&gt;
  
  
  Show Us the Code
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Repo:&lt;/strong&gt; &lt;a href="https://github.com/neicore/notion-reflective" rel="noopener noreferrer"&gt;https://github.com/neicore/notion-reflective&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stack:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Chrome Extension (Manifest V3, React + TypeScript, Vite, Tailwind)&lt;/li&gt;
&lt;li&gt;Node.js + Express backend (TypeScript)&lt;/li&gt;
&lt;li&gt;Anthropic Claude (&lt;code&gt;claude-sonnet-4-5&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Notion API (&lt;code&gt;@notionhq/client&lt;/code&gt; v2)&lt;/li&gt;
&lt;li&gt;Server-Sent Events for streaming progress to the extension&lt;/li&gt;
&lt;li&gt;pnpm workspaces&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  How I Used Notion MCP
&lt;/h2&gt;

&lt;p&gt;Notion is where users read and write their data — and it's also the entire data model. Every piece of state lives there, accessed via &lt;code&gt;@notionhq/client&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Reading: building context for Claude
&lt;/h3&gt;

&lt;p&gt;When you click "Analyze this entry", the backend fetches in parallel:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;rawHistory&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;recentMoods&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
  &lt;span class="nf"&gt;fetchJournalEntries&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;journalDbId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;notionToken&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;  &lt;span class="c1"&gt;// last 50 entries&lt;/span&gt;
  &lt;span class="nf"&gt;queryMoodHistory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;moodLogDbId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;notionToken&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;      &lt;span class="c1"&gt;// 14-day sparkline&lt;/span&gt;
&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then reads the current page blocks directly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;pageObj&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;blocks&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
  &lt;span class="nx"&gt;notion&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;retrieve&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;page_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;pageId&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
  &lt;span class="nx"&gt;notion&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;blocks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;list&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;block_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;pageId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;page_size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The block content becomes the raw text fed to Claude alongside journal history. History is split into "before this date" and "after this date" relative to the entry you're viewing — that's what gives Claude correct temporal framing.&lt;/p&gt;

&lt;h3&gt;
  
  
  Writing: analysis flows back into Notion
&lt;/h3&gt;

&lt;p&gt;When you mark a session complete:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;notion&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;page_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;pageId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;properties&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Mood Score&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;       &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;number&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;moodScore&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Mood Tags&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;        &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;multi_select&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;moodTags&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;}))&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Themes&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;           &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;multi_select&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;themes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;}))&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;AI Summary&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;       &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;rich_text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;aiSummary&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;}]&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Word Count&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;       &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;number&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;wordCount&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Session Complete&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;checkbox&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your Notion database gets richer over time. On future analyses, entries with an &lt;code&gt;AI Summary&lt;/code&gt; are used as-is (fast); entries without one get their blocks fetched (slower, shown in the loading progress bar). First load hydrates your journal — subsequent loads are instant.&lt;/p&gt;

&lt;h3&gt;
  
  
  The loading experience
&lt;/h3&gt;

&lt;p&gt;Hydrating 50 entries takes a while the first time. The &lt;code&gt;/api/init&lt;/code&gt; endpoint streams progress via Server-Sent Events:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;data:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"journal_count"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"total"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;47&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;data:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"hydrating"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"index"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"total"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;47&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"March reflections"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;data:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"hydrating"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"index"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"total"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;47&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"A hard week"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;data:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"done"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"entryContent"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"openingMessage"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"..."&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The extension consumes this with &lt;code&gt;fetch&lt;/code&gt; + &lt;code&gt;ReadableStream&lt;/code&gt; (more reliable than &lt;code&gt;EventSource&lt;/code&gt; in extension contexts), updating the UI: &lt;code&gt;Reading your journal — 3/47 — A hard week&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  What Notion unlocks that a plain database wouldn't
&lt;/h3&gt;

&lt;p&gt;Notion's multi-select properties for &lt;code&gt;Mood Tags&lt;/code&gt; and &lt;code&gt;Themes&lt;/code&gt; mean once entries are analyzed, you can filter, sort, and group your entire journal by mood or theme &lt;em&gt;natively in Notion&lt;/em&gt; — no custom query interface needed. The AI populates the properties; Notion's built-in views do the rest.&lt;/p&gt;

&lt;p&gt;The mood sparkline pulls from a separate &lt;code&gt;Mood Log&lt;/code&gt; database that tracks daily mood independently from journal entries. You can log mood on days you don't write, and the chart reflects it. Two related databases — the kind of structure that's natural in Notion and would need real schema design anywhere else.&lt;/p&gt;

&lt;p&gt;That's the part I keep coming back to: the AI populates the properties, Notion's built-in views do the rest. No custom query interface, no separate dashboard to maintain. Your journal just gets smarter over time.&lt;/p&gt;




</description>
      <category>devchallenge</category>
      <category>notionchallenge</category>
      <category>mcp</category>
      <category>ai</category>
    </item>
    <item>
      <title>Sell your products online with one API call; A technical guide to ClickPesa checkout link integration</title>
      <dc:creator>Neema Adam</dc:creator>
      <pubDate>Wed, 14 Jun 2023 17:17:35 +0000</pubDate>
      <link>https://forem.com/clickpesa/sell-your-products-online-with-one-api-call-a-technical-guide-to-clickpesa-checkout-link-integration-4ncm</link>
      <guid>https://forem.com/clickpesa/sell-your-products-online-with-one-api-call-a-technical-guide-to-clickpesa-checkout-link-integration-4ncm</guid>
      <description>&lt;p&gt;One of the newest features that we offer at ClickPesa is a checkout page.&lt;/p&gt;

&lt;p&gt;ClickPesa's checkout page allows users to create a checkout page from their website or application for their customers to pay for products or services.&lt;/p&gt;

&lt;p&gt;Creating a checkout page only takes one API call to ClickPesa and you will receive a checkout URL that can be shared with the customer to collect payments.&lt;/p&gt;

&lt;p&gt;Here is what you need...&lt;/p&gt;

&lt;p&gt;Base URL: &lt;a href="https://sandbox.clickpesa.com/webshop/generate-checkout-url" rel="noopener noreferrer"&gt;https://sandbox.clickpesa.com/webshop/generate-checkout-url&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Payload:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;orderItems&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Name of your product&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;product_type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;DIGITAL_PRODUCT or PRODUCT&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;download_file_key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;URL to file download&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;//OPTIONAL&lt;/span&gt;
      &lt;span class="na"&gt;unit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;unit of this item eg 1pc&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;price&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;price of the product&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;quantity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;quantity of the product, eg 10&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;orderReference&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;your order reference&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;merchantId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;your merchant id&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;callbackURL&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://your_callback_url.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;//OPTIONAL&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is a table to further explain each field that is added to the payload for checkout URL creation&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1686763419975%2F25aff0e7-4205-4638-8ba9-427a713a408d.png%2520align%3D" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1686763419975%2F25aff0e7-4205-4638-8ba9-427a713a408d.png%2520align%3D" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;--request&lt;/span&gt; POST &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--url&lt;/span&gt; https://sandbox.clickpesa.com/webshop/generate-checkout-url &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--header&lt;/span&gt; &lt;span class="s1"&gt;'Content-Type: application/json'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--data&lt;/span&gt; &lt;span class="s1"&gt;'{
    "orderItems": [
        {
            "name": "Very cool ebook",
            "product_type": "DIGITAL_PRODUCT",
            "download_file_key": "uploads/c0f5a69d-28e8-434c-93ae-0e9dab972bb0.zip", //optional
            "unit": "1 pc(s)",
            "price": 25000,
            "quantity": 1
        },
        {
            "name": "Very cool book hardcopy",
            "product_type": "PRODUCT",
            "unit": "1 pc(s)",
            "price": 40000,
            "quantity": 1
        }
    ],
    "orderReference": "SHOP0.273114256151528d",
    "merchantId": "5f9beaa89c8d037a9b4f795d",
    "callbackURL":"http://hertha.biz" //OPTIONAL
}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above request will return the following response, which is a unique URL for the order's checkout page:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;https://demo.checkout.clickpesa.com/checkout?serviceID&lt;span class="o"&gt;=&lt;/span&gt;88&amp;amp;cartItemsCount&lt;span class="o"&gt;=&lt;/span&gt;2&amp;amp;items&lt;span class="o"&gt;=&lt;/span&gt;%5B%7B%22name%22:%22DIGITAL%20product%20THis%20Is%20a%20long%20lng%20test%20Maybe%20it%20is%22,%22product_type%22:%22DIGITAL_PRODUCT%22,%22download_file_key%22:%22uploads/c0f5a69d-28e8-434c-93ae-0e9dab972bb0.zip%22,%22unit%22:%221%20pc&lt;span class="o"&gt;(&lt;/span&gt;s&lt;span class="o"&gt;)&lt;/span&gt;%22,%22price%22:25000,%22quantity%22:1%7D,%7B%22name%22:%22TEST%20Cylinder%22,%22product_type%22:%22PRODUCT%22,%22unit%22:%22100%20pc&lt;span class="o"&gt;(&lt;/span&gt;s&lt;span class="o"&gt;)&lt;/span&gt;%22,%22price%22:50000,%22quantity%22:1%7D%5D&amp;amp;merchantID&lt;span class="o"&gt;=&lt;/span&gt;5f9beaa89c8d037a9b4f795d&amp;amp;subtotal&lt;span class="o"&gt;=&lt;/span&gt;75000&amp;amp;totalPrice&lt;span class="o"&gt;=&lt;/span&gt;75000&amp;amp;discount&lt;span class="o"&gt;=&lt;/span&gt;0&amp;amp;referenceID&lt;span class="o"&gt;=&lt;/span&gt;SHOP0.273114256151528d
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can then share the URL with a customer via SMS/Email/WhatsApp or any other communication channel you have in place.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PRO TIP:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
You can use services like &lt;a href="https://www.shorturl.at" rel="noopener noreferrer"&gt;https://www.shorturl.at&lt;/a&gt; to shorten the URL before sharing it with your customer. It's free.&lt;/p&gt;

&lt;p&gt;When a customer opens the URL, they will get to the checkout page with all the details of the order.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fslnk4qgfd476ic837ktd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fslnk4qgfd476ic837ktd.png" alt="Sreenshot of ClickPesa Checkout Page" width="800" height="393"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once a customer completes the payment, a notification will be shared via the callback URL added early on the request. The payload to the callback URL will have the following data:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;SUCCESS&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;PROCESSING&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;FAILED&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;CANCELED&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;paymentReference&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Payment reference ID in our system&lt;/span&gt;
  &lt;span class="nx"&gt;orderReference&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Order reference ID you provided during checkout page creation&lt;/span&gt;
  &lt;span class="nx"&gt;collectedAmount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Amount collected if the transaction is successful&lt;/span&gt;
  &lt;span class="nx"&gt;collectedCurrency&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Currency, currently TZS | USD&lt;/span&gt;
  &lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// eg. 'Payment received'&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you don't have a callback URL in place, ClickPesa also provides an administration dashboard that you can use to track all your orders and their payment statuses. It's free!&lt;/p&gt;

&lt;p&gt;Contact ClickPesa at &lt;a href="mailto:info@clickpesa.com"&gt;info@clickpesa.com&lt;/a&gt; to get started. Takes a day max.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Transitioning from a designer to a frontend developer</title>
      <dc:creator>Neema Adam</dc:creator>
      <pubDate>Mon, 08 May 2023 09:29:17 +0000</pubDate>
      <link>https://forem.com/clickpesa/transitioning-from-a-designer-to-a-frontend-developer-30jl</link>
      <guid>https://forem.com/clickpesa/transitioning-from-a-designer-to-a-frontend-developer-30jl</guid>
      <description>&lt;p&gt;Transitioning from a designer to a self-taught front-end developer can be a challenging but rewarding experience. Acknowledging the learning curve and being prepared to learn is the first step toward achieving this goal. For successful learning, you can find learning resources that work for you, such as online courses, tutorials, or documentation. Remember to set goals and track your progress to help you stay motivated throughout the process.&lt;/p&gt;

&lt;p&gt;In the following sections, I am excited to go through some tips that helped me successfully transition into this new career path.&lt;/p&gt;

&lt;h2&gt;
  
  
  Embrace the Learning Curve
&lt;/h2&gt;

&lt;p&gt;Designing and developing share some common aspects but also require different skill sets. As a designer, you might be familiar with UI/UX design principles, but front-end development involves coding, debugging, and building UIs from scratch.&lt;/p&gt;

&lt;p&gt;Start by breaking down the required skills into smaller chunks beginning with the basics and working your way up. Since you are probably a beginner, here is &lt;a href="https://roadmap.sh/frontend?r=frontend-beginner" rel="noopener noreferrer"&gt;a simple roadmap&lt;/a&gt; and &lt;a href="https://roadmap.sh/frontend" rel="noopener noreferrer"&gt;an overwhelming roadmap&lt;/a&gt; that you can use if you can't make your own. There is also this &lt;a href="https://youtu.be/ysEN5RaKOlA" rel="noopener noreferrer"&gt;cool youtube video by Coder Coder&lt;/a&gt; that could help make things less overwhelming.&lt;/p&gt;

&lt;p&gt;There are many online resources available to help you learn front-end development. I learned everything I know online. I started with &lt;a href="https://www.freecodecamp.org/" rel="noopener noreferrer"&gt;FreeCodeCamp&lt;/a&gt;, &lt;a href="https://www.sololearn.com/" rel="noopener noreferrer"&gt;Sololearn&lt;/a&gt;, and &lt;a href="https://www.w3schools.com/" rel="noopener noreferrer"&gt;W3Schools&lt;/a&gt; then added YouTube channels such as &lt;a href="https://www.youtube.com/@TraversyMedia" rel="noopener noreferrer"&gt;Traversy Media&lt;/a&gt;, &lt;a href="https://www.youtube.com/@freecodecamp" rel="noopener noreferrer"&gt;FreeCodeCamp&lt;/a&gt;, and &lt;a href="https://www.youtube.com/@developedbyed" rel="noopener noreferrer"&gt;Dev Ed&lt;/a&gt;. Find learning resources that work for you, such as online courses, tutorials, or documentation. &lt;a href="https://roadmap.sh/frontend?r=frontend-beginner" rel="noopener noreferrer"&gt;The roadmap link&lt;/a&gt; I have shared also contains learning resources for each topic. Click on any topic and a drawer will open with links to different learning resources.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build a Strong Foundation
&lt;/h2&gt;

&lt;p&gt;Building a strong foundation in front-end development requires learning the basics of HTML, CSS, and JavaScript. These are the building blocks of any website. Once you understand these languages, you can start building more complex web pages and applications.&lt;/p&gt;

&lt;p&gt;Learning how to use developer tools is also essential. These tools help you identify and fix issues with your code. Developer tools can also help you optimize your website's performance and improve its accessibility.&lt;/p&gt;

&lt;p&gt;Familiarizing yourself with responsive design and accessibility is also important. Responsive design ensures that your website looks good on any device, while accessibility ensures that your website is usable by people with disabilities.&lt;/p&gt;

&lt;h2&gt;
  
  
  Apply Your Design Skills
&lt;/h2&gt;

&lt;p&gt;One of the advantages of transitioning from a designer to a front-end developer is the ability to apply your design skills to create visually appealing websites or web applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  Collaborate and Build Your Network
&lt;/h2&gt;

&lt;p&gt;Collaborating with other developers and designers is an excellent way to build your network and learn from others. Joining developer communities and attending local meetups or events can help you to meet other like-minded individuals and build relationships.&lt;/p&gt;

&lt;p&gt;Seeking feedback on your work is also important to improve and grow as a developer. Feedback can help you identify areas where you need improvement and areas where you excel.&lt;/p&gt;

&lt;h2&gt;
  
  
  Practice
&lt;/h2&gt;

&lt;p&gt;Building projects and solving challenges is a great way to help you understand concepts that you will be learning and discover new things that you may want to pursue such as learning a frontend framework or exploring Canvas and WebGL. You can get project challenges from places like &lt;a href="https://www.frontendmentor.io/challenges" rel="noopener noreferrer"&gt;Frontend Mentor&lt;/a&gt;, &lt;a href="https://codepen.io/challenges" rel="noopener noreferrer"&gt;CodePen Challenges&lt;/a&gt;, or &lt;a href="https://frontloops.io/" rel="noopener noreferrer"&gt;Frontloops&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In conclusion, transitioning from a designer to a self-taught front-end developer can be a daunting task. As a beginner, It's easy to get bogged down trying to make sense of everything, but it's important to remember that building projects is a great way to discover new knowledge gaps and keep learning. Don't be afraid to make mistakes and seek feedback; this is how you'll continue to grow and develop your skills as a front-end developer. With determination and perseverance, you can achieve your goal and embark on an exciting and rewarding career in front-end development.&lt;/p&gt;

&lt;p&gt;Thank you for reading. If you're interested in learning more about software development, fintech, and other related topics, be sure to check out the ClickPesa publication. Our team is constantly writing and publishing articles that cover a range of topics related to software development, product design, and entrepreneurship.&lt;/p&gt;

&lt;p&gt;At &lt;a href="https://clickpesa.com/" rel="noopener noreferrer"&gt;ClickPesa&lt;/a&gt;, we are passionate about building products that help people and businesses succeed in today's digital economy. If you're interested in learning more about our products and services, be sure to visit our &lt;a href="https://clickpesa.com/" rel="noopener noreferrer"&gt;website&lt;/a&gt; and follow us on &lt;a href="https://www.linkedin.com/company/clickpesa/" rel="noopener noreferrer"&gt;social media&lt;/a&gt;.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Testing React apps with Testing library</title>
      <dc:creator>Neema Adam</dc:creator>
      <pubDate>Thu, 13 Apr 2023 00:11:29 +0000</pubDate>
      <link>https://forem.com/clickpesa/testing-react-apps-with-testing-library-37p4</link>
      <guid>https://forem.com/clickpesa/testing-react-apps-with-testing-library-37p4</guid>
      <description>&lt;p&gt;Testing is an essential aspect of software development that ensures the quality and reliability of software products. React, being one of the most popular JavaScript frameworks, requires a robust testing strategy to ensure that the application functions as expected. Throughout this March and April, I had a chance to learn a lot about writing tests in React while building &lt;a href="https://clickpesa.com/" rel="noopener noreferrer"&gt;ClickPesa’s&lt;/a&gt; UI component library. In this article, I will share some of the things that I have learned.&lt;/p&gt;

&lt;h2&gt;
  
  
  Essential things you can test for in React components
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Render&lt;/strong&gt;: Ensure that the component renders without throwing any errors.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Props&lt;/strong&gt;: Test that the component accepts and uses props correctly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;State&lt;/strong&gt;: Test that the component updates its state correctly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Events&lt;/strong&gt;: Test that the component handles events correctly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lifecycle methods&lt;/strong&gt;: Test that the component correctly handles its lifecycle methods such as componentDidMount, componentDidUpdate, and componentWillUnmount.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Snapshot testing&lt;/strong&gt;: Use snapshot testing to ensure that the component's UI doesn't unexpectedly change over time.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Accessibility&lt;/strong&gt;: Test that the component is accessible to users with disabilities.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Integration testing&lt;/strong&gt;: Test that the component works correctly when integrated with other components.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Performance&lt;/strong&gt;: Test that the component doesn't have any performance issues or memory leaks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Error handling&lt;/strong&gt;: Test that the component handles errors and edge cases gracefully.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;API calls&lt;/strong&gt;: Test that the component makes API calls correctly and handles the response appropriately.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security&lt;/strong&gt;: Test that the component doesn't introduce any security vulnerabilities.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Routing&lt;/strong&gt;: Test that the component navigates correctly between routes in the application.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Authentication&lt;/strong&gt;: Test that the component handles authentication and authorization correctly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Edge cases&lt;/strong&gt;: Test that the component handles edge cases, such as empty or null props, correctly.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  What is React's Testing Library?
&lt;/h2&gt;

&lt;p&gt;React's Testing Library is a testing framework designed to test React components in a way that closely mimics how users interact with the application. The Testing Library provides a set of utilities that allow developers to write tests that simulate user interactions with the components and check that the application behaves correctly.&lt;/p&gt;

&lt;p&gt;The Testing Library is built on top of the Jest testing framework, which is a popular testing tool in the React community. Jest provides a test runner and an assertion library, while the Testing Library provides a set of utilities to help developers write tests.&lt;/p&gt;

&lt;p&gt;The key philosophy behind the Testing Library is to test components as if you were a user interacting with the application. This approach makes it easier to write tests that closely resemble the user experience and ensure that the application is working as intended.&lt;/p&gt;

&lt;h3&gt;
  
  
  How to use React's Testing Library?
&lt;/h3&gt;

&lt;p&gt;To use React's Testing Library, you need to install it as a dependency in your project. If you created your project using create-react-app or bit dev, this library comes pre-installed. To install manually, you can do this by running the following command in your terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-D&lt;/span&gt; @testing-library/react @testing-library/jest-dom @testing-library/user-event @types/jest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once you have installed the Testing Library and other dependencies, you can start writing tests. Let's take a look at an example of how to test a simple React component using the Testing Library.&lt;/p&gt;

&lt;p&gt;Suppose we have a simple component called "Counter" that displays a counter value and allows the user to increment and decrement it. Here's what the component looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Counter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleIncrement&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleDecrement&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handleIncrement&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Increment&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handleDecrement&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Decrement&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;Counter&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To test this component using the Testing Library, we can write a test that checks that the counter value starts at 0, increments when the "Increment" button is clicked, and decrements when the "Decrement" button is clicked.&lt;/p&gt;

&lt;p&gt;Here's what the test looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fireEvent&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@testing-library/react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Counter&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./Counter&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;counter increments and decrements correctly&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;getByText&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Counter&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// check that the counter starts at 0&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;counterValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getByText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;0&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;counterValue&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toBeInTheDocument&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="c1"&gt;// click the increment button and check that the counter increments&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;incrementButton&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getByText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Increment&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;fireEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;click&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;incrementButton&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;counterValue&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toHaveTextContent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// click the decrement button and check that the counter decrements&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;decrementButton&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getByText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Decrement&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;fireEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;click&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;decrementButton&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;counterValue&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toHaveTextContent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;0&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this test, we first render the Counter component using the &lt;strong&gt;&lt;code&gt;render&lt;/code&gt;&lt;/strong&gt; function from the Testing Library. We then use the &lt;strong&gt;&lt;code&gt;getByText&lt;/code&gt;&lt;/strong&gt; function to find the "0" text node and check that it is in the document. We then simulate a click on the "Increment" button using the &lt;strong&gt;&lt;code&gt;fireEvent.click&lt;/code&gt;&lt;/strong&gt; function and check that the counter value is updated correctly using the &lt;strong&gt;&lt;code&gt;toHaveTextContent&lt;/code&gt;&lt;/strong&gt; assertion.&lt;/p&gt;

&lt;p&gt;We then simulate a click on the "Decrement" button and check that the counter value is updated correctly using the same assertion.&lt;/p&gt;

&lt;p&gt;This is a simple example, but it illustrates the power and simplicity of the Testing Library. With just a few lines of code, we can test that our component behaves correctly and that the user experience is what we expect.&lt;/p&gt;

&lt;h2&gt;
  
  
  Best practices for testing with React's Testing Library
&lt;/h2&gt;

&lt;p&gt;To get the most out of React's Testing Library, there are some best practices that you should follow:&lt;/p&gt;

&lt;h3&gt;
  
  
  Test behavior, not implementation
&lt;/h3&gt;

&lt;p&gt;When writing tests, focus on testing the behavior of your components, not their implementation details. This means that you should test what your component does, not how it does it. This approach makes your tests more resilient to changes in the implementation and ensures that they remain valid even if you refactor your code.&lt;/p&gt;

&lt;h3&gt;
  
  
  Test user interactions
&lt;/h3&gt;

&lt;p&gt;Since the Testing Library is designed to test components as if you were a user interacting with the application, you should focus on testing user interactions. This means that you should simulate clicks, key presses, and other user actions to ensure that your components behave as expected.&lt;/p&gt;

&lt;h3&gt;
  
  
  Keep your tests small and focused
&lt;/h3&gt;

&lt;p&gt;When writing tests, it's important to keep them small and focused. Each test should test a single piece of functionality or behavior. This approach makes it easier to debug failing tests and ensures that your tests remain maintainable over time.&lt;/p&gt;

&lt;h3&gt;
  
  
  Use descriptive test names
&lt;/h3&gt;

&lt;p&gt;To make your tests more readable and understandable, use descriptive test names. Your test names should describe what the test does and what it's testing. This makes it easier to understand what your tests are doing and what they're testing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;React's Testing Library is a powerful tool that can help you create high-quality and maintainable code. By testing your components as if you were a user interacting with the application, you can ensure that your code behaves correctly and meets your users' expectations. In this article, we've explored how to use React's Testing Library and some best practices for writing tests. By following these best practices, you can write tests that are resilient, maintainable, and easy to understand.&lt;/p&gt;

&lt;p&gt;Thank you for reading this article on testing React applications using React's Testing Library. We hope that you found it informative and helpful in your development process. If you're interested in learning more about software development, fintech, and other related topics, be sure to check out the ClickPesa publication. Our team is constantly writing and publishing articles that cover a range of topics related to software development, product design, and entrepreneurship.&lt;/p&gt;

&lt;p&gt;At &lt;a href="https://clickpesa.com/" rel="noopener noreferrer"&gt;ClickPesa&lt;/a&gt;, we are passionate about building products that help people and businesses succeed in today's digital economy. If you're interested in learning more about our products and services, be sure to visit our &lt;a href="https://clickpesa.com/" rel="noopener noreferrer"&gt;website&lt;/a&gt; and follow us on &lt;a href="https://www.linkedin.com/company/clickpesa/" rel="noopener noreferrer"&gt;social media&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>react</category>
      <category>testing</category>
      <category>jest</category>
    </item>
    <item>
      <title>Setting up SSH Keys for Github, GitLab, and Bitbucket in one windows pc</title>
      <dc:creator>Neema Adam</dc:creator>
      <pubDate>Tue, 07 Mar 2023 08:11:37 +0000</pubDate>
      <link>https://forem.com/clickpesa/setting-up-ssh-keys-for-github-gitlab-and-bitbucket-in-one-windows-pc-3d9j</link>
      <guid>https://forem.com/clickpesa/setting-up-ssh-keys-for-github-gitlab-and-bitbucket-in-one-windows-pc-3d9j</guid>
      <description>&lt;h2&gt;
  
  
  What are Github, Gitlab and Bitbucket?
&lt;/h2&gt;

&lt;p&gt;Github, GitLab, and Bitbucket are all popular web-based Git repository hosting services that allow developers to collaborate on code and manage version control.&lt;/p&gt;

&lt;p&gt;GitHub is the most well-known of the three and is used by millions of developers worldwide. It offers both free and paid plans and is a popular choice for open-source projects.&lt;/p&gt;

&lt;p&gt;GitLab is another web-based Git repository hosting service that offers both free and paid plans. It is known for its built-in continuous integration and deployment features, making it a popular choice for DevOps teams.&lt;/p&gt;

&lt;p&gt;Bitbucket is a Git repository hosting service that is owned by Atlassian, the company behind popular products like Jira and Confluence. It offers both free and paid plans and is known for its tight integration with other Atlassian products.&lt;/p&gt;

&lt;p&gt;All three services offer similar functionality and are widely used by developers for managing code and collaborating on projects.&lt;/p&gt;

&lt;h2&gt;
  
  
  Connection method
&lt;/h2&gt;

&lt;p&gt;There are several methods available to connect to Github, GitLab, or Bitbucket, including HTTPS and SSH. HTTPS is the default method and uses a username and password for authentication. SSH, on the other hand, uses a public and private key pair for authentication.&lt;/p&gt;

&lt;p&gt;Using SSH has several advantages over HTTPS. First, it is more secure because it uses encryption to protect your credentials. Second, it is more convenient because you don’t need to enter your username and password every time you push or pull code. Finally, it allows for more fine-grained control over access to your repositories.&lt;/p&gt;

&lt;p&gt;This guide shows you how to set up SSH keys for Github, GitLab, and Bitbucket on your Windows PC.&lt;/p&gt;

&lt;p&gt;While SSH has several advantages over HTTPS, there are also some potential disadvantages to consider.&lt;/p&gt;

&lt;p&gt;One is that setting up SSH requires more initial configuration than HTTPS. Additionally, if you lose your private key or it is compromised, it can be difficult to recover access to your repositories. Finally, some corporate firewalls may block SSH traffic, which could prevent you from using it to connect to remote repositories.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up SSH Keys for Github, GitLab, and Bitbucket in One Windows PC
&lt;/h2&gt;

&lt;p&gt;SSH keys are a secure way to authenticate with remote Git repositories like Github, GitLab, and Bitbucket. In this guide, we will show you how to set up SSH keys for all three services on your Windows PC.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Check for existing SSH keys
&lt;/h2&gt;

&lt;p&gt;Before generating new SSH keys, we need to check whether any SSH keys already exist on our machine. Open the Git Bash terminal by right-clicking on your desktop and selecting “Git Bash Here”. Then, enter the following command in the terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ls -al ~/.ssh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If any files with names like id_rsa or id_rsa.pub exist in the output, you already have an SSH key pair. If not, we will generate a new key pair in the next step.&lt;/p&gt;

&lt;p&gt;Step 2: Generate a new SSH key pair&lt;br&gt;
In the Git Bash terminal, enter the following command to generate a new SSH key pair:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command will prompt you for a file name and passphrase.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Add the SSH key to Github, GitLab, and Bitbucket
&lt;/h2&gt;

&lt;p&gt;Next, we need to add the SSH key to our Github, GitLab, and Bitbucket accounts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Github
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Log in to your Github account and go to “Settings”.&lt;/li&gt;
&lt;li&gt;Click on “SSH and GPG keys”.&lt;/li&gt;
&lt;li&gt;Click on “New SSH key”.&lt;/li&gt;
&lt;li&gt;Give your key a title and paste the contents of your id_rsa.pub file into the “Key” field.&lt;/li&gt;
&lt;li&gt;Click “Add SSH key”.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  GitLab
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Log in to your GitLab account and go to “Settings”.&lt;/li&gt;
&lt;li&gt;Click on “SSH Keys”.&lt;/li&gt;
&lt;li&gt;Give your key a title and paste the contents of your id_rsa.pub file into the “Key” field.&lt;/li&gt;
&lt;li&gt;Click “Add key”.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Bitbucket
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Log in to your Bitbucket account and go to “Settings”.&lt;/li&gt;
&lt;li&gt;Click on “SSH keys”.&lt;/li&gt;
&lt;li&gt;Click on “Add key”.&lt;/li&gt;
&lt;li&gt;Give your key a label and paste the contents of your id_rsa.pub file into the “Key” field.&lt;/li&gt;
&lt;li&gt;Click “Add key”.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Step 4: Test the SSH connection
&lt;/h2&gt;

&lt;p&gt;To test the SSH connection, enter the following command in the Git Bash terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ssh -T git@github.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace “github.com” with “gitlab.com” or “bitbucket.org” to test the connection to those services.&lt;/p&gt;

&lt;p&gt;If the SSH connection is successful, you should see a message like “Hi username! You’ve successfully authenticated, but GitHub does not provide shell access.”&lt;/p&gt;

&lt;p&gt;Congratulations! You have now set up SSH keys for Github, GitLab, and Bitbucket on your Windows PC.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Creating a design system from scratch</title>
      <dc:creator>Neema Adam</dc:creator>
      <pubDate>Sun, 19 Feb 2023 23:04:57 +0000</pubDate>
      <link>https://forem.com/clickpesa/creating-a-design-system-from-scratch-3neb</link>
      <guid>https://forem.com/clickpesa/creating-a-design-system-from-scratch-3neb</guid>
      <description>&lt;p&gt;This is the third and final part in my series about my notes on the design system, you can find the introduction part &lt;a href="https://medium.com/clickpesa-engineering-blog/my-notes-on-design-systems-58-introduction-424d6dc5fd60" rel="noopener noreferrer"&gt;here&lt;/a&gt; and the second part &lt;a href="https://medium.com/clickpesa-engineering-blog/customizing-a-prebuilt-design-system-in-figma-d172b09f497c" rel="noopener noreferrer"&gt;here&lt;/a&gt;. In the first part, I talked about design systems, and in the second part, I talked about customizing a prebuilt design system. In this article, I’ll go over some things that I and my team at &lt;a href="https://clickpesa.com/" rel="noopener noreferrer"&gt;ClickPesa&lt;/a&gt; did to successfully ship our custom design system.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. The Scope
&lt;/h2&gt;

&lt;p&gt;The first thing to do when creating a design system is to determine the primary usage of your system. You might want your design system to be a general system that designers and teams building different products can use or you might want it to be something specific to only your projects or narrow it down even more to a single project. The wider the target usage of your system, the broader the scope. &lt;/p&gt;

&lt;p&gt;The scope of your system will determine how many colors and text styles you will have to set up and how many components and their variants you will have to create. Let’s say you want to create a design system like &lt;a href="https://www.untitledui.com/" rel="noopener noreferrer"&gt;Untitled UI&lt;/a&gt; that designers and teams can buy and use in their own projects, in this case, you will have to consider the needs of a lot of designers and create a general solution that will be a time server and yet customizable enough to fit into their products. You might end up creating and maintaining hundreds of components with their variants.&lt;/p&gt;

&lt;p&gt;Another case is if you want to create a design system for your products or for a single product. In this case, you will only have to set up colors and text styles that are needed and create only the components that your products use. At &lt;a href="https://clickpesa.com/" rel="noopener noreferrer"&gt;ClickPesa&lt;/a&gt;, we decided to ship a design system that can be used to design all of our products. We decided that our products will share components and only use different primary colors and font families so I only created components that we need for our products with a few variants. This makes it easy to use and maintain the design system.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Creating the system
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Intro
&lt;/h3&gt;

&lt;p&gt;The team and I dedicated two days and went over our products to determine what components do we need to design, then we prepared a list in google sheets with six columns; &lt;strong&gt;name&lt;/strong&gt;, &lt;strong&gt;type&lt;/strong&gt;, &lt;strong&gt;description&lt;/strong&gt;, &lt;strong&gt;states&lt;/strong&gt;, &lt;strong&gt;variants&lt;/strong&gt;, and &lt;strong&gt;URL to component&lt;/strong&gt;. This document serves as documentation, a rule book, and also a design system checklist. We chose to use google sheet so that every member of the team can have access to it and take a look whenever they want to. &lt;/p&gt;

&lt;h3&gt;
  
  
  Design Tokens
&lt;/h3&gt;

&lt;p&gt;I started by preparing the design tokens. I only prepared colors, text styles, drop shadows, and border-radius. So far those are the only things we needed in our products.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2vvqe9aoevq4x8f73sfe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2vvqe9aoevq4x8f73sfe.png" alt="Design tokens - ClickPesa Design System" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Icons
&lt;/h3&gt;

&lt;p&gt;After setting up all the tokens, I prepared the icons. I used &lt;a href="https://www.figma.com/community/file/903830135544202908" rel="noopener noreferrer"&gt;Phosphor icons&lt;/a&gt; and migrated outlined and filled icons to my design system.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmi3ru77cw9fuzzcjxpzz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmi3ru77cw9fuzzcjxpzz.png" alt="My icons setup" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I also added common keywords that I’d use to search certain icons in their description so it’s easy to find them.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffl8py6c6v3dm5plrou8x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffl8py6c6v3dm5plrou8x.png" alt="Description to help with search" width="800" height="508"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Components
&lt;/h3&gt;

&lt;p&gt;For &lt;a href="https://clickpesa.com/" rel="noopener noreferrer"&gt;ClickPesa&lt;/a&gt; we decided on 33 components that are going to be used in all our products including &lt;a href="https://getpaid.africa/" rel="noopener noreferrer"&gt;GetPaid&lt;/a&gt;. We have essential components such as input, textarea, buttons, and other product-specific components such as the balance card component that we use to display account balances.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fff54z4kunpuu94pmwq0q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fff54z4kunpuu94pmwq0q.png" alt="GetPaid/ClickPesa Balance Cards" width="575" height="366"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you are interested to learn about my process of creating complex components in Figma, I wrote an article about it &lt;a href="https://medium.com/clickpesa-engineering-blog/making-complex-ui-components-in-figma-45c36d2bf818" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Documentation
&lt;/h3&gt;

&lt;p&gt;Apart from having a google sheet with a description of what each component is and where to use it, I also prepared documentation in Figma that goes into specifics on how to use the component. &lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;If your product is huge, creating a design system from scratch can seem daunting, but it's an important investment for any company that wants to create consistent, efficient, and memorable products. Just start small and evolve it according to usage needs.&lt;/p&gt;

</description>
      <category>figma</category>
    </item>
    <item>
      <title>Customizing a prebuilt design system in Figma</title>
      <dc:creator>Neema Adam</dc:creator>
      <pubDate>Thu, 22 Dec 2022 16:36:33 +0000</pubDate>
      <link>https://forem.com/clickpesa/customizing-a-prebuilt-design-system-in-figma-dmf</link>
      <guid>https://forem.com/clickpesa/customizing-a-prebuilt-design-system-in-figma-dmf</guid>
      <description>&lt;p&gt;This post is part of a series about everything I have learned about design systems and I’ll write it from a designer’s point of view. This is the second part, you can find the introduction part &lt;a href="https://dev.to/clickpesa/my-notes-on-design-systems-58-introduction-2baj"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Customizing design tokens
&lt;/h2&gt;

&lt;p&gt;After getting a new design system, you might need to customize all the design tokens to match your product’s. Check if your design system takes full advantage of the Figma Tokens plugin, which will allow you to change the style of the entire design system in a few minutes. For this post, I’ll be working with this open-source &lt;a href="https://www.figma.com/community/file/1134424747403247789" rel="noopener noreferrer"&gt;design system file&lt;/a&gt; I found in the Figma community. This one doesn’t support Figma tokens so this post won’t cover it.&lt;/p&gt;

&lt;p&gt;This file ships with design tokens and a few essential components. You can take a look around by navigating the pages found in your left panel.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiafrfhvqkugqx6p0a3ax.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiafrfhvqkugqx6p0a3ax.png" alt=" " width="425" height="584"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Fonts
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fls2nb94jr21s28hli7o5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fls2nb94jr21s28hli7o5.png" alt=" " width="720" height="579"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once duplicated the file, on the right side, you will see all the local styles available. We want to edit the text styles.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5b6q6pffu1oinpvs6aeq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5b6q6pffu1oinpvs6aeq.png" alt=" " width="375" height="405"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hover over one of the styles, eg. H1 and you will see a controls icon button, click it and a window for editing will appear.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flz2hy7rpa0p379cdzdre.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flz2hy7rpa0p379cdzdre.png" alt=" " width="550" height="461"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There you can change the name of the text style, you can add a description to help designers in your team understand what this text style is used for, and can change the font family and other text properties. For this example, I will change the font family from Poppins to Chivo, and I’ll repeat the same steps for all text styles so the font family used across the design system is Chivo.&lt;/p&gt;

&lt;p&gt;When changing the font family you might find that some font-weight styles from the current font are not found in the font you are trying to use, so instead, you can use a font-weight close to that one. In this case, Chivo doesn’t have a medium font weight so I used bold, in fact for H1 through H5 my font-weight is set to bold.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkyysgldu4v41ts6i2fm2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkyysgldu4v41ts6i2fm2.png" alt=" " width="571" height="466"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After changing the font family and weight in all text styles, this how the typography preview look.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmakegx9umu8rnlbjv3it.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmakegx9umu8rnlbjv3it.png" alt=" " width="512" height="504"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Colors
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fziypvulpjhhal5f6hgrh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fziypvulpjhhal5f6hgrh.png" alt=" " width="750" height="511"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Our example design system ships with five types of colors, the default black and white, neutrals, primaries, critical, and success. I want to add more colors and edit the current color values and their names. &lt;/p&gt;

&lt;h4&gt;
  
  
  Adding new colors
&lt;/h4&gt;

&lt;p&gt;On the left panel, there is a category for color styles, I am going to hover over the title ‘Color Styles’ and use the plus button to add more colors. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8v17ma66fmflooplgsne.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8v17ma66fmflooplgsne.png" alt=" " width="302" height="259"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The new colors I am going to add are yellow color for warning and blue color for progress. I like using the colors created by TailwindCSS, so I’ll visit the link attached and copy the yellow and sky colors from values 500 - 300. I want to only have three colors for each group except neutrals, so my scale will be from 100 to 300.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk2guyx4jxxc8hime1sbs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk2guyx4jxxc8hime1sbs.png" alt=" " width="590" height="385"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6kma6r1umggp5gqs7ys4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6kma6r1umggp5gqs7ys4.png" alt=" " width="611" height="404"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9yqe4lg5r9ozg3kcfwli.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9yqe4lg5r9ozg3kcfwli.png" alt=" " width="548" height="358"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Editing existing colors
&lt;/h4&gt;

&lt;p&gt;For editing existing color styles, I want to delete all the criticals, success, and primary colors from values 70 - 5, and then rename them and change their values. After deleting the values I don’t need and renaming them, here is what I have:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhp0sox0zt48h3ff091nn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhp0sox0zt48h3ff091nn.png" alt=" " width="275" height="426"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For my primary colors, I am going to use Tailwind Fuchsia, values 500 - 300. For errors, I’ll use Tailwind Red from 500 - 300. And for Success, I’ll also use Tailwind Green, values 500 - 300’. This is what my color styles look like:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwomgs5rzild3pecyc41w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwomgs5rzild3pecyc41w.png" alt=" " width="236" height="414"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I also renamed the neutrals:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnqr8lrftc1wz7mz7hjm8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnqr8lrftc1wz7mz7hjm8.png" alt=" " width="242" height="411"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I also edited the colors documentation and now it looks like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8mwyt8222ldkliy3c690.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8mwyt8222ldkliy3c690.png" alt=" " width="709" height="438"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Components
&lt;/h3&gt;

&lt;p&gt;The example design system ships with a couple of essential components. You might need to add your own components or edit the existing ones.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F51avn0bkorfa6dve9j83.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F51avn0bkorfa6dve9j83.png" alt=" " width="289" height="399"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Editing existing components
&lt;/h4&gt;

&lt;p&gt;Let’s start by fixing the button component. When I edited the color styles, by deleting some values I broke the styling of the buttons, they are now not using the color styles defined. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb6zo7o97z3f3fc5loizs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb6zo7o97z3f3fc5loizs.png" alt=" " width="800" height="258"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I’ll fix this by selecting the frame containing all buttons and going to the selection colors section in the right panel where I’ll click and change the values to use my color styles.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frh2lkamb65bmnmvode5p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frh2lkamb65bmnmvode5p.png" alt=" " width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After editing here is what I have&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhcp5b7sgwyw9pkx9ih93.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhcp5b7sgwyw9pkx9ih93.png" alt=" " width="800" height="458"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To edit the contents of a component, you can edit the master component at the top of the variants. Example here is the master component of the input component:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8axriry18xqeu9xrz52g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8axriry18xqeu9xrz52g.png" alt=" " width="800" height="360"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can choose to edit this by adding an icon before the hint text or adding an icon after the label text and your changes will be reflected across all variants. And you can even make new variants that use or don’t use your new elements.&lt;/p&gt;

&lt;h4&gt;
  
  
  Adding new components
&lt;/h4&gt;

&lt;p&gt;To add new components, create a new page, give it a name related to your component and start creating.&lt;br&gt;
Publishing Changes&lt;/p&gt;

&lt;p&gt;With the free plan, you can only publish your styles, like text, color, or effects. With a team or professional plan, you can publish your components. Whenever you publish new changes, files that use your design system will get a notification that there are some new changes needed to be reviewed and applied.&lt;/p&gt;

&lt;p&gt;Here is the version I have been working on in this article, you can duplicate the file and explore it.&lt;/p&gt;

</description>
      <category>ai</category>
    </item>
    <item>
      <title>My Notes on Design Systems: Introduction</title>
      <dc:creator>Neema Adam</dc:creator>
      <pubDate>Thu, 24 Nov 2022 13:59:50 +0000</pubDate>
      <link>https://forem.com/clickpesa/my-notes-on-design-systems-58-introduction-2baj</link>
      <guid>https://forem.com/clickpesa/my-notes-on-design-systems-58-introduction-2baj</guid>
      <description>&lt;h1&gt;
  
  
  My Notes on Design Systems: Introduction
&lt;/h1&gt;

&lt;p&gt;This post is part of a series about everything I have learned about design systems and I’ll write it from a designer's point of view.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a design system?
&lt;/h2&gt;

&lt;p&gt;A design system is a collection of design tokens and reusable components defined by specific standards to reduce redundancy and maintain consistency while designing projects that scale.&lt;/p&gt;

&lt;h3&gt;
  
  
  Things most design systems I have encountered contain:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Design tokens; things like color palette, spacing, font families and sizes, shadow effects, and more.&lt;/li&gt;
&lt;li&gt;Reusable UI components such as buttons, inputs, cards, chips, or other components that might be native to a specific use case.&lt;/li&gt;
&lt;li&gt;Documentation; a clear usage guide for all tokens and components included in the design system.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Design systems in Figma
&lt;/h3&gt;

&lt;p&gt;Figma is a design tool we use at &lt;a href="https://clickpesa.com/" rel="noopener noreferrer"&gt;ClickPesa&lt;/a&gt; and &lt;a href="https://getpaid.africa/" rel="noopener noreferrer"&gt;GetPaid&lt;/a&gt; while designing our products. Figma makes it easy to work with design systems because it provides a way to publish the design system file to be available for the entire team where team members can access all the components and design tokens in any design file in the team. You can check out &lt;a href="https://www.figma.com/community/file/831698976089873405" rel="noopener noreferrer"&gt;Ant Design System&lt;/a&gt;, an open-source design system published in the Figma community.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why design system
&lt;/h2&gt;

&lt;p&gt;Here are some why and why not use a design system I have learned so far.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why use a design system
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;To maintain consistency across the designs created for a particular product.&lt;/li&gt;
&lt;li&gt;To reduce redundancy that might occur while designing.&lt;/li&gt;
&lt;li&gt;Design maintainability. Design systems allow for changes to be made once and applied across the design.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Why not use a design system
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;It's a lot of work. It takes time to create and maintain.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Create a design system from scratch or use a premade one
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Creating a design system from scratch
&lt;/h3&gt;

&lt;p&gt;Making a design system from scratch allows you to add only the items that you will need for your use case but as it grows it becomes more difficult to maintain which will increase the workload to you or your design team.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using a premade design system
&lt;/h2&gt;

&lt;p&gt;Using a pre-made design system is convenient because it is created and maintained by a third party whether it is open source or a vendor that sells design system(s).&lt;/p&gt;

&lt;p&gt;A challenge I faced with this approach was that pre-made design systems contain a lot of things that I don’t need in my use cases and don’t have a lot of things that I need in my use cases so I had to get in there and add things that I’ll have to also maintain as I go. I suppose this is a less workload compared to maintaining a custom one.&lt;/p&gt;

&lt;p&gt;In the next article in this series, I’ll go more in-depth about using a premade design system and customizing it to your specific use case so be sure to follow the ClickPesa publication so you don’t miss it.&lt;/p&gt;

</description>
      <category>designsystem</category>
      <category>figma</category>
      <category>designtokens</category>
      <category>components</category>
    </item>
    <item>
      <title>GetPaid: A platform that uses the Stellar network to simplify online transactions for East Africans</title>
      <dc:creator>Neema Adam</dc:creator>
      <pubDate>Wed, 12 Oct 2022 04:44:03 +0000</pubDate>
      <link>https://forem.com/clickpesa/getpaid-a-platform-that-uses-the-stellar-network-to-simplify-online-transactions-for-east-africans-2kn7</link>
      <guid>https://forem.com/clickpesa/getpaid-a-platform-that-uses-the-stellar-network-to-simplify-online-transactions-for-east-africans-2kn7</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;GetPaid is a platform that helps East Africans send and receive money online via the Stellar blockchain. Users can use their usual payment methods such as mobile money or bank to deposit and withdraw funds from their GetPaid accounts and use their GetPaid accounts to send and receive funds internationally.&lt;/p&gt;

&lt;h3&gt;
  
  
  Building blocks of GetPaid
&lt;/h3&gt;

&lt;h3&gt;
  
  
  Deposit
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqy6idl62gdg42sneaw9b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqy6idl62gdg42sneaw9b.png" alt=" " width="800" height="743"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Withdraw
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu0aywiuik6cqzavsat5d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu0aywiuik6cqzavsat5d.png" alt=" " width="800" height="893"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Swap
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7tumncg0g24vdbgv3wia.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7tumncg0g24vdbgv3wia.png" alt=" " width="800" height="84"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Blockchain overview and why the Stellar network?
&lt;/h3&gt;

&lt;h3&gt;
  
  
  What is blockchain?
&lt;/h3&gt;

&lt;p&gt;A blockchain is a network of computer systems that are all connected or linked together, similar to a chain. This network has a digital ledger of transactions duplicated and distributed across its entire network making it difficult or impossible to change, hack, or cheat the system*&lt;em&gt;.&lt;/em&gt;*&lt;/p&gt;

&lt;h3&gt;
  
  
  Why do we use the Stellar network?
&lt;/h3&gt;

&lt;p&gt;Stellar is an open-source, blockchain-based distributed ledger- that facilitates low-cost financial transfers and cross-border transactions between any currency. Our decision to use the stellar the network is based on the following advantages:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Stellar Network allows for a global payment system with faster transaction speeds than banks and with lower fees. Anyone using the network can send and receive any currency regardless of their physical location. This is achievable through Stellar tethering a token to a traditional asset like USD, Yen, or the Euro.&lt;/li&gt;
&lt;li&gt;Transactions on the Stellar network take under five seconds and the average cost of each transaction is a fraction of a Lumen(XLM), which equates to a millionth of a cent. The low transaction cost opens use case potentials such as micropayments.&lt;/li&gt;
&lt;li&gt;The Stellar Network is truly decentralized, run by peers on the network, and not owned by anyone, just supported by its non-profit organization.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Problems GetPaid is trying to solve
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Lack of appropriate online payment methods in the East Africa region.
&lt;/h3&gt;

&lt;p&gt;East Africans primarily use mobile money and banks to perform their day-to-day transactions like sending money, getting paid, paying bills, etc. These payment options are often not available online or when they are available they have high fees which makes it difficult for most people to perform different transactions online.&lt;/p&gt;

&lt;h3&gt;
  
  
  High transaction costs on cross-border payments.
&lt;/h3&gt;

&lt;p&gt;Cross-border payments incur very high fees in the East Africa region. One example is online freelancers receiving wire transfers are charged between $15 - $30 per transaction which is almost as much money as what this freelancer earned in a job.&lt;/p&gt;

&lt;h2&gt;
  
  
  Our solution
&lt;/h2&gt;

&lt;p&gt;To solve the above problems, we are building a platform to help people in the East African region make fast and secure payments online with minimum transaction fees.&lt;/p&gt;

&lt;h2&gt;
  
  
  Target users
&lt;/h2&gt;

&lt;p&gt;Our target users are people who are looking to reap the benefits of modern-day work and business environments. People like freelancers selling their skills online, content creators selling digital products to their audiences, or traders trading the cryptocurrencies, stocks, or forex markets.&lt;/p&gt;

&lt;h3&gt;
  
  
  User personas
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyjj54681rj40qlh9bcn0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyjj54681rj40qlh9bcn0.png" alt=" " width="800" height="405"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkzfhxxfmahe9mwqzo9lz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkzfhxxfmahe9mwqzo9lz.png" alt=" " width="800" height="405"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Product features
&lt;/h2&gt;

&lt;p&gt;Currently, GetPaid offers two assets, XLM and USDC.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7uigw900h8bsui3timqf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7uigw900h8bsui3timqf.png" alt=" " width="800" height="392"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Deposit or receive funds
&lt;/h3&gt;

&lt;p&gt;Users can deposit funds to their GetPaid accounts or funds can be sent to their GetPaid accounts via mobile money, bank deposit, and credit card.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3ywwfjpsherpkkysvmdr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3ywwfjpsherpkkysvmdr.png" alt=" " width="800" height="389"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Withdraw or send funds
&lt;/h3&gt;

&lt;p&gt;Users can withdraw funds from their GetPaid accounts to a mobile money account, bank account, or another cryptocurrency wallet, e.g XLM to XLM transfer or USDC to USDC transfers.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnq00hlyreq1h8hkz4fjk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnq00hlyreq1h8hkz4fjk.png" alt=" " width="800" height="390"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Swap funds
&lt;/h3&gt;

&lt;p&gt;Users can swap funds from USDC to XLM or from XLM to USDC&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsdnjtkttae98uxoneqyq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsdnjtkttae98uxoneqyq.png" alt=" " width="800" height="387"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Welcome to checkout &lt;a href="https://getpaid.africa" rel="noopener noreferrer"&gt;GetPaid&lt;/a&gt;&lt;/p&gt;

</description>
      <category>crypto</category>
    </item>
    <item>
      <title>Creating a simple table component in Figma</title>
      <dc:creator>Neema Adam</dc:creator>
      <pubDate>Mon, 12 Sep 2022 05:19:28 +0000</pubDate>
      <link>https://forem.com/clickpesa/creating-a-simple-table-component-in-figma-4ep5</link>
      <guid>https://forem.com/clickpesa/creating-a-simple-table-component-in-figma-4ep5</guid>
      <description>&lt;h1&gt;
  
  
  Creating a simple table component in Figma
&lt;/h1&gt;

&lt;p&gt;In this post, I will show my approach to creating a simple table component in Figma.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cells
&lt;/h2&gt;

&lt;p&gt;I want the cells to support different data types like text, image, text plus image, icons, tags, etc so I’ll create a placeholder component that has information about the recommended height and width of components that can be passed inside a cell.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fneicore%2Fimage%2Fupload%2Fv1662959255%2Ftable-component-1%2F1_di6n3x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fneicore%2Fimage%2Fupload%2Fv1662959255%2Ftable-component-1%2F1_di6n3x.png" title="image_tooltip" alt="alt_text" width="722" height="404"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To create a cell, I’ll make a frame around an instance of the placeholder component, add auto layout with width and height set to hug, align content to the left, add padding of 20 in all directions and name the frame Cell. By default, the cell has left alignment, and width and height are set to hug, but later when I put the cells into rows or columns and I’ll set some to center alignment, and width and height to fill container.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fneicore%2Fimage%2Fupload%2Fv1662959255%2Ftable-component-1%2F2_zld7tr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fneicore%2Fimage%2Fupload%2Fv1662959255%2Ftable-component-1%2F2_zld7tr.png" title="image_tooltip" alt="alt_text" width="800" height="262"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I want to have three types of cells, one without a border, another with a border on the bottom, and another with a border on the right to provide division of cells from the column-based tables and row-based tables respectively so I’ll duplicate my Cell frame two times, set one to border-bottom and another to border-right and rename them to Cell/Bottom and Cell/Right respectively, and the first one to Cell/None.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fneicore%2Fimage%2Fupload%2Fv1662959255%2Ftable-component-1%2F3_by4yqm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fneicore%2Fimage%2Fupload%2Fv1662959255%2Ftable-component-1%2F3_by4yqm.png" title="image_tooltip" alt="alt_text" width="788" height="170"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally, I’ll create the cell component by selecting all three frames and use the create a component set option on the top-center toolbar and rename the property to Border.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fneicore%2Fimage%2Fupload%2Fv1662959260%2Ftable-component-1%2F4_bxz0hq.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fneicore%2Fimage%2Fupload%2Fv1662959260%2Ftable-component-1%2F4_bxz0hq.gif" title="image_tooltip" alt="alt_text" width="476" height="332"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Rows
&lt;/h2&gt;

&lt;p&gt;For the rows, I am going to take five cells, I’ll create a frame around them and name it Row and create a component from it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fneicore%2Fimage%2Fupload%2Fv1662959255%2Ftable-component-1%2F5_abvixc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fneicore%2Fimage%2Fupload%2Fv1662959255%2Ftable-component-1%2F5_abvixc.png" title="image_tooltip" alt="alt_text" width="800" height="92"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I can now use the row instance and replace the placeholder component with my custom components, setting the background color or border. For the action cells, I have set the width to be fixed because the title and the view didn’t have the same width with using hug setting.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fneicore%2Fimage%2Fupload%2Fv1662959256%2Ftable-component-1%2F6_yno9ga.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fneicore%2Fimage%2Fupload%2Fv1662959256%2Ftable-component-1%2F6_yno9ga.png" title="image_tooltip" alt="alt_text" width="644" height="251"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Columns
&lt;/h2&gt;

&lt;p&gt;For the columns, I’ll take four instances of the cell component, arrange them vertically, frame them, rename the frame to Column, and then create a component.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fneicore%2Fimage%2Fupload%2Fv1662959256%2Ftable-component-1%2F7_ndvwwe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fneicore%2Fimage%2Fupload%2Fv1662959256%2Ftable-component-1%2F7_ndvwwe.png" title="image_tooltip" alt="alt_text" width="244" height="312"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now I can use the column component to create a column-based table.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fneicore%2Fimage%2Fupload%2Fv1662959258%2Ftable-component-1%2F8_kjwdri.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fneicore%2Fimage%2Fupload%2Fv1662959258%2Ftable-component-1%2F8_kjwdri.png" title="image_tooltip" alt="alt_text" width="655" height="256"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Limitations
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;I can only use the number of cells available when the row or column component was created.&lt;/li&gt;
&lt;li&gt;The height of cells in a column-based table cannot adjust automatically when one cell in a row changes its height.&lt;/li&gt;
&lt;li&gt;The width of cells in a row-based table cannot adjust automatically when one cell in a column changes its width.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>figma</category>
      <category>ui</category>
    </item>
    <item>
      <title>Tools and assets I use in my UI design workflow</title>
      <dc:creator>Neema Adam</dc:creator>
      <pubDate>Fri, 05 Aug 2022 13:36:00 +0000</pubDate>
      <link>https://forem.com/clickpesa/tools-and-assets-i-use-in-my-ui-design-workflow-2nbm</link>
      <guid>https://forem.com/clickpesa/tools-and-assets-i-use-in-my-ui-design-workflow-2nbm</guid>
      <description>&lt;h1&gt;
  
  
  Tools and assets I use in my UI design workflow
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Research &amp;amp; Learning
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fclickpesa%2Fimage%2Fupload%2Fv1659705265%2Fengineering-blog%2Fimages%2Fx44c2gugcmwojavteadq.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fclickpesa%2Fimage%2Fupload%2Fv1659705265%2Fengineering-blog%2Fimages%2Fx44c2gugcmwojavteadq.jpg" alt="alt_text" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Google
&lt;/h3&gt;

&lt;p&gt;Internet research is a crucial part of my workflow and in most cases I don't know exactly what I am searching for but by using a powerful search engine like Google, I am able to input different keywords until I find what I need.&lt;/p&gt;

&lt;h3&gt;
  
  
  Youtube
&lt;/h3&gt;

&lt;p&gt;Youtube has played a major role in my journey to become the designer I am today. Here's a list of YouTube channels where I've been watching design videos.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://youtube.com/c/Mizko" rel="noopener noreferrer"&gt;Mizko&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtube.com/c/DesignCourse" rel="noopener noreferrer"&gt;Designcourse&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtube.com/c/MalewiczHype" rel="noopener noreferrer"&gt;Malewicz&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtube.com/c/DesignCodeTeam" rel="noopener noreferrer"&gt;DesignCode&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtube.com/c/AJSmart" rel="noopener noreferrer"&gt;AJ &amp;amp; Smart&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://youtube.com/c/SatoriGraphics" rel="noopener noreferrer"&gt;Satori Graphics&lt;/a&gt; (is about graphics designing but worth checking out)&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://www.figma.com/community" rel="noopener noreferrer"&gt;Figma community&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Figma community members share their works, design lecture slides, and templates. I have cloned a lot of these works and learned how other designers implement certain things and I have gained a lot of knowledge from presentation slides shared in the community.&lt;/p&gt;

&lt;h2&gt;
  
  
  Inspiration
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fclickpesa%2Fimage%2Fupload%2Fv1659705221%2Fengineering-blog%2Fimages%2Fj2ktjnbbqgffvbyrxkum.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fclickpesa%2Fimage%2Fupload%2Fv1659705221%2Fengineering-blog%2Fimages%2Fj2ktjnbbqgffvbyrxkum.jpg" alt="alt_text" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://ui-patterns.com/patterns" rel="noopener noreferrer"&gt;UI-Patterns&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;My life changed when I found this website. It really helps me get ideas when hitting creative blocks. They have a list of design patterns that solves common design problems.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://dribbble.com/" rel="noopener noreferrer"&gt;Dribbble&lt;/a&gt;, &lt;a href="https://www.pinterest.com/" rel="noopener noreferrer"&gt;Pinterest&lt;/a&gt;, &amp;amp; &lt;a href="https://www.figma.com/community" rel="noopener noreferrer"&gt;Figma community&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Whenever I hit a creative block the first place I go is dribbble, enter my search term, filter by mobile app or web design and then start exploring. The works of other designers in all these platforms show me how they have solved certain design problems which then gives me ideas on how I could also solve mine.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://www.behance.net/" rel="noopener noreferrer"&gt;Behance&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;The difference between Behance and dribbble is that in behance I can also find detailed case studies which are normally very insightful.&lt;/p&gt;

&lt;h2&gt;
  
  
  Designing
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fclickpesa%2Fimage%2Fupload%2Fv1659705293%2Fengineering-blog%2Fimages%2Fk4zsya3osiwwbyldh0go.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fclickpesa%2Fimage%2Fupload%2Fv1659705293%2Fengineering-blog%2Fimages%2Fk4zsya3osiwwbyldh0go.jpg" alt="alt_text" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Figma
&lt;/h3&gt;

&lt;p&gt;Words are not enough to describe how much I love working with Figma. It’s all the amazing features available and learning resources that have helped me understand the platform and use it to the fullest.&lt;/p&gt;

&lt;h3&gt;
  
  
  Design systems
&lt;/h3&gt;

&lt;p&gt;Design systems have helped me speed up my workflow. At ClickPesa we use Ant Design system from Matt Wierzbicki, and on my side project I use Tailwind css style guide by Bonnie Hong&lt;/p&gt;

&lt;h3&gt;
  
  
  Icon Library
&lt;/h3&gt;

&lt;p&gt;I use Bytedance icons, Heroicons, and Bootstrap. They all have different content, look, and feel so I used them in different projects depending on what I want.&lt;/p&gt;

&lt;h3&gt;
  
  
  Figma Shortcuts
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fclickpesa%2Fimage%2Fupload%2Fv1659705787%2Fengineering-blog%2Fimages%2Fs6sh5ddyjnclr591hkfr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fclickpesa%2Fimage%2Fupload%2Fv1659705787%2Fengineering-blog%2Fimages%2Fs6sh5ddyjnclr591hkfr.png" alt="alt_text" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The ones in blue are the shortcuts that I use often. You can see this menu in figma by pressing Ctrl + Shift + ? on windows.&lt;/p&gt;

&lt;h3&gt;
  
  
  Plugins
&lt;/h3&gt;

&lt;p&gt;Here are some of my Figma plugins that i can’t live without:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A selector&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Very useful for when I want to select something that is occurring on multiple places and has the same name.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Blobs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Very useful for when I want to create some organic blobs to enhance my design&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Design system organizer&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I use this to bulk edit my design systems&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Downsize&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I use this to resize images in my designs so the design file doesn’t take too long to load.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Figma Data Faker&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I used this one for generating multiple fake data for my design because I can’t be putting lorem ipsum everywhere&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Figmoji&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I use this one to add emojis to my designs&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Image Palette&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This one helps me generate color palettes from images quickly&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Lorem ipsum&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For generating dummy text for long paragraphs&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ProtoPie&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Helps exporting Figma frames to ProtoPie for prototyping&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Remove BG&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This magical tool removes background from images so smoothly&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Typescales&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I use this for generating typescales&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Unsplash&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This one is my favorite. I get to insert images into my designs without going to google.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prototyping
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fclickpesa%2Fimage%2Fupload%2Fv1659705818%2Fengineering-blog%2Fimages%2Fbfbselwbnmfhb0bvok0p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fclickpesa%2Fimage%2Fupload%2Fv1659705818%2Fengineering-blog%2Fimages%2Fbfbselwbnmfhb0bvok0p.png" alt="alt_text" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Figma prototyping
&lt;/h3&gt;

&lt;p&gt;I use Figma for clickthrough prototyping and interactive components helps enhance the prototypes. But I hope one day Figma adds conditional logics so we can minimize those wires.&lt;/p&gt;

&lt;h3&gt;
  
  
  ProtoPie
&lt;/h3&gt;

&lt;p&gt;ProtoPie recently released a free forever plan which I have been using to learn how to use the platform. So far I like the experience while using the platform and the availability of learning resources in their Youtube channel.&lt;/p&gt;

&lt;p&gt;If you like this article there are more like this in our blogs, follow us on &lt;a href="https://dev.to/clickpesa"&gt;dev.to/clickpesa&lt;/a&gt;, &lt;a href="http://medium.com/@clickpesa" rel="noopener noreferrer"&gt;medium.com/@clickpesa&lt;/a&gt; and &lt;a href="https://clickpesa.hashnode.dev/" rel="noopener noreferrer"&gt;clickpesa.hashnode.dev/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>figma</category>
      <category>ui</category>
    </item>
    <item>
      <title>Making Complex UI Components in Figma</title>
      <dc:creator>Neema Adam</dc:creator>
      <pubDate>Mon, 18 Jul 2022 01:58:59 +0000</pubDate>
      <link>https://forem.com/clickpesa/making-complex-ui-components-in-figma-44m9</link>
      <guid>https://forem.com/clickpesa/making-complex-ui-components-in-figma-44m9</guid>
      <description>&lt;h1&gt;
  
  
  Making Complex UI Components in Figma
&lt;/h1&gt;

&lt;p&gt;Components are pieces of UI elements that can be reused across the design. Apart from maintaining consistency in the design, a complex figma component offers the ability to create states using interactive components feature.&lt;/p&gt;

&lt;p&gt;Figma offers a variety of features that I have been utilizing to create complex yet flexible components. In this blog post, I'll go through a sidebar component that I made for &lt;a href="https://clickpesa.com/" rel="noopener noreferrer"&gt;ClickPesa&lt;/a&gt;'s admin dashboard to show my approach to making complex components in Figma.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F35iaxsqcmufvp7e3ehi0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F35iaxsqcmufvp7e3ehi0.png" alt="alt_text" width="275" height="1024"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Structure and components
&lt;/h2&gt;

&lt;p&gt;I like to use the &lt;a href="https://bradfrost.com/blog/post/atomic-web-design/" rel="noopener noreferrer"&gt;atomic design&lt;/a&gt; approach while making components in Figma. For example the sidebar I mentioned I'd treat it like an organism, the sidebar-item-groups as molecules, and the sidebar-items and sidebar-title as atoms.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvtk1uf8w8scodocti70n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvtk1uf8w8scodocti70n.png" alt="alt_text" width="661" height="1024"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The sidebar-item component
&lt;/h3&gt;

&lt;p&gt;This component consists of two icon components and one text layer. I combined the left icon and the text layer into one frame with an auto layout set to center-left alignment and width of hug content. This will provide the flexibility I need if I ever remove the icon the text will just snap to the left and the hug content width will ensure that the text will always have as much room to the right as the frame container will allow. I’ll also name the frame left-content.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnndeyyfmw1rgajqne77f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnndeyyfmw1rgajqne77f.png" alt="alt_text" width="657" height="282"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I then framed together the left-content frame with the other icon and add auto layout set to space-between or auto center, a width of 250px, and horizontal padding of 15 and vertical padding of 10. Now, I want this component to have three properties; state property which has three values: default, hover, and active, right icon property whose values are just yes or no, and inner sidebar property whose values are either true or false. Using slash-separated naming convention Figma will automatically group instances together, create properties and assign them values.&lt;/p&gt;

&lt;p&gt;So I named the frame sidebar-item / default / yes / false so later Figma can create three properties and pass those names as values to each property starting at “default”. I then duplicated the frame and added a light grey fill and named it sidebar-item / hover / yes / false. I made another duplicate and this time I increased the grey value a little bit and named it sidebar-item / active / yes / false. The end result looks something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F84p7glgt7c7ooroejofm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F84p7glgt7c7ooroejofm.png" alt="alt_text" width="639" height="375"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I duplicated all three frames, removed the left icon and set auto layout to left-center. I then renamed the frames’ “/ yes” to “/ no”. The end result looks like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fli5dkqe96d48xvna38i1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fli5dkqe96d48xvna38i1.png" alt="alt_text" width="477" height="318"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I then duplicated the above frames, detached the padding to independent paddings, assign padding left to 40, and then renamed the frames’ “/ false” to “/ true”. The end result looks like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftc32u12yqbda1zfo4oo2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftc32u12yqbda1zfo4oo2.png" alt="alt_text" width="536" height="352"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I finally selected all the nine variations, click the component dropdown icon at the top center menu in Figma and I selected “Create component set”, which create a component with three properties. On the left panel, the properties have been assigned default names of property 1, 2, and 3 so I’ll rename them to State, Inner, and Right Icon respectively. See the image&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fajnasczf8pi8lll26rsm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fajnasczf8pi8lll26rsm.png" alt="alt_text" width="775" height="531"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The last thing is to make this component interactive. So, I switched to prototype mode and added a hover interaction to all default variant to change to hover variants on-hover. See the image&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fasnu6hxict7c2wmjym73.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fasnu6hxict7c2wmjym73.png" alt="alt_text" width="362" height="608"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The sidebar-body component
&lt;/h3&gt;

&lt;p&gt;In figma, once you create a component with certain number of children or nested components, you wont be able to add more children in an instance and that’s where most of us decide to detach an instance and live life freely until the product manager request changes and now you have to edit 20+ elements individually. To avoid that, I created a body component that houses sidebar-item components ranging between 1 and 10.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fov6gpyle6aamkedhoxpe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fov6gpyle6aamkedhoxpe.png" alt="alt_text" width="309" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I got an instance of sidebar-item from my assets, duplicated it 10 times, selected all 10 instance, framed them with auto layout set to center-center and width and height set to hug content, and then named the frame sidebar-body / 10. I then duplicated it nine more times and decremented the amount of sidebar-items and the number in the name by one on each duplicate. The results looks like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6pn86uk2x8subpisea0x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6pn86uk2x8subpisea0x.png" alt="alt_text" width="772" height="152"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I finally selected all ten variations, click the component dropdown icon at the top center menu in Figma and I selected “Create component set”, and renamed the property to “Number of items”.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxs1lpte9cvjxlj8ltehd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxs1lpte9cvjxlj8ltehd.png" alt="alt_text" width="429" height="346"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With this component, I’ll always be able to increase number of sidebar-items anywhere without having to detach my instances.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj8umb5yqcs0xayulubeh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj8umb5yqcs0xayulubeh.png" alt="alt_text" width="800" height="354"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The sidebar-item-group component
&lt;/h3&gt;

&lt;p&gt;Some of the sidebar items will have inner items, so I need this component to be able to open and close them. This component consists of a sidebar-item and sidebar-item-body components. The sidebar-body component has 2 items for now. The steps I used to create this component is as follow; selected all needed instances &amp;gt; framed them &amp;gt; added auto layout set to center-center &amp;gt; set width and height to hug &amp;gt; rename the frame to sidebar-item-group &amp;gt; Ctrl + Alt + K (create component shortcut in windows).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqmw0yxu7mcm5ps9m7rno.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqmw0yxu7mcm5ps9m7rno.png" alt="alt_text" width="420" height="230"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The sidebar-title component
&lt;/h3&gt;

&lt;p&gt;This component consists of three elements, the logo component, text layer, and icon component. And the reason I use components its so later its easy to swap the logo or the icon with something else. The logo component and text layer are framed together with an auto layout set to left-center, width set to hug, fill of white, and frame renamed to left-content. The left-content frame is then framed together with the right icon with auto layout of center-center and width set to hug.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhseqso0a1oiomlxw8sub.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhseqso0a1oiomlxw8sub.png" alt="alt_text" width="610" height="175"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I suppose I could have used the sidebar-item component but I have other plans in the future with this component that are outside the scope of this sprint so for now, this will do.&lt;/p&gt;

&lt;h3&gt;
  
  
  The sidebar component
&lt;/h3&gt;

&lt;p&gt;This has two components, the sidebar-title and the sidebar-body component. For now the sidebar-body has four items. I then framed the two together, and this time without auto layout just fixed width of 275 and height of 1024. I placed a 20px gap between the sidebar-title and sidebar-body instances. I also added a fill of yellow.&lt;/p&gt;

&lt;h3&gt;
  
  
  Adding state to sidebar-item-group
&lt;/h3&gt;

&lt;p&gt;I want the sidebar items to have open and close states and be activated when someone clicks in the prototype and also have the inner items link to specific pages. I can’t achieve the later because you can’t pass prototype links for every instance of a component. So what I decided to do is creating a component for each sidebar item that need inner items that way I can achieve both of my requirements.&lt;/p&gt;

&lt;p&gt;So this consists of two instances of the sidebar-item-group component. On one instance has no inner items and icon on the right is chevron-down. The other instance has inner items and right icon is chevron-up.&lt;/p&gt;

&lt;p&gt;Naming will depend with the name on the item. Example, for item user, I’ll name the component user / no and user / yes; yes and no being values of property open.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fntskr1pxf661ond5h41e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fntskr1pxf661ond5h41e.png" alt="alt_text" width="461" height="356"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I’ll then select both instances and create a component (Ctrl + Alt + K ). Using prototype mode, I’ll add a click interaction to both instances that will point to each other.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdrjf69cu6gminrm7hk0b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdrjf69cu6gminrm7hk0b.png" alt="alt_text" width="498" height="414"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Creating components in Figma has been a trial and error process. I made a couple of mistakes before that cost me a lot of time to fix. Important lessons I have learned is to properly structure my components and being willing to do the tedious work because its going to save a lot of time in the future.&lt;/p&gt;

</description>
      <category>figma</category>
      <category>components</category>
      <category>figmacomponents</category>
    </item>
  </channel>
</rss>
