QML
← All components

Avatar Group

Show several people together in a compact avatar row, with a count for additional members.

import Syidax.Core.Avatar

Supported QML types

TypeDefinition / role
Displays a profile image, icon, letter or initials.
Arranges avatars in an overlapping group and summarizes overflow.

Learn by example

Previews are images of native Qt runs. Use the buttons below each image to view a result.

01 Basic composition

SyAvatarGroup lays the SyAvatar items declared inside it out in one row

Qt capture · image
Basic composition · Default
Default execution
QML code
import QtQuick
import Syidax.Core

Item {
    component EventLog: Rectangle {
        id: logBox
        property var lines: []
        implicitWidth: 440
        implicitHeight: Math.max(56, logText.implicitHeight + 24)
        radius: 4; color: Theme.semantic.backgroundBold
        function log(value) { lines = lines.slice(-3).concat([String(value)]) }
        Text {
            id: logText; x: 12; y: 12; width: parent.width - 24
            text: logBox.lines.length ? logBox.lines.join("\n") : "Interact with the controls to see event results."
            wrapMode: Text.Wrap; color: Theme.semantic.textDefault
            font.family: Theme.monoFontFamily; font.pixelSize: 12
        }
    }

    implicitWidth: Math.max(360, childrenRect.width)
    implicitHeight: childrenRect.height
    id: story

    property QtObject settings: QtObject {
        id: storyArgs
        property string variant: "stack"
        property string size: "medium"
        property int maxCount: 3
        property bool clickable: false
    }

    

    Column {
        spacing: 12
        SyAvatarGroup {
            variant: storyArgs.variant
            size: storyArgs.size
            maxCount: storyArgs.maxCount
            clickable: storyArgs.clickable
            onSelected: (detail) => output.log(("selected: %1").arg(detail.text))
            SyAvatar { text: "Jane Doe"; variant: "purple" }
            SyAvatar { text: "John Smith"; variant: "blue" }
            SyAvatar { text: "Ada Lovelace"; variant: "green" }
            SyAvatar { text: "Grace Hopper"; variant: "orange" }
            SyAvatar { text: "Alan Turing"; variant: "teal" }
        }
        EventLog { id: output }
    }

}

02 variant

variant sets how the members are placed.

Qt capture · image
variant · Default
Default execution
QML code
import QtQuick
import Syidax.Core

Item {
    implicitWidth: Math.max(360, childrenRect.width)
    implicitHeight: childrenRect.height
    readonly property string members: [
        "SyAvatar { text: " + JSON.stringify("Jane Doe") + "; variant: \"purple\" }",
        "SyAvatar { text: " + JSON.stringify("John Smith") + "; variant: \"blue\" }",
        "SyAvatar { text: " + JSON.stringify("Ada Lovelace") + "; variant: \"green\" }"
    ].join("\n")

    Column {
        spacing: 16
        SyAvatarGroup {
            SyAvatar { text: "Jane Doe"; variant: "purple" }
            SyAvatar { text: "John Smith"; variant: "blue" }
            SyAvatar { text: "Ada Lovelace"; variant: "green" }
        }
        SyAvatarGroup {
            variant: "grid"
            SyAvatar { text: "Jane Doe"; variant: "purple" }
            SyAvatar { text: "John Smith"; variant: "blue" }
            SyAvatar { text: "Ada Lovelace"; variant: "green" }
        }
    }
}

03 selected

selected(detail) is the group's only signal; detail is { letter, text, icon, image } of the member that was clicked (icon / image as strings).

Qt capture · image
selected · Default
Default execution
QML code
import QtQuick
import Syidax.Core

Item {
    component EventLog: Rectangle {
        id: logBox
        property var lines: []
        implicitWidth: 440
        implicitHeight: Math.max(56, logText.implicitHeight + 24)
        radius: 4; color: Theme.semantic.backgroundBold
        function log(value) { lines = lines.slice(-3).concat([String(value)]) }
        Text {
            id: logText; x: 12; y: 12; width: parent.width - 24
            text: logBox.lines.length ? logBox.lines.join("\n") : "Interact with the controls to see event results."
            wrapMode: Text.Wrap; color: Theme.semantic.textDefault
            font.family: Theme.monoFontFamily; font.pixelSize: 12
        }
    }

    implicitWidth: Math.max(360, childrenRect.width)
    implicitHeight: childrenRect.height

    Column {
        spacing: 12
        SyAvatarGroup {
            maxCount: 2; clickable: true
            onSelected: (detail) => output.log(("selected: %1").arg(detail.text))
            SyAvatar { text: "Jane Doe"; variant: "purple" }
            SyAvatar { text: "John Smith"; variant: "blue" }
            SyAvatar { text: "Ada Lovelace"; variant: "green" }
            SyAvatar { text: "Grace Hopper"; variant: "orange" }
        }
        EventLog { id: output }
    }
}

