feat: fontbuilder to streamline font styling

This commit is contained in:
2026-09-30 14:23:31 +02:00
parent 2c90339c77
commit f825e4d53b
115 changed files with 1687 additions and 916 deletions
+21 -42
View File
@@ -80,49 +80,29 @@ Slider {
property bool moving
function update(): void {
animate = !moving;
binding.when = moving;
font.pointSize = moving ? Tokens.font.size.small : Tokens.font.size.larger;
font.family = moving ? Config.appearance.font.family.sans : Config.appearance.font.family.material;
}
anchors.centerIn: parent
anchors.verticalCenterOffset: 1
text: moving ? Math.round(root.value * 100) : root.icon
color: Colors.palette.m3inverseOnSurface
text: root.icon
font: moving ? Tokens.font.body.small : Tokens.font.icon.medium
onMovingChanged: anim.restart()
Binding {
id: binding
property: "text"
target: icon
value: Math.round(root.value * root.multiplier)
when: false
}
SequentialAnimation {
id: anim
Anim {
duration: Tokens.anim.durations.normal / 2
easing: Tokens.anim.standardAccel
property: "scale"
target: icon
to: 0
}
ScriptAction {
script: icon.update()
}
Anim {
duration: Tokens.anim.durations.normal / 2
easing: Tokens.anim.standardDecel
property: "scale"
target: icon
to: 1
Behavior on moving {
SequentialAnimation {
Anim {
target: icon
property: "scale"
to: 0.3
duration: Tokens.anim.durations.small / 2
easing: Tokens.anim.standardAccel
}
PropertyAction {}
Anim {
target: icon
property: "scale"
to: 1
duration: Tokens.anim.durations.normal / 2
easing: Tokens.anim.standardDecel
}
}
}
}
@@ -130,7 +110,7 @@ Slider {
}
Behavior on value {
Anim {
duration: Tokens.anim.durations.large
type: Anim.StandardLarge
}
}
@@ -138,7 +118,6 @@ Slider {
onValueChanged: {
if (!initialized) {
initialized = true;
oldValue = value;
return;
}
+1 -5
View File
@@ -20,11 +20,7 @@ CustomRect {
property color disabledColor: Qt.alpha(Colors.palette.m3onSurface, 0.1)
property color disabledOnColor: Qt.alpha(Colors.palette.m3onSurface, 0.38)
property bool fillWidth
property font font: ({
family: Config.appearance.font.family.sans,
pointSize: Tokens.font.size.larger,
bold: false
})
property font font: Tokens.font.body.small
property real horizontalPadding: padding
readonly property alias hovered: stateLayer.containsMouse
required implicitHeight
+3 -4
View File
@@ -6,7 +6,7 @@ import qs.Services
RadioButton {
id: root
font.pointSize: Tokens.font.size.normal
font: Tokens.font.body.medium
implicitHeight: Math.max(implicitIndicatorHeight, implicitContentHeight)
implicitWidth: implicitIndicatorWidth + implicitContentWidth + contentItem.anchors.leftMargin
@@ -14,7 +14,7 @@ RadioButton {
anchors.left: outerCircle.right
anchors.leftMargin: 10
anchors.verticalCenter: parent.verticalCenter
font.pointSize: root.font.pointSize
font: root.font
text: root.text
}
indicator: Rectangle {
@@ -29,8 +29,7 @@ RadioButton {
radius: Tokens.rounding.full
Behavior on border.color {
CAnim {
}
CAnim {}
}
StateLayer {
+9 -7
View File
@@ -100,15 +100,19 @@ Slider {
anchors.bottom: parent.bottom
anchors.top: parent.top
color: root.insetColor
font.pixelSize: Tokens.font.size.smaller * 2
fontStyle: {
if (root.height < 96)
return Tokens.font.icon.pixelSize(24).build();
else
return Tokens.font.icon.pixelSize(32).build();
}
text: root.insetIcon
verticalAlignment: Text.AlignVCenter
visible: !root.wavy && root.insetIcon !== ""
x: Tokens.spacing.extraSmall + dockT * (handle.x + Tokens.spacing.small)
Behavior on dockT {
Anim {
}
Anim {}
}
}
@@ -138,8 +142,7 @@ Slider {
startX: x
Behavior on color {
CAnim {
}
CAnim {}
}
Anim on waveProgress {
duration: root.waveDuration
@@ -156,8 +159,7 @@ Slider {
Behavior on filledWidth {
id: widthBehavior
Anim {
}
Anim {}
}
Component.onCompleted: {
+3 -6
View File
@@ -14,15 +14,13 @@ Text {
property real animateTo: 1
color: Colors.palette.m3onSurface
font.family: Config.appearance.font.family.sans
font.pointSize: Tokens.font.size.normal
font: Tokens.font.body.small
linkColor: Colors.palette.m3onPrimaryFixedVariant
renderType: Text.NativeRendering
textFormat: Text.PlainText
Behavior on color {
CAnim {
}
CAnim {}
}
Behavior on text {
enabled: root.animate
@@ -34,8 +32,7 @@ Text {
type: Anim.FastEffects
}
PropertyAction {
}
PropertyAction {}
TAnim {
target: root
+4 -2
View File
@@ -29,7 +29,7 @@ TextFieldBase {
property string supportingText
property string trailingIcon
property int smallFontSize: Tokens.font.size.small
property int smallFontSize: Tokens.font.label.small.pointSize
property int type: CustomTextField.Outlined
property var validate // Regex or function
@@ -151,6 +151,7 @@ TextFieldBase {
sourceComponent: MaterialIcon {
color: Colors.palette.m3onSurfaceVariant
text: root.leadingIcon
fontStyle: Tokens.font.icon.builders.medium.scale(0.9).build()
}
}
@@ -165,6 +166,7 @@ TextFieldBase {
sourceComponent: MaterialIcon {
color: Colors.palette.m3onSurfaceVariant
text: root.trailingIcon
fontStyle: Tokens.font.icon.builders.medium.scale(0.9).build()
}
}
}
@@ -179,7 +181,7 @@ TextFieldBase {
sourceComponent: CustomText {
color: root.isError ? Colors.palette.m3error : Colors.palette.m3onSurfaceVariant
font.pointSize: Tokens.font.size.small
font: Tokens.font.label.small
text: root.effectiveSupportingText
}
}
+42
View File
@@ -0,0 +1,42 @@
import QtQuick
import Quickshell
ShaderEffect {
id: root
property Item target: parent
property real glowSize: 40
property real innerGlow: 0
property real lineWidth: 2
property real intensity: 1.0
property real speed: 1.0
property int period: 6000
property bool running: true
property color color1: "#4285F4"
property color color2: "#9B72CB"
property color color3: "#D96570"
property color color4: "#F2A54A"
readonly property size itemSize: Qt.size(width, height)
readonly property size rectSize: target ? Qt.size(target.width, target.height) : Qt.size(0, 0)
readonly property real radius: (target as Rectangle).radius ?? 0
property real phase: 0
anchors.fill: target
anchors.margins: -glowSize
z: -1
enabled: false
fragmentShader: Qt.resolvedUrl(`${Quickshell.shellDir}/assets/shaders/geminiglow.frag.qsb`)
FrameAnimation {
running: root.running && root.visible
onTriggered: {
const dt = frameTime * 1000;
root.phase = (root.phase + dt * root.speed / root.period) % 1.0;
}
}
}
+2 -1
View File
@@ -8,6 +8,7 @@ ButtonBase {
property alias icon: label.text
readonly property alias label: label
font: Tokens.font.icon.medium
activeColor: type === IconButton.Filled ? Colors.palette.m3primary : Colors.palette.m3secondary
activeOnColor: type === IconButton.Filled ? Colors.palette.m3onPrimary : type === IconButton.Tonal ? Colors.palette.m3onSecondary : Colors.palette.m3primary
implicitHeight: {
@@ -36,7 +37,7 @@ ButtonBase {
anchors.verticalCenterOffset: 1
color: root.onColor
fill: !root.isToggle || root.internalChecked ? 1 : 0
font.pointSize: root.font.pointSize
fontStyle: root.font
Behavior on fill {
Anim {
+1 -2
View File
@@ -46,10 +46,9 @@ ButtonBase {
Layout.alignment: Qt.AlignVCenter
color: root.onColor
fill: root.internalChecked ? 1 : 0
font: {
fontStyle: {
const f = Qt.font(root.font);
f.pointSize = Math.round(root.font.pointSize * 1.2);
f.family = "Material Symbols Rounded";
return f;
}
+3 -17
View File
@@ -1,27 +1,13 @@
import QtQuick
import ZShell.Config
import qs.Services
CustomText {
id: root
readonly property list<int> allowed: [20, 24, 40, 48]
property real fill: 0
property int grade: Colors.light ? 0 : -25
readonly property int opsz: clampOpsz(optical)
property int optical: fontInfo.pixelSize
property font fontStyle: Tokens.font.icon.small
function clampOpsz(value): int {
return allowed.reduce((closest, current) => {
return Math.abs(current - value) < Math.abs(closest - value) ? current : closest;
});
}
font.family: "Material Symbols Rounded"
font.pointSize: Tokens.font.size.larger
font.variableAxes: ({
FILL: fill,
GRAD: grade,
opsz: opsz,
wght: fontInfo.weight
})
font: Tokens.font.icon.size(fontStyle.pointSize).weight(fontStyle.weight).vaxes(fontStyle.variableAxes).fill(fill.toFixed(1)).grade(grade).build()
}
+1 -1
View File
@@ -62,7 +62,7 @@ TextFieldBase {
anchors.leftMargin: Tokens.padding.large
anchors.verticalCenter: parent.verticalCenter
color: Colors.palette.m3onSurfaceVariant
font.pointSize: Tokens.font.size.large
fontStyle: Tokens.font.icon.builders.medium.scale(0.9).build()
text: "search"
}
+4 -7
View File
@@ -8,7 +8,7 @@ TextField {
color: Colors.palette.m3onSurface
cursorVisible: !readOnly
font.pointSize: Tokens.font.size.small
font: Tokens.font.body.small
implicitHeight: contentHeight + topPadding + bottomPadding
implicitWidth: contentWidth + leftPadding + rightPadding
placeholderTextColor: Colors.palette.m3onSurfaceVariant // No anim cause placeholder is custom
@@ -18,14 +18,11 @@ TextField {
verticalAlignment: TextInput.AlignVCenter
Behavior on color {
CAnim {
}
}
cursorDelegate: Item {
CAnim {}
}
cursorDelegate: Item {}
Behavior on selectionColor {
CAnim {
}
CAnim {}
}
CustomRect {
+3 -4
View File
@@ -36,8 +36,7 @@ CustomRect {
radius: Tokens.rounding.medium
Behavior on border.color {
CAnim {
}
CAnim {}
}
Elevation {
@@ -84,7 +83,7 @@ CustomRect {
return Colors.palette.m3onError;
return Colors.palette.m3onSurfaceVariant;
}
font.pointSize: Math.round(Tokens.font.size.large * 1.2)
fontStyle: Tokens.font.icon.builders.large.scale(1.2).build()
text: root.modelData.icon
}
}
@@ -107,7 +106,7 @@ CustomRect {
return Colors.palette.m3onSurface;
}
elide: Text.ElideRight
font.pointSize: Tokens.font.size.normal
font: Tokens.font.title.small
text: root.modelData.title
}