Jak vytvořit komponentu časové osy s React

V těchto dnech jsem pracoval na nové stránce pro svůj web. Chtěl jsem mít na časové ose představit některé z mých profesionálních úspěchů v průběhu let.

Udělal jsem to z několika důvodů:

  1. Moje budoucí já se jednoho dne ohlédne a řekne: „Páni… vzpomínám si na den, kdy jsem to udělal! Jak jsem byl šťastný, že jsem toho cíle dosáhl! “Naším úspěchem je cesta, nikoli cíl, a chci si zapsat každý cíl, kterého dosáhnu na cestě.
  2. Mohlo by to přilákat více klientů (uvidíme, jak to jde )
  3. Podle mého názoru je to jiné portfolio. Možná unikátní portfolio?

Přesto… něco teď postavíme!

Na obrázku nahoře můžete vidět, co dnes postavíme pomocí React! Než začneme, rozdělme si kroky, které musíme udělat:

  1. Vytvořte data, která budeme potřebovat
  2. Vytvořte komponentu TimelineItem - každou jednotlivou položku časové osy
  3. Vytvoření kontejneru časové osy - vezme data a předá je do časové osy
  4. Styl všechno

Vytvořte data

Než začneme skutečně vytvářet komponenty React, musíme přesně vědět, jak budou data vypadat, abychom mohli naplánovat strukturu DOM.

Pro tuto aplikaci Časová osa budeme potřebovat řadu objektů. Budeme nazvat toto pole: timelineData.

Uvidíme, jak by to mohlo vypadat:

[
    {
        text: 'Napsal můj první příspěvek na blogu na střední úrovni',
        datum: 03.03.2017,
        kategorie: {
            tag: 'medium',
            barva: '# 018f69'
        },
        odkaz: {
            url:
                'https://medium.com/@popflorin1705/javascript-coding-challenge-1-6d9c712963d2',
            text: 'Číst více'
        }
    },
    {
        // Jiný objekt s daty
    }
];

Vlastnosti jsou docela jednoduché, že? Použil jsem podobné údaje, jaké mám na stránce s časovou osou, takže můžeme říci, že toto je výroba připravená!

Dále sestavíme komponentu TimelineItem. Použijí se data z výše uvedeného objektu:

Komponenta TimelineItem

const TimelineItem = ({data}) => (
    
        
                             {data.category.tag}                                       

{data.text}

            {datové spojení && (                                      {data.link.text}                              )}                      
    
);

Máme následující značky:

  1. .timeline-item div - používá se jako obálka. Tento div bude mít polovinu šířky své rodičovské šířky (50%) a každý další div divize .timeline bude umístěn na pravou stranu pomocí voliče: nth-child (liché)
  2. .timeline-item-content div - další obal (více o tom, proč to potřebujeme v sekci styling)
  3. .tag span - tato značka bude mít vlastní barvu pozadí v závislosti na kategorii
  4. čas / datum a text
  5. odkaz - budeme muset zkontrolovat, zda je k dispozici odkaz, protože nemusí být vždy k dispozici
  6. .circle span - tato značka se použije k umístění kruhu na střední čáru / lištu

Poznámka: Všechno bude mít mnohem větší smysl, když se dostaneme k části CSS / stylingu, ale předtím vytvořme komponentu Časová osa:

Kontejner na časové ose

Tato součást bude v podstatě mapovat pole a pro každý objekt vytvoří komponentu TimelineItem. Přidáme také malou kontrolu, abychom se ujistili, že v poli je alespoň jeden prvek:

import timelineData z '_path_to_file_';
const Časová osa = () =>
    timelineData.length> 0 && (
        
            {timelineData.map ((data, idx) => (                              ))}         
    );

Jak je uvedeno výše, timelineData je pole objektů obsahující všechny požadované informace. V mém případě jsem toto pole uložil do souboru a importoval jsem ho sem, ale můžete si ho vzít z vlastní databáze nebo z koncového bodu API, je to jen na vás.

CSS