04 Avatar grid

Avatar grid, configured with variant.

Qt capture · image
Avatar grid · Result
Default execution
QML code
import QtQuick
import Syidax.Core

Item {
    component EventLog: Rectangle {
        id: logBox
        property var lines: []
        implicitWidth: 440
        implicitHeight: Math.max(56, logText.implicitHeight + 24)
        radius: 4; color: Theme.semantic.backgroundBold
        function log(value) { lines = lines.slice(-3).concat([String(value)]) }
        Text {
            id: logText; x: 12; y: 12; width: parent.width - 24
            text: logBox.lines.length ? logBox.lines.join("\n") : "Interact with the controls to see event results."
            wrapMode: Text.Wrap; color: Theme.semantic.textDefault
            font.family: Theme.monoFontFamily; font.pixelSize: 12
        }
    }

    implicitWidth: Math.max(360, childrenRect.width)
    implicitHeight: childrenRect.height
    id: story

    property QtObject settings: QtObject {
        id: storyArgs
        property string variant: "grid"
        property string size: "medium"
        property int maxCount: 3
        property bool clickable: false
    }

    

    Column {
        spacing: 12
        SyAvatarGroup {
            variant: storyArgs.variant
            size: storyArgs.size
            maxCount: storyArgs.maxCount
            clickable: storyArgs.clickable
            onSelected: (detail) => output.log(("selected: %1").arg(detail.text))
            SyAvatar { text: "Jane Doe"; variant: "purple" }
            SyAvatar { text: "John Smith"; variant: "blue" }
            SyAvatar { text: "Ada Lovelace"; variant: "green" }
            SyAvatar { text: "Grace Hopper"; variant: "orange" }
            SyAvatar { text: "Alan Turing"; variant: "teal" }
        }
        EventLog { id: output }
    }

}

API 37

Hover or select an item for its QML example and copy button.

Properties

PropertyTypeDefaultDescription
——The SyAvatar members (declared or produced by a Repeater).
string"stack"stack (overlap 4 / 6 / 8 px by size) or grid (gap 2 / 4 / 6 px).
string"medium"small 24 · medium 32 · large 40; written into every member.
boolfalsetrue makes every member clickable and enables the "+n" list rows; false leaves a member's own clickable alone.
int0Members shown before the "+n" disc; 0 = all.
var (read-only)—The member items.
int—How many are drawn
var (read-only)—the hidden members.
real (read-only)—The avatar diameter
real (read-only)—the x distance between members.

Methods

MethodDescription
Re-applies size, clickability, visibility and positions to the members (runs automatically on every relevant change).

Signals

SignalArgumentsWhen
detail: { letter, text, icon, image }A visible member was clicked (relayed from the member) or a "+n" list row was clicked; both need clickable.

Behavior

ItemBehavior / conditions
The avatars are the group's children that look like SyAvatar (they expose initials).
At completion, and whenever the children, size, clickable, maxCount or variant change, layout() runs: every member gets the group's size (and clickable: true when the group is clickable — a member's own clickable is left alone otherwise), visible when its index is below shownCount, x = index × step, y = 0, z = index, and its selected is connected to the group's.
At completion, and whenever the children, size, clickable, maxCount or variant change, layout() runs: every member gets the group's size (and clickable: true when the group is clickable — a member's own clickable is left alone otherwise), visible when its index is below shownCount, x = index × step, y = 0, z = index, and its selected is connected to the group's. With the group clickable, the disc and the rows show the pointer cursor, the rows highlight on hover, and a click on a row emits selected with that member's detail and closes the list. The group's selected is the member's selected, relayed: it fires for a visible member only when the member is clickable (every member is when the group is clickable; otherwise the member's own clickable counts) and not disabled. Rows of the list fire only when the group is clickable.
Members shown before the "+n" disc; 0 = all.
stack (overlap 4 / 6 / 8 px by size) or grid (gap 2 / 4 / 6 px).
Re-applies size, clickability, visibility and positions to the members (runs automatically on every relevant change).
small 24 · medium 32 · large 40; written into every member.
true makes every member clickable and enables the "+n" list rows; false leaves a member's own clickable alone.
At completion, and whenever the children, size, clickable, maxCount or variant change, layout() runs: every member gets the group's size (and clickable: true when the group is clickable — a member's own clickable is left alone otherwise), visible when its index is below shownCount, x = index × step, y = 0, z = index, and its selected is connected to the group's.
At completion, and whenever the children, size, clickable, maxCount or variant change, layout() runs: every member gets the group's size (and clickable: true when the group is clickable — a member's own clickable is left alone otherwise), visible when its index is below shownCount, x = index × step, y = 0, z = index, and its selected is connected to the group's. implicitWidth = diameter + (shownCount − 1 + (remaining ? 1 : 0)) × step (0 with no members), implicitHeight = diameter. With maxCount > 0, shownCount = min(maxCount, count) and remaining holds the members beyond it; they are hidden and a "+n" disc (same diameter, lightgray tokens, n = remaining.length) is drawn after the last visible member.
At completion, and whenever the children, size, clickable, maxCount or variant change, layout() runs: every member gets the group's size (and clickable: true when the group is clickable — a member's own clickable is left alone otherwise), visible when its index is below shownCount, x = index × step, y = 0, z = index, and its selected is connected to the group's.
At completion, and whenever the children, size, clickable, maxCount or variant change, layout() runs: every member gets the group's size (and clickable: true when the group is clickable — a member's own clickable is left alone otherwise), visible when its index is below shownCount, x = index × step, y = 0, z = index, and its selected is connected to the group's. stack: step = diameter − (4 | 6 | 8); grid: step = diameter + (2 | 4 | 6). implicitWidth = diameter + (shownCount − 1 + (remaining ? 1 : 0)) × step (0 with no members), implicitHeight = diameter.
At completion, and whenever the children, size, clickable, maxCount or variant change, layout() runs: every member gets the group's size (and clickable: true when the group is clickable — a member's own clickable is left alone otherwise), visible when its index is below shownCount, x = index × step, y = 0, z = index, and its selected is connected to the group's.
A visible member was clicked (relayed from the member) or a "+n" list row was clicked; both need clickable.
diameter is 24 / 32 / 40 for size small / medium / large. stack: step = diameter − (4 | 6 | 8); grid: step = diameter + (2 | 4 | 6). implicitWidth = diameter + (shownCount − 1 + (remaining ? 1 : 0)) × step (0 with no members), implicitHeight = diameter.
implicitWidth = diameter + (shownCount − 1 + (remaining ? 1 : 0)) × step (0 with no members), implicitHeight = diameter.
implicitWidth = diameter + (shownCount − 1 + (remaining ? 1 : 0)) × step (0 with no members), implicitHeight = diameter. With maxCount > 0, shownCount = min(maxCount, count) and remaining holds the members beyond it; they are hidden and a "+n" disc (same diameter, lightgray tokens, n = remaining.length) is drawn after the last visible member.
implicitWidth = diameter + (shownCount − 1 + (remaining ? 1 : 0)) × step (0 with no members), implicitHeight = diameter.
Hovering the disc opens a 160 px popup under it listing each hidden member as a 24 px disc with its initials and colours plus its label (tooltipContent / text / letter, or "Avatar").
Hovering the disc opens a 160 px popup under it listing each hidden member as a 24 px disc with its initials and colours plus its label (tooltipContent / text / letter, or "Avatar").
Hovering the disc opens a 160 px popup under it listing each hidden member as a 24 px disc with its initials and colours plus its label (tooltipContent / text / letter, or "Avatar").
Hovering the disc opens a 160 px popup under it listing each hidden member as a 24 px disc with its initials and colours plus its label (tooltipContent / text / letter, or "Avatar").
With the group clickable, the disc and the rows show the pointer cursor, the rows highlight on hover, and a click on a row emits selected with that member's detail and closes the list.
The group's selected is the member's selected, relayed: it fires for a visible member only when the member is clickable (every member is when the group is clickable; otherwise the member's own clickable counts) and not disabled.

Keyboard

ItemBehavior / conditions
SyAvatar (the members), SyTooltip (if a hover name is wanted on single avatars), SyCard / SyTable (where member rows usually appear).