Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add grid gap property for more flexibility #732

Merged
merged 4 commits into from
Jan 15, 2025
Merged
Changes from all commits
Commits
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
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions packages/angular/src/lib/stencil-generated/components.ts
Original file line number Diff line number Diff line change
@@ -522,14 +522,14 @@ export declare interface GcdsFooter extends Components.GcdsFooter {}


@ProxyCmp({
inputs: ['alignContent', 'alignItems', 'centered', 'columns', 'columnsDesktop', 'columnsTablet', 'container', 'display', 'equalRowHeight', 'justifyContent', 'justifyItems', 'placeContent', 'placeItems', 'tag']
inputs: ['alignContent', 'alignItems', 'centered', 'columns', 'columnsDesktop', 'columnsTablet', 'container', 'display', 'equalRowHeight', 'gap', 'gapDesktop', 'gapTablet', 'justifyContent', 'justifyItems', 'placeContent', 'placeItems', 'tag']
})
@Component({
selector: 'gcds-grid',
changeDetection: ChangeDetectionStrategy.OnPush,
template: '<ng-content></ng-content>',
// eslint-disable-next-line @angular-eslint/no-inputs-metadata-property
inputs: ['alignContent', 'alignItems', 'centered', 'columns', 'columnsDesktop', 'columnsTablet', 'container', 'display', 'equalRowHeight', 'justifyContent', 'justifyItems', 'placeContent', 'placeItems', 'tag'],
inputs: ['alignContent', 'alignItems', 'centered', 'columns', 'columnsDesktop', 'columnsTablet', 'container', 'display', 'equalRowHeight', 'gap', 'gapDesktop', 'gapTablet', 'justifyContent', 'justifyItems', 'placeContent', 'placeItems', 'tag'],
standalone: false,
})
export class GcdsGrid {
3 changes: 3 additions & 0 deletions packages/vue/lib/components.ts
Original file line number Diff line number Diff line change
@@ -196,6 +196,9 @@ export const GcdsGrid = /*@__PURE__*/ defineContainer<JSX.GcdsGrid>('gcds-grid',
'centered',
'display',
'equalRowHeight',
'gap',
'gapTablet',
'gapDesktop',
'tag',
'alignContent',
'justifyContent',
2 changes: 1 addition & 1 deletion packages/web/package.json
Original file line number Diff line number Diff line change
@@ -45,7 +45,7 @@
"@babel/core": "^7.20.12",
"@babel/preset-env": "^7.20.2",
"@babel/preset-typescript": "^7.21.0",
"@cdssnc/gcds-tokens": "^2.0.4",
"@cdssnc/gcds-tokens": "^2.1.0",
"@fortawesome/fontawesome-free": "^6.3.0",
"@stencil/angular-output-target": "file:../../utils/angular-output-target",
"@stencil/postcss": "^2.1.0",
44 changes: 40 additions & 4 deletions packages/web/src/components.d.ts
Original file line number Diff line number Diff line change
@@ -7,11 +7,11 @@
import { HTMLStencilElement, JSXBase } from "@stencil/core/internal";
import { Validator, ValidatorEntry } from "./validators";
import { SpacingValues } from "./utils/types/spacing";
import { ContentValues } from "./components/gcds-grid/gcds-grid";
import { ContentValues, SpacingValues as SpacingValues1 } from "./components/gcds-grid/gcds-grid";
import { RadioObject } from "./components/gcds-radio-group/gcds-radio-group";
export { Validator, ValidatorEntry } from "./validators";
export { SpacingValues } from "./utils/types/spacing";
export { ContentValues } from "./components/gcds-grid/gcds-grid";
export { ContentValues, SpacingValues as SpacingValues1 } from "./components/gcds-grid/gcds-grid";
export { RadioObject } from "./components/gcds-radio-group/gcds-radio-group";
export namespace Components {
interface GcdsAlert {
@@ -434,10 +434,16 @@ export namespace Components {
*/
"centered"?: boolean;
/**
* Defines the columns of the grid Option to set different layouts for desktop | tablet | default (includes mobile)
* Defines the default number of grid columns for all viewports if columnsTablet and columnsDesktop are not defined. Option to set different layouts for desktop with columnsDesktop and for tablet with columnsTablet.
*/
"columns"?: string;
/**
* Provides option to set a different number of grid columns for desktop screens.
*/
"columnsDesktop"?: string;
/**
* Provides option to set a different number of grid columns for tablet screens. If columnsDesktop is not defined, columnsTablet will be used to define the number of columns for desktop as well.
*/
"columnsTablet"?: string;
/**
* Defines grid container size
@@ -451,6 +457,18 @@ export namespace Components {
* Sets all grid items to have an equal height, based on the tallest item.
*/
"equalRowHeight"?: boolean;
/**
* Defines the horizontal and vertical spacing between items in a grid container for all viewports if gapTablet and gapDesktop are not defined. Option to set different spacing for desktop with gapDesktop and for tablet with gapTablet.
*/
"gap"?: SpacingValues1;
/**
* Provides option to set horizontal and vertical spacing between items in a grid container for desktop screens.
*/
"gapDesktop"?: SpacingValues1;
/**
* Provides option to set horizontal and vertical spacing between items in a grid container for tablet screens. If gapDesktop is not defined, gapTablet will be used to define the spacing for desktop screens as well.
*/
"gapTablet"?: SpacingValues1;
/**
* If total grid size is less than the size of its grid container, this property aligns the grid along the inline (row) axis
*/
@@ -2239,10 +2257,16 @@ declare namespace LocalJSX {
*/
"centered"?: boolean;
/**
* Defines the columns of the grid Option to set different layouts for desktop | tablet | default (includes mobile)
* Defines the default number of grid columns for all viewports if columnsTablet and columnsDesktop are not defined. Option to set different layouts for desktop with columnsDesktop and for tablet with columnsTablet.
*/
"columns"?: string;
/**
* Provides option to set a different number of grid columns for desktop screens.
*/
"columnsDesktop"?: string;
/**
* Provides option to set a different number of grid columns for tablet screens. If columnsDesktop is not defined, columnsTablet will be used to define the number of columns for desktop as well.
*/
"columnsTablet"?: string;
/**
* Defines grid container size
@@ -2256,6 +2280,18 @@ declare namespace LocalJSX {
* Sets all grid items to have an equal height, based on the tallest item.
*/
"equalRowHeight"?: boolean;
/**
* Defines the horizontal and vertical spacing between items in a grid container for all viewports if gapTablet and gapDesktop are not defined. Option to set different spacing for desktop with gapDesktop and for tablet with gapTablet.
*/
"gap"?: SpacingValues1;
/**
* Provides option to set horizontal and vertical spacing between items in a grid container for desktop screens.
*/
"gapDesktop"?: SpacingValues1;
/**
* Provides option to set horizontal and vertical spacing between items in a grid container for tablet screens. If gapDesktop is not defined, gapTablet will be used to define the spacing for desktop screens as well.
*/
"gapTablet"?: SpacingValues1;
/**
* If total grid size is less than the size of its grid container, this property aligns the grid along the inline (row) axis
*/
2 changes: 2 additions & 0 deletions packages/web/src/components/gcds-grid/gcds-grid.css
Original file line number Diff line number Diff line change
@@ -205,6 +205,7 @@
--gcds-grid-columns-tablet,
var(--gcds-grid-columns, 1fr)
);
gap: var(--gcds-grid-gap-tablet, var(--gcds-grid-gap));

/* Grid with cols */
&.display-grid-with-cols {
@@ -225,6 +226,7 @@
--gcds-grid-columns-desktop,
var(--gcds-grid-columns-tablet, var(--gcds-grid-columns, 1fr))
);
gap: var(--gcds-grid-gap-desktop, var(--gcds-grid-gap-tablet, var(--gcds-grid-gap)));

/* Grid with cols */
&.display-grid-with-cols {
145 changes: 128 additions & 17 deletions packages/web/src/components/gcds-grid/gcds-grid.tsx
Original file line number Diff line number Diff line change
@@ -9,6 +9,43 @@ export type ContentValues =
| 'start'
| 'stretch';

export type SpacingValues =
| '150'
| '175'
| '200'
| '225'
| '250'
| '300'
| '350'
| '400'
| '450'
| '500'
| '550'
| '600'
| '650'
| '700'
| '750'
| '800';

const SpacingArray = [
'150',
'175',
'200',
'225',
'250',
'300',
'350',
'400',
'450',
'500',
'550',
'600',
'650',
'700',
'750',
'800',
];

@Component({
tag: 'gcds-grid',
styleUrl: 'gcds-grid.css',
@@ -22,11 +59,22 @@ export class GcdsGrid {
*/

/**
* Defines the columns of the grid
* Option to set different layouts for desktop | tablet | default (includes mobile)
* Defines the default number of grid columns for all viewports if columnsTablet
* and columnsDesktop are not defined. Option to set different layouts for
* desktop with columnsDesktop and for tablet with columnsTablet.
*/
@Prop() columns?: string;

/**
* Provides option to set a different number of grid columns for tablet screens.
* If columnsDesktop is not defined, columnsTablet will be used to define the
* number of columns for desktop as well.
*/
@Prop() columnsTablet?: string;

/**
* Provides option to set a different number of grid columns for desktop screens.
*/
@Prop() columnsDesktop?: string;

/**
@@ -50,6 +98,56 @@ export class GcdsGrid {
*/
@Prop() equalRowHeight?: boolean = false;

/**
* Defines the horizontal and vertical spacing between items in
* a grid container for all viewports if gap-tablet and gap-desktop
* are not defined. Option to set different spacing for desktop
* with gap-desktop and for tablet with gap-tablet.
*/
@Prop() gap?: SpacingValues = '300';

@Watch('gap')
validateGap(newValue: string) {
const values = SpacingArray;

if (!values.includes(newValue)) {
this.gap = '300';
}
}

/**
* Provides option to set horizontal and vertical spacing between items in a
* grid container for tablet screens. If gap-desktop is not defined, gap-tablet
* will be used to define the spacing for desktop screens as well.
*/
@Prop() gapTablet?: SpacingValues;

@Watch('gapTablet')
validateGapTablet(newValue: string) {
const values = SpacingArray;

if (newValue != undefined && !values.includes(newValue)) {
this.gapTablet = undefined;
console.error('Not a valid spacing value for gap-tablet.');
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

}
}

/**
* Provides option to set horizontal and vertical spacing between items
* in a grid container for desktop screens.
*/
@Prop() gapDesktop?: SpacingValues;

@Watch('gapDesktop')
validateGapDesktop(newValue: string) {
const values = SpacingArray;

if (newValue != undefined && !values.includes(newValue)) {
this.gapDesktop = undefined;
console.error('Not a valid spacing value for gap-desktop.');
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another spot where we can use the logError helper util

}
}

/**
* Set tag for grid container
*/
@@ -118,6 +216,9 @@ export class GcdsGrid {
componentWillLoad() {
// Validate attributes and set defaults
this.validateTag(this.tag);
this.validateGap(this.gap);
this.validateGapTablet(this.gapTablet);
this.validateGapDesktop(this.gapDesktop);
}

render() {
@@ -131,6 +232,9 @@ export class GcdsGrid {
centered,
display,
equalRowHeight,
gap,
gapTablet,
gapDesktop,
justifyContent,
justifyItems,
placeContent,
@@ -155,35 +259,42 @@ export class GcdsGrid {
${placeItems ? `place-items-${placeItems}` : ''}
`;

// Set CSS variables in style attribute based on passed column properties
function handleColumns() {
const responsiveColumns = {};
// Set CSS variables in style attribute based on passed column + gap properties
function handleGridStyles() {
const gridStyles = {};

if (columns) {
responsiveColumns['--gcds-grid-columns'] = columns;
}
const setGridProperty = (value, property, suffix = '') => {
const gapValue = `var(--gcds-grid-gap-${value})`;
const tokenValue = property === 'gap' ? gapValue : value;

if (columnsTablet) {
responsiveColumns['--gcds-grid-columns-tablet'] = columnsTablet;
}
if (value) {
gridStyles[`--gcds-grid-${property}${suffix}`] = tokenValue;
}
};

if (columnsDesktop) {
responsiveColumns['--gcds-grid-columns-desktop'] = columnsDesktop;
}
// Handle columns
setGridProperty(columns, 'columns');
setGridProperty(columnsTablet, 'columns', '-tablet');
setGridProperty(columnsDesktop, 'columns', '-desktop');

// Handle gap
setGridProperty(gap, 'gap');
setGridProperty(gapTablet, 'gap', '-tablet');
setGridProperty(gapDesktop, 'gap', '-desktop');
Comment on lines +275 to +283
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is clear, it's great!


return responsiveColumns;
return gridStyles;
}

return (
<Host>
{container ? (
<gcds-container size={container} centered={centered}>
<Tag class={classNames} style={handleColumns()}>
<Tag class={classNames} style={handleGridStyles()}>
<slot />
</Tag>
</gcds-container>
) : (
<Tag class={classNames} style={handleColumns()}>
<Tag class={classNames} style={handleGridStyles()}>
<slot />
</Tag>
)}
2 changes: 1 addition & 1 deletion packages/web/src/components/gcds-grid/readme.md
Original file line number Diff line number Diff line change
@@ -16,4 +16,4 @@

----------------------------------------------

*Built with [StencilJS](https://stenciljs.com/)*
*Built with [StencilJS](https://stenciljs.com/)*
Loading