Repository files navigation

PHP-Navigation

GitHub ReleaseGitHub LicensePackagist Downloadscodecov

Overview

A simple and effective Navigation to manage active states in navigation structures.
For Symfony integration, check out the NavigationBundle.

Features

  • Automatically tracks a link's active status and makes it easy to check if a parent navigation item has active child links.
  • Easy to set up and integrate into existing projects.
  • Flexible and extensible for complex navigation structures.

Installation

Install via Composer:

composer require feskol/php-navigation

Usage

Building Your Navigation Structure

useFeskol\Navigation\Link;
useFeskol\Navigation\Navigation;
// create links$navLink = newLink();
$navLink->setTitle('Company')
->setHref('/company');
$subNavLink = newLink();
$subNavLink->setTitle('About us')
->setHref('/company/about-us')
->setIsActive(true);
// add the $subNavLink as $navLinks Child$navLink->addChild($subNavLink);
// To have all links in one place you can use the provided Navigation class:$navigation = newNavigation();
$navigation->setTitle('MyNavigation');
// add the created $navLink to the Navigation$navigation->addLink($navLink);

Iterating through Navigation links:

foreach ($navigation->getLinks() as$link){
echo$link->getTitle(); // "Company"echo$link->hasActiveChildren(); // "true" - because the child is activeforeach($link->getChildren() as$subLink){
echo$link->getTitle(); // "About us"echo$link->isActive(); // "true"
}
}

Common link data

The Link class provides setter and getter methods for the common attributes of an <a>-tag.
The most commonly used ones are href="" and target="":

useFeskol\Navigation\Link;
$link = newLink();
// href$link->setHref('/company/about-us');
$link->getHref(); // "/company/about-us"// target$link->setTarget(Link::TARGET_BLANK);
$link->getTarget(); // "_blank"

To view all available methods for the common link data, check out the AbsctractHyperLink class.

Additional Data

There are often situations where you need additional data for your navigation, such as icons or images.
The best approach is to create your own class (e.g. MyCustomLink) that extends the Link class:

useFeskol\Navigation\Link;
class MyCustomLink extends Link
{
private ?string$icon = null;
publicfunctiongetIcon(): ?string {
return$this->icon;
}
publicfunctionsetIcon(?string$icon): static {
$this->icon = $icon;
return$this;
}
}

Then use your MyCustomLink class instead of the Link class:

$link = newMyCustomLink();
$link->setTitle('Company')
->setHref('/company')
->setIcon('bi bi-user'); // For example, using Bootstrap-Icon classes

Handling translations in your frontend

Symfony

In Symfony, you can use the TranslatableMessage class to hold translation infos which you can use in your frontend.
In Twig, apply the |trans filter to translate the TranslatableMessage.

Both the Navigation and Link classes accept any object implementing the \Stringable interface in their setTitle() methods. This allows you to pass objects like TranslatableMessage or custom classes with a __toString() method.

Example in Symfony

useFeskol\Navigation\Link;
useFeskol\Navigation\Navigation;
useSymfony\Component\Translation\TranslatableMessage;
$navigation = newNavigation();
$navigation->setTitle(newTranslatableMessage('MyNavigation', [], 'navigation'));
$navLink = newLink();
$navLink->setTitle(newTranslatableMessage(
'Nav-Item for %customerName%',
['%customerName%' => $customer->getName()], // Dynamic translation parameters 'navigation'// Translation domain
));
$navigation->addLink($navLink);

And then in your Twig template:

