aboutsummaryrefslogtreecommitdiffstats
path: root/src/components/Widgets/ToC
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/Widgets/ToC')
-rw-r--r--src/components/Widgets/ToC/ToC.module.scss70
-rw-r--r--src/components/Widgets/ToC/ToC.tsx30
2 files changed, 100 insertions, 0 deletions
diff --git a/src/components/Widgets/ToC/ToC.module.scss b/src/components/Widgets/ToC/ToC.module.scss
new file mode 100644
index 0000000..a296659
--- /dev/null
+++ b/src/components/Widgets/ToC/ToC.module.scss
@@ -0,0 +1,70 @@
+@use "@styles/abstracts/functions" as fun;
+@use "@styles/abstracts/mixins" as mix;
+
+.item {
+ width: 100%;
+ margin: 0;
+
+ &::before {
+ display: none;
+ }
+}
+
+.link {
+ display: flex;
+ flex-flow: row nowrap;
+ width: 100%;
+ padding: var(--spacing-2xs) var(--spacing-sm);
+ background: none;
+ border-bottom: fun.convert-px(1) solid var(--color-border-lighter);
+ text-decoration: underline solid transparent 0;
+ transition: all 0.16s ease-in-out 0s, text-decoration-color 0s;
+
+ &:hover,
+ &:focus {
+ background: var(--color-bg-secondary);
+ }
+
+ &:focus {
+ color: var(--color-primary);
+ text-decoration-color: var(--color-primary-light);
+ text-decoration-thickness: 0.25ex;
+ }
+
+ &:active {
+ background: var(--color-bg-tertiary);
+ text-decoration-color: transparent;
+ text-decoration-thickness: 0;
+ }
+}
+
+.list {
+ width: 100%;
+ margin: 0;
+ counter-reset: link;
+
+ @include mix.media("screen") {
+ @include mix.dimensions("lg") {
+ font-size: var(--font-size-sm);
+ font-weight: 500;
+ }
+ }
+
+ > .item .link {
+ counter-increment: link;
+
+ &::before {
+ content: counters(link, ".") ". ";
+ color: var(--color-secondary);
+ padding-right: var(--spacing-2xs);
+ }
+ }
+
+ .item .item .link::before {
+ padding-left: var(--spacing-sm);
+ }
+
+ .item .item .item .link::before {
+ padding-left: var(--spacing-lg);
+ }
+}
diff --git a/src/components/Widgets/ToC/ToC.tsx b/src/components/Widgets/ToC/ToC.tsx
new file mode 100644
index 0000000..6010354
--- /dev/null
+++ b/src/components/Widgets/ToC/ToC.tsx
@@ -0,0 +1,30 @@
+import { ExpandableWidget, OrderedList } from '@components/WidgetParts';
+import { t } from '@lingui/macro';
+import { Heading } from '@ts/types/app';
+import useHeadingsTree from '@utils/hooks/useHeadingsTree';
+
+const ToC = () => {
+ const headingsTree = useHeadingsTree('article');
+ const title = t`Table of contents`;
+
+ const getItems = (headings: Heading[]) => {
+ return headings.map((heading) => {
+ return (
+ <li key={heading.id}>
+ <a href={`#${heading.id}`}>{heading.title}</a>
+ {heading.children.length > 0 && (
+ <OrderedList items={getItems(heading.children)} />
+ )}
+ </li>
+ );
+ });
+ };
+
+ return (
+ <ExpandableWidget title={title} expand={true} withBorders={true}>
+ <OrderedList items={getItems(headingsTree)} />
+ </ExpandableWidget>
+ );
+};
+
+export default ToC;