Skip to content

Cursor

v-0.0.0

Type from to

  • Category
    Start
    from
    19,9 kWh
    to
    25 kWh
  • Category
    End
    from
    25 kWh
    to
    34,5 kWh

You:
21KWh

html
 <div class="cursor" data-from="19.9" data-to="34.5">
    <ul class="cursor__graph">
        <li class="cursor__wrapper">
            <dl class="cursor__item">
                <dt class="cursor__title">Category</dt>
                <dd class="cursor__category bg--secondaryLightest">POWER</dd>
                <dt class="cursor__title">from</dt>
                <dd class="cursor__from">19,9 kWh</dd>
                <dt class="cursor__title">to</dt>
                <dd class="cursor__to">25 kWh</dd>
            </dl>
        </li>
        <li class="cursor__wrapper">
            <dl class="cursor__item">
                <dt class="cursor__title">Category</dt>
                <dd class="cursor__category bg--secondary">POWER+</dd>
                <dt class="cursor__title">from</dt>
                <dd class="cursor__from">25 kWh</dd>
                <dt class="cursor__title">to</dt>
                <dd class="cursor__to">34,5 kWh</dd>
            </dl>
        </li>
    </ul>
    <p class="cursor__bubble cursor__bubble--secondary" data-value='21'>You: 25KWh</p>
</div>

Values

  • Category
    Min.
    Minimum
    50 kWh
  • Category
    Mid.
    Average
    100kWh
  • Category
    Max.
    Maximum
    < 150 kWh

You: 126KWh

html
<div class="cursor" data-from="19.9" data-to="34.5">
    <ul class="cursor__graph">
        <li class="cursor__wrapper">
            <dl class="cursor__item">
                <dt class="cursor__title">Category</dt>
                <dd class="cursor__category bg--secondaryLightest">POWER</dd>
                <dt class="cursor__title">from</dt>
                <dd class="cursor__from">19,9 kWh</dd>
                <dt class="cursor__title">to</dt>
                <dd class="cursor__to">25 kWh</dd>
            </dl>
        </li>
        <li class="cursor__wrapper">
            <dl class="cursor__item">
                <dt class="cursor__title">Category</dt>
                <dd class="cursor__category bg--secondary">POWER+</dd>
                <dt class="cursor__title">from</dt>
                <dd class="cursor__from">25 kWh</dd>
                <dt class="cursor__title">to</dt>
                <dd class="cursor__to">34,5 kWh</dd>
            </dl>
        </li>
    </ul>
    <p class="cursor__bubble cursor__bubble--grey" data-value='21'>You: 25KWh</p>
</div>

Disabled

Use case

To see results, complete something somewhere

  • Category
    POWER
    Minimum
    50 kWh
  • Category
    POWER+
    Average
    100kWh
  • Category
    POWER+
    Maximum
    < 150 kWh
html
<div class="cursor cursor--disabled" data-from="50" data-to="150">
    <p class="cursor__emptyMessage">To see results, complete something somewhere</p>
    <ul class="cursor__graph">
        <li class="cursor__wrapper">
            <dl class="cursor__item">
                <dt class="cursor__title">Category</dt>
                <dd class="cursor__category bg--primaryLightest">POWER</dd>
                <dt class="cursor__title">Minimum</dt>
                <dd class="cursor__value">50 kWh</dd>
            </dl>
        </li>
        <li class="cursor__wrapper">
            <dl class="cursor__item">
                <dt class="cursor__title">Category</dt>
                <dd class="cursor__category bg--primary">POWER+</dd>
                <dt class="cursor__title">Average</dt>
                <dd class="cursor__value">100kWh</dd>
            </dl>
        </li>
        <li class="cursor__wrapper">
            <dl class="cursor__item">
                <dt class="cursor__title">Category</dt>
                <dd class="cursor__category bg--primaryDarker">POWER+</dd>
                <dt class="cursor__title">Maximum</dt>
                <dd class="cursor__value">< 150 kWh</dd>
            </dl>
        </li>
    </ul>
</div>

Javascript

js
export default function cursorModule($cursorCollection) {
    $cursorCollection.forEach(($cursor) => {
        const $bubble = $cursor.querySelector('.cursor__bubble')
        const iTarget = Number($bubble.dataset.value)
        const oValues = {
            from: Number($cursor.dataset.from),
            to: Number($cursor.dataset.to),
        }

        /**
         *  Get the children position relative to its parent
         */
        function getRelativePosition($child, $parent) {
            const oParentPosition = $parent.getBoundingClientRect()
            const oChildPosition = $child.getBoundingClientRect()
            return {
                left: oChildPosition.left - oParentPosition.left,
                right: oParentPosition.right - oChildPosition.right,
                top: oChildPosition.top - oParentPosition.top,
                bottom: oParentPosition.bottom - oChildPosition.bottom,
            }
        }

        /**
         * Set the bubble alignment by adding the modified class
         * cursor__bubble--right or cursor__bubble--right to avoid
         * the bubble overflowing on mobile
         */
        function setAligment() {
            const oRelativePosition = getRelativePosition($bubble, $cursor)

            $bubble.classList.toggle(
                'cursor__bubble--right',
                oRelativePosition.left < 0,
            )

            $bubble.classList.toggle(
                'cursor__bubble--left',
                oRelativePosition.right < 0,
            )
        }

        /**
         * Set the position based on the bubble value and the graph's
         * From To data attribute by calculating a percentage of it
         */
        function setPosition() {
            if (!oValues.form && !oValues.to) return

            let iPosition =
                ((iTarget - oValues.from) / (oValues.to - oValues.from)) * 100

            if (iPosition > 100) {
                iPosition = do
            }

            if (iPosition < 0) {
                iPosition = 0
            }

            $bubble.style.setProperty('--offset', `${iPosition}%`)
        }

        /**
         * Init the module
         */
        function init() {
            setPosition()
            setAligment()
        }

        /**
         * Remove aligment classes
         */
        function reset() {
            $bubble.classList.remove('cursor__bubble--left')
            $bubble.classList.remove('cursor__bubble--right')
        }

        /**
         * Reset aligment classes to allow a fluid window resizing to be sure the
         * bubble is correctly placed, then recalculate aligments
         */
        function update() {
            reset()
            setAligment()
        }

        if ($bubble) {
            init()
            window.document.addEventListener('resize', () => update())
        }
    })
}

Do

  • Use this graphic to show simple data

Don't

  • Put too much text in from, to and value.
  • Write more than one word as category name
  • Add padding arround it.