summaryrefslogtreecommitdiff
path: root/components/controls/CollapsibleSection.qml
blob: e1cd35f28030c5b9399b410e6867291f1dfc2e23 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
import ".."
import qs.components
import qs.components.effects
import qs.services
import qs.config
import QtQuick
import QtQuick.Layouts

ColumnLayout {
    id: root

    required property string title
    property string description: ""
    property bool expanded: false

    signal toggleRequested

    spacing: 0
    Layout.fillWidth: true

    Item {
        id: sectionHeaderItem
        Layout.fillWidth: true
        Layout.preferredHeight: Math.max(titleRow.implicitHeight + Appearance.padding.normal * 2, 48)

        RowLayout {
            id: titleRow
            anchors.left: parent.left
            anchors.right: parent.right
            anchors.verticalCenter: parent.verticalCenter
            anchors.leftMargin: Appearance.padding.normal
            anchors.rightMargin: Appearance.padding.normal
            spacing: Appearance.spacing.normal

            StyledText {
                text: root.title
                font.pointSize: Appearance.font.size.larger
                font.weight: 500
            }

            Item {
                Layout.fillWidth: true
            }

            MaterialIcon {
                text: "expand_more"
                rotation: root.expanded ? 180 : 0
                color: Colours.palette.m3onSurfaceVariant
                font.pointSize: Appearance.font.size.normal
                Behavior on rotation {
                    Anim {
                        duration: Appearance.anim.durations.small
                        easing.bezierCurve: Appearance.anim.curves.standard
                    }
                }
            }
        }

        StateLayer {
            anchors.fill: parent
            color: Colours.palette.m3onSurface
            radius: Appearance.rounding.normal
            showHoverBackground: false
            function onClicked(): void {
                root.toggleRequested();
                root.expanded = !root.expanded;
            }
        }
    }

    Item {
        visible: root.description !== ""
        Layout.fillWidth: true
        Layout.preferredHeight: root.expanded ? descriptionText.implicitHeight + Appearance.spacing.smaller + Appearance.spacing.small : 0
        clip: true

        Behavior on Layout.preferredHeight {
            Anim {
                easing.bezierCurve: Appearance.anim.curves.standard
            }
        }

        StyledText {
            id: descriptionText
            anchors.left: parent.left
            anchors.right: parent.right
            anchors.top: parent.top
            anchors.leftMargin: Appearance.padding.normal
            anchors.rightMargin: Appearance.padding.normal
            anchors.topMargin: Appearance.spacing.smaller
            text: root.description
            color: Colours.palette.m3onSurfaceVariant
            font.pointSize: Appearance.font.size.small
            opacity: root.expanded ? 1.0 : 0.0

            Behavior on opacity {
                Anim {
                    easing.bezierCurve: Appearance.anim.curves.standard
                }
            }
        }
    }

    default property alias content: contentColumn.data

    Item {
        id: contentWrapper
        Layout.fillWidth: true
        Layout.preferredHeight: root.expanded ? (contentColumn.implicitHeight + Appearance.spacing.small * 2) : 0
        clip: true

        Behavior on Layout.preferredHeight {
            Anim {
                easing.bezierCurve: Appearance.anim.curves.standard
            }
        }

        ColumnLayout {
            id: contentColumn
            anchors.left: parent.left
            anchors.right: parent.right
            anchors.top: parent.top
            anchors.leftMargin: Appearance.padding.normal
            anchors.rightMargin: Appearance.padding.normal
            anchors.topMargin: Appearance.spacing.small
            anchors.bottomMargin: Appearance.spacing.small
            spacing: Appearance.spacing.small
            opacity: root.expanded ? 1.0 : 0.0

            Behavior on opacity {
                Anim {
                    easing.bezierCurve: Appearance.anim.curves.standard
                }
            }
        }
    }
}