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

Component - Carousel #100

Closed
wucherpfennig opened this issue Jul 3, 2022 · 3 comments · Fixed by #104
Closed

Component - Carousel #100

wucherpfennig opened this issue Jul 3, 2022 · 3 comments · Fixed by #104
Labels
Feature Feature requested Status: Has PR Waiting in PR to be merge

Comments

@wucherpfennig
Copy link
Contributor

Dear All

Again a new component. Please provide some feedback before I create a PR + Docs.

I have tried to cover most of BS5 configuration options. The latest tabler options with dots, thumbs and vertical are included but not available as we are not on the latest version (https://preview.tabler.io/changelog.html).

Remarks:

  • Adding custom content works fine. It is just 'worthless' as I found no easy way to fix the height of the carousel without breaking all mobile breakpoints etc.
{% macro carousel(items, options) %}
    {% set _id = options.id ?? ('carousel-' ~ random(0, 999)) %}
    {% set _extraClass = options.extraClass ?? '' %}

    {% set _interval = options.interval ?? 5000 %}
    {% set _touch_enabled = options.touch ?? true %}
    {% set _pause = options.pause ?? false %}
    {% set _wrap = options.wrap ?? true %}

    {% set _show_controls = options.controls ?? false %}

    {% set _caption_class = options.caption_custom_class ?? 'd-none d-md-block' %}
    {% set _show_caption_background = options.caption_background ?? true %}

    {% set _show_indicators = options.indicators ?? true %}
    {% set _indicators_type = options.indicators_type ?? '' %}
    {% set _indicators_ratio = options.indicators_ratio ?? '' %}
    {% set _indicators_orientation = options.indicators_orientation ?? 'horizontal' %}

    <div id="{{ _id }}" class="carousel slide {{ _extraClass }}" data-bs-ride="carousel"
         data-bs-interval="{{ _interval == false ? 'false' : _interval }}"
         data-bs-touch="{{ _touch_enabled ? 'true' : 'false' }}"
         data-bs-pause="{{ _pause == true ? 'true' : 'hover' }}" data-bs-wrap="{{ _wrap ? 'true' : 'false' }}">
        {% if _show_indicators %}
            {{ _self.carousel_indicators(items, _id, _indicators_type, _indicators_orientation, _indicators_ratio) }}
        {% endif %}
        {% if _show_controls %}
            <button class="carousel-control-prev" type="button" data-bs-target="#{{ _id }}" data-bs-slide="prev">
                <span class="carousel-control-prev-icon" aria-hidden="true"></span>
            </button>
            <button class="carousel-control-next" type="button" data-bs-target="#{{ _id }}" data-bs-slide="next">
                <span class="carousel-control-next-icon" aria-hidden="true"></span>
            </button>
        {% endif %}
        <div class="carousel-inner">
            {% for item in items %}
                {% set _has_custom = item.custom_content is defined %}
                {% if _has_custom %}
                    {# This is useless: breaks contents and no additional value as making everything same size is cumbersome #}
                    <div class="carousel-item">
                        {{ item.custom_content | raw }}
                    </div>
                {% else %}
                    <div class="carousel-item {% if loop.first %}active{% endif %}">
                        <img src="{{ item.image }}" class="d-block w-100" alt="DEMO 123">
                        {% if item.title is defined or item.description is defined %}
                            {% if _show_caption_background %}
                                <div class="carousel-caption-background {{ _caption_class }}"></div>
                            {% endif %}
                            <div class="carousel-caption {{ _caption_class }}">
                                {% if item.title %}
                                    <h3>{{ item.title }}</h3>
                                {% endif %}
                                {% if item.description %}
                                    {{ item.description }}
                                {% endif %}
                            </div>
                        {% endif %}
                    </div>
                {% endif %}
            {% endfor %}
        </div>
    </div>

{% endmacro %}

{% macro carousel_indicators(items, id, type, orientation, ratio) %}
    {% set _typeClass = '' %}
    {% if type == 'dots' %}{% set _typeClass = 'carousel-indicators-dot' %}{% endif %}
    {% if type == 'thumbs' %}{% set _typeClass = 'carousel-indicators-thumb' %}{% endif %}

    {% set _orientationClass = '' %}
    {% if orientation == 'vertical' %}{% set _orientationClass = 'carousel-indicators-vertical' %}{% endif %}
    {% set _ratio = 'ratio ' ~ (ratio == '' ? 'ratio-1x1' : ratio) %}

    <div class="carousel-indicators {{ _typeClass }} {{ _orientationClass }}">
        {% for item in items %}
            {% set _item_class = loop.first ? 'active' : '' %}
            {% set _item_style = '' %}
            {% if type == 'thumbs' %}
                {% set _item_image = item.image ?? '' %}
                {% set _item_class = _item_class ~ ' ' ~ _ratio %}
                {% set _item_style = 'background-image: url(\'' ~ _item_image ~ '\');' %}
            {% endif %}
            <button type="button" data-bs-target="#{{ id }}" data-bs-slide-to="{{ loop.index - 1 }}"
                    class="{{ _item_class }}" style="{{ _item_style }}"></button>
        {% endfor %}
    </div>
{% endmacro %}

Usage:

    {% embed '@Tabler/embeds/card.html.twig' %}
        {% block box_body %}
            {% from 'macro/carousel.html.twig' import carousel %}

            {% set items =
                {
                    'key0' :
                    {
                        'image': 'https://via.placeholder.com/640x360/1485bc/ffffff?text=Image+0',
                    },
                    'keyContent':
                    {
                        'custom_content': '<h1>Hello World</h1>',
                    },
                    'key1' :
                    {
                        'image': 'https://via.placeholder.com/640x360/9dbf00/ffffff?text=Image+1',
                        'title': 'SOME Fancy Title',
                        'description': 'Lorem Ipsum NO HTML',
                    },
                    'key2' :
                    {
                        'image': 'https://via.placeholder.com/640x360/bc147a/ffffff?text=Image+2',
                    },
                    'key3' :
                    {
                        'image': 'https://via.placeholder.com/640x360/1454bc/ffffff?text=Image+3',
                    }
                }
            %}

            {% set options =
                {
                    'interval': false,
                    'controls': true,
                    'indicators': true,
                    'indicators_type': 'thumbs',
                    'indicators_orientation': 'vertical',
                }
            %}

            {{ carousel(items, options) }}

        {% endblock %}
    {% endembed %}
@wucherpfennig
Copy link
Contributor Author

Update with PR #102 everything works as expected.

(ignore the missing slide as it is just a test for raw html content)

grafik

@kevinpapst
Copy link
Owner

Sorry for ghosting your request, it is large and I don't need it yet ... so I tried to hide 😬

In general I love the idea of every pre-made component which we can simply re-use.
Are the array keys key0, keyContent , key1 ... required?

I will have to test it in the demo app for real feedback, I am not good in theoretical code discussions.
Can you just drop a PR?

@wucherpfennig
Copy link
Contributor Author

No the keys are not required but I did not know anyway better. Basically I wanted to create a array containing an assoc array...

What I wanted (what I am currently also using in my project) is an array like:

            {% set items = [] %}
            {% for i in 0..4 %}
                {% set items = items | merge({(loop.index): {'image' : 'https://via.placeholder.com/640x360/1454bc/ffffff?text=Image+' ~ loop.index}}) %}
            {% endfor %}

a more "real life" example:

// Controller

    /**
     * @param Product $product
     * @param string  $language
     *
     * @return Response
     * @throws InvalidArgumentException
     * @throws UnknownProperties
     * @Entity("product", expr="repository.find(id)")
     */
    public function showGallery(Product $product, string $language): Response
    {
        $templateVars = [];
        $images = $this->productViewerCreatorImageService->getProductImages($product, $language);
        if(!empty($images)){
            $templateVars['images'] = [];
            foreach ($images as $index => $image) {
                $templateVars['images'][] = [
                    'image' => $image->large_square,
                ];
            }
        }
        return $this->render('partials/product_viewer/components/_image_gallery.html.twig', $templateVars);
    }
// _image_gallery.html.twig
<div class="product image-gallery">
    {% from 'macro/carousel.html.twig' import carousel %}
    {% set options =
        {
            'interval': 5000,
            'controls': false,
            'indicators': true,
            'indicators_type': 'thumbs',
            'indicators_orientation': 'horizontal',
        } %}
    {{ carousel(images, options) }}
</div>
// some other template using this gallery
                <div class="images col-lg-6 order-md-1 order-2">
                    {{ render(controller(
                        'App\\Controller\\ProductViewer\\ProductViewerImageController::showGallery',
                        { id: product.id, language: language }
                    )) }}
                </div>

This was referenced Jul 5, 2022
@cavasinf cavasinf linked a pull request Jul 25, 2022 that will close this issue
5 tasks
@cavasinf cavasinf added Feature Feature requested Status: Has PR Waiting in PR to be merge labels Aug 24, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feature Feature requested Status: Has PR Waiting in PR to be merge
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants