Skip to content

Commit

Permalink
Feat(web-twig): Add alignmentX and alignmentY prop to Grid component …
Browse files Browse the repository at this point in the history
…#DS-1414
  • Loading branch information
pavelklibani committed Aug 23, 2024
1 parent db53e7e commit cb37679
Show file tree
Hide file tree
Showing 8 changed files with 207 additions and 18 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
{% extends 'layout/plain.html.twig' %}

{% block content %}

<DocsSection title="Equal Columns">
{% include '@components/Grid/stories/GridEqualColumns.twig' %}
</DocsSection>
Expand Down Expand Up @@ -45,4 +44,12 @@
<DocsSection title="Responsive Centered Grid Item">
{% include '@components/Grid/stories/GridResponsiveCenteredGridItem.twig' %}
</DocsSection>

<DocsSection title="Alignment">
{% include '@components/Grid/stories/GridAlignment.twig' %}
</DocsSection>

<DocsSection title="Responsive Alignment">
{% include '@components/Grid/stories/GridResponsiveAlignment.twig' %}
</DocsSection>
{% endblock %}
47 changes: 46 additions & 1 deletion packages/web-twig/src/Resources/components/Grid/Grid.twig
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
{%- set _spacing = props.spacing | default(null) -%}
{%- set _spacingX = props.spacingX | default(null) -%}
{%- set _spacingY = props.spacingY | default(null) -%}
{%- set _alignmentX = props.alignmentX | default('stretch') -%}
{%- set _alignmentY = props.alignmentY | default('stretch') -%}

