Pantrix UI

Code Block

Okunmak için dizilmiş kod: temanın kod yazısıyla, her satır kendi satırında, her parçası ne olduğunun renginde ve kopyalanmaya hazır.

import com.pantrixui.components.data.codeblock.PantrixCodeBlock

Örnekler

Bir kod parçası

En yalın hâli: bir kod metni, onu renklendiren parçalar ve dilin adı. Blok dili bilmez; neyin anahtar sözcük, neyin metin, neyin yorum olduğunu tokens söyler. Burada onları uygulamanın kendi Kotlin okuyucusu verir.

Anahtar sözcükler temanın primary, türler info, metinler success, sayılar warning, @ ile başlayan adlar danger rolünün rengindedir; yorum textSecondary ile ve eğik yazılır. Başlıktaki düğme kodun tamamını kopyalar ve iki saniye bir onay işareti gösterir.

PantrixCodeBlock(
    code = GREETING,
    tokens = remember { kotlinTokens(GREETING) },
    language = "Kotlin",
    tagKey = "snippet"
)

private val GREETING =
    """
    @Composable
    fun Greeting(name: String) {
        // The greeting a new account is met with.
        val unread = 3
        PantrixText(text = "Hello, " + name + ": " + unread + " new messages")
    }
    """.trimIndent()

Bir dosya, kendi yüksekliğinde

Bir dosya: title adını, icon başındaki ikonu, lineNumbers satır numaralarını verir. Bloğa bir yükseklik verildi: kod onun içinde, yerinde duran başlığın altında kayar ve yalnızca ekrandaki satırlar kurulur.

Sığmayan satır bölünmez. Kodu yana kaydır: satır numaraları yerinde durur, satırlar onların altından geçer. İmleci olan bir ekranda bloğun iki kaydırma çubuğu da görünür ve fareyle sürüklenir; Tab ile satırlara gelince ok tuşları kodu kaydırır.

PantrixCodeBlock(
    code = REPOSITORY,
    modifier = Modifier.height(220.dp),
    tokens = remember { kotlinTokens(REPOSITORY) },
    title = "OrderRepository.kt",
    language = "Kotlin",
    icon = PantrixIcons.Folder,
    lineNumbers = true,
    tagKey = "file"
)

private val REPOSITORY =
    """
    package com.example.orders

    import kotlinx.coroutines.flow.Flow
    import kotlinx.coroutines.flow.map

    /** Reads the orders of an account, newest first. */
    class OrderRepository(private val api: OrderApi, private val cache: OrderCache, private val clock: Clock) {
        fun orders(account: String): Flow<List<Order>> = cache.observe(account).map { it.sortedBy(Order::placedAt) }

        suspend fun refresh(account: String) {
            val fresh = api.orders(account, since = cache.newest(account))
            cache.put(account, fresh, at = clock.now())
        }

        suspend fun cancel(order: Order): Boolean {
            if (order.shipped) return false
            api.cancel(order.id)
            cache.remove(order.id)
            return true
        }
    }
    """.trimIndent()

Bir bulgu, ilgili satırın altında

Bir inceleme: bulgu, hakkında olduğu satırın altında durur. lines alan biçimde her satır kendi işaretini taşır; codeLines metnin satırlarını verir, ekran istediğini işaretler. Bir işaret satırın arkasına tonunun rolünün yumuşak dolgusunu, sol kenarına rolün renginde bir çubuk çizer; message satırın altında, tonun ikonundan sonra yazılır ve source sonunda durur.

İşaretli satır, temanın o dolguyla eşlediği tek renkle yazılır. firstLineNumber parçanın dosyada başladığı yeri verir: bulgunun satırı dosyadaki numarasını taşır.

