1 package SL::Presenter::MaterialComponents;
5 use SL::HTML::Restrict;
6 use SL::Presenter::EscapedText qw(escape);
7 use SL::Presenter::Tag qw(html_tag);
8 use Scalar::Util qw(blessed);
10 use Exporter qw(import);
14 our %EXPORT_TAGS = (ALL => \@EXPORT_OK);
16 use constant BUTTON => 'btn';
17 use constant BUTTON_FLAT => 'btn-flat';
18 use constant BUTTON_FLOATING => 'btn-floating';
19 use constant BUTTON_LARGE => 'btn-large';
20 use constant BUTTON_SMALL => 'btn-small';
21 use constant DISABLED => 'disabled';
22 use constant LEFT => 'left';
23 use constant MATERIAL_ICONS => 'material-icons';
24 use constant RIGHT => 'right';
25 use constant LARGE => 'large';
26 use constant MEDIUM => 'medium';
27 use constant SMALL => 'small';
28 use constant TINY => 'tiny';
30 use constant WAVES_EFFECT => 'waves-effect';
31 use constant WAVES_LIGHT => 'waves-light';
34 my %optional_classes = (
38 floating => BUTTON_FLOATING,
39 large => BUTTON_LARGE,
40 small => BUTTON_SMALL,
55 'if (!confirm("'. _J($_[0]) .'")) return false;'
58 sub _confirm_to_onclick {
59 my ($attributes, $onclick) = @_;
61 if ($attributes->{confirm}) {
63 $$onclick = _confirm_js(delete($attributes->{confirm})) . $attributes->{onlick};
67 # used to extract material properties that need to be translated to classes
68 # supports prefixing for delegation
69 # returns a list of classes, mutates the attributes
70 sub _extract_attribute_classes {
71 my ($attributes, $type, $prefix) = @_;
75 for my $key (keys %$attributes) {
77 next unless $key =~ /^${prefix}_(.*)/;
83 if ($optional_classes{$type}{$attr}) {
84 $attributes->{$key} = undef;
85 push @classes, $optional_classes{$type}{$attr};
89 # delete all undefined values
90 my @delete_keys = grep { !defined $attributes->{$_} } keys %$attributes;
91 delete $attributes->{$_} for @delete_keys;
97 my ($onclick, $value, %attributes) = @_;
99 _set_id_attribute(\%attributes, $attributes{name}) if $attributes{name};
100 _confirm_to_onclick(\%attributes, \$onclick);
102 my @button_classes = _extract_attribute_classes(\%attributes, "button");
103 my @icon_classes = _extract_attribute_classes(\%attributes, "icon", "icon");
105 $attributes{class} = [
106 grep { $_ } $attributes{class}, WAVES_EFFECT, WAVES_LIGHT, BUTTON, @button_classes
109 if ($attributes{icon}) {
110 $value = icon(delete $attributes{icon}, class => \@icon_classes)
114 html_tag('a', $value, %attributes, onclick => $onclick);
118 my ($name, $value, %attributes) = @_;
120 _set_id_attribute(\%attributes, $attributes{name}) if $attributes{name};
121 _confirm_to_onclick(\%attributes, \($attributes{onclick} //= ''));
123 my @button_classes = _extract_attribute_classes(\%attributes, "button");
124 my @icon_classes = _extract_attribute_classes(\%attributes, "icon", "icon");
126 $attributes{class} = [
127 grep { $_ } $attributes{class}, WAVES_EFFECT, WAVES_LIGHT, BUTTON, @button_classes
130 if ($attributes{icon}) {
131 $value = icon(delete $attributes{icon}, class => \@icon_classes)
135 html_tag('button', $value, type => 'submit', %attributes);
140 my ($name, %attributes) = @_;
142 my @icon_classes = _extract_attribute_classes(\%attributes, "icon");
144 html_tag('i', $name, class => [ grep { $_ } MATERIAL_ICONS, @icon_classes, delete $attributes{class} ], %attributes);
149 my ($name, $value, %attributes) = @_;
155 html_tag('input', $name, $value, %attributes) . html_tag('label', for => $attributes{id}, $name);
168 SL::Presenter::MaterialComponents - MaterialCSS Component wrapper
181 Sven Schöling E<lt>s.schoeling@googlemail.comE<gt>