Fluid 1.3.0
Material Design for QtQuick and Qml
Loading...
Searching...
No Matches
FAB.qml
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2026 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
2// SPDX-License-Identifier: MPL-2.0
3
4pragma ComponentBehavior: Bound
5
6import QtQuick
7import QtQuick.Templates as T
8import Fluid as MD
9import "../core/UiMetrics.js" as UiMetrics
10
23T.ToolButton {
24 id: control
25
27 enum Size {
28 Default,
29 Medium,
30 Large
31 }
32
34 enum Variant {
35 Surface,
36 Primary,
37 Secondary,
38 Tertiary
39 }
40
42 property int size: FAB.Size.Default
43
45 property int variant: FAB.Variant.Primary
46
48 property bool lowered: false
49
51 property bool mirrorIconInRtl: false
52
54 property color containerColor: {
55 switch (variant) {
56 case FAB.Variant.Surface:
57 return lowered ? control.MD.Style.surfaceContainerLowColor : control.MD.Style.surfaceContainerHighColor;
58 case FAB.Variant.Primary:
59 return control.MD.Style.primaryContainerColor;
60 case FAB.Variant.Secondary:
61 return control.MD.Style.secondaryContainerColor;
62 case FAB.Variant.Tertiary:
63 return control.MD.Style.tertiaryContainerColor;
64 }
65 }
66
68 property color contentColor: {
69 switch (variant) {
70 case FAB.Variant.Surface:
71 return control.MD.Style.primaryColor;
72 case FAB.Variant.Primary:
73 return control.MD.Style.onPrimaryContainerColor;
74 case FAB.Variant.Secondary:
75 return control.MD.Style.onSecondaryContainerColor;
76 case FAB.Variant.Tertiary:
77 return control.MD.Style.onTertiaryContainerColor;
78 }
79 }
80
82 readonly property color effectiveContentColor: state.contentColor
83
85 readonly property color effectiveContainerColor: state.containerColor
86
88 readonly property real effectiveElevation: state.elevation
89
91 readonly property string effectiveIconName: icon.name
92
94 readonly property url effectiveIconSource: icon.source
95
97 readonly property color effectiveIconColor: icon.color.a > 0 ? icon.color : effectiveContentColor
98
100 readonly property bool effectiveIconMirrored: mirrorIconInRtl && mirrored
101
102 icon.width: state.iconSize
103 icon.height: state.iconSize
104
105 implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, implicitContentWidth + leftPadding + rightPadding)
106 implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, implicitContentHeight + topPadding + bottomPadding)
107
108 leftInset: 0
109 rightInset: 0
110 topInset: 0
111 bottomInset: 0
112 padding: 0
113 spacing: 0
114
115 hoverEnabled: true
116 focusPolicy: Qt.StrongFocus
117
118 Accessible.name: text
119 Accessible.role: Accessible.Button
120
121 QtObject {
122 id: state
123
124 readonly property real containerWidth: {
125 switch (control.size) {
126 case FAB.Size.Default:
127 return MD.Tokens.fab.containerWidth;
128 case FAB.Size.Medium:
129 return MD.Tokens.fab.mediumContainerWidth;
130 case FAB.Size.Large:
131 return MD.Tokens.fab.largeContainerWidth;
132 }
133 }
134 readonly property real containerHeight: {
135 switch (control.size) {
136 case FAB.Size.Default:
137 return MD.Tokens.fab.containerHeight;
138 case FAB.Size.Medium:
139 return MD.Tokens.fab.mediumContainerHeight;
140 case FAB.Size.Large:
141 return MD.Tokens.fab.largeContainerHeight;
142 }
143 }
144 readonly property MD.shapeValue containerShape: {
145 switch (control.size) {
146 case FAB.Size.Default:
147 return MD.Tokens.fab.containerShape;
148 case FAB.Size.Medium:
149 return MD.Tokens.fab.mediumContainerShape;
150 case FAB.Size.Large:
151 return MD.Tokens.fab.largeContainerShape;
152 }
153 }
154 readonly property real iconSize: {
155 switch (control.size) {
156 case FAB.Size.Default:
157 return MD.Tokens.fab.iconSize;
158 case FAB.Size.Medium:
159 return MD.Tokens.fab.mediumIconSize;
160 case FAB.Size.Large:
161 return MD.Tokens.fab.largeIconSize;
162 }
163 }
164
165 property color containerColor: control.containerColor
166 property color contentColor: control.contentColor
167 property color stateLayerColor: "transparent"
168
169 property real elevation: control.lowered ? MD.Tokens.fab.loweredContainerElevation : MD.Tokens.fab.containerElevation
170 property real stateLayerOpacity: 0
171 }
172
173 states: [
174 State {
175 name: "pressed"
176 when: control.down && control.enabled
177
178 PropertyChanges {
179 state.elevation: control.lowered ? MD.Tokens.fab.loweredPressedContainerElevation : MD.Tokens.fab.pressedContainerElevation
180 state.stateLayerColor: control.effectiveIconColor
181 state.stateLayerOpacity: MD.Tokens.fab.pressedStateLayerOpacity
182 }
183 },
184 State {
185 name: "focused"
186 when: control.visualFocus && control.enabled
187
188 PropertyChanges {
189 state.elevation: control.lowered ? MD.Tokens.fab.loweredFocusContainerElevation : MD.Tokens.fab.focusContainerElevation
190 state.stateLayerColor: control.effectiveIconColor
191 state.stateLayerOpacity: MD.Tokens.fab.focusStateLayerOpacity
192 }
193 },
194 State {
195 name: "hovered"
196 when: control.hovered && control.enabled
197
198 PropertyChanges {
199 state.elevation: control.lowered ? MD.Tokens.fab.loweredHoverContainerElevation : MD.Tokens.fab.hoverContainerElevation
200 state.stateLayerColor: control.effectiveIconColor
201 state.stateLayerOpacity: MD.Tokens.fab.hoverStateLayerOpacity
202 }
203 }
204 ]
205
206 contentItem: Item {
207 id: iconContent
208
209 implicitWidth: control.icon.width
210 implicitHeight: control.icon.height
211
212 transform: Scale {
213 origin.x: iconContent.width / 2
214 origin.y: iconContent.height / 2
215 xScale: control.effectiveIconMirrored ? -1 : 1
216 }
217
218 Image {
219 id: sourceIcon
220
221 objectName: "fabSourceImage"
222 anchors.centerIn: parent
223 width: control.icon.width
224 height: control.icon.height
225 source: control.effectiveIconSource
226 sourceSize: Qt.size(control.icon.width, control.icon.height)
227 fillMode: Image.PreserveAspectFit
228 visible: control.effectiveIconSource.toString().length > 0
229 }
230
231 MD.Symbol {
232 objectName: "fabSymbol"
233 anchors.centerIn: parent
234 name: control.effectiveIconName
235 iconWidth: control.icon.width
236 iconHeight: control.icon.height
237 color: control.effectiveIconColor
238 visible: control.effectiveIconSource.toString().length === 0 && name.length > 0
239 }
240 }
241
242 background: MD.ElevationRectangle {
243 implicitWidth: state.containerWidth
244 implicitHeight: state.containerHeight
245 topLeftRadius: UiMetrics.resolveShapeRadius(state.containerShape.topLeft, width, height)
246 topRightRadius: UiMetrics.resolveShapeRadius(state.containerShape.topRight, width, height)
247 bottomLeftRadius: UiMetrics.resolveShapeRadius(state.containerShape.bottomLeft, width, height)
248 bottomRightRadius: UiMetrics.resolveShapeRadius(state.containerShape.bottomRight, width,
249 height)
250 color: state.containerColor
251 elevation: state.elevation
252
253 MD.Ripple {
254 objectName: "fabRipple"
255 anchors.fill: parent
256 topLeftRadius: parent.topLeftRadius
257 topRightRadius: parent.topRightRadius
258 bottomLeftRadius: parent.bottomLeftRadius
259 bottomRightRadius: parent.bottomRightRadius
260 pressed: control.pressed
261 pressX: control.pressX
262 pressY: control.pressY
263 stateOpacity: state.stateLayerOpacity
264 color: state.stateLayerColor
265 }
266 }
267}
A Material Design 3 Expressive floating action button.
Definition FAB.qml:18