val lines = remember {
    codeLines(REVIEWED, kotlinTokens(REVIEWED)).mapIndexed { index, line ->
        when (index) {
            1 -> {
                line.copy(
                    mark = CodeMark(
                        tone = CodeTone.Danger,
                        message = "Jeton burada boş olabilir; `!!` uygulamayı çökertir.",
                        source = "kotlin:S2259"
                    )
                )
            }

            4 -> {
                line.copy(mark = CodeMark(CodeTone.Warning, message = "Süre sabiti bir ada alınmalı."))
            }

            else -> {
                line
            }
        }
    }
}
PantrixCodeBlock(
    lines = lines,
    title = "AuthRepository.kt",
    lineNumbers = true,
    firstLineNumber = 41,
    tagKey = "finding"
)

private val REVIEWED =
    """
    suspend fun token(): String {
        val cached = cache.token!!
        if (cached.isFresh()) return cached.value
        val fresh = api.refresh(cached.refreshToken)
        cache.keep(fresh, seconds = 3600)
        return fresh.value
    }
    """.trimIndent()

Eklenen ve çıkarılan satırlar

Mesajı olmayan bir işaret yalnızca bir banttır: iki sürümün farkında eklenen satırlar Success, çıkarılanlar Danger tonunda. Bandın ne demek olduğunu burada satırın başındaki + ve - de söyler: bir renk, onu göremeyene bir şey söylemez.

val lines = remember {
    codeLines(CHANGES, kotlinTokens(CHANGES)).map { line ->
        when {
            line.text.startsWith("+") -> line.copy(mark = CodeMark(CodeTone.Success))
            line.text.startsWith("-") -> line.copy(mark = CodeMark(CodeTone.Danger))
            else -> line
        }
    }
}
PantrixCodeBlock(lines = lines, title = "Greeting.kt", tagKey = "changes")

private val CHANGES =
    """
      @Composable
      fun Greeting(name: String) {
    -     PantrixText(text = "Hello")
    +     PantrixText(text = "Hello, " + name)
    +     PantrixDivider()
      }
    """.trimIndent()

Bir kılavuzun adımları

İşaretler ekranın verisidir: bir kılavuzun hangi adımında olunduğu değişince başka satırlar öne çıkar. Burada her adım kendi satırlarını Primary tonuyla işaretler; adımı değiştir, bant öteki satırlara geçer.

var step by remember { mutableIntStateOf(0) }
val lines = remember(step) {
    codeLines(GREETING, kotlinTokens(GREETING)).mapIndexed { index, line ->
        if (index in STEP_LINES[step]) line.copy(mark = CodeMark(CodeTone.Primary)) else line
    }
}
PantrixSegmentButton(
    options = STEPS,
    selected = step,
    onSelect = { step = it },
    fullWidth = false,
    tagKey = "step"
)
PantrixCodeBlock(lines = lines, lineNumbers = true, copyable = false, tagKey = "steps")

private val STEPS = listOf(
    SegmentOption(value = 0, label = "1. İmza", tagKey = "signature"),
    SegmentOption(value = 1, label = "2. Durum", tagKey = "state"),
    SegmentOption(value = 2, label = "3. Çizim", tagKey = "drawing")
)

private val STEP_LINES = listOf(0..1, 3..3, 4..4)

private val GREETING =
    """
    @Composable
    fun Greeting(name: String) {
        // The greeting a new account is met with.
        val unread = 3
        PantrixText(text = "Hello, " + name + ": " + unread + " new messages")
    }
    """.trimIndent()

Bölünen satırlar

Uzun bir komut. softWrap ile satır bloğa sığmadığı yerde kendi altında sürer ve blok yana kaymaz; kapalıyken komut tek satırdır ve kod yana kayar. Anahtarı çevir, ikisini karşılaştır.

Bölünen bir satır girintisini kaybeder: softWrap bir komut ya da bir günlük satırı için iyidir, girintisi anlam taşıyan kod için değil.

var wraps by remember { mutableStateOf(true) }
PantrixSwitchButton(
    checked = wraps,
    onCheckedChange = { wraps = it },
    label = "Uzun satır kendi altında sürsün",
    tagKey = "code_wraps"
)
PantrixCodeBlock(code = COMMAND, softWrap = wraps, language = "Shell", tagKey = "command")

