Skip to content

  • Projects
  • Groups
  • Snippets
  • Help
    • Loading...
    • Help
    • Submit feedback
    • Contribute to GitLab
  • Sign in
H
Hello Gargan
  • Project
    • Project
    • Details
    • Activity
    • Releases
    • Cycle Analytics
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
    • Charts
  • Issues 0
    • Issues 0
    • List
    • Board
    • Labels
    • Milestones
  • Merge Requests 0
    • Merge Requests 0
  • CI / CD
    • CI / CD
    • Pipelines
    • Jobs
    • Schedules
    • Charts
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Members
    • Members
  • Collapse sidebar
  • Activity
  • Graph
  • Charts
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
  • arturo
  • Hello Gargan
  • Wiki
    • 2—components
  • 2.1—Component structure

2.1—Component structure

Last edited by arturo Sep 29, 2021
Page history

Boilerplates

From the tediousness of jQuery, to AngularJS (v1: producer, directive, ... heavy API) to modern frontend libraries, an evolution regarding structure and boilerplate emerges.

  • first of all, recent JavaScript frontend libraries provide a simple yet comprehensive creational/structural/behavioral paradigms. ReactJS (Hooks API) opts for a fully JavaScript-ly functional composition paradigm. VueJS adheres to a Single-File-Component abstraction. The former more difficult to understand for newcomers, but the latter less flexible. It is not a surprise here, but Reactix + Toestand in a PureScript context is the most reliable paradigm
  • secondly, regarding the boilerplate: when we compare a VueJS Single-File-Component with a Svelte component format, we can only applause the reduction of boilerplate. Each JavaScript frontend librarie offers an iteration in this regards. This is one of the reason to adopt the following structure for each component of the project:
module Hello.Components.Example.Bar (bar) where

import Prelude

import Hello.Plugins.Core.UI as UI
import Reactix as R

-- Spec parts for <bar>
type Props =
  ( foo :: String
  )

bar :: UI.Tree Props
bar = UI.tree component

component :: R.Component Props
component = R.hooksComponent "bar" cpt where
  cpt props children = do
    -- Component parts for <bar>
    pure $ R.fragment children

Kinds

  • Two kinds of components:
    • Leaf: no child
    • Tree: has children

Optional props

There is a distinction to be noted here, mainly due to PureScript paradigms. As a fully FP language, it is a requirement to be explicit with null coalescing values. But if we look closer, eg. by taking the "purescript-react-basic" library, we can see an inclination opposite to this requirement. In what measures can we write PureScript component specs by knowing this variadic arity in their attributes/props?

Here is were the optional prop comes to mind. For now, let's put aside the fact that a base component (such as <a/>) can have an undefined amount yet possibly numerous of attributes. Here we will focus on components that receive spec-able props. For example:

module Hello.Components.Example.Icon (icon) where

import Prelude

import Hello.Plugins.Core.UI as UI
import Reactix as R

type Props =
  ( name :: String
  | Options
  )

type Options =
  ( theme :: String
  )

options :: Record Options
options =
  { theme: "filled" -- filled/two-tones/outlined/etc. Filled is the default theme of Google Material Design Icons
  }

icon :: forall r. UI.OptLeaf Options Props r
icon = UI.optLeaf component options

component :: R.Component Props
component = R.hooksComponent "icon" cpt where
  cpt props _ = do
    -- Component parts for <icon>
    pure mempty

DOMAttrs Prop

As we can see in ReactJS, all non props (ie. all non used variables inside a component) could be DOM attributes passing through the parent: “note that attributes/props just become arguments to a function”.

In VueJS, a distinction is made between props and DOM attributes, as props have to respect an implementation. So we can decide to either inherit the DOM attributes, or pass it via a variable to another inner child component.

The transmission of DOM Attributes (programmatically or not) is a useful feature, either for base components or to avoid extra unwanted <div> just to set some BEM classes ("div blindness").

Ideally with PureScript + Reactix, the aim could be to have a Row such as attrs :: DOMAttrs. Where DOMAttrs could be used as a Record of optional values (such as the use in "purescript-react-basic"). Hence, two tweaks to work: attrs has to be optional, the content of the attrs Record also have to be optional. They have not vocation to be programmatically treated, just handed over from one component to another.


  • POC opened in milestones for DOM Attrs

« 1 — Application structure             2.2 — Page and Layout structure »
Clone repository
  • 1—Application structure
  • 2—Components
    • 2.1—Component structure
    • 2.2—Page and Layout structure
    • 2.3—Store structure
  • 3—SASS-usage
    • 3.1—SASS files
    • 3.2—CSS integration model
  • 4—UI library
  • 5—Form validation
  • 6—Component Cookbook
  • 7—Miscellaneous
  • 8—Milestones
  • Home
More Pages

New Wiki Page

Tip: You can specify the full path for the new file. We will automatically create any missing directories.