diff --git a/.vscode/settings.json b/.vscode/settings.json
index 94d854b..5470d32 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -13,7 +13,7 @@
"**/config/ci/**/caller.mk": "${dirname}.caller",
"**/config/ci/**/runner.ts": "${dirname}.runner",
// react-func pattern
- "**/src/**/func.tsx": "${dirname(-3)}.${dirname}.func",
+ "**/src/**/func.tsx": "${dirname}.func",
"**/src/**/styles.ts": "${dirname}.styles",
"**/src/**/stories.{ts,tsx}": "${dirname}.stories",
"**/src/**/index.ts": "${dirname}.module",
diff --git a/apps/frontend/ui/src/layout/partials/Sidebar/index.ts b/apps/frontend/ui/src/layout/partials/Sidebar/index.ts
deleted file mode 100644
index f2e757c..0000000
--- a/apps/frontend/ui/src/layout/partials/Sidebar/index.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-import Sidebar from "@app-ui/layout/partials/Sidebar/func";
-
-export default Sidebar;
diff --git a/apps/frontend/ui/src/layout/partials/Sidebar/shards/MenuList/index.ts b/apps/frontend/ui/src/layout/partials/Sidebar/shards/MenuList/index.ts
deleted file mode 100644
index 18089a9..0000000
--- a/apps/frontend/ui/src/layout/partials/Sidebar/shards/MenuList/index.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-import MenuList from "@app-ui/layout/partials/Sidebar/shards/MenuList/func";
-
-export default MenuList;
diff --git a/apps/frontend/ui/src/layout/partials/Sidebar/shards/MenuList/templates/Tab/index.ts b/apps/frontend/ui/src/layout/partials/Sidebar/shards/MenuList/templates/Tab/index.ts
deleted file mode 100644
index 71e4719..0000000
--- a/apps/frontend/ui/src/layout/partials/Sidebar/shards/MenuList/templates/Tab/index.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-import Tab from "@app-ui/layout/partials/Sidebar/shards/MenuList/templates/Tab/func";
-
-export default Tab;
diff --git a/apps/frontend/ui/src/layout/partials/Sidebar/shards/MenuList/templates/index.ts b/apps/frontend/ui/src/layout/partials/Sidebar/shards/MenuList/templates/index.ts
deleted file mode 100644
index d439ef7..0000000
--- a/apps/frontend/ui/src/layout/partials/Sidebar/shards/MenuList/templates/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export { default as TabTemplate } from "@app-ui/layout/partials/Sidebar/shards/MenuList/templates/Tab/func";
diff --git a/apps/frontend/ui/src/layout/partials/Sidebar/shards/ToggleButton/index.ts b/apps/frontend/ui/src/layout/partials/Sidebar/shards/ToggleButton/index.ts
deleted file mode 100644
index c8253a5..0000000
--- a/apps/frontend/ui/src/layout/partials/Sidebar/shards/ToggleButton/index.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-import ToggleButton from "@app-ui/layout/partials/Sidebar/shards/ToggleButton/func";
-
-export default ToggleButton;
diff --git a/apps/frontend/ui/src/layout/partials/Sidebar/shards/index.ts b/apps/frontend/ui/src/layout/partials/Sidebar/shards/index.ts
deleted file mode 100644
index c8a53c2..0000000
--- a/apps/frontend/ui/src/layout/partials/Sidebar/shards/index.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-export { default as MenuListShard } from "@app-ui/layout/partials/Sidebar/shards/MenuList";
-export { default as ToggleButtonShard } from "@app-ui/layout/partials/Sidebar/shards/ToggleButton";
diff --git a/apps/frontend/ui/src/layout/partials/index.ts b/apps/frontend/ui/src/layout/partials/index.ts
deleted file mode 100644
index c5249f9..0000000
--- a/apps/frontend/ui/src/layout/partials/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export { default as SidebarPartial } from "@app-ui/layout/partials/Sidebar";
diff --git a/apps/frontend/ui/src/layout/index.ts b/apps/frontend/ui/src/navigation/index.ts
similarity index 74%
rename from apps/frontend/ui/src/layout/index.ts
rename to apps/frontend/ui/src/navigation/index.ts
index 9637ffe..eeefd46 100644
--- a/apps/frontend/ui/src/layout/index.ts
+++ b/apps/frontend/ui/src/navigation/index.ts
@@ -1 +1 @@
-export { SidebarPartial as SidebarPartialLayout } from "@app-ui/layout/partials";
+export { SidebarPartial as SidebarPartialLayout } from "@app-ui/navigation/partials";
diff --git a/apps/frontend/ui/src/navigation/partials/BrowseMenu/constants.ts b/apps/frontend/ui/src/navigation/partials/BrowseMenu/constants.ts
new file mode 100644
index 0000000..290d95f
--- /dev/null
+++ b/apps/frontend/ui/src/navigation/partials/BrowseMenu/constants.ts
@@ -0,0 +1,8 @@
+export default {
+ testIdExpandButton: "expand-button",
+ testIdCatalogueTab: "catalogue-tab",
+ testIdConceptsTab: "concepts-tab",
+ testIdRandomTab: "random-tab",
+ testIdWordTab: "word-tab",
+ testIdFilterTab: "filter-tab",
+};
diff --git a/apps/frontend/ui/src/navigation/partials/BrowseMenu/func.tsx b/apps/frontend/ui/src/navigation/partials/BrowseMenu/func.tsx
new file mode 100644
index 0000000..69c715d
--- /dev/null
+++ b/apps/frontend/ui/src/navigation/partials/BrowseMenu/func.tsx
@@ -0,0 +1,61 @@
+import type { JSX } from "react";
+
+import { ChevronRightRegular, ChevronLeftRegular } from "@fluentui/react-icons";
+
+import { Flex, Button, Tooltip } from "@lib-components";
+import { LargeTitle } from "@lib-theme";
+
+import constants from "@app-ui/navigation/partials/BrowseMenu/constants";
+import type { TUiBrowseMenuOption } from "@app-ui/navigation/partials/BrowseMenu/types";
+
+import {
+ BrowseListShard,
+ BrowseToListConnectorShard,
+ ListToBrowseConnectorShard,
+} from "@app-ui/navigation/partials/BrowseMenu/shards";
+
+type TProps = {
+ currentSelection: TUiBrowseMenuOption;
+ setCurrentSelection: (selection: TUiBrowseMenuOption) => void;
+ isExpanded: boolean;
+ toggleExpand: () => void;
+ optionSlot: JSX.Element | null;
+};
+
+export default function BrowseMenu({
+ optionSlot,
+ currentSelection,
+ isExpanded,
+ setCurrentSelection,
+ toggleExpand,
+}: TProps): JSX.Element {
+ return (
+
+
+ Browse
+
+ : }
+ size="small"
+ onClick={toggleExpand}
+ />
+
+
+
+ {isExpanded && (
+
+ )}
+ {isExpanded && (
+
+ )}
+ {optionSlot}
+
+ );
+}
diff --git a/apps/frontend/ui/src/navigation/partials/BrowseMenu/index.ts b/apps/frontend/ui/src/navigation/partials/BrowseMenu/index.ts
new file mode 100644
index 0000000..c24d2a6
--- /dev/null
+++ b/apps/frontend/ui/src/navigation/partials/BrowseMenu/index.ts
@@ -0,0 +1,3 @@
+import BrowseMenu from "@app-ui/navigation/partials/BrowseMenu/func";
+
+export default BrowseMenu;
diff --git a/apps/frontend/ui/src/navigation/partials/BrowseMenu/shards/BrowseList/func.tsx b/apps/frontend/ui/src/navigation/partials/BrowseMenu/shards/BrowseList/func.tsx
new file mode 100644
index 0000000..758a480
--- /dev/null
+++ b/apps/frontend/ui/src/navigation/partials/BrowseMenu/shards/BrowseList/func.tsx
@@ -0,0 +1,55 @@
+import type { JSX } from "react";
+
+import { TabList } from "@lib-components";
+
+import type { TUiBrowseMenuOption } from "@app-ui/navigation/partials/BrowseMenu/types";
+import constants from "@app-ui/navigation/partials/BrowseMenu/constants";
+
+import useBrowseListClasses from "@app-ui/navigation/partials/BrowseMenu/shards/BrowseList/styles";
+import { TabTemplate } from "@app-ui/navigation/partials/BrowseMenu/shards/BrowseList/templates";
+
+type TProps = {
+ currentSelection: TUiBrowseMenuOption;
+ setCurrentSelection: (selection: TUiBrowseMenuOption) => void;
+};
+
+export default function BrowseList({
+ currentSelection,
+ setCurrentSelection,
+}: TProps): JSX.Element {
+ const classes = useBrowseListClasses();
+ return (
+
+
+
+
+
+
+
+ );
+}
diff --git a/apps/frontend/ui/src/navigation/partials/BrowseMenu/shards/BrowseList/index.ts b/apps/frontend/ui/src/navigation/partials/BrowseMenu/shards/BrowseList/index.ts
new file mode 100644
index 0000000..967ee27
--- /dev/null
+++ b/apps/frontend/ui/src/navigation/partials/BrowseMenu/shards/BrowseList/index.ts
@@ -0,0 +1,3 @@
+import BrowseList from "@app-ui/navigation/partials/BrowseMenu/shards/BrowseList/func";
+
+export default BrowseList;
diff --git a/apps/frontend/ui/src/navigation/partials/BrowseMenu/shards/BrowseList/styles.ts b/apps/frontend/ui/src/navigation/partials/BrowseMenu/shards/BrowseList/styles.ts
new file mode 100644
index 0000000..ce8ce0c
--- /dev/null
+++ b/apps/frontend/ui/src/navigation/partials/BrowseMenu/shards/BrowseList/styles.ts
@@ -0,0 +1,9 @@
+import { makeStyles, EThemeSpacing } from "@lib-theme";
+
+const useBrowseListClasses = makeStyles({
+ root: {
+ gap: EThemeSpacing.XXL,
+ },
+});
+
+export default useBrowseListClasses;
diff --git a/apps/frontend/ui/src/navigation/partials/BrowseMenu/shards/BrowseList/templates/Tab/func.tsx b/apps/frontend/ui/src/navigation/partials/BrowseMenu/shards/BrowseList/templates/Tab/func.tsx
new file mode 100644
index 0000000..88d4823
--- /dev/null
+++ b/apps/frontend/ui/src/navigation/partials/BrowseMenu/shards/BrowseList/templates/Tab/func.tsx
@@ -0,0 +1,32 @@
+import type { JSX } from "react";
+
+import { Tab as OriginalTab } from "@lib-components";
+
+import type { TUiBrowseMenuOption } from "@app-ui/navigation/partials/BrowseMenu/types";
+
+import useTabClasses from "@app-ui/navigation/partials/BrowseMenu/shards/BrowseList/templates/Tab/styles";
+
+type TProps = {
+ value: TUiBrowseMenuOption;
+ onClick: (value: TUiBrowseMenuOption) => void;
+ dataTestId: string;
+};
+
+export default function Tab({
+ value,
+ onClick,
+ dataTestId,
+}: TProps): JSX.Element {
+ const classes = useTabClasses();
+ return (
+ {
+ onClick(value);
+ }}
+ >
+ {value}
+
+ );
+}
diff --git a/apps/frontend/ui/src/navigation/partials/BrowseMenu/shards/BrowseList/templates/Tab/index.ts b/apps/frontend/ui/src/navigation/partials/BrowseMenu/shards/BrowseList/templates/Tab/index.ts
new file mode 100644
index 0000000..4948b42
--- /dev/null
+++ b/apps/frontend/ui/src/navigation/partials/BrowseMenu/shards/BrowseList/templates/Tab/index.ts
@@ -0,0 +1,3 @@
+import Tab from "@app-ui/navigation/partials/BrowseMenu/shards/BrowseList/templates/Tab/func";
+
+export default Tab;
diff --git a/apps/frontend/ui/src/navigation/partials/BrowseMenu/shards/BrowseList/templates/Tab/styles.ts b/apps/frontend/ui/src/navigation/partials/BrowseMenu/shards/BrowseList/templates/Tab/styles.ts
new file mode 100644
index 0000000..3b75859
--- /dev/null
+++ b/apps/frontend/ui/src/navigation/partials/BrowseMenu/shards/BrowseList/templates/Tab/styles.ts
@@ -0,0 +1,9 @@
+import { makeStyles, tokens } from "@lib-theme";
+
+const useTabClasses = makeStyles({
+ root: {
+ fontSize: tokens.fontSizeHero700,
+ },
+});
+
+export default useTabClasses;
diff --git a/apps/frontend/ui/src/navigation/partials/BrowseMenu/shards/BrowseList/templates/index.ts b/apps/frontend/ui/src/navigation/partials/BrowseMenu/shards/BrowseList/templates/index.ts
new file mode 100644
index 0000000..5708353
--- /dev/null
+++ b/apps/frontend/ui/src/navigation/partials/BrowseMenu/shards/BrowseList/templates/index.ts
@@ -0,0 +1 @@
+export { default as TabTemplate } from "@app-ui/navigation/partials/BrowseMenu/shards/BrowseList/templates/Tab";
diff --git a/apps/frontend/ui/src/navigation/partials/BrowseMenu/shards/BrowseToListConnector/func.tsx b/apps/frontend/ui/src/navigation/partials/BrowseMenu/shards/BrowseToListConnector/func.tsx
new file mode 100644
index 0000000..634d4b0
--- /dev/null
+++ b/apps/frontend/ui/src/navigation/partials/BrowseMenu/shards/BrowseToListConnector/func.tsx
@@ -0,0 +1,36 @@
+import type { JSX } from "react";
+
+import { Flex } from "@lib-components";
+
+import useBrowseToListConnectorClasses from "@app-ui/navigation/partials/BrowseMenu/shards/BrowseToListConnector/styles";
+
+type TProps = {
+ isExpanded: boolean;
+};
+
+export default function BrowseToListConnector({
+ isExpanded,
+}: TProps): JSX.Element {
+ const classes = useBrowseToListConnectorClasses();
+ return (
+
+
+ {isExpanded && (
+
+
+
+
+
+
+
+
+ )}
+
+ );
+}
diff --git a/apps/frontend/ui/src/navigation/partials/BrowseMenu/shards/BrowseToListConnector/index.ts b/apps/frontend/ui/src/navigation/partials/BrowseMenu/shards/BrowseToListConnector/index.ts
new file mode 100644
index 0000000..62e58c9
--- /dev/null
+++ b/apps/frontend/ui/src/navigation/partials/BrowseMenu/shards/BrowseToListConnector/index.ts
@@ -0,0 +1,3 @@
+import BrowseToListConnector from "@app-ui/navigation/partials/BrowseMenu/shards/BrowseToListConnector/func";
+
+export default BrowseToListConnector;
diff --git a/apps/frontend/ui/src/navigation/partials/BrowseMenu/shards/BrowseToListConnector/styles.ts b/apps/frontend/ui/src/navigation/partials/BrowseMenu/shards/BrowseToListConnector/styles.ts
new file mode 100644
index 0000000..e7c1b2d
--- /dev/null
+++ b/apps/frontend/ui/src/navigation/partials/BrowseMenu/shards/BrowseToListConnector/styles.ts
@@ -0,0 +1,24 @@
+import { makeStyles } from "@lib-theme";
+import shared from "@app-ui/navigation/partials/BrowseMenu/shared";
+
+const useBrowseToListConnectorClasses = makeStyles({
+ root: {
+ gap: shared.connectorGap,
+ },
+ connectorVertical: {
+ width: shared.connectorThickness,
+ backgroundColor: shared.connectorColor,
+ borderRadius: shared.connectorBorderRadius,
+ transform: "translateX(-24px)",
+ position: "absolute",
+ height: "100%",
+ },
+ connectorHorizontal: {
+ height: shared.connectorThickness,
+ backgroundColor: shared.connectorColor,
+ width: shared.connectorMinLength,
+ borderRadius: shared.connectorBorderRadius,
+ },
+});
+
+export default useBrowseToListConnectorClasses;
diff --git a/apps/frontend/ui/src/navigation/partials/BrowseMenu/shards/ListToBrowseConnector/func.tsx b/apps/frontend/ui/src/navigation/partials/BrowseMenu/shards/ListToBrowseConnector/func.tsx
new file mode 100644
index 0000000..c858a3b
--- /dev/null
+++ b/apps/frontend/ui/src/navigation/partials/BrowseMenu/shards/ListToBrowseConnector/func.tsx
@@ -0,0 +1,93 @@
+import type { JSX } from "react";
+
+import { Flex } from "@lib-components";
+import { mergeClasses } from "@lib-theme";
+
+import type { TUiBrowseMenuOption } from "@app-ui/navigation/partials/BrowseMenu/types";
+
+import { useEnhancedConnectorClass } from "@app-ui/navigation/partials/BrowseMenu/shards/ListToBrowseConnector/hooks";
+
+import useListToBrowseConnectorClasses from "@app-ui/navigation/partials/BrowseMenu/shards/ListToBrowseConnector/styles";
+
+type TProps = {
+ currentSelection: TUiBrowseMenuOption;
+};
+
+export default function ListToBrowseConnector({
+ currentSelection,
+}: TProps): JSX.Element {
+ const classes = useListToBrowseConnectorClasses();
+ const createHorConnClass = useEnhancedConnectorClass(
+ classes.connectorHorizontalBase,
+ classes.activeLine,
+ );
+ const createVerConnClass = useEnhancedConnectorClass(
+ classes.connectorVerticalBase,
+ classes.activeLine,
+ );
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {currentSelection !== "None" && (
+
+
+
+ )}
+
+ );
+}
diff --git a/apps/frontend/ui/src/navigation/partials/BrowseMenu/shards/ListToBrowseConnector/hooks.ts b/apps/frontend/ui/src/navigation/partials/BrowseMenu/shards/ListToBrowseConnector/hooks.ts
new file mode 100644
index 0000000..de58576
--- /dev/null
+++ b/apps/frontend/ui/src/navigation/partials/BrowseMenu/shards/ListToBrowseConnector/hooks.ts
@@ -0,0 +1,13 @@
+import { mergeClasses } from "@lib-theme";
+
+function useEnhancedConnectorClass(baseClass: string, activeClass: string) {
+ return (isCurrentlySelected: boolean, specialClass?: string) => {
+ return mergeClasses(
+ baseClass,
+ specialClass,
+ isCurrentlySelected ? activeClass : undefined,
+ );
+ };
+}
+
+export { useEnhancedConnectorClass };
diff --git a/apps/frontend/ui/src/navigation/partials/BrowseMenu/shards/ListToBrowseConnector/index.ts b/apps/frontend/ui/src/navigation/partials/BrowseMenu/shards/ListToBrowseConnector/index.ts
new file mode 100644
index 0000000..cbe5a7e
--- /dev/null
+++ b/apps/frontend/ui/src/navigation/partials/BrowseMenu/shards/ListToBrowseConnector/index.ts
@@ -0,0 +1,3 @@
+import ListToBrowseConnector from "@app-ui/navigation/partials/BrowseMenu/shards/ListToBrowseConnector/func";
+
+export default ListToBrowseConnector;
diff --git a/apps/frontend/ui/src/navigation/partials/BrowseMenu/shards/ListToBrowseConnector/styles.ts b/apps/frontend/ui/src/navigation/partials/BrowseMenu/shards/ListToBrowseConnector/styles.ts
new file mode 100644
index 0000000..42fe726
--- /dev/null
+++ b/apps/frontend/ui/src/navigation/partials/BrowseMenu/shards/ListToBrowseConnector/styles.ts
@@ -0,0 +1,47 @@
+import { EThemeDimensions, makeStyles } from "@lib-theme";
+import shared from "@app-ui/navigation/partials/BrowseMenu/shared";
+
+const useListToBrowseConnectorClasses = makeStyles({
+ root: {},
+ backboneContainer: {
+ transform: "translateX(-4px)",
+ },
+ horizontalShift: {
+ transform: "translateX(-8px)",
+ },
+ connectorContainer: {
+ gap: shared.connectorGap,
+ width: shared.connectorMinLength,
+ },
+ connectorVerticalBase: {
+ width: shared.connectorThickness,
+ height: "68px",
+ },
+ connectorHorizontalBase: {
+ height: shared.connectorThickness,
+ minWidth: shared.connectorMinLength,
+ borderRadius: shared.connectorBorderRadius,
+ },
+
+ activeLine: {
+ backgroundColor: shared.connectorColor,
+ },
+
+ connectorCatalogue: {
+ width: EThemeDimensions.S3,
+ },
+ connectorConcepts: {
+ width: EThemeDimensions.S4,
+ },
+ connectorRandom: {
+ width: EThemeDimensions.S6,
+ },
+ connectorWord: {
+ width: EThemeDimensions.M1,
+ },
+ connectorFilter: {
+ width: "124px",
+ },
+});
+
+export default useListToBrowseConnectorClasses;
diff --git a/apps/frontend/ui/src/navigation/partials/BrowseMenu/shards/index.ts b/apps/frontend/ui/src/navigation/partials/BrowseMenu/shards/index.ts
new file mode 100644
index 0000000..dd2de13
--- /dev/null
+++ b/apps/frontend/ui/src/navigation/partials/BrowseMenu/shards/index.ts
@@ -0,0 +1,3 @@
+export { default as BrowseListShard } from "@app-ui/navigation/partials/BrowseMenu/shards/BrowseList";
+export { default as BrowseToListConnectorShard } from "@app-ui/navigation/partials/BrowseMenu/shards/BrowseToListConnector";
+export { default as ListToBrowseConnectorShard } from "@app-ui/navigation/partials/BrowseMenu/shards/ListToBrowseConnector";
diff --git a/apps/frontend/ui/src/navigation/partials/BrowseMenu/shared.ts b/apps/frontend/ui/src/navigation/partials/BrowseMenu/shared.ts
new file mode 100644
index 0000000..472b9ce
--- /dev/null
+++ b/apps/frontend/ui/src/navigation/partials/BrowseMenu/shared.ts
@@ -0,0 +1,9 @@
+import { tokens, EThemeDimensions } from "@lib-theme";
+
+export default {
+ connectorThickness: EThemeDimensions.XS1,
+ connectorColor: tokens.colorNeutralStencil1,
+ connectorMinLength: EThemeDimensions.S2,
+ connectorBorderRadius: tokens.borderRadiusSmall,
+ connectorGap: "63px",
+};
diff --git a/apps/frontend/ui/src/navigation/partials/BrowseMenu/stories.tsx b/apps/frontend/ui/src/navigation/partials/BrowseMenu/stories.tsx
new file mode 100644
index 0000000..7f82be9
--- /dev/null
+++ b/apps/frontend/ui/src/navigation/partials/BrowseMenu/stories.tsx
@@ -0,0 +1,42 @@
+import { useState } from "react";
+import type { Meta, StoryObj } from "@storybook/react";
+
+import BrowseMenu from "@app-ui/navigation/partials/BrowseMenu";
+import type { TUiBrowseMenuOption } from "@app-ui/navigation/partials/BrowseMenu/types";
+
+const meta: Meta = {
+ title: "App/UI/Navigation/Partials/BrowseMenu",
+ component: BrowseMenu,
+ args: {
+ optionSlot:
Option Slot
,
+ currentSelection: "Concepts",
+ setCurrentSelection: () => {},
+ isExpanded: true,
+ },
+};
+
+export default meta;
+
+type Story = StoryObj;
+
+export const Index: Story = {
+ render: (props) => {
+ const [currentSelection, setCurrentSelection] =
+ useState("None");
+ const [isExpanded, setIsExpanded] = useState(true);
+
+ return (
+ {
+ setCurrentSelection(self);
+ }}
+ isExpanded={isExpanded}
+ toggleExpand={() => {
+ setIsExpanded((prev) => !prev);
+ }}
+ />
+ );
+ },
+};
diff --git a/apps/frontend/ui/src/navigation/partials/BrowseMenu/tests.tsx b/apps/frontend/ui/src/navigation/partials/BrowseMenu/tests.tsx
new file mode 100644
index 0000000..dd3217d
--- /dev/null
+++ b/apps/frontend/ui/src/navigation/partials/BrowseMenu/tests.tsx
@@ -0,0 +1,82 @@
+import { useState } from "react";
+import { render, screen, fireEvent } from "@tests-unit-browser";
+import "@testing-library/jest-dom";
+
+import { BrowseMenuPartial } from "@app-ui/navigation/partials";
+import type { TUiBrowseMenuOption } from "@app-ui/navigation/partials/BrowseMenu/types";
+import constants from "@app-ui/navigation/partials/BrowseMenu/constants";
+
+function Wrapper() {
+ const optionSlot = Option Slot
;
+
+ const [currentSelection, setCurrentSelection] =
+ useState("None");
+ const [isExpanded, setIsExpanded] = useState(true);
+
+ return (
+ {
+ setCurrentSelection(self);
+ }}
+ isExpanded={isExpanded}
+ toggleExpand={() => {
+ setIsExpanded((prev) => !prev);
+ }}
+ />
+ );
+}
+
+describe("BrowseMenu", () => {
+ it("should render without a selection and without any slot", () => {
+ render();
+ expect(screen.queryByText("Option Slot")).not.toBeInTheDocument();
+
+ const catalogueTab = screen.getByTestId(constants.testIdCatalogueTab);
+ const conceptsTab = screen.getByTestId(constants.testIdConceptsTab);
+ const randomTab = screen.getByTestId(constants.testIdRandomTab);
+ const wordTab = screen.getByTestId(constants.testIdWordTab);
+ const filterTab = screen.getByTestId(constants.testIdFilterTab);
+ expect(catalogueTab).toHaveAttribute("aria-selected", "false");
+ expect(conceptsTab).toHaveAttribute("aria-selected", "false");
+ expect(randomTab).toHaveAttribute("aria-selected", "false");
+ expect(wordTab).toHaveAttribute("aria-selected", "false");
+ expect(filterTab).toHaveAttribute("aria-selected", "false");
+ });
+ it("should render with any selection and with a slot", () => {
+ render();
+ const conceptsTab = screen.getByTestId(constants.testIdConceptsTab);
+
+ fireEvent.click(conceptsTab);
+ expect(screen.queryByText("Option Slot")).toBeInTheDocument();
+ expect(conceptsTab).toHaveAttribute("aria-selected", "true");
+ });
+ it("should toggle the expansion", () => {
+ render();
+ const toggleButton = screen.getByTestId(constants.testIdExpandButton);
+ const catalogueTab = screen.getByTestId(constants.testIdCatalogueTab);
+ const conceptsTab = screen.getByTestId(constants.testIdConceptsTab);
+ const randomTab = screen.getByTestId(constants.testIdRandomTab);
+ const wordTab = screen.getByTestId(constants.testIdWordTab);
+ const filterTab = screen.getByTestId(constants.testIdFilterTab);
+
+ fireEvent.click(wordTab);
+
+ expect(catalogueTab).toBeVisible();
+ expect(conceptsTab).toBeVisible();
+ expect(randomTab).toBeVisible();
+ expect(wordTab).toBeVisible();
+ expect(filterTab).toBeVisible();
+ expect(screen.queryByText("Option Slot")).toBeInTheDocument();
+
+ fireEvent.click(toggleButton);
+
+ expect(catalogueTab).not.toBeVisible();
+ expect(conceptsTab).not.toBeVisible();
+ expect(randomTab).not.toBeVisible();
+ expect(wordTab).not.toBeVisible();
+ expect(filterTab).not.toBeVisible();
+ expect(screen.queryByText("Option Slot")).toBeInTheDocument();
+ });
+});
diff --git a/apps/frontend/ui/src/navigation/partials/BrowseMenu/types.ts b/apps/frontend/ui/src/navigation/partials/BrowseMenu/types.ts
new file mode 100644
index 0000000..cf291ae
--- /dev/null
+++ b/apps/frontend/ui/src/navigation/partials/BrowseMenu/types.ts
@@ -0,0 +1,7 @@
+export type TUiBrowseMenuOption =
+ | "Catalogue"
+ | "Concepts"
+ | "Random"
+ | "Word"
+ | "Filter"
+ | "None";
diff --git a/apps/frontend/ui/src/layout/partials/Sidebar/constants.ts b/apps/frontend/ui/src/navigation/partials/Sidebar/constants.ts
similarity index 100%
rename from apps/frontend/ui/src/layout/partials/Sidebar/constants.ts
rename to apps/frontend/ui/src/navigation/partials/Sidebar/constants.ts
diff --git a/apps/frontend/ui/src/layout/partials/Sidebar/func.tsx b/apps/frontend/ui/src/navigation/partials/Sidebar/func.tsx
similarity index 89%
rename from apps/frontend/ui/src/layout/partials/Sidebar/func.tsx
rename to apps/frontend/ui/src/navigation/partials/Sidebar/func.tsx
index a8b37a6..5090a55 100644
--- a/apps/frontend/ui/src/layout/partials/Sidebar/func.tsx
+++ b/apps/frontend/ui/src/navigation/partials/Sidebar/func.tsx
@@ -7,10 +7,10 @@ import { Logo } from "@lib-theme";
import {
MenuListShard,
ToggleButtonShard,
-} from "@app-ui/layout/partials/Sidebar/shards";
+} from "@app-ui/navigation/partials/Sidebar/shards";
-import useSidebarClasses from "@app-ui/layout/partials/Sidebar/styles";
-import type { TUiSidebarPageOption } from "@app-ui/layout/partials/Sidebar/types";
+import useSidebarClasses from "@app-ui/navigation/partials/Sidebar/styles";
+import type { TUiSidebarPageOption } from "@app-ui/navigation/partials/Sidebar/types";
type TProps = {
defaultTab: TUiSidebarPageOption;
diff --git a/apps/frontend/ui/src/navigation/partials/Sidebar/index.ts b/apps/frontend/ui/src/navigation/partials/Sidebar/index.ts
new file mode 100644
index 0000000..e8f34a8
--- /dev/null
+++ b/apps/frontend/ui/src/navigation/partials/Sidebar/index.ts
@@ -0,0 +1,3 @@
+import Sidebar from "@app-ui/navigation/partials/Sidebar/func";
+
+export default Sidebar;
diff --git a/apps/frontend/ui/src/layout/partials/Sidebar/shards/MenuList/func.tsx b/apps/frontend/ui/src/navigation/partials/Sidebar/shards/MenuList/func.tsx
similarity index 86%
rename from apps/frontend/ui/src/layout/partials/Sidebar/shards/MenuList/func.tsx
rename to apps/frontend/ui/src/navigation/partials/Sidebar/shards/MenuList/func.tsx
index f1f1932..8b6c868 100644
--- a/apps/frontend/ui/src/layout/partials/Sidebar/shards/MenuList/func.tsx
+++ b/apps/frontend/ui/src/navigation/partials/Sidebar/shards/MenuList/func.tsx
@@ -9,10 +9,10 @@ import {
import { Flex, TabList } from "@lib-components";
-import constants from "@app-ui/layout/partials/Sidebar/constants";
-import type { TUiSidebarPageOption } from "@app-ui/layout/partials/Sidebar/types";
+import constants from "@app-ui/navigation/partials/Sidebar/constants";
+import type { TUiSidebarPageOption } from "@app-ui/navigation/partials/Sidebar/types";
-import { TabTemplate } from "@app-ui/layout/partials/Sidebar/shards/MenuList/templates";
+import { TabTemplate } from "@app-ui/navigation/partials/Sidebar/shards/MenuList/templates";
type TProps = {
isExpanded: boolean;
diff --git a/apps/frontend/ui/src/navigation/partials/Sidebar/shards/MenuList/index.ts b/apps/frontend/ui/src/navigation/partials/Sidebar/shards/MenuList/index.ts
new file mode 100644
index 0000000..9c9d4e7
--- /dev/null
+++ b/apps/frontend/ui/src/navigation/partials/Sidebar/shards/MenuList/index.ts
@@ -0,0 +1,3 @@
+import MenuList from "@app-ui/navigation/partials/Sidebar/shards/MenuList/func";
+
+export default MenuList;
diff --git a/apps/frontend/ui/src/layout/partials/Sidebar/shards/MenuList/templates/Tab/func.tsx b/apps/frontend/ui/src/navigation/partials/Sidebar/shards/MenuList/templates/Tab/func.tsx
similarity index 92%
rename from apps/frontend/ui/src/layout/partials/Sidebar/shards/MenuList/templates/Tab/func.tsx
rename to apps/frontend/ui/src/navigation/partials/Sidebar/shards/MenuList/templates/Tab/func.tsx
index ad913de..05ecb24 100644
--- a/apps/frontend/ui/src/layout/partials/Sidebar/shards/MenuList/templates/Tab/func.tsx
+++ b/apps/frontend/ui/src/navigation/partials/Sidebar/shards/MenuList/templates/Tab/func.tsx
@@ -5,7 +5,7 @@ import { Tab as OriginalTab, Flex } from "@lib-components";
import { EThemeIconSizes } from "@lib-theme";
import type { TFluentIcon } from "@lib-theme";
-import useTabClasses from "@app-ui/layout/partials/Sidebar/shards/MenuList/templates/Tab/styles";
+import useTabClasses from "@app-ui/navigation/partials/Sidebar/shards/MenuList/templates/Tab/styles";
type TProps = {
action: () => void;
diff --git a/apps/frontend/ui/src/navigation/partials/Sidebar/shards/MenuList/templates/Tab/index.ts b/apps/frontend/ui/src/navigation/partials/Sidebar/shards/MenuList/templates/Tab/index.ts
new file mode 100644
index 0000000..884a801
--- /dev/null
+++ b/apps/frontend/ui/src/navigation/partials/Sidebar/shards/MenuList/templates/Tab/index.ts
@@ -0,0 +1,3 @@
+import Tab from "@app-ui/navigation/partials/Sidebar/shards/MenuList/templates/Tab/func";
+
+export default Tab;
diff --git a/apps/frontend/ui/src/layout/partials/Sidebar/shards/MenuList/templates/Tab/styles.ts b/apps/frontend/ui/src/navigation/partials/Sidebar/shards/MenuList/templates/Tab/styles.ts
similarity index 100%
rename from apps/frontend/ui/src/layout/partials/Sidebar/shards/MenuList/templates/Tab/styles.ts
rename to apps/frontend/ui/src/navigation/partials/Sidebar/shards/MenuList/templates/Tab/styles.ts
diff --git a/apps/frontend/ui/src/navigation/partials/Sidebar/shards/MenuList/templates/index.ts b/apps/frontend/ui/src/navigation/partials/Sidebar/shards/MenuList/templates/index.ts
new file mode 100644
index 0000000..d68fc6c
--- /dev/null
+++ b/apps/frontend/ui/src/navigation/partials/Sidebar/shards/MenuList/templates/index.ts
@@ -0,0 +1 @@
+export { default as TabTemplate } from "@app-ui/navigation/partials/Sidebar/shards/MenuList/templates/Tab/func";
diff --git a/apps/frontend/ui/src/layout/partials/Sidebar/shards/ToggleButton/func.tsx b/apps/frontend/ui/src/navigation/partials/Sidebar/shards/ToggleButton/func.tsx
similarity index 85%
rename from apps/frontend/ui/src/layout/partials/Sidebar/shards/ToggleButton/func.tsx
rename to apps/frontend/ui/src/navigation/partials/Sidebar/shards/ToggleButton/func.tsx
index 7225e75..3fe9763 100644
--- a/apps/frontend/ui/src/layout/partials/Sidebar/shards/ToggleButton/func.tsx
+++ b/apps/frontend/ui/src/navigation/partials/Sidebar/shards/ToggleButton/func.tsx
@@ -3,9 +3,9 @@ import type { JSX, Dispatch, SetStateAction } from "react";
import { ChevronLeftFilled, ChevronRightFilled } from "@fluentui/react-icons";
import { Button, Tooltip } from "@lib-components";
-import constants from "@app-ui/layout/partials/Sidebar/constants";
+import constants from "@app-ui/navigation/partials/Sidebar/constants";
-import useToggleButtonClasses from "@app-ui/layout/partials/Sidebar/shards/ToggleButton/styles";
+import useToggleButtonClasses from "@app-ui/navigation/partials/Sidebar/shards/ToggleButton/styles";
type TProps = {
isExpanded: boolean;
diff --git a/apps/frontend/ui/src/navigation/partials/Sidebar/shards/ToggleButton/index.ts b/apps/frontend/ui/src/navigation/partials/Sidebar/shards/ToggleButton/index.ts
new file mode 100644
index 0000000..f66364f
--- /dev/null
+++ b/apps/frontend/ui/src/navigation/partials/Sidebar/shards/ToggleButton/index.ts
@@ -0,0 +1,3 @@
+import ToggleButton from "@app-ui/navigation/partials/Sidebar/shards/ToggleButton/func";
+
+export default ToggleButton;
diff --git a/apps/frontend/ui/src/layout/partials/Sidebar/shards/ToggleButton/styles.ts b/apps/frontend/ui/src/navigation/partials/Sidebar/shards/ToggleButton/styles.ts
similarity index 100%
rename from apps/frontend/ui/src/layout/partials/Sidebar/shards/ToggleButton/styles.ts
rename to apps/frontend/ui/src/navigation/partials/Sidebar/shards/ToggleButton/styles.ts
diff --git a/apps/frontend/ui/src/navigation/partials/Sidebar/shards/index.ts b/apps/frontend/ui/src/navigation/partials/Sidebar/shards/index.ts
new file mode 100644
index 0000000..a191b50
--- /dev/null
+++ b/apps/frontend/ui/src/navigation/partials/Sidebar/shards/index.ts
@@ -0,0 +1,2 @@
+export { default as MenuListShard } from "@app-ui/navigation/partials/Sidebar/shards/MenuList";
+export { default as ToggleButtonShard } from "@app-ui/navigation/partials/Sidebar/shards/ToggleButton";
diff --git a/apps/frontend/ui/src/layout/partials/Sidebar/stories.tsx b/apps/frontend/ui/src/navigation/partials/Sidebar/stories.tsx
similarity index 90%
rename from apps/frontend/ui/src/layout/partials/Sidebar/stories.tsx
rename to apps/frontend/ui/src/navigation/partials/Sidebar/stories.tsx
index 0e03a37..d3c4303 100644
--- a/apps/frontend/ui/src/layout/partials/Sidebar/stories.tsx
+++ b/apps/frontend/ui/src/navigation/partials/Sidebar/stories.tsx
@@ -2,12 +2,12 @@ import { useState } from "react";
import type { Meta, StoryObj } from "@storybook/react";
-import Sidebar from "@app-ui/layout/partials/Sidebar";
+import Sidebar from "@app-ui/navigation/partials/Sidebar";
import { tokens } from "@lib-theme";
const meta: Meta = {
- title: "App/UI/Layout/Partials/Sidebar",
+ title: "App/UI/Navigation/Partials/Sidebar",
component: Sidebar,
args: {
defaultTab: "Overview",
diff --git a/apps/frontend/ui/src/layout/partials/Sidebar/styles.ts b/apps/frontend/ui/src/navigation/partials/Sidebar/styles.ts
similarity index 100%
rename from apps/frontend/ui/src/layout/partials/Sidebar/styles.ts
rename to apps/frontend/ui/src/navigation/partials/Sidebar/styles.ts
diff --git a/apps/frontend/ui/src/layout/partials/Sidebar/tests.tsx b/apps/frontend/ui/src/navigation/partials/Sidebar/tests.tsx
similarity index 97%
rename from apps/frontend/ui/src/layout/partials/Sidebar/tests.tsx
rename to apps/frontend/ui/src/navigation/partials/Sidebar/tests.tsx
index 4bb0ba8..07e031e 100644
--- a/apps/frontend/ui/src/layout/partials/Sidebar/tests.tsx
+++ b/apps/frontend/ui/src/navigation/partials/Sidebar/tests.tsx
@@ -3,8 +3,8 @@ import { useState } from "react";
import { render, screen, fireEvent } from "@tests-unit-browser";
import "@testing-library/jest-dom";
-import constants from "@app-ui/layout/partials/Sidebar/constants";
-import SidebarPartial from "@app-ui/layout/partials/Sidebar";
+import constants from "@app-ui/navigation/partials/Sidebar/constants";
+import SidebarPartial from "@app-ui/navigation/partials/Sidebar";
describe("Sidebar", () => {
describe("when specified", () => {
diff --git a/apps/frontend/ui/src/layout/partials/Sidebar/types.ts b/apps/frontend/ui/src/navigation/partials/Sidebar/types.ts
similarity index 100%
rename from apps/frontend/ui/src/layout/partials/Sidebar/types.ts
rename to apps/frontend/ui/src/navigation/partials/Sidebar/types.ts
diff --git a/apps/frontend/ui/src/navigation/partials/index.ts b/apps/frontend/ui/src/navigation/partials/index.ts
new file mode 100644
index 0000000..d294e90
--- /dev/null
+++ b/apps/frontend/ui/src/navigation/partials/index.ts
@@ -0,0 +1,2 @@
+export { default as SidebarPartial } from "@app-ui/navigation/partials/Sidebar";
+export { default as BrowseMenuPartial } from "@app-ui/navigation/partials/BrowseMenu";
diff --git a/libs/theme/src/index.ts b/libs/theme/src/index.ts
index c2d3d19..d24d7b1 100644
--- a/libs/theme/src/index.ts
+++ b/libs/theme/src/index.ts
@@ -1,4 +1,25 @@
-import { makeStyles, tokens, mergeClasses } from "@fluentui/react-components";
+import {
+ makeStyles,
+ tokens,
+ mergeClasses,
+ Caption2,
+ Caption2Strong,
+ Caption1,
+ Caption1Strong,
+ Caption1Stronger,
+ Body1,
+ Body1Strong,
+ Body1Stronger,
+ Body2,
+ Subtitle2,
+ Subtitle2Stronger,
+ Subtitle1,
+ Title3,
+ Title2,
+ Title1,
+ LargeTitle,
+ Display,
+} from "@fluentui/react-components";
import ThemeProvider from "@lib-theme/Provider";
import Logo from "@lib-theme/Logo";
@@ -14,4 +35,24 @@ export {
export { ThemeProvider, Logo, useFuiProviderNode };
+export {
+ Caption2,
+ Caption2Strong,
+ Caption1,
+ Caption1Strong,
+ Caption1Stronger,
+ Body1,
+ Body1Strong,
+ Body1Stronger,
+ Body2,
+ Subtitle2,
+ Subtitle2Stronger,
+ Subtitle1,
+ Title3,
+ Title2,
+ Title1,
+ LargeTitle,
+ Display,
+};
+
export { makeStyles, mergeClasses, tokens };
diff --git a/makefile b/makefile
index fb9f20f..47c51b3 100644
--- a/makefile
+++ b/makefile
@@ -10,3 +10,9 @@ help:
@make -pRrq -f $(MAKEFILE_LIST) : 2>/dev/null | awk -v RS= -F: '/^# Files/,/^# Finished Make data base/ { if ($$1 !~ "^[#.]") print $$1 }' | sort | uniq
.PHONY: help
+
+git-sync-production:
+ git fetch origin production:production
+
+git-sync-development:
+ git fetch origin development:development
diff --git a/package-lock.json b/package-lock.json
index 401c162..cb1af74 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -10,7 +10,7 @@
"@fluentui/react-motion-components-preview": "^0.3.1",
"@griffel/react": "^1.5.25",
"@reduxjs/toolkit": "^2.2.8",
- "fluentui-helpers": "0.2.0",
+ "fluentui-helpers": "0.2.1",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-redux": "^9.1.2"
@@ -9951,9 +9951,9 @@
"dev": true
},
"node_modules/fluentui-helpers": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/fluentui-helpers/-/fluentui-helpers-0.2.0.tgz",
- "integrity": "sha512-b7WgaUK5nRkqcF6gJq/vkALy195uXbNVyGH1Vf+I1EteyqyP2Ae5gqSWOUj4ZJUdcROO+uTmwSQhEqyrTGctwQ==",
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/fluentui-helpers/-/fluentui-helpers-0.2.1.tgz",
+ "integrity": "sha512-yVTr0yz2ZQLwGX3bgph1pOt4zP7W3b30iNEyNFlWyOPuqUlxMl2JDEGeg/8QOcObsyPPY2D27svFoxz7QT4aag==",
"license": "MIT",
"peerDependencies": {
"@fluentui/react-components": "^9",
diff --git a/package.json b/package.json
index 9975024..84ac324 100644
--- a/package.json
+++ b/package.json
@@ -10,7 +10,7 @@
"@fluentui/react-motion-components-preview": "^0.3.1",
"@griffel/react": "^1.5.25",
"@reduxjs/toolkit": "^2.2.8",
- "fluentui-helpers": "0.2.0",
+ "fluentui-helpers": "0.2.1",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-redux": "^9.1.2"