4pragma ComponentBehavior: Bound
7import QtQuick.Templates as T
9import "../core/BadgeContent.js" as BadgeContent
10import "../internal" as Internal
41 property var badgeContent: _badgeAction ? _badgeAction.badgeContent :
""
44 property bool badgeNotification: _badgeAction ? _badgeAction.badgeNotification :
false
47 property bool badgeVisible: _badgeAction ? _badgeAction.badgeVisible :
true
50 property string badgeAccessibleDescription: _badgeAction ? _badgeAction.badgeAccessibleDescription :
""
53 property int badgeVariant: MD.Badge.Auto
55 readonly
property MD.Action _badgeAction: action as MD.Action
56 readonly
property bool _showBadge: badgeVisible
57 && (badgeNotification || BadgeContent.hasContent(badgeContent))
58 readonly property
bool _useTrailingBadge: _expandedPlacement && _hasLabel
59 && !badgeNotification && badgeVariant !== MD.
Badge.Small
65 property bool tintSourceIcon: true
68 property color selectedIconColor: control.MD.Style.onSecondaryContainerColor
71 property color selectedLabelColor: control.MD.Style.secondaryColor
74 property color selectedIndicatorColor: control.MD.Style.secondaryContainerColor
77 property color unselectedIconColor: control.MD.Style.onSurfaceVariantColor
80 property color unselectedLabelColor: control.MD.Style.onSurfaceVariantColor
86 property int _railIndex: -1
89 readonly property bool _railExpanded: rail ? rail.expanded : false
92 readonly property bool _tabStop: !rail || rail._tabStopIndex === _railIndex
95 readonly property real _positionProgress: rail ? rail._layoutProgress
96 : (_railExpanded ? 1 : 0)
99 readonly property bool _expandedPlacement: _positionProgress >= 0.5
102 readonly property bool _hasNamedIcon: icon.name.length > 0
105 readonly property bool _hasSourceIcon: icon.source.toString().length > 0
108 readonly property bool _hasLabel: text.length > 0
111 readonly property color _iconColor: checked ? selectedIconColor : unselectedIconColor
114 readonly property color _labelColor: checked ? selectedLabelColor : unselectedLabelColor
117 readonly property real _contentOpacity: enabled ? 1 : MD.
Tokens.navigationRail.disabledContentOpacity
120 readonly property real _stateLayerOpacity: {
124 return MD.
Tokens.navigationRail.pressedStateLayerOpacity;
126 return MD.Tokens.navigationRail.focusStateLayerOpacity;
128 return MD.Tokens.navigationRail.hoverStateLayerOpacity;
135 focusPolicy: _tabStop || activeFocus ? Qt.StrongFocus : Qt.ClickFocus
137 spacing: _railExpanded ? MD.Tokens.navigationRail.horizontalIconLabelSpace
138 : MD.Tokens.navigationRail.verticalIconLabelSpace
140 icon.width: MD.Tokens.navigationRail.iconSize
141 icon.height: MD.Tokens.navigationRail.iconSize
143 Accessible.role: Accessible.PageTab
144 Accessible.name: BadgeContent.accessibleName(text,
145 trailingBadge && trailingBadge.visible ? trailingBadge.accessibleDescription
146 : overlayBadge && overlayBadge.visible ? overlayBadge.accessibleDescription :
"")
147 Accessible.selectable: true
148 Accessible.selected: checked
150 Accessible.onPressAction: control.click()
153 readonly property real _expandedImplicitWidth:
154 MD.
Tokens.navigationRail.horizontalFullWidthLeadingSpace
157 ? MD.
Tokens.navigationRail.horizontalIconLabelSpace
158 + expandedLabelMeasure.implicitWidth
160 + MD.
Tokens.navigationRail.horizontalFullWidthTrailingSpace
162 implicitWidth: _railExpanded
163 ? _expandedImplicitWidth
164 : MD.
Tokens.navigationRail.collapsedContainerWidth
165 implicitHeight: MD.
Tokens.navigationRail.itemContainerHeight
166 + (MD.
Tokens.navigationRail.horizontalActiveIndicatorHeight
167 - MD.
Tokens.navigationRail.itemContainerHeight) * _positionProgress
169 Keys.onUpPressed: event => {
171 control.rail._moveSelection(-1);
173 event.accepted =
false;
175 Keys.onDownPressed:
event => {
177 control.rail._moveSelection(1);
179 event.accepted =
false;
181 Keys.onPressed:
event => {
183 event.accepted =
false;
184 }
else if (event.key === Qt.Key_Home) {
185 control.rail._selectBoundary(
false);
186 event.accepted =
true;
187 }
else if (event.key === Qt.Key_End) {
188 control.rail._selectBoundary(
true);
189 event.accepted =
true;
191 event.accepted =
false;
198 function onClicked() {
200 control.rail._activateItem(control);
203 function onCheckedChanged() {
205 control.rail._itemCheckedChanged(control);
211 objectName:
"navigationRailItemContent"
213 function lerp(start, end, progress) {
214 return start + (end - start) * progress;
217 readonly
property real collapsedIndicatorX: (width - MD.Tokens.navigationRail.verticalActiveIndicatorWidth) / 2
218 readonly property real collapsedIndicatorY: control._hasLabel
220 : (height - MD.
Tokens.navigationRail.verticalActiveIndicatorHeight) / 2
221 readonly property real expandedIndicatorY: (height - MD.
Tokens.navigationRail.horizontalActiveIndicatorHeight) / 2
222 readonly property real collapsedIconX: (width - control.icon.width) / 2
223 readonly property real collapsedIconY: collapsedIndicatorY
224 + (MD.
Tokens.navigationRail.verticalActiveIndicatorHeight - control.icon.height) / 2
225 readonly property real expandedIconX: control._hasLabel
227 ? width - MD.
Tokens.navigationRail.horizontalFullWidthLeadingSpace - control.icon.width
228 : MD.
Tokens.navigationRail.horizontalFullWidthLeadingSpace
229 : (width - control.icon.width) / 2
230 readonly property real expandedIconY: (height - control.icon.height) / 2
231 readonly property real collapsedLabelWidth: Math.min(width,
232 collapsedLabelMeasure.implicitWidth)
233 readonly property real badgeReservedWidth: trailingBadge.visible
234 ? trailingBadge.width + MD.
Tokens.measurement.space100 : 0
236 implicitWidth: control.implicitWidth
237 implicitHeight: control.implicitHeight
240 id: collapsedLabelMeasure
243 typescale: MD.
Tokens.typescale.labelMedium
244 wrapMode: Text.NoWrap
245 Accessible.ignored: true
249 id: expandedLabelMeasure
252 typescale: MD.
Tokens.typescale.labelLarge
253 wrapMode: Text.NoWrap
254 Accessible.ignored: true
257 Internal.NavigationRailItemIndicator {
259 objectName:
"navigationRailItemIndicator"
261 x: content.lerp(content.collapsedIndicatorX, 0, control._positionProgress)
262 y: content.lerp(content.collapsedIndicatorY, content.expandedIndicatorY,
263 control._positionProgress)
264 width: content.lerp(MD.
Tokens.navigationRail.verticalActiveIndicatorWidth,
265 content.width, control._positionProgress)
266 height: content.lerp(MD.
Tokens.navigationRail.verticalActiveIndicatorHeight,
267 MD.
Tokens.navigationRail.horizontalActiveIndicatorHeight,
268 control._positionProgress)
269 selected: control.checked
270 pressed: control.down
271 pressX: control.pressX - x
272 pressY: control.pressY - y
273 selectedColor: control.selectedIndicatorColor
274 stateLayerColor: control._iconColor
275 stateLayerOpacity: control._stateLayerOpacity
281 objectName:
"navigationRailItemIcon"
283 x: content.lerp(content.collapsedIconX, content.expandedIconX,
284 control._positionProgress)
285 y: content.lerp(content.collapsedIconY, content.expandedIconY,
286 control._positionProgress)
287 width: control.icon.width
288 height: control.icon.height
289 opacity: control._contentOpacity
290 visible: control._hasNamedIcon || control._hasSourceIcon
291 Accessible.ignored: true
295 anchors.fill: iconSlot
296 source: control.icon.source
297 sourceSize: Qt.size(sourceIcon.width, sourceIcon.height)
298 fillMode: Image.PreserveAspectFit
299 color: control.tintSourceIcon ? control._iconColor :
"transparent"
300 visible: control._hasSourceIcon
301 Accessible.ignored: true
306 name: control.icon.name
309 color: control._iconColor
310 fill: control.checked
311 visible: !control._hasSourceIcon && control._hasNamedIcon
312 Accessible.ignored: true
318 objectName:
"navigationRailBadgeOverlay"
320 layoutMirrored: control.mirrored
321 count: BadgeContent.count(control.badgeContent)
322 text: BadgeContent.text(control.badgeContent)
323 locale: control.locale
324 variant: control.badgeNotification ? MD.
Badge.Small : control.badgeVariant
325 accessibleDescription: control.badgeAccessibleDescription.length > 0
326 ? control.badgeAccessibleDescription : _defaultAccessibleDescription
327 visible: control._showBadge && !control._useTrailingBadge && targetAvailable
332 objectName:
"navigationRailItemLabel"
334 x: control._expandedPlacement
336 ? MD.
Tokens.navigationRail.horizontalFullWidthTrailingSpace
337 + content.badgeReservedWidth
338 : MD.
Tokens.navigationRail.horizontalFullWidthLeadingSpace
339 + control.icon.width + MD.
Tokens.navigationRail.horizontalIconLabelSpace
340 : (content.width - content.collapsedLabelWidth) / 2
341 y: control._expandedPlacement
342 ? (content.height - height) / 2
343 : content.collapsedIndicatorY
344 + MD.
Tokens.navigationRail.verticalActiveIndicatorHeight
345 + MD.
Tokens.navigationRail.verticalIconLabelSpace
346 width: control._expandedPlacement
348 ? Math.max(0, content.expandedIconX
349 - MD.
Tokens.navigationRail.horizontalIconLabelSpace
350 - MD.
Tokens.navigationRail.horizontalFullWidthTrailingSpace
351 - content.badgeReservedWidth)
352 : Math.max(0, content.width
353 - MD.
Tokens.navigationRail.horizontalFullWidthLeadingSpace
355 - MD.
Tokens.navigationRail.horizontalIconLabelSpace
356 - MD.
Tokens.navigationRail.horizontalFullWidthTrailingSpace
357 - content.badgeReservedWidth)
358 : content.collapsedLabelWidth
360 color: control._labelColor
361 opacity: control._contentOpacity
362 * Math.pow(control._positionProgress * 2 - 1, 2)
363 visible: control._hasLabel
364 elide: Text.ElideRight
365 wrapMode: Text.NoWrap
366 typescale: control._expandedPlacement ? MD.
Tokens.typescale.labelLarge
367 : MD.
Tokens.typescale.labelMedium
368 horizontalAlignment: control._expandedPlacement
369 ? (control.mirrored ? Text.AlignRight : Text.AlignLeft)
371 Accessible.ignored: true
377 objectName:
"navigationRailBadgeTrailing"
378 x: control.mirrored ? MD.
Tokens.navigationRail.horizontalFullWidthTrailingSpace
379 : content.width - MD.
Tokens.navigationRail.horizontalFullWidthTrailingSpace - width
380 y: (content.height - height) / 2
381 count: BadgeContent.count(control.badgeContent)
382 text: BadgeContent.text(control.badgeContent)
383 locale: control.locale
384 variant: control.badgeVariant
385 accessibleDescription: control.badgeAccessibleDescription.length > 0
386 ? control.badgeAccessibleDescription : _defaultAccessibleDescription
387 visible: control._showBadge && control._useTrailingBadge
Places a badge at an icon's logical upper trailing corner.
Material Design 3 design tokens.
Tokens(QObject *parent=nullptr)
Displays text using a selectable Material 3 type scale.
Immutable Material Design 3 badge metrics.
Material Design 3 Expressive navigation rail tokens.
Material Symbols icon tokens.