Files
metabuilder/qml/components/atoms/CCodeBlock.qml
johndoe6345789 de3a3ac194 feat(qml): MD3 rework batch 2 — 17 more components rewritten
Feedback: CAlert (tonal + accent bar), CDialog (radius 28, scale anim), CSnackbar (inverse surface, slide-in)
Navigation: CTabBar (animated indicator pill), CListItem (state layers), CBreadcrumbs (full rewrite)
Data: CAvatar (tonal primary), CDivider (theme-aware), CTable (hover rows, sort arrows, proper padding)
Typography: CText (full MD3 type scale inline), CTitle (extends CText), CCodeBlock (radius 12), CCodeInline (radius 4)
Forms: CFormGroup (focus/error states), CFormLabel (animated color), CLabel (control association), CAutocomplete (styled popup)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 04:03:58 +00:00

115 lines
3.2 KiB
QML

import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import QmlComponents 1.0
/**
* CCodeBlock.qml - Material Design 3 code block
* Displays code with optional line numbers, copy button, and horizontal scroll
*/
Rectangle {
id: root
property string code: ""
property string language: ""
property bool showCopy: true
property bool showLineNumbers: false
property int maxHeight: 400
color: Qt.lighter(Theme.surface, 1.15)
radius: 12
implicitWidth: parent ? parent.width : 400
implicitHeight: Math.min(contentCol.implicitHeight + 32, maxHeight)
ColumnLayout {
id: contentCol
anchors.fill: parent
anchors.margins: 16
spacing: 8
// Header with language label and copy button
RowLayout {
Layout.fillWidth: true
visible: root.language !== "" || root.showCopy
Text {
text: root.language
color: Theme.textSecondary
font.pixelSize: 12
font.family: Theme.fontFamilyMono
font.weight: Font.Medium
visible: root.language !== ""
}
Item { Layout.fillWidth: true }
CButton {
text: "Copy"
size: "sm"
variant: "text"
visible: root.showCopy
onClicked: {
text = "Copied!"
copyTimer.start()
}
Timer {
id: copyTimer
interval: 2000
onTriggered: parent.text = "Copy"
}
}
}
// Scrollable code content
Flickable {
Layout.fillWidth: true
Layout.fillHeight: true
contentWidth: codeRow.implicitWidth
contentHeight: codeRow.implicitHeight
clip: true
boundsBehavior: Flickable.StopAtBounds
ScrollBar.vertical: ScrollBar { policy: ScrollBar.AsNeeded }
ScrollBar.horizontal: ScrollBar { policy: ScrollBar.AsNeeded }
RowLayout {
id: codeRow
spacing: 12
// Line numbers column
Column {
visible: root.showLineNumbers
spacing: 0
Repeater {
model: root.code.split('\n').length
Text {
text: (index + 1).toString()
color: Theme.textSecondary
font.family: Theme.fontFamilyMono
font.pixelSize: 14
horizontalAlignment: Text.AlignRight
width: 32
opacity: 0.6
}
}
}
// Code text
Text {
id: codeText
text: root.code
color: Theme.text
font.family: Theme.fontFamilyMono
font.pixelSize: 14
textFormat: Text.PlainText
wrapMode: Text.NoWrap
}
}
}
}
}