{# @var \Feskol\Navigation\Navigation navigation #} Translated Navigation Title: {{ navigation.title|trans }} {% forlinkinnavigation.links %} Translated Link Title: {{ link.title|trans }} {% endfor %} 

Contribution Guidelines

We welcome contributions to this project! To ensure clarity and fairness for all contributors, we require that all contributors sign our Contributor License Agreement (CLA).

By signing the CLA, you confirm that:

  1. You grant us the perpetual, worldwide, non-exclusive, royalty-free, irrevocable right to use, modify, sublicense, and distribute your contribution as part of this project or any other project.
  2. You retain ownership of your contribution, but grant us the rights necessary to use it without restriction.
  3. Your contribution does not violate the rights of any third party.

How to Sign the CLA

Before submitting a pull request, please sign the CLA using the following link:
Sign the CLA

Contributions cannot be merged unless the CLA is signed.

Thank you for your contributions and for helping us build something great!

Testing

We're using phpunit.

Run tests:

php vendor/bin/phpunit

❤️ Support This Project

If you find this project helpful and would like to support my work:

  • 🌟 Star the repository to show your appreciation.
  • 💸 Donate via:
    • Buy Me a Coffe: Buy Me A Coffee
    • PayPal: PayPal

Thank you for your support!

About

A simple and effective Navigation to manage active states in navigation structures.

Topics

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

PHP-Navigation

GitHub ReleaseGitHub LicensePackagist Downloadscodecov

Overview

A simple and effective Navigation to manage active states in navigation structures.
For Symfony integration, check out the NavigationBundle.

Features

  • Automatically tracks a link's active status and makes it easy to check if a parent navigation item has active child links.
  • Easy to set up and integrate into existing projects.
  • Flexible and extensible for complex navigation structures.

Installation

Install via Composer:

composer require feskol/php-navigation

Usage

Building Your Navigation Structure

useFeskol\Navigation\Link;
useFeskol\Navigation\Navigation;
// create links$navLink = newLink();
$navLink->setTitle('Company')
->setHref('/company');
$subNavLink = newLink();
$subNavLink->setTitle('About us')
->setHref('/company/about-us')
->setIsActive(true);
// add the $subNavLink as $navLinks Child$navLink->addChild($subNavLink);
// To have all links in one place you can use the provided Navigation class:$navigation = newNavigation();
$navigation->setTitle('MyNavigation');
// add the created $navLink to the Navigation$navigation->addLink($navLink);

Iterating through Navigation links:

foreach ($navigation->getLinks() as$link){
echo$link->getTitle(); // "Company"echo$link->hasActiveChildren(); // "true" - because the child is activeforeach($link->getChildren() as$subLink){
echo$link->getTitle(); // "About us"echo$link->isActive(); // "true"
}
}

Common link data

The Link class provides setter and getter methods for the common attributes of an <a>-tag.
The most commonly used ones are href="" and target="":

useFeskol\Navigation\Link;
$link = newLink();
// href$link->setHref('/company/about-us');
$link->getHref(); // "/company/about-us"// target$link->setTarget(Link::TARGET_BLANK);
$link->getTarget(); // "_blank"

To view all available methods for the common link data, check out the AbsctractHyperLink class.

Additional Data

There are often situations where you need additional data for your navigation, such as icons or images.
The best approach is to create your own class (e.g. MyCustomLink) that extends the Link class:

useFeskol\Navigation\Link;
class MyCustomLink extends Link
{
private ?string$icon = null;
publicfunctiongetIcon(): ?string {
return$this->icon;
}
publicfunctionsetIcon(?string$icon): static {
$this->icon = $icon;
return$this;
}
}

Then use your MyCustomLink class instead of the Link class:

$link = newMyCustomLink();
$link->setTitle('Company')
->setHref('/company')
->setIcon('bi bi-user'); // For example, using Bootstrap-Icon classes

Handling translations in your frontend

Symfony

In Symfony, you can use the TranslatableMessage class to hold translation infos which you can use in your frontend.
In Twig, apply the |trans filter to translate the TranslatableMessage.

Both the Navigation and Link classes accept any object implementing the \Stringable interface in their setTitle() methods. This allows you to pass objects like TranslatableMessage or custom classes with a __toString() method.

Example in Symfony

useFeskol\Navigation\Link;
useFeskol\Navigation\Navigation;
useSymfony\Component\Translation\TranslatableMessage;
$navigation = newNavigation();
$navigation->setTitle(newTranslatableMessage('MyNavigation', [], 'navigation'));
$navLink = newLink();
$navLink->setTitle(newTranslatableMessage(
'Nav-Item for %customerName%',
['%customerName%' => $customer->getName()], // Dynamic translation parameters 'navigation'// Translation domain
));
$navigation->addLink($navLink);

And then in your Twig template:

{# @var \Feskol\Navigation\Navigation navigation #} Translated Navigation Title: {{ navigation.title|trans }} {% forlinkinnavigation.links %} Translated Link Title: {{ link.title|trans }} {% endfor %} 

Contribution Guidelines

We welcome contributions to this project! To ensure clarity and fairness for all contributors, we require that all contributors sign our Contributor License Agreement (CLA).

By signing the CLA, you confirm that:

  1. You grant us the perpetual, worldwide, non-exclusive, royalty-free, irrevocable right to use, modify, sublicense, and distribute your contribution as part of this project or any other project.
  2. You retain ownership of your contribution, but grant us the rights necessary to use it without restriction.
  3. Your contribution does not violate the rights of any third party.

How to Sign the CLA

Before submitting a pull request, please sign the CLA using the following link:
Sign the CLA

Contributions cannot be merged unless the CLA is signed.

Thank you for your contributions and for helping us build something great!

Testing

We're using phpunit.

Run tests:

php vendor/bin/phpunit

❤️ Support This Project

If you find this project helpful and would like to support my work:

  • 🌟 Star the repository to show your appreciation.
  • 💸 Donate via:
    • Buy Me a Coffe: Buy Me A Coffee
    • PayPal: PayPal

Thank you for your support!

About

A simple and effective Navigation to manage active states in navigation structures.

Topics

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

PHP-Navigation

GitHub ReleaseGitHub LicensePackagist Downloadscodecov

Overview

A simple and effective Navigation to manage active states in navigation structures.
For Symfony integration, check out the NavigationBundle.

Features

  • Automatically tracks a link's active status and makes it easy to check if a parent navigation item has active child links.
  • Easy to set up and integrate into existing projects.
  • Flexible and extensible for complex navigation structures.

Installation

Install via Composer:

composer require feskol/php-navigation

Usage

Building Your Navigation Structure

useFeskol\Navigation\Link;
useFeskol\Navigation\Navigation;
// create links$navLink = newLink();
$navLink->setTitle('Company')
->setHref('/company');
$subNavLink = newLink();
$subNavLink->setTitle('About us')
->setHref('/company/about-us')
->setIsActive(true);
// add the $subNavLink as $navLinks Child$navLink->addChild($subNavLink);
// To have all links in one place you can use the provided Navigation class:$navigation = newNavigation();
$navigation->setTitle('MyNavigation');
// add the created $navLink to the Navigation$navigation->addLink($navLink);

Iterating through Navigation links:

foreach ($navigation->getLinks() as$link){
echo$link->getTitle(); // "Company"echo$link->hasActiveChildren(); // "true" - because the child is activeforeach($link->getChildren() as$subLink){
echo$link->getTitle(); // "About us"echo$link->isActive(); // "true"
}
}

Common link data

The Link class provides setter and getter methods for the common attributes of an <a>-tag.
The most commonly used ones are href="" and target="":

useFeskol\Navigation\Link;
$link = newLink();
// href$link->setHref('/company/about-us');
$link->getHref(); // "/company/about-us"// target$link->setTarget(Link::TARGET_BLANK);
$link->getTarget(); // "_blank"

To view all available methods for the common link data, check out the AbsctractHyperLink class.

Additional Data

There are often situations where you need additional data for your navigation, such as icons or images.
The best approach is to create your own class (e.g. MyCustomLink) that extends the Link class:

useFeskol\Navigation\Link;
class MyCustomLink extends Link
{
private ?string$icon = null;
publicfunctiongetIcon(): ?string {
return$this->icon;
}
publicfunctionsetIcon(?string$icon): static {
$this->icon = $icon;
return$this;
}
}

Then use your MyCustomLink class instead of the Link class:

$link = newMyCustomLink();
$link->setTitle('Company')
->setHref('/company')
->setIcon('bi bi-user'); // For example, using Bootstrap-Icon classes

Handling translations in your frontend

Symfony

In Symfony, you can use the TranslatableMessage class to hold translation infos which you can use in your frontend.
In Twig, apply the |trans filter to translate the TranslatableMessage.

Both the Navigation and Link classes accept any object implementing the \Stringable interface in their setTitle() methods. This allows you to pass objects like TranslatableMessage or custom classes with a __toString() method.

Example in Symfony

useFeskol\Navigation\Link;
useFeskol\Navigation\Navigation;
useSymfony\Component\Translation\TranslatableMessage;
$navigation = newNavigation();
$navigation->setTitle(newTranslatableMessage('MyNavigation', [], 'navigation'));
$navLink = newLink();
$navLink->setTitle(newTranslatableMessage(
'Nav-Item for %customerName%',
['%customerName%' => $customer->getName()], // Dynamic translation parameters 'navigation'// Translation domain
));
$navigation->addLink($navLink);

And then in your Twig template:

{# @var \Feskol\Navigation\Navigation navigation #} Translated Navigation Title: {{ navigation.title|trans }} {% forlinkinnavigation.links %} Translated Link Title: {{ link.title|trans }} {% endfor %} 

Contribution Guidelines

We welcome contributions to this project! To ensure clarity and fairness for all contributors, we require that all contributors sign our Contributor License Agreement (CLA).

By signing the CLA, you confirm that:

  1. You grant us the perpetual, worldwide, non-exclusive, royalty-free, irrevocable right to use, modify, sublicense, and distribute your contribution as part of this project or any other project.
  2. You retain ownership of your contribution, but grant us the rights necessary to use it without restriction.
  3. Your contribution does not violate the rights of any third party.

How to Sign the CLA

Before submitting a pull request, please sign the CLA using the following link:
Sign the CLA

Contributions cannot be merged unless the CLA is signed.

Thank you for your contributions and for helping us build something great!

Testing

We're using phpunit.

Run tests:

php vendor/bin/phpunit

❤️ Support This Project

If you find this project helpful and would like to support my work:

  • 🌟 Star the repository to show your appreciation.
  • 💸 Donate via:
    • Buy Me a Coffe: Buy Me A Coffee
    • PayPal: PayPal

Thank you for your support!

About

A simple and effective Navigation to manage active states in navigation structures.

Topics

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

PHP-Navigation

GitHub ReleaseGitHub LicensePackagist Downloadscodecov

Overview

A simple and effective Navigation to manage active states in navigation structures.
For Symfony integration, check out the NavigationBundle.

Features

  • Automatically tracks a link's active status and makes it easy to check if a parent navigation item has active child links.
  • Easy to set up and integrate into existing projects.
  • Flexible and extensible for complex navigation structures.

Installation

Install via Composer:

composer require feskol/php-navigation

Usage

Building Your Navigation Structure

useFeskol\Navigation\Link;
useFeskol\Navigation\Navigation;
// create links$navLink = newLink();
$navLink->setTitle('Company')
->setHref('/company');
$subNavLink = newLink();
$subNavLink->setTitle('About us')
->setHref('/company/about-us')
->setIsActive(true);
// add the $subNavLink as $navLinks Child$navLink->addChild($subNavLink);
// To have all links in one place you can use the provided Navigation class:$navigation = newNavigation();
$navigation->setTitle('MyNavigation');
// add the created $navLink to the Navigation$navigation->addLink($navLink);

Iterating through Navigation links:

foreach ($navigation->getLinks() as$link){
echo$link->getTitle(); // "Company"echo$link->hasActiveChildren(); // "true" - because the child is activeforeach($link->getChildren() as$subLink){
echo$link->getTitle(); // "About us"echo$link->isActive(); // "true"
}
}

Common link data

The Link class provides setter and getter methods for the common attributes of an <a>-tag.
The most commonly used ones are href="" and target="":

useFeskol\Navigation\Link;
$link = newLink();
// href$link->setHref('/company/about-us');
$link->getHref(); // "/company/about-us"// target$link->setTarget(Link::TARGET_BLANK);
$link->getTarget(); // "_blank"

To view all available methods for the common link data, check out the AbsctractHyperLink class.

Additional Data

There are often situations where you need additional data for your navigation, such as icons or images.
The best approach is to create your own class (e.g. MyCustomLink) that extends the Link class:

useFeskol\Navigation\Link;
class MyCustomLink extends Link
{
private ?string$icon = null;
publicfunctiongetIcon(): ?string {
return$this->icon;
}
publicfunctionsetIcon(?string$icon): static {
$this->icon = $icon;
return$this;
}
}

Then use your MyCustomLink class instead of the Link class:

$link = newMyCustomLink();
$link->setTitle('Company')
->setHref('/company')
->setIcon('bi bi-user'); // For example, using Bootstrap-Icon classes

Handling translations in your frontend

Symfony

In Symfony, you can use the TranslatableMessage class to hold translation infos which you can use in your frontend.
In Twig, apply the |trans filter to translate the TranslatableMessage.

Both the Navigation and Link classes accept any object implementing the \Stringable interface in their setTitle() methods. This allows you to pass objects like TranslatableMessage or custom classes with a __toString() method.

Example in Symfony

useFeskol\Navigation\Link;
useFeskol\Navigation\Navigation;
useSymfony\Component\Translation\TranslatableMessage;
$navigation = newNavigation();
$navigation->setTitle(newTranslatableMessage('MyNavigation', [], 'navigation'));
$navLink = newLink();
$navLink->setTitle(newTranslatableMessage(
'Nav-Item for %customerName%',
['%customerName%' => $customer->getName()], // Dynamic translation parameters 'navigation'// Translation domain
));
$navigation->addLink($navLink);

And then in your Twig template:

{# @var \Feskol\Navigation\Navigation navigation #} Translated Navigation Title: {{ navigation.title|trans }} {% forlinkinnavigation.links %} Translated Link Title: {{ link.title|trans }} {% endfor %} 

Contribution Guidelines

We welcome contributions to this project! To ensure clarity and fairness for all contributors, we require that all contributors sign our Contributor License Agreement (CLA).

By signing the CLA, you confirm that:

  1. You grant us the perpetual, worldwide, non-exclusive, royalty-free, irrevocable right to use, modify, sublicense, and distribute your contribution as part of this project or any other project.
  2. You retain ownership of your contribution, but grant us the rights necessary to use it without restriction.
  3. Your contribution does not violate the rights of any third party.

How to Sign the CLA

Before submitting a pull request, please sign the CLA using the following link:
Sign the CLA

Contributions cannot be merged unless the CLA is signed.

Thank you for your contributions and for helping us build something great!

Testing

We're using phpunit.

Run tests:

php vendor/bin/phpunit

❤️ Support This Project

If you find this project helpful and would like to support my work:

  • 🌟 Star the repository to show your appreciation.
  • 💸 Donate via:
    • Buy Me a Coffe: Buy Me A Coffee
    • PayPal: PayPal

Thank you for your support!

About

A simple and effective Navigation to manage active states in navigation structures.

Topics

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

PHP-Navigation

GitHub ReleaseGitHub LicensePackagist Downloadscodecov

Overview

A simple and effective Navigation to manage active states in navigation structures.
For Symfony integration, check out the NavigationBundle.

Features

  • Automatically tracks a link's active status and makes it easy to check if a parent navigation item has active child links.
  • Easy to set up and integrate into existing projects.
  • Flexible and extensible for complex navigation structures.

Installation

Install via Composer:

composer require feskol/php-navigation

Usage

Building Your Navigation Structure

useFeskol\Navigation\Link;
useFeskol\Navigation\Navigation;
// create links$navLink = newLink();
$navLink->setTitle('Company')
->setHref('/company');
$subNavLink = newLink();
$subNavLink->setTitle('About us')
->setHref('/company/about-us')
->setIsActive(true);
// add the $subNavLink as $navLinks Child$navLink->addChild($subNavLink);
// To have all links in one place you can use the provided Navigation class:$navigation = newNavigation();
$navigation->setTitle('MyNavigation');
// add the created $navLink to the Navigation$navigation->addLink($navLink);

Iterating through Navigation links:

foreach ($navigation->getLinks() as$link){
echo$link->getTitle(); // "Company"echo$link->hasActiveChildren(); // "true" - because the child is activeforeach($link->getChildren() as$subLink){
echo$link->getTitle(); // "About us"echo$link->isActive(); // "true"
}
}

Common link data

The Link class provides setter and getter methods for the common attributes of an <a>-tag.
The most commonly used ones are href="" and target="":

useFeskol\Navigation\Link;
$link = newLink();
// href$link->setHref('/company/about-us');
$link->getHref(); // "/company/about-us"// target$link->setTarget(Link::TARGET_BLANK);
$link->getTarget(); // "_blank"

To view all available methods for the common link data, check out the AbsctractHyperLink class.

Additional Data

There are often situations where you need additional data for your navigation, such as icons or images.
The best approach is to create your own class (e.g. MyCustomLink) that extends the Link class:

useFeskol\Navigation\Link;
class MyCustomLink extends Link
{
private ?string$icon = null;
publicfunctiongetIcon(): ?string {
return$this->icon;
}
publicfunctionsetIcon(?string$icon): static {
$this->icon = $icon;
return$this;
}
}

Then use your MyCustomLink class instead of the Link class:

$link = newMyCustomLink();
$link->setTitle('Company')
->setHref('/company')
->setIcon('bi bi-user'); // For example, using Bootstrap-Icon classes

Handling translations in your frontend

Symfony

In Symfony, you can use the TranslatableMessage class to hold translation infos which you can use in your frontend.
In Twig, apply the |trans filter to translate the TranslatableMessage.

Both the Navigation and Link classes accept any object implementing the \Stringable interface in their setTitle() methods. This allows you to pass objects like TranslatableMessage or custom classes with a __toString() method.

Example in Symfony

useFeskol\Navigation\Link;
useFeskol\Navigation\Navigation;
useSymfony\Component\Translation\TranslatableMessage;
$navigation = newNavigation();
$navigation->setTitle(newTranslatableMessage('MyNavigation', [], 'navigation'));
$navLink = newLink();
$navLink->setTitle(newTranslatableMessage(
'Nav-Item for %customerName%',
['%customerName%' => $customer->getName()], // Dynamic translation parameters 'navigation'// Translation domain
));
$navigation->addLink($navLink);

And then in your Twig template:

{# @var \Feskol\Navigation\Navigation navigation #} Translated Navigation Title: {{ navigation.title|trans }} {% forlinkinnavigation.links %} Translated Link Title: {{ link.title|trans }} {% endfor %} 

Contribution Guidelines

We welcome contributions to this project! To ensure clarity and fairness for all contributors, we require that all contributors sign our Contributor License Agreement (CLA).

By signing the CLA, you confirm that:

  1. You grant us the perpetual, worldwide, non-exclusive, royalty-free, irrevocable right to use, modify, sublicense, and distribute your contribution as part of this project or any other project.
  2. You retain ownership of your contribution, but grant us the rights necessary to use it without restriction.
  3. Your contribution does not violate the rights of any third party.

How to Sign the CLA

Before submitting a pull request, please sign the CLA using the following link:
Sign the CLA

Contributions cannot be merged unless the CLA is signed.

Thank you for your contributions and for helping us build something great!

Testing

We're using phpunit.

Run tests:

php vendor/bin/phpunit

❤️ Support This Project

If you find this project helpful and would like to support my work:

  • 🌟 Star the repository to show your appreciation.
  • 💸 Donate via:
    • Buy Me a Coffe: Buy Me A Coffee
    • PayPal: PayPal

Thank you for your support!

About

A simple and effective Navigation to manage active states in navigation structures.

Topics

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

PHP-Navigation

GitHub ReleaseGitHub LicensePackagist Downloadscodecov

Overview

A simple and effective Navigation to manage active states in navigation structures.
For Symfony integration, check out the NavigationBundle.

Features

  • Automatically tracks a link's active status and makes it easy to check if a parent navigation item has active child links.
  • Easy to set up and integrate into existing projects.
  • Flexible and extensible for complex navigation structures.

Installation

Install via Composer:

composer require feskol/php-navigation

Usage

Building Your Navigation Structure

useFeskol\Navigation\Link;
useFeskol\Navigation\Navigation;
// create links$navLink = newLink();
$navLink->setTitle('Company')
->setHref('/company');
$subNavLink = newLink();
$subNavLink->setTitle('About us')
->setHref('/company/about-us')
->setIsActive(true);
// add the $subNavLink as $navLinks Child$navLink->addChild($subNavLink);
// To have all links in one place you can use the provided Navigation class:$navigation = newNavigation();
$navigation->setTitle('MyNavigation');
// add the created $navLink to the Navigation$navigation->addLink($navLink);

Iterating through Navigation links:

foreach ($navigation->getLinks() as$link){
echo$link->getTitle(); // "Company"echo$link->hasActiveChildren(); // "true" - because the child is activeforeach($link->getChildren() as$subLink){
echo$link->getTitle(); // "About us"echo$link->isActive(); // "true"
}
}

Common link data

The Link class provides setter and getter methods for the common attributes of an <a>-tag.
The most commonly used ones are href="" and target="":

useFeskol\Navigation\Link;
$link = newLink();
// href$link->setHref('/company/about-us');
$link->getHref(); // "/company/about-us"// target$link->setTarget(Link::TARGET_BLANK);
$link->getTarget(); // "_blank"

To view all available methods for the common link data, check out the AbsctractHyperLink class.

Additional Data

There are often situations where you need additional data for your navigation, such as icons or images.
The best approach is to create your own class (e.g. MyCustomLink) that extends the Link class:

useFeskol\Navigation\Link;
class MyCustomLink extends Link
{
private ?string$icon = null;
publicfunctiongetIcon(): ?string {
return$this->icon;
}
publicfunctionsetIcon(?string$icon): static {
$this->icon = $icon;
return$this;
}
}

Then use your MyCustomLink class instead of the Link class:

$link = newMyCustomLink();
$link->setTitle('Company')
->setHref('/company')
->setIcon('bi bi-user'); // For example, using Bootstrap-Icon classes

Handling translations in your frontend

Symfony

In Symfony, you can use the TranslatableMessage class to hold translation infos which you can use in your frontend.
In Twig, apply the |trans filter to translate the TranslatableMessage.

Both the Navigation and Link classes accept any object implementing the \Stringable interface in their setTitle() methods. This allows you to pass objects like TranslatableMessage or custom classes with a __toString() method.

Example in Symfony

useFeskol\Navigation\Link;
useFeskol\Navigation\Navigation;
useSymfony\Component\Translation\TranslatableMessage;
$navigation = newNavigation();
$navigation->setTitle(newTranslatableMessage('MyNavigation', [], 'navigation'));
$navLink = newLink();
$navLink->setTitle(newTranslatableMessage(
'Nav-Item for %customerName%',
['%customerName%' => $customer->getName()], // Dynamic translation parameters 'navigation'// Translation domain
));
$navigation->addLink($navLink);

And then in your Twig template:

{# @var \Feskol\Navigation\Navigation navigation #} Translated Navigation Title: {{ navigation.title|trans }} {% forlinkinnavigation.links %} Translated Link Title: {{ link.title|trans }} {% endfor %} 

Contribution Guidelines

We welcome contributions to this project! To ensure clarity and fairness for all contributors, we require that all contributors sign our Contributor License Agreement (CLA).

By signing the CLA, you confirm that:

  1. You grant us the perpetual, worldwide, non-exclusive, royalty-free, irrevocable right to use, modify, sublicense, and distribute your contribution as part of this project or any other project.
  2. You retain ownership of your contribution, but grant us the rights necessary to use it without restriction.
  3. Your contribution does not violate the rights of any third party.

How to Sign the CLA

Before submitting a pull request, please sign the CLA using the following link:
Sign the CLA

Contributions cannot be merged unless the CLA is signed.

Thank you for your contributions and for helping us build something great!

Testing

We're using phpunit.

Run tests:

php vendor/bin/phpunit

❤️ Support This Project

If you find this project helpful and would like to support my work:

  • 🌟 Star the repository to show your appreciation.
  • 💸 Donate via:
    • Buy Me a Coffe: Buy Me A Coffee
    • PayPal: PayPal

Thank you for your support!

About

A simple and effective Navigation to manage active states in navigation structures.

Topics

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

PHP-Navigation

GitHub ReleaseGitHub LicensePackagist Downloadscodecov

Overview

A simple and effective Navigation to manage active states in navigation structures.
For Symfony integration, check out the NavigationBundle.

Features

  • Automatically tracks a link's active status and makes it easy to check if a parent navigation item has active child links.
  • Easy to set up and integrate into existing projects.
  • Flexible and extensible for complex navigation structures.

Installation

Install via Composer:

composer require feskol/php-navigation

Usage

Building Your Navigation Structure

useFeskol\Navigation\Link;
useFeskol\Navigation\Navigation;
// create links$navLink = newLink();
$navLink->setTitle('Company')
->setHref('/company');
$subNavLink = newLink();
$subNavLink->setTitle('About us')
->setHref('/company/about-us')
->setIsActive(true);
// add the $subNavLink as $navLinks Child$navLink->addChild($subNavLink);
// To have all links in one place you can use the provided Navigation class:$navigation = newNavigation();
$navigation->setTitle('MyNavigation');
// add the created $navLink to the Navigation$navigation->addLink($navLink);

Iterating through Navigation links:

foreach ($navigation->getLinks() as$link){
echo$link->getTitle(); // "Company"echo$link->hasActiveChildren(); // "true" - because the child is activeforeach($link->getChildren() as$subLink){
echo$link->getTitle(); // "About us"echo$link->isActive(); // "true"
}
}

Common link data

The Link class provides setter and getter methods for the common attributes of an <a>-tag.
The most commonly used ones are href="" and target="":

useFeskol\Navigation\Link;
$link = newLink();
// href$link->setHref('/company/about-us');
$link->getHref(); // "/company/about-us"// target$link->setTarget(Link::TARGET_BLANK);
$link->getTarget(); // "_blank"

To view all available methods for the common link data, check out the AbsctractHyperLink class.

Additional Data

There are often situations where you need additional data for your navigation, such as icons or images.
The best approach is to create your own class (e.g. MyCustomLink) that extends the Link class:

useFeskol\Navigation\Link;
class MyCustomLink extends Link
{
private ?string$icon = null;
publicfunctiongetIcon(): ?string {
return$this->icon;
}
publicfunctionsetIcon(?string$icon): static {
$this->icon = $icon;
return$this;
}
}

Then use your MyCustomLink class instead of the Link class:

$link = newMyCustomLink();
$link->setTitle('Company')
->setHref('/company')
->setIcon('bi bi-user'); // For example, using Bootstrap-Icon classes

Handling translations in your frontend

Symfony

In Symfony, you can use the TranslatableMessage class to hold translation infos which you can use in your frontend.
In Twig, apply the |trans filter to translate the TranslatableMessage.

Both the Navigation and Link classes accept any object implementing the \Stringable interface in their setTitle() methods. This allows you to pass objects like TranslatableMessage or custom classes with a __toString() method.

Example in Symfony

useFeskol\Navigation\Link;
useFeskol\Navigation\Navigation;
useSymfony\Component\Translation\TranslatableMessage;
$navigation = newNavigation();
$navigation->setTitle(newTranslatableMessage('MyNavigation', [], 'navigation'));
$navLink = newLink();
$navLink->setTitle(newTranslatableMessage(
'Nav-Item for %customerName%',
['%customerName%' => $customer->getName()], // Dynamic translation parameters 'navigation'// Translation domain
));
$navigation->addLink($navLink);

And then in your Twig template:

{# @var \Feskol\Navigation\Navigation navigation #} Translated Navigation Title: {{ navigation.title|trans }} {% forlinkinnavigation.links %} Translated Link Title: {{ link.title|trans }} {% endfor %} 

Contribution Guidelines

We welcome contributions to this project! To ensure clarity and fairness for all contributors, we require that all contributors sign our Contributor License Agreement (CLA).

By signing the CLA, you confirm that:

  1. You grant us the perpetual, worldwide, non-exclusive, royalty-free, irrevocable right to use, modify, sublicense, and distribute your contribution as part of this project or any other project.
  2. You retain ownership of your contribution, but grant us the rights necessary to use it without restriction.
  3. Your contribution does not violate the rights of any third party.

How to Sign the CLA

Before submitting a pull request, please sign the CLA using the following link:
Sign the CLA

Contributions cannot be merged unless the CLA is signed.

Thank you for your contributions and for helping us build something great!

Testing

We're using phpunit.

Run tests:

php vendor/bin/phpunit

❤️ Support This Project

If you find this project helpful and would like to support my work:

  • 🌟 Star the repository to show your appreciation.
  • 💸 Donate via:
    • Buy Me a Coffe: Buy Me A Coffee
    • PayPal: PayPal

Thank you for your support!

About

A simple and effective Navigation to manage active states in navigation structures.

Topics

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

PHP-Navigation

GitHub ReleaseGitHub LicensePackagist Downloadscodecov

Overview

A simple and effective Navigation to manage active states in navigation structures.
For Symfony integration, check out the NavigationBundle.

Features

  • Automatically tracks a link's active status and makes it easy to check if a parent navigation item has active child links.
  • Easy to set up and integrate into existing projects.
  • Flexible and extensible for complex navigation structures.

Installation

Install via Composer:

composer require feskol/php-navigation

Usage

Building Your Navigation Structure

useFeskol\Navigation\Link;
useFeskol\Navigation\Navigation;
// create links$navLink = newLink();
$navLink->setTitle('Company')
->setHref('/company');
$subNavLink = newLink();
$subNavLink->setTitle('About us')
->setHref('/company/about-us')
->setIsActive(true);
// add the $subNavLink as $navLinks Child$navLink->addChild($subNavLink);
// To have all links in one place you can use the provided Navigation class:$navigation = newNavigation();
$navigation->setTitle('MyNavigation');
// add the created $navLink to the Navigation$navigation->addLink($navLink);

Iterating through Navigation links:

foreach ($navigation->getLinks() as$link){
echo$link->getTitle(); // "Company"echo$link->hasActiveChildren(); // "true" - because the child is activeforeach($link->getChildren() as$subLink){
echo$link->getTitle(); // "About us"echo$link->isActive(); // "true"
}
}

Common link data

The Link class provides setter and getter methods for the common attributes of an <a>-tag.
The most commonly used ones are href="" and target="":

useFeskol\Navigation\Link;
$link = newLink();
// href$link->setHref('/company/about-us');
$link->getHref(); // "/company/about-us"// target$link->setTarget(Link::TARGET_BLANK);
$link->getTarget(); // "_blank"

To view all available methods for the common link data, check out the AbsctractHyperLink class.

Additional Data

There are often situations where you need additional data for your navigation, such as icons or images.
The best approach is to create your own class (e.g. MyCustomLink) that extends the Link class:

useFeskol\Navigation\Link;
class MyCustomLink extends Link
{
private ?string$icon = null;
publicfunctiongetIcon(): ?string {
return$this->icon;
}
publicfunctionsetIcon(?string$icon): static {
$this->icon = $icon;
return$this;
}
}

Then use your MyCustomLink class instead of the Link class:

$link = newMyCustomLink();
$link->setTitle('Company')
->setHref('/company')
->setIcon('bi bi-user'); // For example, using Bootstrap-Icon classes

Handling translations in your frontend

Symfony

In Symfony, you can use the TranslatableMessage class to hold translation infos which you can use in your frontend.
In Twig, apply the |trans filter to translate the TranslatableMessage.

Both the Navigation and Link classes accept any object implementing the \Stringable interface in their setTitle() methods. This allows you to pass objects like TranslatableMessage or custom classes with a __toString() method.

Example in Symfony

useFeskol\Navigation\Link;
useFeskol\Navigation\Navigation;
useSymfony\Component\Translation\TranslatableMessage;
$navigation = newNavigation();
$navigation->setTitle(newTranslatableMessage('MyNavigation', [], 'navigation'));
$navLink = newLink();
$navLink->setTitle(newTranslatableMessage(
'Nav-Item for %customerName%',
['%customerName%' => $customer->getName()], // Dynamic translation parameters 'navigation'// Translation domain
));
$navigation->addLink($navLink);

And then in your Twig template:

{# @var \Feskol\Navigation\Navigation navigation #} Translated Navigation Title: {{ navigation.title|trans }} {% forlinkinnavigation.links %} Translated Link Title: {{ link.title|trans }} {% endfor %} 

Contribution Guidelines

We welcome contributions to this project! To ensure clarity and fairness for all contributors, we require that all contributors sign our Contributor License Agreement (CLA).

By signing the CLA, you confirm that:

  1. You grant us the perpetual, worldwide, non-exclusive, royalty-free, irrevocable right to use, modify, sublicense, and distribute your contribution as part of this project or any other project.
  2. You retain ownership of your contribution, but grant us the rights necessary to use it without restriction.
  3. Your contribution does not violate the rights of any third party.

How to Sign the CLA

Before submitting a pull request, please sign the CLA using the following link:
Sign the CLA

Contributions cannot be merged unless the CLA is signed.

Thank you for your contributions and for helping us build something great!

Testing

We're using phpunit.

Run tests:

php vendor/bin/phpunit

❤️ Support This Project

If you find this project helpful and would like to support my work:

  • 🌟 Star the repository to show your appreciation.
  • 💸 Donate via:
    • Buy Me a Coffe: Buy Me A Coffee
    • PayPal: PayPal

Thank you for your support!

About

A simple and effective Navigation to manage active states in navigation structures.

Topics

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Contributors

Languages