Poznámka: většina obalů budou kontejnery flexboxu, protože s jejich umístěním si můžeme snadněji hrát.

Začněme s CSS koncového řádku:

.timeline-container {
    displej: flex;
    flex-direction: sloupec;
    poloha: relativní;
    marže: 40px 0;
}
.timeline-container :: po {
    barva pozadí: # e17b77;
    obsah: '';
    pozice: absolutní;
    vlevo: Calc (50% - 2px);
    šířka: 4px;
    výška: 100%;
}

Pomocí selektoru :: after vytvoříme červenou čáru / lištu uprostřed kontejneru .timeline. Pomocí funkce calc () můžeme řádek přesně umístit do středu odečtením poloviny jeho velikosti (2px) od 50%. Musíme to udělat, protože ve výchozím nastavení je levá vlastnost umístěna podle levého okraje prvku a nikoli uprostřed.

Nyní přejdeme k obálce .timeline-item.

Níže vidíte příklad, jak jsou umístěny v jejich rodiči (kontejner .timeline). Pro demonstrační účely jsem přidal rámeček pro zvýraznění těchto obalů:

Jak vidíte, každý druhý obal jde doprava a vnitřní obal (obsah .timeline-item-content) zabírá méně místa - prostor daný značkou p, která je uvnitř (většinou).

Podívejme se na CSS:

.timeline-item {
    displej: flex;
    justify-content: flex-end;
    padding right: 30px;
    poloha: relativní;
    okraj: 10px 0;
    šířka: 50%;
}
.timeline-item: nth-child (liché) {
    align-self: flex-end;
    justify-content: flex-start;
    padding-left: 30px;
    padding right: 0;
}

Klíčem k tomu je, že používáme: nth-child (lichý) selektor a nastavíme vlastnost align-self na flex-end, což znamená: „Jděte doprava, jak jen můžete“!

Protože tyto obálky mají šířku 50%, můžete vidět, že dva z nich zabírají celou šířku. Od této chvíle, pokaždé, když chceme něco jiného na pravé straně odlišit, musíme použít tento přístup.

Dále obálka obsahu .timeline-item-content:

.timeline-item-content {
    stín stínu: 0 0 5px rgba (0, 0, 0, 0,3);
    poloměr ohraničení: 5px;
    barva pozadí: #fff;
    displej: flex;
    flex-direction: sloupec;
    Zarovnat položky: flex-end;
    výplň: 15px;
    poloha: relativní;
    šířka: 400px;
    maximální šířka: 70%;
    zarovnání textu: vpravo;
}
.timeline-item-content :: po {
    obsah: ' ';
    barva pozadí: #fff;
    stín stínu: 1px -1px 1px rgba (0, 0, 0, 0,2);
    pozice: absolutní;
    vpravo: -7,5px;
    nahoře: Calc (50% - 7,5 px);
    transformace: rotace (45deg);
    šířka: 15px;
    výška: 15px;
}
.timeline-item: nth-child (liché) .timeline-item-content {
    zarovnání textu: vlevo;
    Zarovnat položky: flex-start;
}
.timeline-item: nth-child (liché) .timeline-item-content :: po {
    vpravo: auto;
    vlevo: -7,5px;
    stín stínu: -1px 1px 1px rgba (0, 0, 0, 0,2);
}

Děje se několik věcí:

  1. Tento obal má pevnou šířku a také maximální šířku. Je to proto, že chceme, aby to mělo nějaké hranice, což znamená, že pokud existuje jen několik slov, chceme, aby rámeček byl široký alespoň 400px, ale pokud existuje mnoho textu, nemělo by zabírat celé místo (50% z obálky .timeline-item), ale text by se měl přesunout na další řádek -> proto jsme použili tento druhý wrapper: .timeline-item-content
  2. Vlastnosti zarovnání textu a zarovnání položek se používají k posouvání vnitřních prvků doleva nebo doprava, v závislosti na nadřazeném objektu
  3. Malá šipka, která ukazuje na střední čáru, je dána styly použitými na voliči :: po. V zásadě se jedná o krabici s aplikovaným stínem, která je otočena o 45 °
  4. Jak je uvedeno výše, stylujeme pravou stranu výběrem rodiče pomocí: nth-child (lichý) selektor

