Skip to content

Commit 9db7e00

Browse files
committed
Adding the "tabs" directive
1 parent faf2c5f commit 9db7e00

File tree

8 files changed

+209
-0
lines changed

8 files changed

+209
-0
lines changed

src/Directive/GroupTabDirective.php

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Docs Builder package.
5+
* (c) Ryan Weaver <ryan@symfonycasts.com>
6+
* For the full copyright and license information, please view the LICENSE
7+
* file that was distributed with this source code.
8+
*/
9+
10+
namespace SymfonyDocsBuilder\Directive;
11+
12+
use Doctrine\RST\Directives\SubDirective;
13+
use Doctrine\RST\Nodes\CodeNode;
14+
use Doctrine\RST\Nodes\Node;
15+
use Doctrine\RST\Nodes\QuoteNode;
16+
use Doctrine\RST\Parser;
17+
use SymfonyDocsBuilder\Node\GroupTabNode;
18+
use function strtoupper;
19+
20+
/**
21+
* Directive that only appears within the "tabs" directive.
22+
*/
23+
class GroupTabDirective extends SubDirective
24+
{
25+
public function getName(): string
26+
{
27+
return 'group-tab';
28+
}
29+
30+
public function processSub(Parser $parser, ?Node $document, string $variable, string $data, array $options): ?Node
31+
{
32+
$tabName = $data;
33+
if (!$tabName) {
34+
throw new \RuntimeException(sprintf('The "group-tab" directive requires a tab name: ".. group-tab:: Tab Name".'));
35+
}
36+
foreach ($document->getNodes() as $childNode) {
37+
var_dump(get_class($childNode));
38+
}
39+
40+
return new GroupTabNode($document->getNodes(), $data);
41+
}
42+
43+
private function parseGroupTabNode($groupTabNode)
44+
{
45+
46+
}
47+
}

src/Directive/TabsDirective.php

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Docs Builder package.
5+
* (c) Ryan Weaver <ryan@symfonycasts.com>
6+
* For the full copyright and license information, please view the LICENSE
7+
* file that was distributed with this source code.
8+
*/
9+
10+
namespace SymfonyDocsBuilder\Directive;
11+
12+
use Doctrine\RST\Directives\SubDirective;
13+
use Doctrine\RST\Nodes\CodeNode;
14+
use Doctrine\RST\Nodes\Node;
15+
use Doctrine\RST\Nodes\QuoteNode;
16+
use Doctrine\RST\Parser;
17+
use SymfonyDocsBuilder\Node\GroupTabNode;
18+
use function strtoupper;
19+
20+
class TabsDirective extends SubDirective
21+
{
22+
public function getName(): string
23+
{
24+
return 'tabs';
25+
}
26+
27+
public function processSub(Parser $parser, ?Node $document, string $variable, string $data, array $options): ?Node
28+
{
29+
$tabsTitle = $data;
30+
if (!$tabsTitle) {
31+
throw new \RuntimeException(sprintf('The "tabs" directive requires a title: ".. tabs:: Title".'));
32+
}
33+
34+
$tabs = [];
35+
foreach ($document->getNodes() as $groupTabNode) {
36+
if (!$groupTabNode instanceof GroupTabNode) {
37+
throw new \RuntimeException(sprintf('Only ".. group-tab::" content can appear within the "tab" directive.'));
38+
}
39+
40+
$content = '';
41+
foreach ($groupTabNode->getNodes() as $node) {
42+
$content .= $node->render();
43+
}
44+
45+
$tabs[] = [
46+
'hash' => hash('sha1', $groupTabNode->getTabName()),
47+
'tabName' => $groupTabNode->getTabName(),
48+
'content' => $content,
49+
];
50+
}
51+
52+
$wrapperDiv = $parser->renderTemplate(
53+
'directives/tabs.html.twig',
54+
[
55+
'title' => $tabsTitle,
56+
'tabs' => $tabs,
57+
]
58+
);
59+
60+
return $parser->getNodeFactory()->createWrapperNode(null, $wrapperDiv, '</div>');
61+
}
62+
}

src/KernelFactory.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ private static function getDirectives(): array
8282
new SymfonyDirectives\DeprecatedDirective(),
8383
new SymfonyDirectives\ErrorDirective(),
8484
new SymfonyDirectives\FigureDirective(),
85+
new SymfonyDirectives\GroupTabDirective(),
8586
new SymfonyDirectives\HintDirective(),
8687
new SymfonyDirectives\ImportantDirective(),
8788
new SymfonyDirectives\IndexDirective(),
@@ -91,6 +92,7 @@ private static function getDirectives(): array
9192
new SymfonyDirectives\ScreencastDirective(),
9293
new SymfonyDirectives\SeeAlsoDirective(),
9394
new SymfonyDirectives\SidebarDirective(),
95+
new SymfonyDirectives\TabsDirective(),
9496
new SymfonyDirectives\TipDirective(),
9597
new SymfonyDirectives\TopicDirective(),
9698
new SymfonyDirectives\WarningDirective(),

