Skip to content

Commit

Permalink
Feat(web-twig): Introduce custom Stack spacing #DS-1079
Browse files Browse the repository at this point in the history
  • Loading branch information
crishpeen committed Dec 4, 2023
1 parent b40d453 commit c1fe433
Show file tree
Hide file tree
Showing 8 changed files with 190 additions and 8 deletions.
34 changes: 27 additions & 7 deletions packages/web-twig/src/Resources/components/Stack/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,35 @@ Without lexer:
{% endembed %}
```

## Custom Spacing

You can use the `spacing` prop to apply custom spacing between items. The prop
accepts either a spacing token (eg. `space-100`) or an object with breakpoint keys and spacing token values.

```twig
<Stack hasSpacing spacing="space-1200">
<div>Block 1</div>
<div>Block 2</div>
<div>Block 3</div>
</Stack>
<Stack hasSpacing spacing="{{ { mobile: 'space-400', tablet: 'space-800' } }}">
<div>Block 1</div>
<div>Block 2</div>
<div>Block 3</div>
</Stack>
```

## API

| Name | Type | Default | Required | Description |
| ------------------------- | -------- | ------- | -------- | -------------------------------------- |
| `elementType` | `string` | `div` || Element type of the wrapper element |
| `hasEndDivider` | `bool` | `false` || Render a divider after the last item |
| `hasIntermediateDividers` | `bool` | `false` || Render dividers between items |
| `hasSpacing` | `bool` | `false` || Apply a spacing between items |
| `hasStartDivider` | `bool` | `false` || Render a divider before the first item |
| Name | Type | Default | Required | Description |
| ------------------------- | ----------------------------- | ------- | -------- | ------------------------------------------------------------------- |
| `elementType` | `string` | `div` || Element type of the wrapper element |
| `hasEndDivider` | `bool` | `false` || Render a divider after the last item |
| `hasIntermediateDividers` | `bool` | `false` || Render dividers between items |
| `hasSpacing` | `bool` | `false` || Apply a spacing between items |
| `hasStartDivider` | `bool` | `false` || Render a divider before the first item |
| `spacing` | [`spacing token` \| `object`] | `null` || Custom spacing between items, see [Custom Spacing](#custom-spacing) |

You can add `id`, `data-*` or `aria-*` attributes to further extend component's
descriptiveness and accessibility. Also, UNSAFE styling props are available,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,16 @@
{% include '@components/Stack/stories/StackBlocksWithInnerDividersWithoutVerticalSpacing.twig' %}
</DocsSection>

<DocsSection title="Stacked Blocks with Custom Spacing" stackAlignment="stretch">
{% include '@components/Stack/stories/StackBlocksWithCustomSpacing.twig' %}
</DocsSection>

<DocsSection title="Stacked Blocks with Custom Spacing from Tablet Breakpoint" stackAlignment="stretch">
{% include '@components/Stack/stories/StackBlocksWithCustomSpacingFromTabletBreakpoint.twig' %}
</DocsSection>

<DocsSection title="Stacked Blocks with Custom Spacing for Each Breakpoint" stackAlignment="stretch">
{% include '@components/Stack/stories/StackBlocksWithCustomSpacingForEachBreakpoint.twig' %}
</DocsSection>

{% endblock %}
17 changes: 16 additions & 1 deletion packages/web-twig/src/Resources/components/Stack/Stack.twig
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
{%- set _hasIntermediateDividers = props.hasIntermediateDividers | default(false) -%}
{%- set _hasSpacing = props.hasSpacing | default(false) -%}
{%- set _hasStartDivider = props.hasStartDivider | default(false) -%}
{%- set _spacing = props.spacing | default(null) -%}

{# Class names #}
{%- set _rootClassName = _spiritClassPrefix ~ 'Stack' -%}
Expand All @@ -24,6 +25,20 @@
_styleProps.className,
] -%}

<{{ _elementType }} {{ mainProps(props) }} {{ styleProp(_styleProps) }} {{ classProp(_classNames) }}>
{%- set _style = '' -%}

{%- if _spacing is iterable -%}
{%- for breakpoint, bpValue in _spacing -%}
{%- set suffix = (breakpoint == 'mobile') ? '' : '-' ~ breakpoint -%}
{%- set _style = _style ~ '--stack-spacing' ~ suffix ~ ': var(--spirit-' ~ bpValue ~ ');' -%}
{%- endfor -%}
{%- elseif _spacing -%}
{%- set _style = _style ~ '--stack-spacing: var(--spirit-' ~ _spacing ~ ');' -%}
{%- endif -%}

{# Attributes #}
{%- set _styleAttr = _style or (_styleProps.style is not same as(null)) ? 'style="' ~ _style ~ _styleProps.style | join() ~ '"' -%}

<{{ _elementType }} {{ mainProps(props) }} {{ classProp(_classNames) }} {{ _styleAttr | raw }}>
{%- block content %}{% endblock -%}
</{{ _elementType }}>
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
<div>Block 2</div>
<div>Block 3</div>
</Stack>

<!-- Render as different element type -->
<Stack elementType="ul">
<li>
<div>List item 1</div>
Expand All @@ -14,3 +16,46 @@
<div>List item 1</div>
</li>
</Stack>

<!-- Render with spacing -->
<Stack hasSpacing>
<div>Block 1</div>
<div>Block 2</div>
<div>Block 3</div>
</Stack>

<!-- Render with custom spacing -->
<Stack hasSpacing spacing="space-1200">
<div>Block 1</div>
<div>Block 2</div>
<div>Block 3</div>
</Stack>

<!-- Render with custom breakpoint spacing -->
<Stack hasSpacing spacing="{{ { mobile: 'space-100', tablet: 'space-1000', desktop: 'space-1200' } }}">
<div>Block 1</div>
<div>Block 2</div>
<div>Block 3</div>
</Stack>

<!-- Render with all props -->
<Stack
as="ul"
hasSpacing
spacing="space-1200"
hasEndDivider
hasIntermediateDividers
hasStartDivider
UNSAFE_className="custom-class-name"
UNSAFE_style="color: red;"
>
<li>
<div>List item 1</div>
</li>
<li>
<div>List item 1</div>
</li>
<li>
<div>List item 1</div>
</li>
</Stack>
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
Block 3
</div>
</div>
<!-- Render as different element type -->

<ul class="Stack">
<li>
Expand All @@ -38,5 +39,73 @@
</div>
</li>
</ul>
<!-- Render with spacing -->

<div class="Stack Stack--hasSpacing">
<div>
Block 1
</div>

<div>
Block 2
</div>

<div>
Block 3
</div>
</div>
<!-- Render with custom spacing -->

<div class="Stack Stack--hasSpacing" style="--stack-spacing: var(--spirit-space-1200);">
<div>
Block 1
</div>

<div>
Block 2
</div>

<div>
Block 3
</div>
</div>
<!-- Render with custom breakpoint spacing -->

<div class="Stack Stack--hasSpacing" style="--stack-spacing: var(--spirit-space-100);--stack-spacing-tablet: var(--spirit-space-1000);--stack-spacing-desktop: var(--spirit-space-1200);">
<div>
Block 1
</div>

<div>
Block 2
</div>

<div>
Block 3
</div>
</div>
<!-- Render with all props -->

<div class="Stack Stack--hasEndDivider Stack--hasIntermediateDividers Stack--hasSpacing Stack--hasStartDivider custom-class-name" style="--stack-spacing: var(--spirit-space-1200);color: red;">
<ul>
<li>
<div>
List item 1
</div>
</li>

<li>
<div>
List item 1
</div>
</li>

<li>
<div>
List item 1
</div>
</li>
</ul>
</div>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<Stack elementType="ul" hasSpacing spacing="space-1200">
{% for i in 1..3 %}
<li>
<DocsBox>Block {{ i }}</DocsBox>
</li>
{% endfor %}
</Stack>
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<Stack elementType="ul" hasSpacing spacing="{{ { mobile: 'space-100', tablet: 'space-1000', desktop: 'space-1200' } }}">
{% for i in 1..3 %}
<li>
<DocsBox>Block {{ i }}</DocsBox>
</li>
{% endfor %}
</Stack>
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<Stack elementType="ul" hasSpacing spacing="{{ { tablet: 'space-1200' } }}">
{% for i in 1..3 %}
<li>
<DocsBox>Block {{ i }}</DocsBox>
</li>
{% endfor %}
</Stack>

0 comments on commit c1fe433

Please sign in to comment.