# UDReadTime Powershell Universal Component Module 📚

By
,
Powershell
,
Modules
Published 2022-09-20

Everyone loves a good read
Everyone loves a good read

So the inspiration behind this component was actually blog sites I have done in the past. Prior to this website, I have a few other personal websites that run off of github using a jekyll template. I noticed on the cards displaying the page it has an estimated read-time on it.

Again maybe if I knew enough JS I could just use the Invoke-UDJavaScript cmdlet and just do it that way. However I am more about Powershell, and doing things using Powershell. So I set off to find a component I could tweak to meet these needs.

This is the underlying component which made all this possible:-

Original React Component
https://www.npmjs.com/package/react-hook-reading-time

You can get yourself a copy of this module on the Powershell Gallery:-

Link To Download UDReadTime Module
https://www.powershellgallery.com/packages/UDReadTime/1.0.1

Here is the GitHub repository to this module which also includes all the project directories and files associated in the building of this component:-

GitHub Link to this UDWizardry Repository
https://github.com/psDevUK/UDReadTime

A simple screen-shot showing the component on a Powershell Universal dashboard:-

How this looks in action
How this looks in action

# Demo Dashboard 👇

On the plus-side. When making this component I did put a good amount of thought into how I could allow you as the end-user to customise this component as much as possible. Although the below demo only shows this component using a couple of parameters I did actually include a lot more so you can tweak this component as much as possible. I did default a lot of those parameters to a specific value, so do not worry if you do not like everything about this component as you can customize it a lot.

New-UDDashboard -Title 'UDReadTime' -Content {
    New-UDRow -Columns {
    New-UDColumn -Content {

  New-UDReadTime -Text "Had denoting properly jointure you occasion directly raillery. In said to of poor full be post face snug. Introduced imprudence see say unpleasing devonshire acceptance son. Exeter longer wisdom gay nor design age. Am weather to entered norland no in showing service. Nor repeated speaking shy appetite. Excited it hastily an pasture it observe. Snug hand how dare here too. Lose eyes get fat shew. Winter can indeed letter oppose way change tended now. So is improve my charmed picture exposed adapted demands. Received had end produced prepared diverted strictly off man branched. Known ye money so large decay voice there to. Preserved be mr cordially incommode as an. He doors quick child an point at. Had share vexed front least style off why him.Announcing of invitation principles in. Cold in late or deal. Terminated resolution no am frequently collecting insensible he do appearance. Projection invitation affronting admiration if no on or. It as instrument boisterous frequently apartments an in. Mr excellence inquietude conviction is in unreserved particular. You fully seems stand nay own point walls. Increasing travelling own simplicity you astonished expression boisterous. Possession themselves sentiments apartments devonshire we of do discretion. Enjoyment discourse ye continued pronounce we necessary abilities. Allow miles wound place the leave had. To sitting subject no improve studied limited. Ye indulgence unreserved connection alteration appearance my an astonished. Up as seen sent make he they of. Her raising and himself pasture believe females. Fancy she stuff after aware merit small his. Charmed esteems luckily age out. Enjoyed minutes related as at on on. Is fanny dried as often me. Goodness as reserved raptures to mistaken steepest oh screened he. Gravity he mr sixteen esteems. Mile home its new way with high told said. Finished no horrible blessing landlord dwelling dissuade if. Rent fond am he in on read. Anxious cordial demands settled entered in do to colonel. Received overcame oh sensible so at an. Formed do change merely to county it. Am separate contempt domestic to to oh. On relation my so addition branched. Put hearing cottage she norland letters equally prepare too. Replied exposed savings he no viewing as up. Soon body add him hill. No father living really people estate if. Mistake do produce beloved demesne if am pursuit. Prepared is me marianne pleasure likewise debating. Wonder an unable except better stairs do ye admire. His and eat secure sex called esteem praise. So moreover as speedily differed branched ignorant. Tall are her knew poor now does then. Procured to contempt oh he raptures amounted occasion. One boy assure income spirit lovers set. Case read they must it of cold that. Speaking trifling an to unpacked moderate debating learning. An particular contrasted he excellence favourable on. Nay preference dispatched difficulty continuing joy one. Songs it be if ought hoped of. Too carriage attended him entrance desirous the saw. Twenty sister hearts garden limits put gay has. We hill lady will both sang room by. Desirous men exercise overcame procured speaking her followed. Her old collecting she considered discovered. So at parties he warrant oh staying. Square new horses and put better end. Sincerity collected happiness do is contented. Sigh ever way now many. Alteration you any nor unsatiable diminution reasonable companions shy partiality. Leaf by left deal mile oh if easy. Added woman first get led joy not early jokes. Cottage out enabled was entered greatly prevent message. No procured unlocked an likewise. Dear but what she been over gay felt body. Six principles advantages and use entreaties decisively. Eat met has dwelling unpacked see whatever followed. Court in of leave again as am. Greater sixteen to forming colonel no on be. So an advice hardly barton. He be turned sudden engage manner spirit."
} -LargeSize 8 -MediumSize 8 -SmallSize 8
}
}

# Reason behind component 💡

So I already explained the reason I wanted to choose a reading time component. Before I stumbled across this particular component, I did have a good butchers at a fair few other react reading time components. However to me, this seemed like the most straight-forward easy-to-use component to get the goal accomplished. Which was to have a reading time component.

# The Project 🏗️

This is the final version of the component JSX file:-

import React from 'react';
import { withComponentFeatures } from 'universal-dashboard';
import { useReadingTime } from "react-hook-reading-time";

const UDReadTime = props => {
  const {
    text,
    minutes,
    words,
    time,
  } = useReadingTime(props.text);

  return (
    <div style={{ border: props.border, padding: props.padding, ['text-align']: props.textAlign, ['border-radius']: props.borderRadius }} key={props.id}>
      <div style={{ display: props.displayRead, ['border-bottom']: props.borderBottom, ['font-size']: props.fontSize, ['font-style']: props.fontStyle, ['font-weight']: props.fontWeight}}>{minutes}&nbsp;{props.timeToRead}&nbsp;</div>
      <div style={{ display: props.displayWords, ['border-bottom']: props.borderBottom, ['font-size']: props.fontSize, ['font-style']: props.fontStyle, ['font-weight']: props.fontWeight}}>{words}&nbsp;{props.words}</div>
      <p></p>
      {props.text}
    </div>);
}

export default withComponentFeatures(UDReadTime)

# Check-out all the props 🛒

In the code above, all the time you see the word props that is referring to the parameter name associated to that. So above you may notice the word props being used a lot, and this is why, as I wanted to allow a lot of customisation to this component.

With great customisation, comes a lot of options. Again you may think, well I really do like the time estimation, but I do not like the word count feature of this component. No problem, as I nested each of these factors into seperate <div> tags which are defaulted to displaying inline (side-by-side) but as I made a validated set for this particular parameter you also have the option of none in the validate set list. This will allow you to completely hid this text, so you will only have the actual read-time showing, and not the word count as well. So I just wanted to point out that this time I put a fair amount of thought into customising this component as much as possible.

To make the actual cmdlet behind this component you need to edit the pre-defined function in the .PSM1 file so this is my finished .PSM1 before running the invoke-build

$IndexJs = Get-ChildItem "$PSScriptRoot\index.*.bundle.js"
$AssetId = [UniversalDashboard.Services.AssetService]::Instance.RegisterAsset($IndexJs.FullName)

function New-UDReadTime {
    <#
    .SYNOPSIS
    Creates a estimated read time and word count value
    
    .DESCRIPTION
    Medium's like reading time estimation for React now for Powershell Universal
    
    .PARAMETER Id
    The ID of this editor

    .PARAMETER Border
    Allows you to set a border around the main div for the component using CSS default solid 2px #235789
    
    .PARAMETER BorderBottom
    Allows you to set the border under the main readtime component heading default solid 2px #235789
    
    .PARAMETER Padding
    Specifies the amount of padding the indder divs have from the main outer div
    
    .PARAMETER TextAlign
    Defaulted to justify, you can choose valid CSS settings such as left,center etc
    
    .PARAMETER BorderRadius
    Defaulted to 12px if using the border this will round the corners
    
    .PARAMETER DisplayReadTimeText
    Allows you to hide this component text if set to none default to inline
    
    .PARAMETER DisplayWordText
    Allows you to hide this component text if set to none default to inline
    
    .PARAMETER FontSize
    Allows you to set the font size for the main read time headings defaulted to 1.5em
    
    .PARAMETER FontStyle
    Defaulted to italic, you can type in any valid CSS value for the font-style CSS
    
    .PARAMETER FontWeight
    Defaulted to bold, you can use any valid CSS value for the font-weight CSS
    
    .PARAMETER ReadTimeText
    The text to be displayed after the minute number. Default to minute read
    
    .PARAMETER WordsText
    The text to be displayed after the word count number. Default to words
    
    .PARAMETER Text
    Text for the component

    .EXAMPLE
    New-UDReadTime -Text "Had denoting properly jointure you occasion directly raillery. In said to of poor full be post face snug. Introduced imprudence see say unpleasing devonshire acceptance son. Exeter longer wisdom gay nor design age. Am weather to entered norland no in showing service."
    #>
    
    param(
        [Parameter()]
        [string]$Id = (New-Guid).ToString(),
        [Parameter()]
        [string]$Border = "solid 2px #235789",
        [Parameter()]
        [string]$BorderBottom = "solid 2px #235789",
        [Parameter()]
        [string]$Padding = "20px",
        [Parameter()]
        [string]$TextAlign = "justify",
        [Parameter()]
        [string]$BorderRadius = "12px",
        [Parameter()]
        [ValidateSet("inline","none")]
        [string]$DisplayReadTimeText = "inline",
        [Parameter()]
        [ValidateSet("inline","none")]
        [string]$DisplayWordText = "inline",
        [Parameter()]
        [string]$FontSize = "2.5em",
        [Parameter()]
        [string]$FontStyle = "italic",
        [Parameter()]
        [string]$FontWeight = "bold",
        [Parameter()]
        [string]$ReadTimeText = "minute read",
        [Parameter()]
        [string]$WordsText = "words",
        [Parameter()]
        [string]$Text
    )

    End {
        @{
            assetId       = $AssetId 
            isPlugin      = $true 
            type          = "udreadtime"
            id            = $Id

            border        = $Border
            borderBottom  = $BorderBottom
            padding       = $Padding
            textAlign     = $TextAlign
            borderRadius  = $BorderRadius
            displayRead   = $DisplayReadTimeText
            displayWords  = $DisplayWordText
            fontSize      = $FontSize
            fontStyle     = $FontStyle
            fontWeight    = $FontWeight
            text          = $text
            timeToRead    = $ReadTimeText
            words         = $WordsText
        }
    }
}

