Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
6da2fb6
Removed 'new' tag from props that were added in 15.0.0 or before
Mil4n0r Nov 11, 2025
5344e79
Merge branch 'Mil4n0r/tree_navigation' of github.com:dxc-technology/h…
Mil4n0r Nov 11, 2025
28fbd07
Removed new tag from an already existing prop
Mil4n0r Nov 11, 2025
2c34fd9
Merge branch 'Mil4n0r/tree_navigation' of github.com:dxc-technology/h…
Mil4n0r Nov 11, 2025
1a7f079
Merge branch 'Mil4n0r/tree_navigation' of github.com:dxc-technology/h…
Mil4n0r Nov 11, 2025
977eb58
Merge branch 'master' of github.com:dxc-technology/halstack-react int…
Mil4n0r Nov 12, 2025
3115e09
Prepared skeleton for new migration section
Mil4n0r Nov 12, 2025
ffb8af6
Included information about API changes and new/removed components
Mil4n0r Nov 13, 2025
499a969
Emotion migration skeleton
Mil4n0r Nov 14, 2025
fde5b8f
Updated emotion and components migration page
Mil4n0r Nov 14, 2025
9dc47e8
Updated components migration doc
Mil4n0r Nov 17, 2025
2cb3acb
Merge branch 'master' of github.com:dxc-technology/halstack-react int…
Mil4n0r Nov 17, 2025
8d09eba
Added new tags for the sidenav props
Mil4n0r Nov 18, 2025
2caaf0f
Included documentation for alias tokens and rest of migration
Mil4n0r Nov 19, 2025
109e785
Merge branch 'master' of github.com:dxc-technology/halstack-react int…
Mil4n0r Nov 19, 2025
83a19aa
Fixed typo within migration link
Mil4n0r Nov 19, 2025
ccfa6e8
Merge branch 'master' of github.com:dxc-technology/halstack-react int…
Mil4n0r Nov 21, 2025
a079e49
Fixed issue with selected/scroll in navigationTree
Mil4n0r Nov 21, 2025
06089e5
Fixed typo
Mil4n0r Nov 21, 2025
840965f
Added fix for navigationTree when navItems are modified dynamically
Mil4n0r Nov 24, 2025
20a70e4
Added condition to effect to prevent incosistent behavior
Mil4n0r Nov 24, 2025
e8b5861
Remove comment
Mil4n0r Nov 24, 2025
4bb42ce
Modified intermediate structure and _app logic to handle multi-level
Mil4n0r Nov 24, 2025
b85350c
Added separated token lists in documentation
Mil4n0r Nov 25, 2025
bda7101
Fixed conflicts and added footer doc
Mil4n0r Nov 26, 2025
fb9d79f
Fixed link for alias/core tokens list inside migration doc
Mil4n0r Nov 26, 2025
4bb46c5
Fixed typos
Mil4n0r Nov 26, 2025
8abce6d
Added logo prop back
Mil4n0r Nov 26, 2025
07fa352
Fixed normalizeNavTabs typing
Mil4n0r Nov 26, 2025
e36fc3e
Fixed typos
Mil4n0r Nov 26, 2025
e35bf1a
Added fixes for migration doc based on feedback
Mil4n0r Nov 26, 2025
cfd31b9
Fixed typo in Sidenav typing doc
Mil4n0r Nov 26, 2025
e884331
Merge branch 'master' into Mil4n0r/halstack-16-migration
Mil4n0r Nov 26, 2025
0c3c2ba
Fixed typo
Mil4n0r Nov 26, 2025
52b13a9
Fixed typo
Mil4n0r Nov 26, 2025
1f4eead
Merge branch 'Mil4n0r/halstack-16-migration' of github.com:dxc-techno…
Mil4n0r Nov 26, 2025
7f76f05
Added fix for sections being displayed even if they had no items
Mil4n0r Nov 27, 2025
19dff5e
Merge branch 'master' into Mil4n0r/halstack-16-migration
PelayoFelgueroso Nov 27, 2025
e584ae7
Added theming documentation
Mil4n0r Nov 28, 2025
48bfe08
Merge branch 'master' into Mil4n0r/halstack-16-migration
PelayoFelgueroso Nov 28, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
110 changes: 57 additions & 53 deletions apps/website/pages/_app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import Head from "next/head";
import { DxcApplicationLayout, DxcTextInput, DxcToastsQueue } from "@dxc-technology/halstack-react";
import MainContent from "@/common/MainContent";
import { useRouter } from "next/router";
import { LinksSectionDetails, LinksSections } from "@/common/pagesList";
import { LinkDetails, LinksSectionDetails, LinksSections } from "@/common/pagesList";
import StatusBadge from "@/common/StatusBadge";
import "../global-styles.css";
import createCache, { EmotionCache } from "@emotion/cache";
Expand Down Expand Up @@ -33,66 +33,70 @@ export default function App({ Component, pageProps, emotionCache = clientSideEmo
const [isExpanded, setIsExpanded] = useState(true);
const { asPath: currentPath } = useRouter();

const filterSections = (sections: Section[], query: string): Section[] => {
const q = query.trim().toLowerCase();
if (!q) return sections;
const matchPaths = (linkPath: string) => {
const desiredPaths = [linkPath, `${linkPath}/code`];
const pathToBeMatched = currentPath?.split("#")[0]?.slice(0, -1);
return pathToBeMatched ? desiredPaths.includes(pathToBeMatched) : false;
};

const filterItem = (item: Item | GroupItem): Item | GroupItem | null => {
const labelMatches = item.label.toLowerCase().includes(q);
const createNavItem = (link: LinkDetails): Item => ({
label: link.label,
href: link.path,
selected: matchPaths(link.path),
badge: link.status && link.status !== "stable" ? <StatusBadge hasTitle status={link.status} /> : undefined,
renderItem: ({ children }: { children: ReactNode }) => (
<Link href={link.path} passHref legacyBehavior>
{children}
</Link>
),
});

if (!isGroupItem(item)) return labelMatches ? item : null;
const normalizeNavTabs = (links: (LinkDetails | LinksSectionDetails)[]): (Item | GroupItem)[] => {
return links.map((link) => {
if ("links" in link) {
return {
label: link.label,
items: normalizeNavTabs(link.links),
} as GroupItem;
}

const items = item.items.reduce<(Item | GroupItem)[]>((acc, child) => {
const filtered = filterItem(child);
if (filtered) acc.push(filtered);
return acc;
}, []);
return createNavItem(link);
});
};

return labelMatches || items.length ? { ...item, items } : null;
};
const filterNavTree = (items: (Item | GroupItem)[], q: string): (Item | GroupItem)[] => {
const result: (Item | GroupItem)[] = [];

return sections.reduce<Section[]>((acc, section) => {
const items = section.items.reduce<(Item | GroupItem)[]>((acc, item) => {
const filtered = filterItem(item);
if (filtered) acc.push(filtered);
return acc;
}, []);
if (items.length) acc.push({ ...section, items });
return acc;
}, []);
};
for (const item of items) {
if (isGroupItem(item)) {
const filteredChildren = filterNavTree(item.items, q);
const matches = item.label.toLowerCase().includes(q);

const mapLinksToGroupItems = (sections: LinksSectionDetails[]): Section[] => {
const matchPaths = (linkPath: string) => {
const desiredPaths = [linkPath, `${linkPath}/code`];
const pathToBeMatched = currentPath?.split("#")[0]?.slice(0, -1);
return pathToBeMatched ? desiredPaths.includes(pathToBeMatched) : false;
};
if (matches || filteredChildren.length > 0) {
result.push({ ...item, items: filteredChildren });
}
} else {
if (item.label.toLowerCase().includes(q)) {
result.push(item);
}
}
}

return sections.map((section) => ({
title: section.label,
items: section.links.map((link) => ({
label: link.label,
href: link.path,
selected: matchPaths(link.path),
...(link.status && {
badge: link.status !== "stable" ? <StatusBadge hasTitle status={link.status} /> : undefined,
}),
renderItem: ({ children }: { children: ReactNode }) => (
<Link key={link.path} href={link.path} passHref legacyBehavior>
{children}
</Link>
),
})),
}));
return result;
};

// TODO: ADD NEW CATEGORIZATION
const navItems: Section[] = useMemo(() => {
return LinksSections.map((section) => {
const baseItems = normalizeNavTabs(section.links);

const items = filter ? filterNavTree(baseItems, filter.trim().toLowerCase()) : baseItems;

const filteredSections = useMemo(() => {
const sections = mapLinksToGroupItems(LinksSections);
return filterSections(sections, filter);
}, [filter]);
return {
title: section.label,
items,
};
}).filter((section) => section.items.length > 0);
}, [currentPath, filter]);

return (
<CacheProvider value={emotionCache}>
Expand All @@ -103,14 +107,14 @@ export default function App({ Component, pageProps, emotionCache = clientSideEmo
header={<DxcApplicationLayout.Header logo={{ src: dxcLogo, alt: "DXC Technology" }} />}
sidenav={
<DxcApplicationLayout.Sidenav
navItems={filteredSections}
navItems={navItems}
branding={isExpanded && <SidenavLogo />}
topContent={
isExpanded && (
<DxcTextInput
placeholder="Search docs"
value={filter}
onChange={({ value }: { value: string }) => {
onChange={({ value }) => {
setFilter(value);
}}
size="fillParent"
Expand Down
13 changes: 13 additions & 0 deletions apps/website/pages/foundations/tokens/alias.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import Head from "next/head";
import AliasTokensPage from "screens/foundations/tokens/AliasTokenList";

const Tokens = () => (
<>
<Head>
<title>Alias Tokens — Halstack Design System</title>
</Head>
<AliasTokensPage />
</>
);

export default Tokens;
13 changes: 13 additions & 0 deletions apps/website/pages/foundations/tokens/core.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import Head from "next/head";
import CoreTokensPage from "screens/foundations/tokens/CoreTokenList";

const Tokens = () => (
<>
<Head>
<title>Core Tokens — Halstack Design System</title>
</Head>
<CoreTokensPage />
</>
);

export default Tokens;
13 changes: 13 additions & 0 deletions apps/website/pages/migration/16/component-updates.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import Head from "next/head";
import Components16MigrationPage from "screens/migration/Components16MigrationPage";

const Components16Migration = () => (
<>
<Head>
<title>Component updates in v16 — Halstack Design System</title>
</Head>
<Components16MigrationPage />
</>
);

export default Components16Migration;
13 changes: 13 additions & 0 deletions apps/website/pages/migration/16/migrating-to-emotion.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import Head from "next/head";
import EmotionPage from "screens/migration/EmotionMigrationPage";

const EmotionMigration = () => (
<>
<Head>
<title>Migrating to Emotion — Halstack Design System</title>
</Head>
<EmotionPage />
</>
);

export default EmotionMigration;
13 changes: 13 additions & 0 deletions apps/website/pages/migration/16/migrating-tokens.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import Head from "next/head";
import TokensMigrationPage from "screens/migration/TokensMigrationPage";

const TokensMigration = () => (
<>
<Head>
<title>Migrating tokens — Halstack Design System</title>
</Head>
<TokensMigrationPage />
</>
);

export default TokensMigration;
2 changes: 1 addition & 1 deletion apps/website/screens/common/componentsList.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
{
"label": "Data grid",
"path": "/components/data-grid",
"status": "experimental"
"status": "new"
},
{
"label": "Date input",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@ import componentsList from "./componentsList.json";

export type ComponentStatus = "experimental" | "new" | "stable" | "legacy" | "deprecated";

type LinkDetails = {
export type LinkDetails = {
label: string;
path: string;
status?: ComponentStatus;
};

export type LinksSectionDetails = {
label: string;
links: LinkDetails[];
links: (LinkDetails | LinksSectionDetails)[];
};

type NavigationLinks = {
Expand All @@ -37,46 +37,69 @@ const principlesLinks: LinkDetails[] = [
{ label: "Localization", path: "/principles/localization" },
];

const foundationsLinks: LinkDetails[] = [
const tokensLinks: LinkDetails[] = [
{ label: "Overview", path: "/foundations/tokens" },
{ label: "Core tokens", path: "/foundations/tokens/core" },
{ label: "Alias tokens", path: "/foundations/tokens/alias" },
];

const foundationsLinks: (LinkDetails | LinksSectionDetails)[] = [
{ label: "Color", path: "/foundations/color" },
{ label: "Elevation", path: "/foundations/elevation" },
{ label: "Height", path: "/foundations/height" },
{ label: "Iconography", path: "/foundations/iconography" },
{ label: "Layout", path: "/foundations/layout" },
{ label: "Spacing", path: "/foundations/spacing" },
{ label: "Tokens", path: "/foundations/tokens" },
{ label: "Tokens", links: tokensLinks },
{ label: "Typography", path: "/foundations/typography" },
];

const v16Links: LinkDetails[] = [
{ label: "Component updates", path: "/migration/16/component-updates" },
{ label: "Migrating to Emotion", path: "/migration/16/migrating-to-emotion" },
{ label: "Migrating tokens", path: "/migration/16/migrating-tokens" },
];

const migrationLinks: LinksSectionDetails[] = [{ label: "v16", links: v16Links }];

const componentsLinks = componentsList as LinkDetails[];

export const LinksSections: LinksSectionDetails[] = [
{ label: "Overview", links: overviewLinks },
{ label: "Principles", links: principlesLinks },
{ label: "Foundations", links: foundationsLinks },
{ label: "Migration", links: migrationLinks },
{ label: "Utilities", links: utilitiesLinks },
{ label: "Components", links: componentsLinks },
];

const isNavLink = (item: LinkDetails | LinksSectionDetails): item is LinkDetails => "path" in item;

const flattenLinks = (items: (LinkDetails | LinksSectionDetails)[]): LinkDetails[] =>
items.flatMap((item) => (isNavLink(item) ? [item] : flattenLinks(item.links)));

const getCurrentLinkIndex = (links: LinkDetails[], currentPath: string) => {
let currentLinkIndex = -1;
let matchedWords = 0;
links.forEach((link, index) => {
if (currentPath.startsWith(link.path) && link.path.length > matchedWords) {
currentLinkIndex = index;
matchedWords = link.path.length;
let current = -1;
let best = 0;

links.forEach((link, i) => {
if (currentPath.startsWith(link.path) && link.path.length > best) {
current = i;
best = link.path.length;
}
});
return currentLinkIndex;

return current;
};

export const getNavigationLinks = (currentPath: string): NavigationLinks => {
const links = LinksSections.flatMap((section) => section.links);
const currentLinkIndex = getCurrentLinkIndex(links, currentPath);
return currentLinkIndex === -1
? {}
: {
nextLink: currentLinkIndex + 1 < links.length ? links[currentLinkIndex + 1] : undefined,
previousLink: currentLinkIndex - 1 >= 0 ? links[currentLinkIndex - 1] : undefined,
};
const flatLinks = flattenLinks(LinksSections);

const index = getCurrentLinkIndex(flatLinks, currentPath);
if (index === -1) return {};

return {
previousLink: flatLinks[index - 1],
nextLink: flatLinks[index + 1],
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -126,12 +126,7 @@ const sections = [
<td>-</td>
</tr>
<tr>
<td>
<DxcFlex direction="column" gap="var(--spacing-gap-xs)" alignItems="baseline">
<StatusBadge status="new" />
badge
</DxcFlex>
</td>
<td>badge</td>
<td>
<TableCode>{"{ position: 'before' | 'after'; element: ReactNode }"}</TableCode>
</td>
Expand Down Expand Up @@ -190,25 +185,15 @@ const sections = [
<td>-</td>
</tr>
<tr>
<td>
<DxcFlex direction="column" gap="var(--spacing-gap-xs)" alignItems="baseline">
<StatusBadge status="new" />
statusLight
</DxcFlex>
</td>
<td>statusLight</td>
<td>
<TableCode>React.ReactNode</TableCode>
</td>
<td>Status light component to add extra value to the accordion.</td>
<td>-</td>
</tr>
<tr>
<td>
<DxcFlex direction="column" gap="var(--spacing-gap-xs)" alignItems="baseline">
<StatusBadge status="new" />
subLabel
</DxcFlex>
</td>
<td>subLabel</td>
<td>
<TableCode>string</TableCode>
</td>
Expand Down
Loading