The best solution is to use a recursive function, you can have as many deep levels as you want without modifying the code and adding new code
In your "article/article-toc" partial - the name you want
===============================
{% macro render_toc(categories, activeSlug) %}
{% for category in categories %}
{% if category.is_enabled %}
{% set hasChildren = category.children %}
{% set isActive = category.slug == activeSlug %}
<li class="{{ hasChildren ? 'collapsible' }} {{ isActive ? 'active' }}">
<a href="{{ 'your_page'|page({ slug: category.slug }) }}" class="label">{{ category.title }}</a>
{% if hasChildren %}
<ul id="tocItem{{ category.id }}" class="collapse {{ isActive ? 'show' }}">
{% if category.children %}
{{ _self.render_toc(category.children, activeSlug) }}
{% endif %}
</ul>
{% endif %}
</li>
{% endif %}
{% endfor %}
{% endmacro %}
{% import _self as categoryMenuLinks %}
{{ categoryMenuLinks.render_toc(categories, activeSlug|default(this.param.slug|default('')))|trim }}
In your template file
==========================
Set partial programmically
{% set articleTOC = partial('article/article-toc',{ categories:blogCategories })|trim %}
Or basic way
{% partial "article/article-toc" categories=blogCategories %}