{# Class names #}
{%- set _rootClassName = _spiritClassPrefix ~ 'Grid' -%}
Expand All @@ -21,7 +23,50 @@
{%- set _colsClasses = [_spiritClassPrefix ~ 'Grid--cols-' ~ _cols] -%}
{%- endif -%}

{%- set _classNames = [ _rootClassName, _styleProps.className ] | merge(_colsClasses) -%}
{%- set _alignmentXClasses = [] -%}
{%- if _alignmentX is iterable and _alignmentX is not null -%}
{%- set hasMobile = false -%}
{%- for breakpoint, breakpointValue in _alignmentX -%}
{%- if breakpoint == 'mobile' -%}
{%- set hasMobile = true -%}
{%- endif -%}
{%- endfor -%}
{%- if not hasMobile -%}
{%- set _alignmentX = { 'mobile': 'stretch' } | merge(_alignmentX) -%}
{%- endif -%}
{%- for breakpoint, breakpointValue in _alignmentX -%}
{%- set infix = (breakpoint == 'mobile') ? '' : '--' ~ breakpoint -%}
{%- set breakpointValueCapitalized = breakpointValue[:1] | upper ~ breakpointValue[1:] -%}
{%- set _alignmentXClasses = _alignmentXClasses | merge([ _spiritClassPrefix ~ 'Grid' ~ infix ~ '--alignmentX' ~ breakpointValueCapitalized ]) -%}
{%- endfor -%}
{%- elseif _alignmentX is not null -%}
{%- set _alignmentXCapitalized = _alignmentX[:1] | upper ~ _alignmentX[1:] -%}
{%- set _alignmentXClasses = [ _spiritClassPrefix ~ 'Grid--alignmentX' ~ _alignmentXCapitalized ] -%}
{%- endif -%}

{%- set _alignmentYClasses = [] -%}
{%- if _alignmentY is iterable and _alignmentY is not null -%}
{%- set hasMobile = false -%}
{%- for breakpoint, breakpointValue in _alignmentY -%}
{%- if breakpoint == 'mobile' -%}
{%- set hasMobile = true -%}
{%- endif -%}
{%- endfor -%}
{%- if not hasMobile -%}
{%- set _alignmentY = { 'mobile': 'stretch' } | merge(_alignmentY) -%}
{%- endif -%}
{%- for breakpoint, breakpointValue in _alignmentY -%}
{%- set infix = (breakpoint == 'mobile') ? '' : '--' ~ breakpoint -%}
{%- set breakpointValueCapitalized = breakpointValue[:1] | upper ~ breakpointValue[1:] -%}
{%- set _alignmentYClasses = _alignmentYClasses | merge([ _spiritClassPrefix ~ 'Grid' ~ infix ~ '--alignmentY' ~ breakpointValueCapitalized ]) -%}
{%- endfor -%}
{%- elseif _alignmentY is not null -%}
{%- set _alignmentYCapitalized = _alignmentY[:1] | upper ~ _alignmentY[1:] -%}
{%- set _alignmentYClasses = [ _spiritClassPrefix ~ 'Grid--alignmentY' ~ _alignmentYCapitalized ] -%}
{%- endif -%}


{%- set _classNames = [ _rootClassName, _styleProps.className ] | merge(_colsClasses, _alignmentXClasses, _alignmentYClasses) -%}
{%- set _style = '' -%}

{%- if _spacing is iterable -%}
Expand Down
56 changes: 49 additions & 7 deletions packages/web-twig/src/Resources/components/Grid/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,15 +96,56 @@ Custom vertical (y-axis) spacing:
</Grid>
```

## Item Alignment

The `alignmentX` and `alignmentY` props are used to control the alignment of items within the `Grid` container.
The available values for these properties can be found in our [alignment dictionary][alignment-dictionary].

`alignmentX`: Manages horizontal alignment, allowing you to position items to the left, center, or right of the container. It can also be configured with responsive values for different breakpoints.
`alignmentY`: Manages vertical alignment, enabling you to position items at the top, center, or bottom of the container. It supports responsive values for various breakpoints as well.

Both props can be set using either fixed values or objects with breakpoint-specific settings to ensure the alignment adapts across different screen sizes.

Horizontal alignment:

```twig
<Grid alignmentX="left">
<!-- Grid content -->
</Grid>
```

Horizontal and vertical alignment:

```twig
<Grid alignmentX="left" alignmentY="top">
<!-- Grid content -->
</Grid>
```

Responsive horizontal and vertical alignment:

```twig
<Grid
alignmentX="{{ { mobile: 'left', tablet: 'center', desktop: 'right' } }}"
alignmentY="{{ { mobile: 'top', tablet: 'center', desktop: 'bottom' } }}"
>
<!-- Grid content -->
</Grid>
```

👉 Please note that the `stretch` option may have undesired impact on elements with a defined size or aspect ratio. The dimensions (or the ratio) will not be respected by `Grid` and the element will be stretched just like any other item.

### API

| Name | Type | Default | Required | Description |
| ------------- | ------------------------------------------------------------ | ------- | -------- | ---------------------------------------------------------------------------------------------------------- |
| `cols` | [`1` \| `2` \| `3` \| `4` \| `5` \| `6` \| `12` \| `object`] | `null` || Number of columns to use, use object to set responsive values, e.g. `{ mobile: 1, tablet: 2, desktop: 3 }` |
| `elementType` | `string` | `div` || HTML tag to render |
| `spacing` | [`spacing token` \| `object`] | `null` || Apply [custom spacing](#custom-spacing) in both horizontal and vertical directions between items |
| `spacingX` | [`spacing token` \| `object`] | `null` || Apply horizontal [custom spacing](#custom-spacing) between items |
| `spacingY` | [`spacing token` \| `object`] | `null` || Apply vertical [custom spacing](#custom-spacing) between items |
| Name | Type | Default | Required | Description |
| ------------- | -------------------------------------------------------------------- | --------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| `alignmentX` | [ [AlignmentXExtended dictionary][dictionary-alignment] \| `object`] | `stretch` || Apply vertical alignment of items, use object to set responsive values, e.g. `{ mobile: 'left', tablet: 'center', desktop: 'right' }` |
| `alignmentY` | [ [AlignmentYExtended dictionary][dictionary-alignment] \| `object`] | `stretch` || Apply horizontal alignment of items, use object to set responsive values, e.g. `{ mobile: 'top', tablet: 'center', desktop: 'bottom' }` |
| `cols` | [`1` \| `2` \| `3` \| `4` \| `5` \| `6` \| `12` \| `object`] | `null` || Number of columns to use, use object to set responsive values, e.g. `{ mobile: 1, tablet: 2, desktop: 3 }` |
| `elementType` | `string` | `div` || HTML tag to render |
| `spacing` | [`spacing token` \| `object`] | `null` || Apply [custom spacing](#custom-spacing) in both horizontal and vertical directions between items |
| `spacingX` | [`spacing token` \| `object`] | `null` || Apply horizontal [custom spacing](#custom-spacing) between items |
| `spacingY` | [`spacing token` \| `object`] | `null` || Apply vertical [custom spacing](#custom-spacing) between items |

On top of the API options, the components accept [additional attributes][readme-additional-attributes].
If you need more control over the styling of a component, you can use [style props][readme-style-props]
Expand Down Expand Up @@ -190,6 +231,7 @@ On top of the API options, the components accept [additional attributes][readme-
If you need more control over the styling of a component, you can use [style props][readme-style-props]
and [escape hatches][readme-escape-hatches].

[dictionary-alignment]: https://github.com/lmc-eu/spirit-design-system/blob/main/docs/DICTIONARIES.md#alignment
[digitalocean-span]: https://www.digitalocean.com/community/tutorials/css-css-grid-layout-span-keyword
[grid]: https://github.com/lmc-eu/spirit-design-system/tree/main/packages/web/src/scss/components/Grid
[readme-additional-attributes]: https://github.com/lmc-eu/spirit-design-system/blob/main/packages/web-twig/README.md#additional-attributes
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,29 @@
<li>col 5</li>
<li>col 6</li>
</Grid>

<!-- Render with item alignment -->
<Grid cols="2" alignmentX="left" alignmentY="top">
<span>col 1</span>
<span>col 2</span>
</Grid>

<!-- Render with responsive item with all alignments -->
<Grid
cols="2"
alignmentX="{{ { mobile: 'left', tablet: 'center', desktop: 'right' } }}"
alignmentY="{{ { mobile: 'top', tablet: 'center', desktop: 'bottom' } }}"
>
<span>col 1</span>
<span>col 2</span>
</Grid>

<!-- Render with responsive item with some alignments -->
<Grid
cols="2"
alignmentX="{{ { tablet: 'center', desktop: 'right' } }}"
alignmentY="{{ { tablet: 'center', desktop: 'bottom' } }}"
>
<span>col 1</span>
<span>col 2</span>
</Grid>
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,16 @@
</title>
</head>
<body>
<div class="Grid">
<div class="Grid Grid--alignmentXStretch Grid--alignmentYStretch">
</div>
<!-- Render with two columns -->

<div class="Grid Grid--cols-2">
<div class="Grid Grid--cols-2 Grid--alignmentXStretch Grid--alignmentYStretch">
<span>col 1</span>
</div>
<!-- Render as unordered list -->

<ul class="Grid">
<ul class="Grid Grid--alignmentXStretch Grid--alignmentYStretch">
<li>col 1
</li>

Expand All @@ -23,27 +23,27 @@
</ul>
<!-- Render with responsive number of columns -->

<div class="Grid Grid--cols-2 Grid--tablet--cols-3 Grid--desktop--cols-4">
<div class="Grid Grid--cols-2 Grid--tablet--cols-3 Grid--desktop--cols-4 Grid--alignmentXStretch Grid--alignmentYStretch">
<span>col 1</span> <span>col 2</span> <span>col 3</span> <span>col 4</span> <span>col 5</span> <span>col 6</span>
</div>
<!-- Render with uniform spacing for both axes -->

<div class="Grid" style="--grid-spacing-x: var(--spirit-space-1000); --grid-spacing-y: var(--spirit-space-1000);">
<div class="Grid Grid--alignmentXStretch Grid--alignmentYStretch" style="--grid-spacing-x: var(--spirit-space-1000); --grid-spacing-y: var(--spirit-space-1000);">
<span>col 1</span> <span>col 2</span> <span>col 3</span> <span>col 4</span> <span>col 5</span> <span>col 6</span>
</div>
<!-- Render with responsive spacing for both axes -->

<div class="Grid" style="--grid-spacing-x: var(--spirit-space-600); --grid-spacing-y: var(--spirit-space-600);--grid-spacing-x-tablet: var(--spirit-space-1000); --grid-spacing-y-tablet: var(--spirit-space-1000);--grid-spacing-x-desktop: var(--spirit-space-1200); --grid-spacing-y-desktop: var(--spirit-space-1200);">
<div class="Grid Grid--alignmentXStretch Grid--alignmentYStretch" style="--grid-spacing-x: var(--spirit-space-600); --grid-spacing-y: var(--spirit-space-600);--grid-spacing-x-tablet: var(--spirit-space-1000); --grid-spacing-y-tablet: var(--spirit-space-1000);--grid-spacing-x-desktop: var(--spirit-space-1200); --grid-spacing-y-desktop: var(--spirit-space-1200);">
<span>col 1</span> <span>col 2</span> <span>col 3</span> <span>col 4</span> <span>col 5</span> <span>col 6</span>
</div>
<!-- Render with responsive spacing for horizontal axis from tablet up -->

<div class="Grid" style="--grid-spacing-x-tablet: var(--spirit-space-1000);">
<div class="Grid Grid--alignmentXStretch Grid--alignmentYStretch" style="--grid-spacing-x-tablet: var(--spirit-space-1000);">
<span>col 1</span> <span>col 2</span> <span>col 3</span> <span>col 4</span> <span>col 5</span> <span>col 6</span>
</div>
<!-- Render with all props -->

<ul class="Grid custom-class Grid--cols-2 Grid--tablet--cols-3 Grid--desktop--cols-4" style="--grid-spacing-x: var(--spirit-space-100); --grid-spacing-y: var(--spirit-space-100);--grid-spacing-x-tablet: var(--spirit-space-200); --grid-spacing-y-tablet: var(--spirit-space-200);--grid-spacing-x-desktop: var(--spirit-space-300); --grid-spacing-y-desktop: var(--spirit-space-300);--grid-spacing-x: var(--spirit-space-400);--grid-spacing-x-tablet: var(--spirit-space-500);--grid-spacing-x-desktop: var(--spirit-space-600);--grid-spacing-y: var(--spirit-space-700);--grid-spacing-y-tablet: var(--spirit-space-800);--grid-spacing-y-desktop: var(--spirit-space-900);">
<ul class="Grid custom-class Grid--cols-2 Grid--tablet--cols-3 Grid--desktop--cols-4 Grid--alignmentXStretch Grid--alignmentYStretch" style="--grid-spacing-x: var(--spirit-space-100); --grid-spacing-y: var(--spirit-space-100);--grid-spacing-x-tablet: var(--spirit-space-200); --grid-spacing-y-tablet: var(--spirit-space-200);--grid-spacing-x-desktop: var(--spirit-space-300); --grid-spacing-y-desktop: var(--spirit-space-300);--grid-spacing-x: var(--spirit-space-400);--grid-spacing-x-tablet: var(--spirit-space-500);--grid-spacing-x-desktop: var(--spirit-space-600);--grid-spacing-y: var(--spirit-space-700);--grid-spacing-y-tablet: var(--spirit-space-800);--grid-spacing-y-desktop: var(--spirit-space-900);">
<li>col 1
</li>

Expand All @@ -62,5 +62,20 @@
<li>col 6
</li>
</ul>
<!-- Render with item alignment -->

<div class="Grid Grid--cols-2 Grid--alignmentXLeft Grid--alignmentYTop">
<span>col 1</span> <span>col 2</span>
</div>
<!-- Render with responsive item with all alignments -->

<div class="Grid Grid--cols-2 Grid--alignmentXLeft Grid--tablet--alignmentXCenter Grid--desktop--alignmentXRight Grid--alignmentYTop Grid--tablet--alignmentYCenter Grid--desktop--alignmentYBottom">
<span>col 1</span> <span>col 2</span>
</div>
<!-- Render with responsive item with some alignments -->

<div class="Grid Grid--cols-2 Grid--alignmentXStretch Grid--tablet--alignmentXCenter Grid--desktop--alignmentXRight Grid--alignmentYStretch Grid--tablet--alignmentYCenter Grid--desktop--alignmentYBottom">
<span>col 1</span> <span>col 2</span>
</div>
</body>
</html>
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
</title>
</head>
<body>
<div class="Grid">
<div class="Grid Grid--alignmentXStretch Grid--alignmentYStretch">
<div class="GridItem d-tablet-none" style="--grid-item-column-start: 1;--grid-item-column-end: 10;">
1&acirc;&#128;&#147;10
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<Grid cols="2">
<Grid cols="1" UNSAFE_className="bg-cover">
<DocsBox size="small">Stretch (default)<br/>…</DocsBox>
</Grid>
<Grid cols="1" UNSAFE_className="bg-cover">
<DocsBox size="small">Stretch (default)</DocsBox>
</Grid>
</Grid>

<Grid cols="2">
<Grid cols="1" alignmentX="left" alignmentY="top" UNSAFE_className="bg-cover">
<DocsBox size="small">Left<br/>…</DocsBox>
</Grid>
<Grid cols="1" alignmentX="left" alignmentY="top" UNSAFE_className="bg-cover">
<DocsBox size="small">Top</DocsBox>
</Grid>
</Grid>

<Grid cols="2" >
<Grid cols="1" alignmentX="center" alignmentY="center" UNSAFE_className="bg-cover">
<DocsBox size="small">Center<br/>…</DocsBox>
</Grid>
<Grid cols="1" alignmentX="center" alignmentY="center" UNSAFE_className="bg-cover">
<DocsBox size="small">Center</DocsBox>
</Grid>
</Grid>

<Grid cols="2">
<Grid cols="1" alignmentX="right" alignmentY="bottom" UNSAFE_className="bg-cover">
<DocsBox size="small">Right<br/>…</DocsBox>
</Grid>
<Grid cols="1" alignmentX="right" alignmentY="bottom" UNSAFE_className="bg-cover">
<DocsBox size="small">Bottom</DocsBox>
</Grid>
</Grid>
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<Grid cols="2"
>
<Grid
cols="1"
alignmentX="{{ { mobile: 'left', tablet: 'center', desktop: 'right' } }}"
alignmentY="{{ { mobile: 'top', tablet: 'center', desktop: 'bottom' } }}"
UNSAFE_className="bg-cover"
>
<DocsBox size="small">Horizontal Alignment<br/>…</DocsBox>
</Grid>
<Grid
cols="1"
alignmentX="{{ { mobile: 'left', tablet: 'center', desktop: 'right' } }}"
alignmentY="{{ { mobile: 'top', tablet: 'center', desktop: 'bottom' } }}"
UNSAFE_className="bg-cover"
>
<DocsBox size="small">Vertical Alignment</DocsBox>
</Grid>
</Grid>

0 comments on commit cb37679

Please sign in to comment.