Dále všechny vnitřní prvky:

.timeline-item-content .tag {
    barva: #fff;
    velikost písma: 12px;
    font-weight: bold;
    nahoru: 5px;
    vlevo: 5px;
    mezery mezi písmeny: 1px;
    čalounění: 5px;
    pozice: absolutní;
    textová transformace: velká písmena;
}
.timeline-item: nth-child (liché) .timeline-item-content .tag {
    vlevo: auto;
    vpravo: 5px;
}
.timeline-item-time content {
    barva: # 777;
    velikost písma: 12px;
    font-weight: bold;
}
.timeline-item-content p {
    velikost písma: 16px;
    výška řádku: 24 pixelů;
    marže: 15px 0;
    max-width: 250px;
}
.timeline-item-content a {
    velikost písma: 14px;
    font-weight: bold;
}
.timeline-item-content a :: after {
    obsah: '►';
    velikost písma: 12px;
}
.timeline-item-content .circle {
    barva pozadí: #fff;
    ohraničení: 3px solidní # e17b77;
    poloměr hranice: 50%;
    pozice: absolutní;
    nahoře: Calc (50% - 10px);
    vpravo: -40px;
    šířka: 20px;
    výška: 20px;
    z-index: 100;
}
.timeline-item: nth-child (liché) .timeline-item-content .circle {
    vpravo: auto;
    vlevo: -40px;
}

Zde je několik poznámek:

  1. Jak jste možná uhodli, je .tag umístěn absolutně, protože ho chceme ponechat v levém horním rohu (nebo pravém) rohu bez ohledu na velikost pole
  2. Chceme přidat za značku malou stříšku, abychom zdůraznili, že se jedná o odkaz
  3. Vytvoříme .circle a umístíme jej na horní středovou linii / bar přímo před šipku

Už jsme skoro hotovi! Jedinou věcí, kterou zbývá udělat, je přidat CSS, aby vše reagovalo napříč všemi velikostmi obrazovky:

@media pouze obrazovka a (maximální šířka: 1023 pixelů) {
    .timeline-item-content {
        maximální šířka: 100%;
    }
}
@media pouze obrazovka a (maximální šířka: 767 pixelů) {
    .timeline-item-content,
    .timeline-item: nth-child (liché) .timeline-item-content {
        čalounění: 15px 10px;
        zarovnání textu: střed;
        Zarovnat položky: střed;
    }
    .timeline-item-content .tag {
        šířka: Calc (100% - 10px);
        zarovnání textu: střed;
    }
    .timeline-item-time content {
        okraj: 20px;
    }
    .timeline-item-content a {
        dekorace textu: podtržení;
    }
    .timeline-item-content a :: after {
        displej: žádný;
    }
}

Máme dva dotazy na média:

U malých velikostí obrazovky notebooku - max-width: 1023px - chceme povolit, aby obsah .timeline-item-go procházel celou šířkou svého nadřazeného objektu, protože obrazovka je menší a jinak by vypadala vymačkaná

  1. Na telefonech - maximální šířka: 767 pixelů
  • nastavit .tag na plnou šířku (a proto nemusíme zapomenout odečíst 10px z celkových 100% - je to proto, že jsme jej umístili vlevo: 5px, takže odstraníme dvojnásobek této částky)
  • vycentrujte celý text a trochu ho posuňte dolů z hora
  • odeberte na odkazu odkaz a přidejte podtržení - vypadá lépe na mobilu

Aaaand ... hotovo!

Závěr

Jak jsem již zmínil, tato součást je na stránce Časová osa. Podívejte se na to a uvidíte to v akci!

Pokud jste v tomto článku něco, čemu jste nerozuměli, ujistěte se, že jste mě kontaktovali, a my vám rádi zodpovíme vaše dotazy!

Happy Coding!

Původně zveřejněno na www.florin-pop.com.