diff --git a/packages/terra-application/CHANGELOG.md b/packages/terra-application/CHANGELOG.md
index acedd6465..2ef015ee8 100644
--- a/packages/terra-application/CHANGELOG.md
+++ b/packages/terra-application/CHANGELOG.md
@@ -2,6 +2,9 @@
## Unreleased
+* Changed
+ * Added support for theme data density.
+
## 1.56.0 - (September 19, 2023)
* Changed
diff --git a/packages/terra-application/src/application-base/ApplicationBase.jsx b/packages/terra-application/src/application-base/ApplicationBase.jsx
index d24773dfd..4caedf53b 100644
--- a/packages/terra-application/src/application-base/ApplicationBase.jsx
+++ b/packages/terra-application/src/application-base/ApplicationBase.jsx
@@ -65,6 +65,10 @@ const propTypes = {
* The name of the theme to apply to the application using terra-theme-provider.
*/
themeName: PropTypes.string,
+ /**
+ * The density of the theme to apply to the application using terra-theme-provider.
+ */
+ themeDensity: PropTypes.string,
/**
* By default, the elements rendered by ApplicationBase are fit to the Application's parent using 100% height.
* If `fitToParentIsDisabled` is provided, the Application will render at its intrinsic content height and
@@ -86,7 +90,7 @@ const propTypes = {
};
const ApplicationBase = ({
- locale, customTranslatedMessages, translationsLoadingPlaceholder, themeName, fitToParentIsDisabled, children, unloadPromptIsDisabled, noScroll,
+ locale, customTranslatedMessages, translationsLoadingPlaceholder, themeName, themeDensity, fitToParentIsDisabled, children, unloadPromptIsDisabled, noScroll,
}) => {
const registeredPromptsRef = useRef();
@@ -122,11 +126,12 @@ const ApplicationBase = ({
// If the theme class name is undefined or an empty string, that indicates we have the root theme and should apply the root theme name.
name: themeOverride || themeName || rootThemeName,
className: themeOverride || themeName,
- }), [themeOverride, themeName]);
+ density: themeDensity || themeConfig?.density,
+ }), [themeOverride, themeName, themeDensity]);
return (
-
+
{
@@ -44,4 +43,34 @@ describe('ApplicationBase', () => {
));
expect(wrapper).toMatchSnapshot();
});
+
+ it('should render with theme and density', () => {
+ const wrapper = shallow((
+
+ content
+
+ ));
+
+ const themeProvider = wrapper.find('ThemeProvider');
+ expect(themeProvider.props().themeName).toBe('test-theme');
+ expect(themeProvider.props().density).toBe('compact');
+
+ const themeContext = wrapper.find('ThemeContextProvider');
+ expect(themeContext.props().theme).toStrictEqual({ name: 'test-theme', className: 'test-theme', density: 'compact' });
+ });
+
+ it('should render with density', () => {
+ const wrapper = shallow((
+
+ content
+
+ ));
+
+ const themeProvider = wrapper.find('ThemeProvider');
+ expect(themeProvider.props().themeName).toBeUndefined();
+ expect(themeProvider.props().density).toBe('compact');
+
+ const themeContext = wrapper.find('ThemeContextProvider');
+ expect(themeContext.props().theme).toStrictEqual({ name: 'terra-default-theme', className: undefined, density: 'compact' });
+ });
});
diff --git a/packages/terra-application/tests/jest/application-base/__snapshots__/ApplicationBase.test.jsx.snap b/packages/terra-application/tests/jest/application-base/__snapshots__/ApplicationBase.test.jsx.snap
index f6e569b18..6f1611cba 100644
--- a/packages/terra-application/tests/jest/application-base/__snapshots__/ApplicationBase.test.jsx.snap
+++ b/packages/terra-application/tests/jest/application-base/__snapshots__/ApplicationBase.test.jsx.snap
@@ -12,6 +12,7 @@ exports[`ApplicationBase should render with all props 1`] = `
theme={
Object {
"className": "test-theme",
+ "density": undefined,
"name": "test-theme",
}
}
@@ -73,6 +74,7 @@ exports[`ApplicationBase should render with minimal props 1`] = `
theme={
Object {
"className": undefined,
+ "density": undefined,
"name": "terra-default-theme",
}
}
@@ -125,6 +127,7 @@ exports[`ApplicationBase should render with the preferred browser local 1`] = `
theme={
Object {
"className": undefined,
+ "density": undefined,
"name": "terra-default-theme",
}
}
@@ -177,6 +180,7 @@ exports[`ApplicationBase should render without scroll 1`] = `
theme={
Object {
"className": undefined,
+ "density": undefined,
"name": "terra-default-theme",
}
}
diff --git a/packages/terra-application/tests/jest/application-navigation/private/utility-menu/__snapshots__/UtilityMenu.test.jsx.snap b/packages/terra-application/tests/jest/application-navigation/private/utility-menu/__snapshots__/UtilityMenu.test.jsx.snap
index 6ee89759f..a96c7c4e8 100644
--- a/packages/terra-application/tests/jest/application-navigation/private/utility-menu/__snapshots__/UtilityMenu.test.jsx.snap
+++ b/packages/terra-application/tests/jest/application-navigation/private/utility-menu/__snapshots__/UtilityMenu.test.jsx.snap
@@ -744,7 +744,7 @@ exports[`UtilityMenu should render with function callbacks 1`] = `
type="button"
>
{
const appSettings = React.useContext(AppSettingsContext);
- const [state, setState] = useState({ locale: appSettings.currentLocale, theme: appSettings.currentTheme, direction: appSettings.currentDirection });
+ const [state, setState] = useState({
+ locale: appSettings.currentLocale, theme: appSettings.currentTheme, density: appSettings.currentDensity, direction: appSettings.currentDirection,
+ });
const {
- locale, theme, direction,
+ locale, theme, density, direction,
} = state;
const { locales, themes, directions } = appSettings;
const disclosureManager = React.useContext(DisclosureManagerContext);
@@ -41,6 +43,7 @@ const SettingsModal = () => {
appSettings.onUpdate({
locale,
theme,
+ density,
direction,
});
disclosureManager.dismiss();
@@ -74,6 +77,7 @@ const SettingsModal = () => {
setState({
locale: event.currentTarget.value,
theme,
+ density,
direction,
});
}}
@@ -95,6 +99,7 @@ const SettingsModal = () => {
setState({
locale,
theme: event.currentTarget.value,
+ density,
direction,
});
}}
@@ -102,6 +107,26 @@ const SettingsModal = () => {
/>
) : undefined}
+
+ {
+ setState({
+ locale,
+ theme,
+ density: event.currentTarget.value,
+ direction,
+ });
+ }}
+ options={[{ value: 'compact', display: 'compact' }, { value: 'comfortable', display: 'comfortable' }, { value: 'spacious', display: 'spacious' }]}
+ />
+
{directions.length > 1 ? (
{
const {
defaultLocale = 'en',
defaultTheme = defaultThemeName,
+ defaultDensity = themesConfig.density,
defaultDirection = 'ltr',
} = settingsConfig;
const [currentLocale, setCurrentLocale] = useState(defaultLocale);
const [currentDirection, setCurrentDirection] = useState(defaultDirection);
const [currentTheme, setCurrentTheme] = useState(defaultTheme);
+ const [currentDensity, setCurrentDensity] = useState(defaultDensity);
/**
* Place settings on dom
@@ -74,7 +76,9 @@ const AppSettingsProvider = ({ settingsConfig, children }) => {
* Handle setting update and store new settings in state.
* @param {*} newSettings
*/
- const onUpdate = ({ locale, theme, direction }) => {
+ const onUpdate = ({
+ locale, theme, density, direction,
+ }) => {
if (locale) {
setCurrentLocale(locale);
}
@@ -83,6 +87,10 @@ const AppSettingsProvider = ({ settingsConfig, children }) => {
setCurrentTheme(theme);
}
+ if (density) {
+ setCurrentDensity(density);
+ }
+
if (direction) {
setCurrentDirection(direction);
}
@@ -92,13 +100,14 @@ const AppSettingsProvider = ({ settingsConfig, children }) => {
locales,
currentLocale,
currentTheme,
+ currentDensity,
currentDirection,
directions: ['ltr', 'rtl'],
themes,
currentThemeClassName: themesMap[currentTheme],
onUpdate,
});
- }, [currentLocale, currentTheme, currentDirection]);
+ }, [currentLocale, currentTheme, currentDensity, currentDirection]);
return (
diff --git a/packages/terra-dev-site/src/site/_DevSiteApplicationBase.jsx b/packages/terra-dev-site/src/site/_DevSiteApplicationBase.jsx
index 91a655e5f..38ccefe1b 100644
--- a/packages/terra-dev-site/src/site/_DevSiteApplicationBase.jsx
+++ b/packages/terra-dev-site/src/site/_DevSiteApplicationBase.jsx
@@ -18,12 +18,13 @@ const propTypes = {
const DevSiteApplicationContainer = ({ children, ApplicationBase }) => {
const isRaw = useRouteMatch('/raw');
- const { currentLocale, currentThemeClassName } = React.useContext(AppSettingsContext);
+ const { currentLocale, currentThemeClassName, currentDensity } = React.useContext(AppSettingsContext);
const AppBase = ApplicationBase || TerraApplicationBase;
return (
diff --git a/packages/terra-dev-site/tests/jest/site/AppSettingsProvider.test.jsx b/packages/terra-dev-site/tests/jest/site/AppSettingsProvider.test.jsx
index f6323e974..240eb38d7 100644
--- a/packages/terra-dev-site/tests/jest/site/AppSettingsProvider.test.jsx
+++ b/packages/terra-dev-site/tests/jest/site/AppSettingsProvider.test.jsx
@@ -18,6 +18,7 @@ describe('ThemeContextProvider', () => {
const config = {
defaultLocale: 'es',
defaultTheme: 'my theme',
+ defaultDensity: 'compact',
defaultDirection: 'rtl',
};
const wrapper = shallow((
diff --git a/packages/terra-dev-site/tests/jest/site/__snapshots__/AppSettingsProvider.test.jsx.snap b/packages/terra-dev-site/tests/jest/site/__snapshots__/AppSettingsProvider.test.jsx.snap
index 3a76d4446..0cb3093fe 100644
--- a/packages/terra-dev-site/tests/jest/site/__snapshots__/AppSettingsProvider.test.jsx.snap
+++ b/packages/terra-dev-site/tests/jest/site/__snapshots__/AppSettingsProvider.test.jsx.snap
@@ -4,6 +4,7 @@ exports[`ThemeContextProvider Snapshots should render with default config specif