feat(css): add CSS utility classes to the ionic theme bundle to match other themes (#29974)

The default (iOS/MD) bundle is removed from the tests for the `ionic` theme because it adds global component styles that the `ionic` theme does not need. The missing utility files are imported, and padding/margin classes are generated from the design tokens, as many tests rely on `ion-padding` and `ion-text-center` being available. This change ensures the `ionic` theme includes the same classes offered in our documentation: https://ionicframework.com/docs/layout/css-utilities.
This commit is contained in:
Brandy Carney
2024-10-30 09:48:32 -04:00
committed by GitHub
parent a5a7bee25c
commit 3306d717ef
67 changed files with 310 additions and 112 deletions

View File

@ -47,6 +47,11 @@
linkTag.setAttribute('href', '/css/ionic/bundle.ionic.css'); linkTag.setAttribute('href', '/css/ionic/bundle.ionic.css');
document.head.appendChild(linkTag); document.head.appendChild(linkTag);
} }
const defaultThemeLinkTag = document.querySelector('link[href*="css/ionic.bundle.css"]');
if (defaultThemeLinkTag) {
defaultThemeLinkTag.remove();
}
} }
window.Ionic = window.Ionic || {}; window.Ionic = window.Ionic || {};

View File

@ -12,6 +12,7 @@
generateTypographyOutput, generateTypographyOutput,
generateValue, generateValue,
generateColorUtilityClasses, generateColorUtilityClasses,
generateDefaultSpaceUtilityClasses,
generateSpaceUtilityClasses, generateSpaceUtilityClasses,
removeConsecutiveRepeatedWords, removeConsecutiveRepeatedWords,
setPrefixValue, setPrefixValue,
@ -23,136 +24,138 @@
} = require('./utils.js'); } = require('./utils.js');
const StyleDictionary = (await import('style-dictionary')).default; const StyleDictionary = (await import('style-dictionary')).default;
// Set the prefix for variables and classes // Set the prefix for variables and classes
setPrefixValue('ion'); setPrefixValue('ion');
// Register a custom file header // Register a custom file header
StyleDictionary.registerFileHeader({ StyleDictionary.registerFileHeader({
name: 'custom-header', name: 'custom-header',
fileHeader: async (defaultMessages = []) => { fileHeader: async (defaultMessages = []) => {
return [...defaultMessages, 'Do not edit directly, this file was auto-generated.']; return [...defaultMessages, 'Do not edit directly, this file was auto-generated.'];
}, },
}); });
// SCSS variables format // SCSS variables format
StyleDictionary.registerFormat({ StyleDictionary.registerFormat({
name: 'scssVariablesFormat', name: 'scssVariablesFormat',
format: async function({ dictionary, file}) { format: async function ({ dictionary, file }) {
console.log('Generating SCSS variables...'); console.log('Generating SCSS variables...');
// Separate typography tokens from the rest // Separate typography tokens from the rest
const typographyProperties = dictionary.allTokens.filter((prop) => prop.$type === 'typography'); const typographyProperties = dictionary.allTokens.filter((prop) => prop.$type === 'typography');
const otherProperties = dictionary.allTokens.filter((prop) => prop.$type !== 'typography'); const otherProperties = dictionary.allTokens.filter((prop) => prop.$type !== 'typography');
// Make sure the reused scss variables are defined first, to avoid compilation errors // Make sure the reused scss variables are defined first, to avoid compilation errors
const sortedProperties = [...otherProperties, ...typographyProperties]; const sortedProperties = [...otherProperties, ...typographyProperties];
const prefixedVariables = sortedProperties.map((prop) => { const prefixedVariables = sortedProperties.map((prop) => {
// Remove consecutive repeated words from the token name, like border-border-color // Remove consecutive repeated words from the token name, like border-border-color
const propName = removeConsecutiveRepeatedWords(prop.name); const propName = removeConsecutiveRepeatedWords(prop.name);
switch (prop.$type) { switch (prop.$type) {
case 'boxShadow': case 'boxShadow':
return generateShadowValue(prop, propName); return generateShadowValue(prop, propName);
case 'fontFamilies': case 'fontFamilies':
return generateFontFamilyValue(prop, propName, 'scss'); return generateFontFamilyValue(prop, propName, 'scss');
case 'fontSizes': case 'fontSizes':
return generateFontSizeValue(prop, propName, 'scss'); return generateFontSizeValue(prop, propName, 'scss');
case 'typography': case 'typography':
return generateTypographyOutput(prop, propName, true); return generateTypographyOutput(prop, propName, true);
default: default:
return generateValue(prop, propName); return generateValue(prop, propName);
} }
}); });
const fileHeader = await file.options.fileHeader(); const fileHeader = await file.options.fileHeader();
return [ return [
`/*\n${fileHeader.join('\n')}\n*/`, `/*\n${fileHeader.join('\n')}\n*/`,
'@use "../themes/functions.sizes" as font;\n', '@use "../themes/functions.sizes" as font;\n',
prefixedVariables.join('\n') + '\n', prefixedVariables.join('\n') + '\n',
].join('\n'); ].join('\n');
}, },
}); });
// Create utility-classes // Create utility-classes
StyleDictionary.registerFormat({ StyleDictionary.registerFormat({
name: 'cssUtilityClassesFormat', name: 'cssUtilityClassesFormat',
format: async function({ dictionary, file}) { format: async function ({ dictionary, file }) {
console.log('Generating Utility-Classes...'); console.log('Generating Utility-Classes...');
// Arrays to store specific utility classes
const typographyUtilityClasses = [];
const otherUtilityClasses = [];
// Generate utility classes for each token // Arrays to store specific utility classes
dictionary.allTokens.map((prop) => { const typographyUtilityClasses = [];
const otherUtilityClasses = [];
const tokenCategory = prop.attributes.category; // Generate utility classes for each token
dictionary.allTokens.map((prop) => {
if (prop.$type === 'fontFamilies' || tokenCategory === 'scale' || tokenCategory === 'backdrop') { const tokenCategory = prop.attributes.category;
// Not creating for the tokens below, as they make no sense to exist as utility-classes.
return;
}
// Remove consecutive repeated words from the token name, like border-border-color if (prop.$type === 'fontFamilies' || tokenCategory === 'scale' || tokenCategory === 'backdrop') {
const propName = removeConsecutiveRepeatedWords(prop.name); // Not creating for the tokens below, as they make no sense to exist as utility-classes.
return;
if (prop.$type === 'typography') { }
// Typography tokens are handled differently, as each might have a different tokenType
return typographyUtilityClasses.push(generateTypographyOutput(prop, propName, false));
} else if(tokenCategory.startsWith('round') || tokenCategory.startsWith('rectangular') || tokenCategory.startsWith('soft')) {
// Generate utility classes for border-radius shape tokens, as they have their own token json file, based on primitive tokens
return otherUtilityClasses.push(generateRadiusUtilityClasses(propName));
} // Remove consecutive repeated words from the token name, like border-border-color
const propName = removeConsecutiveRepeatedWords(prop.name);
let utilityClass = ''; if (prop.$type === 'typography') {
// Typography tokens are handled differently, as each might have a different tokenType
return typographyUtilityClasses.push(generateTypographyOutput(prop, propName, false));
switch (tokenCategory) { } else if (tokenCategory.startsWith('round') || tokenCategory.startsWith('rectangular') || tokenCategory.startsWith('soft')) {
case 'color': // Generate utility classes for border-radius shape tokens, as they have their own token json file, based on primitive tokens
case 'primitives': return otherUtilityClasses.push(generateRadiusUtilityClasses(propName));
case 'semantics': }
case 'text':
case 'bg':
case 'icon':
case 'state':
utilityClass = generateColorUtilityClasses(prop, propName);
break;
case 'border-size':
utilityClass = generateBorderSizeUtilityClasses(propName);
break;
case 'font':
utilityClass = generateFontUtilityClasses(prop, propName);
break;
case 'space':
utilityClass = generateSpaceUtilityClasses(prop, propName);
break;
case 'shadow':
case 'elevation':
utilityClass = generateShadowUtilityClasses(propName);
break;
default:
utilityClass = generateUtilityClasses(tokenCategory, propName);
}
return otherUtilityClasses.push(utilityClass); let utilityClass = '';
});
// Concatenate typography utility classes at the beginning switch (tokenCategory) {
const finalOutput = typographyUtilityClasses.concat(otherUtilityClasses).join('\n'); case 'color':
case 'primitives':
case 'semantics':
case 'text':
case 'bg':
case 'icon':
case 'state':
utilityClass = generateColorUtilityClasses(prop, propName);
break;
case 'border-size':
utilityClass = generateBorderSizeUtilityClasses(propName);
break;
case 'font':
utilityClass = generateFontUtilityClasses(prop, propName);
break;
case 'space':
utilityClass = generateSpaceUtilityClasses(prop, propName);
break;
case 'shadow':
case 'elevation':
utilityClass = generateShadowUtilityClasses(propName);
break;
default:
utilityClass = generateUtilityClasses(tokenCategory, propName);
}
const fileHeader = await file.options.fileHeader(); return otherUtilityClasses.push(utilityClass);
});
return [
`/*\n${fileHeader.join('\n')}\n*/`, const defaultSpaceUtilityClasses = generateDefaultSpaceUtilityClasses();
'@import "./ionic.vars";\n@import "../themes/mixins";\n', otherUtilityClasses.push(defaultSpaceUtilityClasses);
finalOutput,
].join('\n'); // Concatenate typography utility classes at the beginning
const finalOutput = typographyUtilityClasses.concat(otherUtilityClasses).join('\n');
const fileHeader = await file.options.fileHeader();
return [
`/*\n${fileHeader.join('\n')}\n*/`,
'@import "./ionic.vars";\n@import "../themes/mixins";\n',
finalOutput,
].join('\n');
}, },
}); });
@ -163,24 +166,24 @@ module.exports = {
source: ["node_modules/outsystems-design-tokens/tokens/**/*.json"], source: ["node_modules/outsystems-design-tokens/tokens/**/*.json"],
platforms: { platforms: {
scss: { scss: {
transformGroup: "scss", transformGroup: "scss",
buildPath: './src/foundations/', buildPath: './src/foundations/',
files: [ files: [
{ {
destination: "ionic.vars.scss", destination: "ionic.vars.scss",
format: "scssVariablesFormat", format: "scssVariablesFormat",
options: { options: {
fileHeader: `custom-header`, fileHeader: `custom-header`,
},
}, },
{ },
destination: "ionic.utility.scss", {
format: "cssUtilityClassesFormat", destination: "ionic.utility.scss",
options: { format: "cssUtilityClassesFormat",
fileHeader: `custom-header` options: {
} fileHeader: `custom-header`
} }
] }
]
} }
} }
}; };

View File

@ -125,6 +125,73 @@ function generateColorUtilityClasses(prop, className) {
.${variablesPrefix}-background-${className} {\n background-color: $${variablesPrefix}-${prop.name};\n}`; .${variablesPrefix}-background-${className} {\n background-color: $${variablesPrefix}-${prop.name};\n}`;
} }
// Generates margin and padding utility classes to match the token-agnostic
// utilities provided by the Ionic Framework
function generateDefaultSpaceUtilityClasses() {
const zeroMarginPaddingToken = 'space-0';
const defaultMarginPaddingToken = 'space-400';
const marginPaddingTemplate = (type) => `
.${variablesPrefix}-no-${type} {
--${type}-top: #{$${variablesPrefix}-${zeroMarginPaddingToken}};
--${type}-end: #{$${variablesPrefix}-${zeroMarginPaddingToken}};
--${type}-bottom: #{$${variablesPrefix}-${zeroMarginPaddingToken}};
--${type}-start: #{$${variablesPrefix}-${zeroMarginPaddingToken}};
@include ${type}($${variablesPrefix}-${zeroMarginPaddingToken});
};
.${variablesPrefix}-${type} {
--${type}-top: #{$${variablesPrefix}-${defaultMarginPaddingToken}};
--${type}-end: #{$${variablesPrefix}-${defaultMarginPaddingToken}};
--${type}-bottom: #{$${variablesPrefix}-${defaultMarginPaddingToken}};
--${type}-start: #{$${variablesPrefix}-${defaultMarginPaddingToken}};
@include ${type}($${variablesPrefix}-${defaultMarginPaddingToken});
};
.${variablesPrefix}-${type}-top {
--${type}-top: #{$${variablesPrefix}-${defaultMarginPaddingToken}};
@include ${type}($${variablesPrefix}-${defaultMarginPaddingToken}, null, null, null);
};
.${variablesPrefix}-${type}-end {
--${type}-end: #{$${variablesPrefix}-${defaultMarginPaddingToken}};
@include ${type}(null, $${variablesPrefix}-${defaultMarginPaddingToken}, null, null);
};
.${variablesPrefix}-${type}-bottom {
--${type}-bottom: #{$${variablesPrefix}-${defaultMarginPaddingToken}};
@include ${type}(null, null, $${variablesPrefix}-${defaultMarginPaddingToken}, null);
};
.${variablesPrefix}-${type}-start {
--${type}-start: #{$${variablesPrefix}-${defaultMarginPaddingToken}};
@include ${type}(null, null, null, $${variablesPrefix}-${defaultMarginPaddingToken});
};
.${variablesPrefix}-${type}-vertical {
--${type}-top: #{$${variablesPrefix}-${defaultMarginPaddingToken}};
--${type}-bottom: #{$${variablesPrefix}-${defaultMarginPaddingToken}};
@include ${type}($${variablesPrefix}-${defaultMarginPaddingToken}, null, $${variablesPrefix}-${defaultMarginPaddingToken}, null);
};
.${variablesPrefix}-${type}-horizontal {
--${type}-start: #{$${variablesPrefix}-${defaultMarginPaddingToken}};
--${type}-end: #{$${variablesPrefix}-${defaultMarginPaddingToken}};
@include ${type}(null, $${variablesPrefix}-${defaultMarginPaddingToken}, null, $${variablesPrefix}-${defaultMarginPaddingToken});
};
`;
return `${marginPaddingTemplate('margin')}\n${marginPaddingTemplate('padding')}`;
}
// Generates a margin or padding based css utility-class from a space Design Token structure // Generates a margin or padding based css utility-class from a space Design Token structure
function generateSpaceUtilityClasses(prop, className) { function generateSpaceUtilityClasses(prop, className) {
// This exact format is needed so that it compiles the tokens with the expected lint rules // This exact format is needed so that it compiles the tokens with the expected lint rules
@ -203,6 +270,7 @@ module.exports = {
setPrefixValue, setPrefixValue,
generateRadiusUtilityClasses, generateRadiusUtilityClasses,
generateColorUtilityClasses, generateColorUtilityClasses,
generateDefaultSpaceUtilityClasses,
generateSpaceUtilityClasses, generateSpaceUtilityClasses,
removeConsecutiveRepeatedWords, removeConsecutiveRepeatedWords,
generateBorderSizeUtilityClasses, generateBorderSizeUtilityClasses,

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 857 B

After

Width:  |  Height:  |  Size: 857 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 911 B

After

Width:  |  Height:  |  Size: 913 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 855 B

After

Width:  |  Height:  |  Size: 866 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 KiB

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 KiB

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

After

Width:  |  Height:  |  Size: 49 KiB

View File

@ -1 +1,11 @@
@forward "../../foundations/ionic.utility"; @forward "../../foundations/ionic.utility";
// The padding utility is not included here because it
// uses hardcoded pixel values. Instead, the margin
// and padding related utilities are generated by
// the design tokens.
@import "../float-elements";
@import "../text-alignment";
@import "../text-transformation";
@import "../flex-utils";
@import "../display";

View File

@ -3650,3 +3650,115 @@ Do not edit directly, this file was auto-generated.
.ion-soft-2xl { .ion-soft-2xl {
border-radius: $ion-soft-2xl; border-radius: $ion-soft-2xl;
} }
.ion-no-margin {
--margin-top: #{$ion-space-0};
--margin-end: #{$ion-space-0};
--margin-bottom: #{$ion-space-0};
--margin-start: #{$ion-space-0};
@include margin($ion-space-0);
}
.ion-margin {
--margin-top: #{$ion-space-400};
--margin-end: #{$ion-space-400};
--margin-bottom: #{$ion-space-400};
--margin-start: #{$ion-space-400};
@include margin($ion-space-400);
}
.ion-margin-top {
--margin-top: #{$ion-space-400};
@include margin($ion-space-400, null, null, null);
}
.ion-margin-end {
--margin-end: #{$ion-space-400};
@include margin(null, $ion-space-400, null, null);
}
.ion-margin-bottom {
--margin-bottom: #{$ion-space-400};
@include margin(null, null, $ion-space-400, null);
}
.ion-margin-start {
--margin-start: #{$ion-space-400};
@include margin(null, null, null, $ion-space-400);
}
.ion-margin-vertical {
--margin-top: #{$ion-space-400};
--margin-bottom: #{$ion-space-400};
@include margin($ion-space-400, null, $ion-space-400, null);
}
.ion-margin-horizontal {
--margin-start: #{$ion-space-400};
--margin-end: #{$ion-space-400};
@include margin(null, $ion-space-400, null, $ion-space-400);
}
.ion-no-padding {
--padding-top: #{$ion-space-0};
--padding-end: #{$ion-space-0};
--padding-bottom: #{$ion-space-0};
--padding-start: #{$ion-space-0};
@include padding($ion-space-0);
}
.ion-padding {
--padding-top: #{$ion-space-400};
--padding-end: #{$ion-space-400};
--padding-bottom: #{$ion-space-400};
--padding-start: #{$ion-space-400};
@include padding($ion-space-400);
}
.ion-padding-top {
--padding-top: #{$ion-space-400};
@include padding($ion-space-400, null, null, null);
}
.ion-padding-end {
--padding-end: #{$ion-space-400};
@include padding(null, $ion-space-400, null, null);
}
.ion-padding-bottom {
--padding-bottom: #{$ion-space-400};
@include padding(null, null, $ion-space-400, null);
}
.ion-padding-start {
--padding-start: #{$ion-space-400};
@include padding(null, null, null, $ion-space-400);
}
.ion-padding-vertical {
--padding-top: #{$ion-space-400};
--padding-bottom: #{$ion-space-400};
@include padding($ion-space-400, null, $ion-space-400, null);
}
.ion-padding-horizontal {
--padding-start: #{$ion-space-400};
--padding-end: #{$ion-space-400};
@include padding(null, $ion-space-400, null, $ion-space-400);
}