Core
Provides the fundamentals to build with the design system.The <Core /> component provides some font-smoothing, applies the current theme via CSS variables and allows for a global link override.
<Core><YourApp></Core>
All standard style tokens are available to import from the @eds/core package, and can then be used in your CSS:
import { backgroundColor, color } from '@eds/core';const Component = () => {return (<Box className={css({ backgroundColor: backgroundColor.neutral, color: color.critical })}>Important information</Box>);};
Components that expose props that match tokens â e.g. the backgroundColor prop on the <Box /> component â can use tokens by name rather than importing them:
const Component = () => {return (<Box backgroundColor="neutral" color="critical">Important information</Box>);};
The following tokens are available:
- backgroundColor
- borderColor
- borderWidth
- color
- themePalette
- focusRing
- fontFamily
- fontSize
- fontWeight
- headingSize
- iconSize
- lineHeight
- borderRadius
- boxShadow
- space
- zIndex
- inputSize
There are two supported theming methods.
- Automated theming: A primary and accent colour is provided and a theme palette is automatically generated, with fully accessible colours being used throughout themed components.
- TMS theming: The existing theming used by TMS where clients can specify exact colours for some components.
In both methods a theming palette is automatically generated from two colours, a primary colour and an accent colour, but in TMS theming some component themes are overwritten by the TMS settings.
The theme palette colours are stored as CSS variables so the values can be changed dynamically if required. They can be accessed with the themePalette token.
All theme tokens including the palette and component theme tokens are available with the theme token.
The useTheme hook provides two methods to apply the theme for each theming method.
- setAutomatedTheme accepts two brand colours, themePrimary and themeAccent, and autogenerates the theme.
- setTMSTheme accepts TMS theme values in the structure of the /user-ui-preference/theme API.
To prevent un-themed components from being rendered, the useTheme hook also provides a themeLoaded variable that will update once the theme has been loaded.
// Automated theme example where the theme is not loaded asyncconst AutomatedTheme = () => {const { setAutomatedTheme, themeLoaded } = useTheme();// Set the ELMO colour palettesetAutomatedTheme({themePrimary: '#0160AE',themeAccent: '#EE2925',});// Prevent the menu from flashing with the default themeif (!themeLoaded) {return <LoadingSpinner />;}// Theme has loaded, display the menu with the correct coloursreturn <Menu />;};// TMS theme example where the theme is loaded asyncconst TMSTheme = () => {const { setTMSTheme, themeLoaded } = useTheme();// Get the userPreferences data from TMSconst { data: userPreferences } = useQuery('/user-ui-preference/theme', fetchJson('/user-ui-preference/theme'));useEffect(() => {if (userPreferences) {setTMSTheme(userPreferences);}}, [userPreferences, setTMSTheme]);// Prevent the menu from flashing with the default themeif (!themeLoaded) {return <LoadingSpinner />;}// Theme has loaded, display the menu with the correct coloursreturn <Menu />;};
EDS components that render links (like <Link />, <ButtonLink />, and <TabItem href="..." />) can integrate with your routing frameworkâs link component. This enables client-side navigation, prefetching, and other routing features.
Pass a linkComponent to the <Core /> provider. It will be used whenever EDS renders a link.
The new API accepts standard anchor props. Enable it with shouldUseNewLinkApi on <Core />.
import Link from 'next/link';const GlobalLink = ({ href, children, ...props }) => (<Link href={href} {...props}>{children}</Link>);<Core linkComponent={GlobalLink} shouldUseNewLinkApi><YourApp /></Core>;
import { Link } from 'react-router-dom';const GlobalLink = ({ href, children, ...props }) => (<Link to={href} {...props}>{children}</Link>);<Core linkComponent={GlobalLink} shouldUseNewLinkApi><YourApp /></Core>;
Your component should accept common anchor props (href, className, target, rel, download, children) and render the appropriate element for your framework.
The legacy API remains the default for backward compatibility. It follows the Next.js 12 pattern, where EDS renders an <a> without an href, and your link component wraps it using passHref. This was required because Next.js 12 expected an <a> as the child of <Link>.
import Link from 'next/link';const GlobalLink = ({ children, ...props }) => (<Link passHref {...props}>{children}</Link>);<Core linkComponent={GlobalLink}><YourApp /></Core>;
The new API removes the need for this pattern by passing href directly to your component, aligning with Next.js 13's behaviour where <Link> renders an <a> internally.
- Add shouldUseNewLinkApi to <Core />.
- Update your link component to accept href directly.
- Remove passHref.
- Remove the <a> wrapper.
- Support standard anchor props (className, target, rel, etc.).