search spec components factored out of T365
[catagits/Reaction.git] / lib / Reaction / UI / Widget / Container.pm
CommitLineData
1c41e332 1package Reaction::UI::Widget::Container;
2
3use Reaction::UI::WidgetClass;
4
5use aliased 'Reaction::UI::ViewPort';
6
bae75bee 7use namespace::clean -except => [ qw(meta) ];
1c41e332 8
bae75bee 9
10our $child_name;
11
12# somewhat evil. fragment returns ($name, $code) to pass to implements
13# or a method modifier name, so [1] will get us just the code
14
15# This is convenient to do here but DO NOT duplicate this code outside of
16# the same dist as WidgetClass since it's internals-dependent.
17
18my $child_fragment_method
19 = (fragment container_child {
20 arg '_' => $_{viewport}->$child_name;
21 render 'viewport';
22 })[1];
23
24around _method_for_fragment_name => sub {
25 my $orig = shift;
26 my $self = shift;
27 my ($fragment_name) = @_;
28 if (defined($child_name)
29 && $fragment_name eq $child_name) {
30 return $self->$orig(@_) || $child_fragment_method;
31 }
32 return $self->$orig(@_);
1c41e332 33};
bae75bee 34
35before _fragment_widget => sub {
36 my ($self, $do_render, $args, $new_args) = @_;
37 my @contained_names = $self->_contained_names($args->{viewport});
38 foreach my $name (@contained_names) {
39 $new_args->{$name} ||= sub {
40 local $child_name = $name;
41 $self->render($name, @_);
42 };
43 }
44};
45
46implements _contained_names => sub {
47 my ($self, $vp) = @_;
48 my @names;
49 foreach my $attr ($vp->meta->compute_all_applicable_attributes) {
50 next unless eval { $attr->type_constraint->name->isa(ViewPort) };
51 my $name = $attr->name;
52 next if ($name eq 'outer');
53 push(@names, $name);
54 }
55 return @names;
56};
57
58__PACKAGE__->meta->make_immutable;
59
1c41e332 601;
f9b32c83 61
62__END__
63
64=head1 NAME
65
66Reaction::UI::Widget::Container - Provide viewport attibutes in the current viewport
67
68=head1 DESCRIPTION
69
70This widget base class (with no corresponding layout set) will search the viewports
71attributes for those that contain L<Reaction::UI::ViewPort> classes or subclasses.
72
73These attributes will then be provided as arguments to the C<widget> fragment and
74can be rendered by their attribute name.
75
76=head1 FRAGMENTS
77
78=head2 widget
79
80Provides rendering callbacks to those attributes of the viewport that can contain
81viewport objects as arguments to the C<widget> layout.
82
83=head1 AUTHORS
84
85See L<Reaction::Class> for authors.
86
87=head1 LICENSE
88
89See L<Reaction::Class> for the license.
90
91=cut