Brickrouge from me

Brickrouge is an object-oriented toolkit for PHP5.5+ that helps you create inputs, widgets, forms and many other common elements, with all the CSS and JavaScript needed to make them beautiful and magical.

Brickrouge uses Bootstrap from twitter for its style, and JavaScript for its magic. Ready in a minute, you'll have everything you need to create beautiful and clean UIs.

Together with ICanBoogie, Brickrouge is one of the precious components that make the CMS Icybee, but it remains a standalone project for everyone to enjoy!

  • Standalone and patchable
  • Compatible with Bootstrap
  • Support localization
  • Is a Composer package
  • Object-oriented
  • Create any kind of element
  • Populate and validate forms
  • Framework agnostic

This is Alpha!

The following website demonstrates the upcoming Brickrouge v3, currently in development, which focuses on the following features:

You are very welcome to contribute, either by reporting issues or creating pull requests.

Getting started

To start using Brickrouge you just have to install it with Composer:

$ composer require brickrouge/brickrouge

Then include the following resources:

Forms

Form controls

Creating a form is super easy with instances of Form, Element, Text, …

This is some placeholder block-level help text for the above input. It's a bit lighter and easily wraps to a new line, provided the line is long enough.
Note: A label surround each option for much larger click areas and a more usable form.
<?php

namespace Brickrouge;

echo new Form([

    Form::ACTIONS => [

        new Button('Submit', [ 'type' => 'submit', 'class' => 'btn-primary' ])

    ],

    Form::RENDERER => Form\GroupRenderer::class,

    Element::CHILDREN => [

        'email' => new Text([

            Group::LABEL => "Email address",
            Element::DESCRIPTION => "We'll never share your email with anyone else.",

            'placeholder' => "Enter email",
            'type' => 'email'

        ]),

        'password' => new Text([

            Group::LABEL => "Password",

            'placeholder' => "Password",
            'type' => 'password'

        ]),

        'select01' => new Element('select', [

            Group::LABEL => "Select",
            Element::OPTIONS => array_combine(range(1, 5), range(1, 5))

        ]),

        'multiSelect' => new Element('select', [

            Group::LABEL => "Multiple select",
            Element::OPTIONS => array_combine(range(1, 5), range(1, 5)),

            'multiple' => true

        ]),

        'textarea' => new Element('textarea', [

            Group::LABEL => "Textarea",

            'rows' => 3

        ]),

        'fileInput' => new Element('input', [

            Group::LABEL => "File input",
            Element::DESCRIPTION => "This is some placeholder block-level help text for the above input. It's a bit lighter and easily wraps to a new line, provided the line is long enough.",

            'type' => 'file',
            'class' => 'input-file'

        ]),

        'optionsRadios' => new Element(Element::TYPE_RADIO_GROUP, [

            Element::DESCRIPTION => "<strong>Note:</strong> A label surround each option for much larger click areas and a more usable form.",
            Element::DEFAULT_VALUE => 1,
            Element::OPTIONS_DISABLED => [ 3 => true ],
            Element::OPTIONS => [

                1 => "Option one is this and that—be sure to include why it's great",
                2 => "Option two can be something else and selecting it will deselect option one",
                3 => "Option three is disabled"

            ]

        ]),

        'checkbox' => new Element(Element::TYPE_CHECKBOX, [

            Element::LABEL => "Check me out"

        ])

    ]

]);

Prepend & append inputs

Text inputs—with appended or prepended text—provide an easy way to give more context for your inputs. Great examples include the @ sign for Twitter usernames or for finances. The ADDON attribute defines the add-on text, the ADDON_POSITION attribute to define its position.

@
Here's some help text
Here's some help text
<?php

namespace Brickrouge;

echo new Group([

    Element::CHILDREN => [

        'prependedInput' => new Text([

            Group::LABEL => "Prepended text",
            Text::ADDON => "@",
            Text::ADDON_POSITION => 'before',
            Element::DESCRIPTION => "Here's some help text"

        ]),

        'appendedInput' => new Text([

            Group::LABEL => "Appended text",
            Text::ADDON => "€",
            Text::ADDON_POSITION => 'after',
            Element::DESCRIPTION => "Here's some help text"

        ]),

    ]

]);

Grouping elements

Elements may be grouped using a Group instance. The WEIGHT attribute may be used to specify the order in which the elements should be displayed. The weight may be specified as a number or a position relative to another element e.g. 123, before:other_element, after:other_element. Additionally the LEGEND attribute may be used to give the group a title.

What's your name ?
<?php

namespace Brickrouge;