src/Node/GroupTabNode.php

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php
2+
3+
namespace SymfonyDocsBuilder\Node;
4+
5+
use Doctrine\RST\Nodes\Node;
6+
7+
/**
8+
* Wraps nodes + options in a GroupTabDirective.
9+
*/
10+
class GroupTabNode extends Node
11+
{
12+
/**
13+
* @var Node[]
14+
*/
15+
private array $nodes;
16+
17+
private string $tabName;
18+
19+
public function __construct(array $nodes, string $tabName)
20+
{
21+
$this->nodes = $nodes;
22+
$this->tabName = $tabName;
23+
24+
parent::__construct();
25+
}
26+
27+
public function getNodes(): array
28+
{
29+
return $this->nodes;
30+
}
31+
32+
public function getTabName(): string
33+
{
34+
return $this->tabName;
35+
}
36+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<div class="configuration-block">
2+
<div role="tablist" aria-label="{{ title }}" class="configuration-tabs configuration-tabs-length-{{ tabs|length }}">
3+
{% for tab in tabs %}
4+
<button role="tab" type="button"
5+
aria-controls="{{ 'tab-tabpanel-' ~ tab.hash }}" aria-selected="{{ loop.first ? 'true' : 'false' }}"
6+
{{ loop.first ? 'data-active="true"' }} {{ not loop.first ? 'tabindex="-1"' }}>
7+
<span>{{ tab.tabName }}</span>
8+
</button>
9+
{% endfor %}
10+
</div>
11+
12+
{% for tab in tabs %}
13+
<div role="tabpanel" id="{{ 'tab-tabpanel-' ~ tab.hash }}" aria-label="{{ tab.tabName }}" class="configuration-codeblock" style="{{ not loop.first ? 'display: none' }}">
14+
{{ tab.content|raw }}
15+
</div>
16+
{% endfor %}
17+
</div>

tests/IntegrationTest.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,10 @@ public function parserUnitBlockProvider()
206206
'blockName' => 'directives/sidebar-code-block-nested',
207207
];
208208

209+
yield 'tabs' => [
210+
'blockName' => 'directives/tabs',
211+
];
212+
209213
yield 'class-reference' => [
210214
'blockName' => 'references/class',
211215
];
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<div class="configuration-block">
2+
<div role="tablist" aria-label="UX Installation"
3+
class="configuration-tabs configuration-tabs-length-2">
4+
<button role="tab" type="button" aria-controls="tab-tabpanel-97a055193fa707f2025ee25bb469c74aa29b2c6c" aria-selected="true" data-active="true">
5+
<span>Webpack Encore</span>
6+
</button>
7+
<button role="tab" type="button" aria-controls="tab-tabpanel-1865de6b2b585de79e8700d7968050722e562c44" aria-selected="false" tabindex="-1">
8+
<span>AssetMapper</span>
9+
</button>
10+
</div>
11+
12+
<div role="tabpanel" id="tab-tabpanel-97a055193fa707f2025ee25bb469c74aa29b2c6c" aria-label="Webpack Encore" class="configuration-codeblock" style="">
13+
<p>Webpack Encore stuff!</p>
14+
<div translate="no" data-loc="1" class="notranslate codeblock codeblock-length-sm codeblock-yaml">
15+
<div class="codeblock-scroll">
16+
<pre class="codeblock-lines">1</pre>
17+
<pre class="codeblock-code"><code><span class="hljs-attr">I am yaml:</span></code></pre>
18+
</div>
19+
</div>
20+
</div>
21+
<div role="tabpanel" id="tab-tabpanel-1865de6b2b585de79e8700d7968050722e562c44" aria-label="AssetMapper" class="configuration-codeblock" style="display: none">
22+
<p>AssetMapper stuff!</p>
23+
<p>And another paragraph.</p>
24+
</div>
25+
</div>
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
2+
.. tabs:: UX Installation
3+
4+
.. group-tab:: Webpack Encore
5+
6+
Webpack Encore stuff!
7+
8+
.. code-block:: yaml
9+
10+
I am yaml:
11+
12+
.. group-tab:: AssetMapper
13+
14+
AssetMapper stuff!
15+
16+
And another paragraph.

0 commit comments

Comments
 (0)