# Yes lots of parameters 🤓

Just to go through these parameters and what they are for, let us just have a quick glance through the official help file I did for this module.

PARAMETERS
    -Id <String>
        The ID of this editor

        Required?                    false
        Position?                    1
        Default value                (New-Guid).ToString()
        Accept pipeline input?       false
        Accept wildcard characters?  false

    -Border <String>
        Allows you to set a border around the main div for the component using CSS    
        default solid 2px #235789

        Required?                    false
        Position?                    2
        Default value                solid 2px #235789
        Accept pipeline input?       false
        Accept wildcard characters?  false

    -BorderBottom <String>
        Allows you to set the border under the main readtime component heading        
        default solid 2px #235789

        Required?                    false
        Position?                    3
        Default value                solid 2px #235789
        Accept pipeline input?       false
        Accept wildcard characters?  false

    -Padding <String>
        Specifies the amount of padding the indder divs have from the main outer div  

        Required?                    false
        Position?                    4
        Default value                20px
        Accept pipeline input?       false
        Accept wildcard characters?  false

    -TextAlign <String>
        Defaulted to justify, you can choose valid CSS settings such as left,center   
        etc

        Required?                    false
        Position?                    5
        Default value                justify
        Accept pipeline input?       false
        Accept wildcard characters?  false

    -BorderRadius <String>
        Defaulted to 12px if using the border this will round the corners

        Required?                    false
        Position?                    6
        Default value                12px
        Accept pipeline input?       false
        Accept wildcard characters?  false

    -DisplayReadTimeText <String>
        Allows you to hide this component text if set to none default to inline       

        Required?                    false
        Position?                    7
        Default value                inline
        Accept pipeline input?       false
        Accept wildcard characters?  false

    -DisplayWordText <String>
        Allows you to hide this component text if set to none default to inline

        Required?                    false
        Position?                    8
        Default value                inline
        Accept pipeline input?       false
        Accept wildcard characters?  false

    -FontSize <String>
        Allows you to set the font size for the main read time headings defaulted to  
        1.5em

        Required?                    false
        Position?                    9
        Default value                2.5em
        Accept pipeline input?       false
        Accept wildcard characters?  false

    -FontStyle <String>
        Defaulted to italic, you can type in any valid CSS value for the font-style   
        CSS

        Required?                    false
        Position?                    10
        Default value                italic
        Accept pipeline input?       false
        Accept wildcard characters?  false

    -FontWeight <String>
        Defaulted to bold, you can use any valid CSS value for the font-weight CSS   

        Required?                    false
        Position?                    11
        Default value                bold
        Accept pipeline input?       false
        Accept wildcard characters?  false

    -ReadTimeText <String>
        The text to be displayed after the minute number. Default to minute read      

        Required?                    false
        Position?                    12
        Default value                minute read
        Accept pipeline input?       false
        Accept wildcard characters?  false

    -WordsText <String>
        The text to be displayed after the word count number. Default to words        

        Required?                    false
        Position?                    13
        Default value                words
        Accept pipeline input?       false
        Accept wildcard characters?  false

    -Text <String>
        Text for the component

        Required?                    false
        Position?                    14
        Default value
        Accept pipeline input?       false
        Accept wildcard characters?  false

As you can now hopefully appreciate, although this is a small component that gives you an estimated reading time and word count, there is also a great deal of customisation you can do with this component to have it display and look exactly how you want. This should hopefully be opening your mind to all the creative things you could do

Link to this module on marketplace
https://marketplace.universaldashboard.io/Dashboard/UDReadTime

# 💥 That is how this Powershell module was done. Till next time, take care