echo new Group([

    Element::LEGEND => "What's your name ?",
    Element::CHILDREN => [

        'lastname' => new Text([

            Group::LABEL => "Last name",
            Element::WEIGHT => 1,
            'type' => 'text',
            'value' => "Laviale"

        ]),

        'firstname' => new Text([

            Group::LABEL => "First name",
            'type' => 'text',
            'value' => "Olivier"

        ]),

        'salutation' => new Element(Element::TYPE_RADIO_GROUP, [

            Group::LABEL => "Salutation",
            Element::WEIGHT => Element::WEIGHT_BEFORE_PREFIX . 'firstname',
            Element::OPTIONS => [

                1 => "Misses",
                2 => "Mister"

            ],

            'class' => 'inline-inputs',
            'value' => 2

        ])

    ]

]);

Popovers overlays of information or action

Add small overlays of content to any element for housing secondary information.

Hover popover

Hover over the button to trigger the popover.

<?php

namespace Brickrouge;

echo new A("hover for popover", "javascript://", [

    'class' => "btn btn-danger",
    'rel' => "popover",
    'data-title' => "A title",
    'data-content' => "And here's some amazing content. It's very engaging. right?",
    'data-animate' => true,
    'data-placement' => Popover::PLACEMENT_RIGHT

]);

Anchored to an element

Popovers are usually anchored to an element and can follow it on the page, wherever it goes, adjusting their box trying to stay as much visible as possible.

Popover

Etiam porta sem malesuada magna mollis euismod. Maecenas faucibus mollis interdum. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.
<?php

namespace Brickrouge;

echo new PopoverWidget([

    Popover::TITLE => "Popover",
    Popover::INNER_HTML => "Etiam porta sem malesuada magna mollis euismod. Maecenas faucibus mollis interdum. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.",
    Popover::ANCHOR => "popover-anchor-0",
    Popover::PLACEMENT => Popover::PLACEMENT_LEFT,
    PopoverWidget::VISIBLE => true

]);

Placement

Popover elements can be placed all around their anchor: before, after, above or below.

Popover elements are automatically repositioned to follow their anchor and may change their placement according to the available space around it.

If the there is not enough available space for the right popover it will jump to the left of the anchor.

Popover above, without title.

Popover after

Pellentesque vitae ligula et est consequat accumsan.

Popover below

Morbi convallis vehicula bibendum. Morbi vestibulum, augue a blandit blandit.
<?php

namespace Brickrouge;

echo new PopoverWidget([

    Popover::INNER_HTML => "Popover above, without title.",
    Popover::ANCHOR => "popover-anchor-1",
    Popover::PLACEMENT => Popover::PLACEMENT_TOP,
    PopoverWidget::VISIBLE => true

]);

echo new PopoverWidget([

    Popover::TITLE => "Popover after",
    Popover::INNER_HTML => "Pellentesque vitae ligula et est consequat accumsan.",
    Popover::ANCHOR => "popover-anchor-1",
    Popover::PLACEMENT => Popover::PLACEMENT_RIGHT,
    PopoverWidget::VISIBLE => true

]);

echo new PopoverWidget([

    Popover::TITLE => "Popover below",
    Popover::INNER_HTML => "Morbi convallis vehicula bibendum. Morbi vestibulum, augue a blandit blandit.",
    Popover::ANCHOR => "popover-anchor-1",
    Popover::PLACEMENT => Popover::PLACEMENT_BOTTOM,
    PopoverWidget::VISIBLE => true

]);

Contrast and actions

Contrast can be used to indicate that the content of the popover is not directly related to the current page.

Popovers can be used to provide a way to edit complex data which are presented more simply on the page.

Caching options

Mo
Min
<?php

namespace Brickrouge;

echo new PopoverWidget([

    Popover::TITLE => "Caching options",
    Popover::INNER_HTML => new Form([

        Form::RENDERER => Form\GroupRenderer::class,
        Form::CHILDREN => [

            new Text([

                Group::LABEL => 'Maximum size of the cache',
                Text::ADDON => 'Mo',

                'class' => 'measure',
                'value' => 8

            ]),

            new Text([

                Group::LABEL => 'Interval between cleanup',
                Text::ADDON => 'Min',

                'class' => 'measure',
                'value' => 15

            ])

        ],

        'class' => 'stacked'

    ]),

    Popover::ANCHOR => "popover-anchor-options",
    Popover::ACTIONS => 'boolean',
    PopoverWidget::VISIBLE => true,

    'class' => 'popover contrast'

]);

?>

<button class="form-control form-control-inline" id="popover-anchor-options" title="Configure caching options">The cache size is 8Mo and it's cleaned up every 15 minutes</button>

Buttons

The Button class is used to create buttons. Their label is translated in the button scope. The initial type of the button is button.

