@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.)
hq.recaptime.dev/wiki/Phorge
phorge
phabricator
1<?php
2
3final class PHUICrumbsView extends AphrontView {
4
5 private $crumbs = array();
6 private $actions = array();
7 private $border;
8
9 protected function canAppendChild() {
10 return false;
11 }
12
13
14 /**
15 * Convenience method for adding a simple crumb with just text, or text and
16 * a link.
17 *
18 * @param string $text Text of the crumb.
19 * @param string $href (optional) href for the crumb.
20 * @param bool $strikethrough (optional) Strikethrough (=inactive/disabled)
21 * for the crumb.
22 * @return $this
23 */
24 public function addTextCrumb($text, $href = null, $strikethrough = false) {
25 return $this->addCrumb(
26 id(new PHUICrumbView())
27 ->setName($text)
28 ->setHref($href)
29 ->setStrikethrough($strikethrough));
30 }
31
32 public function addCrumb(PHUICrumbView $crumb) {
33 $this->crumbs[] = $crumb;
34 return $this;
35 }
36
37 public function addAction(PHUIListItemView $action) {
38 $this->actions[] = $action;
39 return $this;
40 }
41
42 public function setBorder($border) {
43 $this->border = $border;
44 return $this;
45 }
46
47 public function getActions() {
48 return $this->actions;
49 }
50
51 public function render() {
52 require_celerity_resource('phui-crumbs-view-css');
53
54 $action_view = null;
55 if ($this->actions) {
56 // TODO: This block of code takes "PHUIListItemView" objects and turns
57 // them into some weird abomination by reading most of their properties
58 // out. Some day, this workflow should render the items and CSS should
59 // resytle them in place without needing a wholly separate set of
60 // DOM nodes.
61
62 $actions = array();
63 foreach ($this->actions as $action) {
64 if ($action->getType() == PHUIListItemView::TYPE_DIVIDER) {
65 $actions[] = phutil_tag(
66 'span',
67 array(
68 'class' => 'phui-crumb-action-divider',
69 ));
70 continue;
71 }
72
73 $icon = null;
74 if ($action->getIcon()) {
75 $icon_name = $action->getIcon();
76 if ($action->getDisabled()) {
77 $icon_name .= ' lightgreytext';
78 }
79
80 $icon = id(new PHUIIconView())
81 ->setIcon($icon_name);
82
83 }
84
85 $action_classes = $action->getClasses();
86 $action_classes[] = 'phui-crumbs-action';
87
88 $name = null;
89 if ($action->getName()) {
90 $name = phutil_tag(
91 'span',
92 array(
93 'class' => 'phui-crumbs-action-name',
94 ),
95 $action->getName());
96 } else {
97 $action_classes[] = 'phui-crumbs-action-icon';
98 }
99
100 $action_sigils = $action->getSigils();
101 if ($action->getWorkflow()) {
102 $action_sigils[] = 'workflow';
103 }
104
105 if ($action->getDisabled()) {
106 $action_classes[] = 'phui-crumbs-action-disabled';
107 }
108
109 $aria_label = null;
110 $metadata = $action->getMetadata();
111 if ($metadata && isset($metadata['tip'])) {
112 $aria_label = $metadata['tip'];
113 }
114
115 $actions[] = javelin_tag(
116 'a',
117 array(
118 'href' => $action->getHref(),
119 'class' => implode(' ', $action_classes),
120 'sigil' => implode(' ', $action_sigils),
121 'aria-label' => $aria_label,
122 'style' => $action->getStyle(),
123 'meta' => $action->getMetadata(),
124 ),
125 array(
126 $icon,
127 $name,
128 ));
129 }
130
131 $action_view = phutil_tag(
132 'div',
133 array(
134 'class' => 'phui-crumbs-actions',
135 ),
136 $actions);
137 }
138
139 if ($this->crumbs) {
140 last($this->crumbs)->setIsLastCrumb(true);
141 }
142
143 $classes = array();
144 $classes[] = 'phui-crumbs-view';
145 if ($this->border) {
146 $classes[] = 'phui-crumbs-border';
147 }
148
149 return phutil_tag(
150 'div',
151 array(
152 'class' => implode(' ', $classes),
153 ),
154 array(
155 $action_view,
156 $this->crumbs,
157 ));
158 }
159
160}