A component that renders a Bootstrap Button element using OverReact’s statically-typed React prop API.
Use props.skin
to choose from one of six predefined styles for the
Button
component, each serving its own semantic purpose.
part of over_react.web.demos;
ReactElement buttonExamplesDemo() =>
(Dom.div()..className = 'btn-toolbar')(
Button()('Primary'),
(Button()..skin = ButtonSkin.SECONDARY)('Secondary'),
(Button()..skin = ButtonSkin.SUCCESS)('Success'),
(Button()..skin = ButtonSkin.INFO)('Info'),
(Button()..skin = ButtonSkin.WARNING)('Warning'),
(Button()..skin = ButtonSkin.DANGER)('Danger'),
(Button()..skin = ButtonSkin.LINK)('Link')
);
part of over_react.web.demo_components;
/// Nest one or more `Button` components within a [ListGroup]
/// to render individual items within a list.
///
/// See: <http://v4-alpha.getbootstrap.com/components/list-group/>
@Factory()
UiFactory<ButtonProps> Button;
@Props()
class ButtonProps extends UiProps {
/// The skin / "context" for the [Button].
///
/// See: <http://v4-alpha.getbootstrap.com/components/buttons/#examples>.
///
/// Default: [ButtonSkin.PRIMARY]
ButtonSkin skin;
/// The size of the [Button].
///
/// See: <http://v4-alpha.getbootstrap.com/components/buttons/#sizes>.
///
/// Default: [ButtonSize.DEFAULT]
ButtonSize size;
/// Whether the [Button] should appear "active".
///
/// See: <http://v4-alpha.getbootstrap.com/components/buttons/#active-state>
///
/// Default: false
bool isActive;
/// Whether the [Button] is disabled.
///
/// See: <http://v4-alpha.getbootstrap.com/components/buttons/#disabled-state>
///
/// Default: false
@Accessor(key: 'disabled', keyNamespace: '')
bool isDisabled;
/// Whether the [Button] is a block level button -- that which spans the full
/// width of its parent.
///
/// Default: false
bool isBlock;
/// The HTML `href` attribute value for the [Button].
///
/// If set, the item will render via [Dom.a].
///
/// _Proxies [DomProps.href]_
@Accessor(keyNamespace: '')
String href;
/// The HTML `target` attribute value for the [Button].
///
/// If set, the item will render via [Dom.a].
///
/// _Proxies [DomProps.target]_
@Accessor(keyNamespace: '')
String target;
/// The HTML `type` attribute value for the [Button] when
/// rendered via [Dom.button].
///
/// This will only be applied if [href] is not set.
///
/// _Proxies [DomProps.type]_
///
/// Default: [ButtonType.BUTTON]
ButtonType type;
}
@Component()
class ButtonComponent extends UiComponent<ButtonProps> {
@override
Map getDefaultProps() => (newProps()
..skin = ButtonSkin.PRIMARY
..size = ButtonSize.DEFAULT
..isActive = false
..isDisabled = false
..isBlock = false
..type = ButtonType.BUTTON
);
@override
render() {
BuilderOnlyUiFactory<DomProps> factory = _buttonDomNodeFactory;
return (factory()
..addProps(copyUnconsumedDomProps())
..className = _getButtonClasses().toClassName()
..href = props.href
..target = props.target
..type = _isAnchorLink ? null : props.type.typeName
..disabled = _isAnchorLink ? null : props.isDisabled
..addProps(ariaProps()
..disabled = _isAnchorLink ? props.isDisabled : null
)
)(props.children);
}
ClassNameBuilder _getButtonClasses() {
return forwardingClassNameBuilder()
..add('btn')
..add('btn-block', props.isBlock)
..add('active', props.isActive)
..add('disabled', props.isDisabled)
..add(props.skin.className);
}
BuilderOnlyUiFactory<DomProps> get _buttonDomNodeFactory => _isAnchorLink ? Dom.a : Dom.button;
bool get _isAnchorLink => props.href != null;
}
/// Contextual skin options for a [Button] component.
class ButtonSkin extends ClassNameConstant {
const ButtonSkin._(String name, String className) : super(name, className);
/// [className] value: 'btn-primary'
static const ButtonSkin PRIMARY =
const ButtonSkin._('PRIMARY', 'btn-primary');
/// [className] value: 'btn-secondary'
static const ButtonSkin SECONDARY =
const ButtonSkin._('SECONDARY', 'btn-secondary');
/// [className] value: 'btn-danger'
static const ButtonSkin DANGER =
const ButtonSkin._('DANGER', 'btn-danger');
/// [className] value: 'btn-success'
static const ButtonSkin SUCCESS =
const ButtonSkin._('SUCCESS', 'btn-success');
/// [className] value: 'btn-warning'
static const ButtonSkin WARNING =
const ButtonSkin._('WARNING', 'btn-warning');
/// [className] value: 'btn-info'
static const ButtonSkin INFO =
const ButtonSkin._('INFO', 'btn-info');
/// [className] value: 'btn-link'
static const ButtonSkin LINK =
const ButtonSkin._('LINK', 'btn-link');
/// [className] value: 'btn-outline-primary'
static const ButtonSkin PRIMARY_OUTLINE =
const ButtonSkin._('PRIMARY', 'btn-outline-primary');
/// [className] value: 'btn-outline-secondary'
static const ButtonSkin SECONDARY_OUTLINE =
const ButtonSkin._('SECONDARY', 'btn-outline-secondary');
/// [className] value: 'btn-outline-danger'
static const ButtonSkin DANGER_OUTLINE =
const ButtonSkin._('DANGER', 'btn-outline-danger');
/// [className] value: 'btn-outline-success'
static const ButtonSkin SUCCESS_OUTLINE =
const ButtonSkin._('SUCCESS', 'btn-outline-success');
/// [className] value: 'btn-outline-warning'
static const ButtonSkin WARNING_OUTLINE =
const ButtonSkin._('WARNING', 'btn-outline-warning');
/// [className] value: 'btn-outline-info'
static const ButtonSkin INFO_OUTLINE =
const ButtonSkin._('INFO', 'btn-outline-info');
}
/// Size options for a [Button] component.
class ButtonSize extends ClassNameConstant {
const ButtonSize._(String name, String className) : super(name, className);
/// [className] value: ''
static const ButtonSize DEFAULT =
const ButtonSize._('DEFAULT', '');
/// [className] value: 'btn-lg'
static const ButtonSize LARGE =
const ButtonSize._('LARGE', 'btn-lg');
/// [className] value: 'btn-sm'
static const ButtonSize SMALL =
const ButtonSize._('SMALL', 'btn-sm');
}
By default, the Button
component renders a <button>
element.
However, if props.href
is set, an <a>
will be rendered instead.
Optionally, set props.type
to ButtonType.SUBMIT
or ButtonType.RESET
to
render a submit / reset form button, respectively.
part of over_react.web.demos;
ReactElement buttonTypesDemo() =>
(Dom.div()..className = 'btn-toolbar')(
Button()('Button'),
(Button()..href = '#')('Link'),
(Button()..type = ButtonType.SUBMIT)('Submit'),
(Button()..type = ButtonType.RESET)('Reset')
);
Set props.skin
to one of the "outline" options when you are in need of a
Button
, but not the ones that come with a hefty background color.
part of over_react.web.demos;
ReactElement buttonOutlineDemo() =>
(Dom.div()..className = 'btn-toolbar')(
(Button()..skin = ButtonSkin.PRIMARY_OUTLINE)('Primary'),
(Button()..skin = ButtonSkin.SECONDARY_OUTLINE)('Secondary'),
(Button()..skin = ButtonSkin.SUCCESS_OUTLINE)('Success'),
(Button()..skin = ButtonSkin.INFO_OUTLINE)('Info'),
(Button()..skin = ButtonSkin.WARNING_OUTLINE)('Warning'),
(Button()..skin = ButtonSkin.DANGER_OUTLINE)('Danger')
);
Set props.size
if you fancy larger or smaller Button
s.
part of over_react.web.demos;
ReactElement buttonSizesDemo() =>
(Dom.div()..className = 'btn-toolbar')(
(Button()..size = ButtonSize.SMALL)('Small'),
Button()('Default'),
(Button()..size = ButtonSize.LARGE)('Large')
);
Set props.isBlock
to render Button
s that span the
full width of a parent element.
part of over_react.web.demos;
ReactElement buttonBlockDemo() => Dom.div()(
(Button()
..isBlock = true
)('Block level button'),
(Button()
..isBlock = true
..skin = ButtonSkin.SECONDARY
)('Block level button')
);
Set props.isActive
to make a Button
appear active.
part of over_react.web.demos;
ReactElement buttonActiveDemo() =>
(Dom.div()..className = 'btn-toolbar')(
(Button()
..isActive = true
)('Primary button'),
(Button()
..isActive = true
..skin = ButtonSkin.SECONDARY
)('Button')
);
Set props.isDisabled
to disable a Button
.
part of over_react.web.demos;
ReactElement buttonDisabledDemo() =>
(Dom.div()..className = 'btn-toolbar')(
(Button()
..isDisabled = true
)('Primary button'),
(Button()
..href = '#'
..isDisabled = true
..skin = ButtonSkin.SECONDARY
)('Link')
);