The .btn class can be used to make elements such as the <a> element look like buttons. Compared to Bootstrap, <button> elements don't require the .btn class to be styled.

Button Code Description
<?= new Button('Default');
Standard gray button with gradient
<?= new Button('Primary', [ 'class' => 'btn-primary' ]);
Provides extra visual weight and identifies the primary action in a set of buttons
<?= new Button('Info', [ 'class' => 'btn-info' ]);
Used as an alternate to the default styles
<?= new Button('Success', [ 'class' => 'btn-success' ]);
Indicates a successful or positive action
<?= new Button('Warning', [ 'class' => 'btn-warning' ]);
Indicates caution should be taken with this action
<?= new Button('Danger', [ 'class' => 'btn-danger' ]);
Indicates a dangerous or potentially negative action

Multiple sizes

Fancy larger or smaller buttons? Have at it!

<?= new Button('Primary action', [ 'class' =>'btn-large btn-primary' ])
. PHP_EOL . new Button('Action', [ 'class' =>'btn-large' ]);

<?= new Button('Primary action', [ 'class' => 'btn-small btn-primary' ])
. PHP_EOL . new Button('Action', [ 'class' => 'btn-small' ]);

Disabled state

For buttons that are not active or are disabled by the app for one reason or another, use the disabled state. That’s .disabled for links and :disabled for <button> elements.

Primary action Action

<?= new A('Primary action', '#', [ 'class' => 'btnbtn-large btn-primary disabled' ])
. PHP_EOL . new A('Action', '#', [ 'class' => 'btn btn-large disabled' ]);

<?= new Button('Primary action', [ 'class' =>'btn-large btn-primary', 'disabled' => true ])
. PHP_EOL . new Button('Action', [ 'class' => 'large', 'disabled' =>true ]);

Split button dropdowns

Split buttons feature a standard action on the left and a dropdown toggle on the right with contextual links.

Dropdown menu options are defined using the OPTION attribute, the same way options are defined for select, TYPE_CHECKBOX_GROUP or TYPE_RADIO_GROUP element, the twist is that false options are turned into separators.

All btn-* class names are forwarded to the button elements, thus you can create a small primary split button with btn-primary btn-sm. The disabled class name is forwarded as well.

<?php

namespace Brickrouge;

echo new SplitButton('Action', [

    Element::OPTIONS => [

        'Action',
        'Another action',
        'Something else here',
        false,
        'Separated link'

    ],

    'class' => 'btn-secondary'

]);

Alerts Success, warning, and error messages

Error or danger

<?php

namespace Brickrouge;

echo new Alert("<strong>Oh snap!</strong> Change a few things up and try submitting again.", [

    Alert::CONTEXT => Alert::CONTEXT_DANGER

]);

Success

<?php

namespace Brickrouge;

echo new Alert("<strong>Well done!</strong> You successfully read this important alert message.", [

    Alert::CONTEXT => Alert::CONTEXT_SUCCESS

]);

Information

<?php

namespace Brickrouge;

echo new Alert("<strong>Heads up!</strong> This alert needs your attention, but it’s not super important.", [

    Alert::CONTEXT => Alert::CONTEXT_INFO

]);

Heading & multi-line

Easily extend the standard alert message with two optional classes: .alert-block for more padding and text controls and .alert-heading for a matching heading.

The HEADING attribute may be used to define a heading.

<?php

namespace Brickrouge;

echo new Alert("<p>Best check yo self, you’re not looking too good.</p><p>Nulla vitae elit libero, a pharetra augue. Praesent commodo cursus magna, vel scelerisque nisl consectetur et.</p>", [

    Alert::HEADING => "Warning!"

]);

Dismissible alerts

Alerts may be dismissible. If a dismissible alert is tied to a form when the alert is dismissed the errors of the form are dismissed as well.

<?php

namespace Brickrouge;

use ICanBoogie\ErrorCollection;

$errors = (new ErrorCollection)
    ->add('input0', "The field <q>{label}</q> <code>{name}</code> is required.");

echo new Form([

    Element::CHILDREN => [

        'input0' => new Text([ Group::LABEL => 'Required', 'required' => true ]),
        'input1' => new Text([ Group::LABEL => 'Optional' ])

    ],

    Form::ERRORS => $errors,
    Form::RENDERER => Form\GroupRenderer::class

]);

Error collections

The Alert class can also render ErrorCollection instances, any Traversable or array really.

<?php

namespace Brickrouge;

use ICanBoogie\ErrorCollection;

$errors = (new ErrorCollection)
    ->add('username', "Unknown username/password combination.")
    ->add('username', "Funny username by the way ;-)")
    ->add_generic("Login failed!")
;

echo new Alert($errors);
Fork me on GitHub