diff --git a/.changeset/proud-wasps-travel.md b/.changeset/proud-wasps-travel.md
new file mode 100644
index 0000000000..4df118858f
--- /dev/null
+++ b/.changeset/proud-wasps-travel.md
@@ -0,0 +1,10 @@
+---
+"@stackoverflow/stacks": patch
+"@stackoverflow/stacks-svelte": patch
+---
+
+fix(navigation): make vertical navigation more accessible
+
+BREAKING CHANGES:
+* Navigation markup has been updated
+* Svelte NavigationTitle component has been renamed to NavigationGroup
diff --git a/packages/stacks-classic/lib/components/navigation/navigation.a11y.test.ts b/packages/stacks-classic/lib/components/navigation/navigation.a11y.test.ts
index 23af1a8741..eb92922df2 100644
--- a/packages/stacks-classic/lib/components/navigation/navigation.a11y.test.ts
+++ b/packages/stacks-classic/lib/components/navigation/navigation.a11y.test.ts
@@ -2,7 +2,14 @@ import { html } from "@open-wc/testing";
import { runA11yTests } from "../../test/a11y-test-utils";
import "../../index";
-const items = [
+interface NavigationItem {
+ label: string;
+ title?: boolean;
+ selected?: boolean;
+ dropdown?: boolean;
+}
+
+const items: NavigationItem[] = [
{
label: "Group 1",
title: true,
@@ -38,20 +45,43 @@ const items = [
},
];
-const getChildren = (includeTitles = false): string =>
- items
- .map((item) => {
+const getChildren = (includeTitles = false): string => {
+ const getClasses = function (item: NavigationItem) {
+ return `s-navigation--item${
+ item.selected ? " is-selected" : ""
+ }${item.dropdown ? " s-navigation--item__dropdown" : ""}`;
+ };
+
+ if (!includeTitles) {
+ return items
+ .map((item) => {
+ if (item.title) {
+ return ""; //don't print title
+ }
+ return `
${item.label}`;
+ })
+ .join("");
+ } else {
+ //Vertical nav
+ let html = "";
+ for (const item of items) {
if (item.title) {
- return includeTitles
- ? `${item.label}`
- : "";
+ if (html.length > 0) {
+ html += "";
+ }
+ const groupName = item.label.replace(" ", "");
+ html += `
+ ${item.label}
+
+ `;
+ } else {
+ html += `- ${item.label}
`;
}
- const classes = `s-navigation--item${
- item.selected ? " is-selected" : ""
- }${item.dropdown ? " s-navigation--item__dropdown" : ""}`;
- return `- ${item.label}
`;
- })
- .join("");
+ }
+ html += "
";
+ return html;
+ }
+};
describe("navigation", () => {
runA11yTests({
diff --git a/packages/stacks-classic/lib/components/navigation/navigation.less b/packages/stacks-classic/lib/components/navigation/navigation.less
index 24e07ad0d2..2bfcb816c8 100644
--- a/packages/stacks-classic/lib/components/navigation/navigation.less
+++ b/packages/stacks-classic/lib/components/navigation/navigation.less
@@ -1,4 +1,5 @@
-.s-navigation {
+.s-navigation,
+.s-navigation ul {
--_na-fd: row;
--_na-fw: wrap;
--_na-p: var(--su2) 0;
@@ -15,7 +16,6 @@
--_na-item-selected-bg-hover: var(--_na-item-bg-hover);
--_na-item-selected-h: var(--su2);
--_na-item-text-ta: center;
- --_na-title-mt: var(--su24);
--_na-after-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M11.35 4.35 6 9.71.65 4.35l.7-.7L6 8.29l4.65-4.64z'/%3E%3C/svg%3E");
--_na-after-bg-color: var(--black-400);
@@ -42,7 +42,8 @@
--_na-item-p: var(--su6) var(--su4);
}
- &&__vertical {
+ &&__vertical,
+ &&__vertical ul {
--_na-fd: column;
--_na-gap: 0;
--_na-p: 0;
@@ -51,6 +52,7 @@
--_na-item-selected-h: 0;
--_na-item-p: var(--su6) var(--su8);
--_na-item-fc: var(--black-600);
+
& .s-navigation--item {
&.is-selected {
--_na-item-bg: var(--black-150);
@@ -151,20 +153,22 @@
}
& &--title {
- &:first-child {
- --_na-title-mt: 0;
- }
-
& .s-btn {
color: var(--black-400);
}
- margin-top: var(--_na-title-mt);
+ margin-bottom: 0;
font-size: var(--fs-fine);
+ font-weight: normal;
color: var(--black-400);
padding: calc(var(--su16) + var(--su2)) var(--su8);
}
+ //Add top margin to titles except the first one
+ & > li ~ li .s-navigation--title {
+ margin-top: var(--su24);
+ }
+
& &--icon {
color: inherit;
margin-right: var(--su4);
diff --git a/packages/stacks-classic/lib/components/navigation/navigation.visual.test.ts b/packages/stacks-classic/lib/components/navigation/navigation.visual.test.ts
index 38285937e3..3d0520e54c 100644
--- a/packages/stacks-classic/lib/components/navigation/navigation.visual.test.ts
+++ b/packages/stacks-classic/lib/components/navigation/navigation.visual.test.ts
@@ -9,7 +9,14 @@ const filledIcon = IconHomeFill.replace(
'class="s-navigation--icon '
);
-const items = [
+interface NavigationItem {
+ label: string;
+ title?: boolean;
+ selected?: boolean;
+ dropdown?: boolean;
+}
+
+const items: NavigationItem[] = [
{
label: "Group 1",
title: true,
@@ -45,25 +52,47 @@ const items = [
},
];
-const getChildren = (includeTitles = false, includeIcons = false): string =>
- items
- .map((item) => {
+const getChildren = (includeTitles = false, includeIcons = false): string => {
+ const getClasses = function (item: NavigationItem) {
+ return `s-navigation--item${
+ item.selected ? " is-selected" : ""
+ }${item.dropdown ? " s-navigation--item__dropdown" : ""}`;
+ };
+
+ const getIcon = function (item: NavigationItem) {
+ return includeIcons ? (item.selected ? filledIcon : outlineIcon) : "";
+ };
+
+ if (!includeTitles) {
+ return items
+ .map((item) => {
+ if (item.title) {
+ return ""; //don't print title
+ }
+ return `${getIcon(item)}${item.label}`;
+ })
+ .join("");
+ } else {
+ //Vertical nav
+ let html = "";
+ for (const item of items) {
if (item.title) {
- return includeTitles
- ? `${item.label}`
- : "";
+ if (html.length > 0) {
+ html += "";
+ }
+ const groupName = item.label.replace(" ", "");
+ html += `
+ ${item.label}
+
+ `;
+ } else {
+ html += `- ${getIcon(item)}${item.label}
`;
}
- const icon = includeIcons
- ? item.selected
- ? filledIcon
- : outlineIcon
- : "";
- const classes = `s-navigation--item${
- item.selected ? " is-selected" : ""
- }${item.dropdown ? " s-navigation--item__dropdown" : ""}`;
- return `- ${icon}${item.label}
`;
- })
- .join("");
+ }
+ html += "
";
+ return html;
+ }
+};
describe("navigation", () => {
runVisualTests({
diff --git a/packages/stacks-docs/_includes/layouts/home.html b/packages/stacks-docs/_includes/layouts/home.html
index 40e3194b91..46351c20bc 100644
--- a/packages/stacks-docs/_includes/layouts/home.html
+++ b/packages/stacks-docs/_includes/layouts/home.html
@@ -202,11 +202,11 @@ Stacks