private val COMMAND =
    "./gradlew :ui:components:jvmTest --tests 'com.pantrixui.components.CodeBlockTest' --offline --console=plain"

Kopyalama ve başlığın sonu

onCopy düğmeye basıldıktan sonra, kodun panoya ulaşıp ulaşmadığıyla çağrılır: bunu kendi yoluyla söyleyen ekran burayı dinler. trailing başlığın sonuna, kopyalama düğmesinden önce ekranın kendi şeyini koyar: burada satır sayısı.

İkinci blokta copyable ve selectable kapalı, başlıkta duracak başka bir şey de yok: başlığı yoktur ve kod seçilmez.

val report = LocalExampleEvents.current
PantrixCodeBlock(
    code = DEPENDENCIES,
    title = "build.gradle.kts",
    onCopy = { copied -> report(if (copied) "Kod panoya kopyalandı" else "Kod panoya kopyalanamadı") },
    trailing = { PantrixText(text = "4 satır", style = PantrixTheme.typography.caption) },
    tagKey = "copied"
)
PantrixCodeBlock(code = DEPENDENCIES, selectable = false, copyable = false, tagKey = "plain")

private val DEPENDENCIES =
    """
    dependencies {
        implementation("com.pantrixui:foundation:0.1.0")
        implementation("com.pantrixui:components:0.1.0")
    }
    """.trimIndent()

Başlıkta sekmeler

leading başlığın başına, ikondan ve başlıktan önce ekranın kendi şeyini koyar: burada aynı satırın iki biçimi arasında seçen iki sekme, bir belgelemenin kurulum adımındaki gibi. Başlığın yazı renginde yazılırlar.

textStyle kodu temanın code'undan başka bir stille yazar: burada caption boyunda, kodun ailesiyle, dar bir sütun için. style'ın headerLineWidth'i başlığın altındaki çizginin kalınlığıdır; headerHorizontalPadding başlıktakileri kenara satırlardan daha yakın durdurur.

var form by remember { mutableIntStateOf(0) }
val code = FORMS[form].second
val type = PantrixTheme.typography
PantrixCodeBlock(
    code = code,
    tokens = remember(code) { kotlinTokens(code) },
    style = CodeBlockStyle(headerLineWidth = 2.dp, headerHorizontalPadding = PantrixTheme.spacing.xs),
    leading = {
        FORMS.forEachIndexed { index, (name, _) ->
            PantrixButton(
                text = name,
                onClick = { form = index },
                variant = if (index == form) ButtonVariant.Soft else ButtonVariant.Text,
                size = ButtonSize.Small,
                tagKey = "form_$index"
            )
        }
    },
    textStyle = type.caption.copy(fontFamily = type.code.fontFamily),
    tagKey = "tabs"
)

private val FORMS = listOf(
    "Kotlin" to """implementation("com.pantrixui:components:0.1.0")""",
    "Groovy" to """implementation 'com.pantrixui:components:0.1.0'"""
)

Bir kartın içinde, kendi renkleriyle

Bloğun kendi dolgusu ve kenarı vardır: dolgu temanın surface'ı, kenar temanın divider'ıdır. İkisi de olan bir kartın içinde colors ikisini de saydam verir. Verilen renk kullanılır, verilmeyen temanınki kalır.

style bloğun geometrisini değiştirir; yalnızca verilen alanlar değişir. Burada satırlar kartın iç boşluğunun bittiği yerden başlasın diye horizontalPadding sıfır verildi.

PantrixCard(modifier = Modifier.fillMaxWidth(), variant = CardVariant.Outlined) {
    PantrixText(text = "Kurulum", style = PantrixTheme.typography.title)
    PantrixCodeBlock(
        code = DEPENDENCIES,
        tokens = remember { kotlinTokens(DEPENDENCIES) },
        style = CodeBlockStyle(horizontalPadding = 0.dp),
        colors = CodeBlockColors(container = Color.Transparent, border = Color.Transparent),
        tagKey = "in_a_card"
    )
}

private val DEPENDENCIES =
    """
    dependencies {
        implementation("com.pantrixui:foundation:0.1.0")
        implementation("com.pantrixui:components:0.1.0")
    }
    """.trimIndent()

Elle yazılan parçalar

Blok bir dil okuyucusu taşımaz; parçaları uygulama verir. Okuyucusu olmayan kısa bir metnin parçaları elle de yazılır: her CodeToken satırdaki bir aralığın (start'tan end'e) ne olduğudur (CodeTokenKind). Burada bir kabuk komutunun satırları doğrudan CodeLine olarak kuruldu: yorum Comment, komut Keyword, görev StringLiteral, seçenek Type.

PantrixCodeBlock(lines = SHELL_LINES, language = "Shell", tagKey = "hand_tokens")

private val SHELL_LINES = listOf(
    CodeLine(text = "# Masaüstü demosunu çalıştır", tokens = listOf(CodeToken(0, 28, CodeTokenKind.Comment))),
    CodeLine(
        text = "./gradlew :app:desktopApp:run --offline",
        tokens = listOf(
            CodeToken(0, 9, CodeTokenKind.Keyword),
            CodeToken(10, 29, CodeTokenKind.StringLiteral),
            CodeToken(30, 39, CodeTokenKind.Type)
        )
    )
)

API

code

Okunmak için dizilmiş kod: temanın kod yazısıyla, her satır kendi satırında, her parçası ne olduğunun renginde ve kopyalanmaya hazır.

ParametreTürVarsayılanNe olduğu
codeStringKod. Satırları bir satır beslemede, bir satır başında ya da ikisi birlikteyken biter; metni bitiren satır sonu yeni bir satır başlatmaz.
modifierModifierModifierBloğun modifier'ı. Burada verilen yükseklik, kodun içinde kaydığı yerdir.
tokensList<CodeToken>emptyList()code'un rengi olan parçaları; yerleri metnin tamamının harfleriyle sayılır. Verilmezse hiçbiri yoktur.
titleString?nullBaşlığın ilk söylediği: bir dosyanın adı ya da kodun ne olduğu. Başlığa sığmayan ad kısaltılır.
languageString?nullDilin adı; başlıkta addan sonra, okunacağı gibi yazılır: Kotlin, TS. Blok bir dil listesi tutmaz.
iconImageVector?nullAdın önündeki ikon.
lineNumbersBooleanfalseHer satırın, numarasını kodun önünde taşıyıp taşımadığı.
firstLineNumberInt1İlk satırın numarası. Bir dosyadan alınmış bir parça, orada başladığı yerden başlar.
softWrapBooleanfalseBloğa sığmayan satırın kendi altında sürüp sürmediği. Verilmezse hiçbir satır sürmez ve kod yana kayar.
selectableBooleantrueKodun seçilip seçilemediği: üstünde bir imleç sürüklenerek ya da parmak basılı tutularak seçilir ve sistemin kendi yoluyla kopyalanır. Böyle kopyalanan, ekrandaki satırların gösterdiğidir: numaraları ve haklarında söylenen olmadan. Kendi yüksekliğinde kayan kod yalnızca ekranındaki satırları kurmuştur; orada "tümünü seç" de onları seçer. Düğme ise kodun tamamını kopyalar.
copyableBooleantrueBlokta kodu kopyalayan düğmenin olup olmadığı.
onCopy((copied: Boolean) -> Unit)?nullO düğmeye basıldıktan sonra, kodun panoya ulaşıp ulaşmadığıyla çağrılır: bunu kendi yoluyla söyleyen ekran burayı dinler. Düğmenin kendisi kısa bir süre bir onay işareti gösterir ve ekran okuyucuya söyler; sistem her kopyayı kendisi gösteriyorsa (PantrixClipboard.traits) söylemez: orada başka bir şey gerekmez.
trailing(@Composable () -> Unit)?nullEkranın başlığın sonuna, kopyalama düğmesinden önce koyduğu şey: bir sayı, kendi düğmesi. Bloğun yazı rengiyle çizilir.
styleCodeBlockStyle?nullbu çağrının kendi stili: çevreleyen her stilin üstünde, yoğunluğun altında. Her platformda yalnızca verdiği alanlar değişir.
colorsCodeBlockColors?nullBu bloğun, temadan gelmeyen kendi renkleri: burada verilenler kullanılır, gerisi temanınki kalır.
tagKeyString?nullBloğun otomasyon anahtarı: blok CodeBlock_<tagKey>, bir satırı CodeBlock_<tagKey>.Line_<number>, bir satırın altındaki mesaj CodeBlock_<tagKey>.Note_<number>, klavyenin kaydırdığı satır penceresi CodeBlock_<tagKey>.Lines_window, kopyalama düğmesi CodeBlock_<tagKey>.Button_copy olur. O düğmeye basış, kodun panoya ulaşıp ulaşmadığıyla, bir CodeBlock copy olayı olarak bildirilir. Koddan hiçbir şey bildirilmez.
leading(@Composable RowScope.() -> Unit)?nullEkranın başlığın başına, ikondan ve başlıktan önce koyduğu şey; başlığın renginde yazılır: bir belge sayfasının iki depo için bir kurulumu gösterdiği gibi, aynı dosyanın iki biçiminin sekmeleri.
textStyleTextStyle?nullKodun yazıldığı stil: verilmezse temanın code'u, bir telefonun sayfasında daha küçüğü.

lines

Satırları tek tek verilen PantrixCodeBlock; her satır kendisi hakkında söyleneni taşır: bakılacak bir satırın arkasındaki bant, eklenen ve çıkarılan satırlar, hakkında olduğu satırın altında mesajıyla bir bulgu.

ParametreTürVarsayılanNe olduğu
linesList<CodeLine>Satırlar, sırasıyla. Düğme onların metinlerini satır satır kopyalar.
modifierModifierModifierBloğun modifier'ı. Burada verilen yükseklik, kodun içinde kaydığı yerdir.
titleString?nullBaşlığın ilk söylediği: bir dosyanın adı ya da kodun ne olduğu.
languageString?nullDilin adı; başlıkta addan sonra, okunacağı gibi yazılır.
iconImageVector?nullAdın önündeki ikon.
lineNumbersBooleanfalseHer satırın, numarasını kodun önünde taşıyıp taşımadığı.
firstLineNumberInt1İlk satırın numarası. Bir dosyadan alınmış bir parça, orada başladığı yerden başlar.
softWrapBooleanfalseBloğa sığmayan satırın kendi altında sürüp sürmediği.
selectableBooleantrueKodun seçilip sistemin kendi yoluyla kopyalanıp kopyalanamadığı.
copyableBooleantrueBlokta kodu kopyalayan düğmenin olup olmadığı.
onCopy((copied: Boolean) -> Unit)?nullO düğmeye basıldıktan sonra, kodun panoya ulaşıp ulaşmadığıyla çağrılır.
trailing(@Composable () -> Unit)?nullEkranın başlığın sonuna, kopyalama düğmesinden önce koyduğu şey.
styleCodeBlockStyle?nullbu çağrının kendi stili: çevreleyen her stilin üstünde, yoğunluğun altında. Her platformda yalnızca verdiği alanlar değişir.
colorsCodeBlockColors?nullBu bloğun, temadan gelmeyen kendi renkleri: burada verilenler kullanılır, gerisi temanınki kalır.
tagKeyString?nullBloğun otomasyon anahtarı; öteki biçimdeki gibi.
leading(@Composable RowScope.() -> Unit)?nullEkranın başlığın başına, ikondan ve başlıktan önce koyduğu şey: bir dosyanın iki biçiminin sekmeleri, başlığın renginde yazılır.
textStyleTextStyle?nullKodun yazıldığı stil: verilmezse temanın code'u.

CodeBlockStyle

PantrixCodeBlock'un geometrisi: satırlarının çevresindeki boşluk, başlığı, satırlar numaralıyken kodun önündeki yer ve kenar.

ParametreTürVarsayılanNe olduğu
shapeShapeSpecShapeSpec.UnspecifiedBloğun köşeleri: markanın şekil ölçeğinden bir basamak ya da sabit bir şekil.
horizontalPaddingDpDp.UnspecifiedBloğun yanları ile içindekiler arasındaki boşluk: başlığın yazısı, satırlar, bir satırın altındaki mesaj. Bir işaretin bandı bu boşluğun üstünden, yanlara kadar çizilir.
verticalPaddingDpDp.Unspecifiedİlk satırın üstündeki ve son satırın altındaki, bir de bir mesajın altındaki boşluk. Bir mesajın yazısının üstünde bunun yarısı vardır.
linePaddingDpDp.UnspecifiedHer satırın yazısının üstündeki ve altındaki boşluk.
headerHeightDpDp.UnspecifiedBaşlığın en az yüksekliği. İçinde durana göre büyür. Başlığında kopyalama düğmesinden başka bir şey olmayan bloğun başlığı yoktur: düğmenin şeridi düğme kadar yüksektir.
gutterGapDpDp.UnspecifiedSatırlar numaralıyken, satır numaraları ile kod arasındaki aralık.
iconSizeDpDp.UnspecifiedBaşlıktaki ikonun, kopyalama düğmesinin ikonunun ve bir mesajın önündeki ikonun eni ve boyu.
borderWidthDpDp.UnspecifiedBloğun çevresindeki kenarın ve, headerLineWidth verilmediğinde, başlığının altındaki çizginin kalınlığı. Sıfır hiçbirini çizmez.
barWidthDpDp.Unspecifiedİşaretli bir satırın sol kenarından inen çubuğun kalınlığı. Sıfır verilirse çizilmez.
headerLineWidthDpDp.UnspecifiedBaşlığın altındaki çizginin kalınlığı: verilmezse borderWidth; böylece kenarı olmayan bir bloğun başlığı da bir çizgiyle ayrılabilir. Sıfır hiçbirini çizmez.
headerHorizontalPaddingDpDp.UnspecifiedBloğun yanlarıyla başlığındakiler arasındaki boşluk: verilmezse horizontalPadding. Başlığın başındaki sekmeler kenara satırlardan daha yakın durur.

CodeBlockColors

Temanın renklerini almayan bir blok için PantrixCodeBlock'un renkleri: verilen renk kullanılır, verilmeyen temanınki kalır.

ParametreTürVarsayılanNe olduğu
containerColorColor.UnspecifiedBaşlığın ve satırların arkasındaki dolgu: temanın surface'ı. Color.Transparent verilirse bloğun arkasındaki görünür.
textColorColor.UnspecifiedHiçbir parçanın boyamadığı yazı ve başlıktaki ad. Temanın textPrimary'si.
commentColorColor.UnspecifiedYorum; ayrıca eğik yazılır. Temanın textSecondary'si.
keywordColorColor.UnspecifiedDilin bir sözcüğü. Temanın primary rolü.
typeColorColor.UnspecifiedBir türün adı. Temanın info rolü.
stringColorColor.UnspecifiedBir metin. Temanın success rolü.
numberColorColor.UnspecifiedBir sayı. Temanın warning rolü.
punctuationColorColor.UnspecifiedParantezler, virgüller ve noktalı virgüller. Temanın textSecondary'si.
annotationColorColor.UnspecifiedArdından geleni niteleyen bir ad. Temanın danger rolü.
lineNumberColorColor.UnspecifiedSatır numaraları, başlıktaki dil ve ikon, kopyalama düğmesinin ikonu ve kaydırma çubukları. Temanın textSecondary'si.
borderColorColor.UnspecifiedBloğun çevresindeki kenar ve başlığının altındaki çizgi. Temanın kendi zeminlerinde temanın divider'ıdır; o çizginin okunmayacağı bir dolgunun üstünde ise orada yazılan rengin bir payıdır.

Erişilebilirlik