working muon monitor
This commit is contained in:
parent
3f144a5dbd
commit
b5a1296070
@ -17,7 +17,7 @@ public fun NameCrumbs(name: Name?, link: (Name) -> Unit): Unit = Nav({
|
|||||||
classes("breadcrumb")
|
classes("breadcrumb")
|
||||||
style {
|
style {
|
||||||
property("--bs-breadcrumb-divider", "'.'")
|
property("--bs-breadcrumb-divider", "'.'")
|
||||||
property("--bs-breadcrumb-item-padding-x",".2rem")
|
property("--bs-breadcrumb-item-padding-x",".1rem")
|
||||||
}
|
}
|
||||||
}) {
|
}) {
|
||||||
Li({
|
Li({
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
package space.kscience.visionforge.compose
|
package space.kscience.visionforge.compose
|
||||||
|
|
||||||
import androidx.compose.runtime.*
|
import androidx.compose.runtime.*
|
||||||
|
import app.softwork.bootstrapcompose.CloseButton
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.channels.awaitClose
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.flow.callbackFlow
|
import kotlinx.coroutines.flow.callbackFlow
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import org.jetbrains.compose.web.attributes.disabled
|
|
||||||
import org.jetbrains.compose.web.css.AlignItems
|
import org.jetbrains.compose.web.css.AlignItems
|
||||||
import org.jetbrains.compose.web.css.alignItems
|
import org.jetbrains.compose.web.css.alignItems
|
||||||
import org.jetbrains.compose.web.css.px
|
import org.jetbrains.compose.web.css.px
|
||||||
import org.jetbrains.compose.web.css.width
|
import org.jetbrains.compose.web.css.width
|
||||||
import org.jetbrains.compose.web.dom.Button
|
|
||||||
import org.jetbrains.compose.web.dom.Div
|
import org.jetbrains.compose.web.dom.Div
|
||||||
import org.jetbrains.compose.web.dom.Span
|
import org.jetbrains.compose.web.dom.Span
|
||||||
import org.jetbrains.compose.web.dom.Text
|
import org.jetbrains.compose.web.dom.Text
|
||||||
@ -35,13 +35,13 @@ public sealed class EditorPropertyState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param meta Root config object - always non-null
|
* @param rootMeta Root config object - always non-null
|
||||||
* @param rootDescriptor Full path to the displayed node in [meta]. Could be empty
|
* @param rootDescriptor Full path to the displayed node in [rootMeta]. Could be empty
|
||||||
*/
|
*/
|
||||||
@Composable
|
@Composable
|
||||||
public fun PropertyEditor(
|
public fun PropertyEditor(
|
||||||
scope: CoroutineScope,
|
scope: CoroutineScope,
|
||||||
meta: MutableMeta,
|
rootMeta: MutableMeta,
|
||||||
getPropertyState: (Name) -> EditorPropertyState,
|
getPropertyState: (Name) -> EditorPropertyState,
|
||||||
updates: Flow<Name>,
|
updates: Flow<Name>,
|
||||||
name: Name = Name.EMPTY,
|
name: Name = Name.EMPTY,
|
||||||
@ -50,11 +50,11 @@ public fun PropertyEditor(
|
|||||||
) {
|
) {
|
||||||
var expanded: Boolean by remember { mutableStateOf(initialExpanded ?: true) }
|
var expanded: Boolean by remember { mutableStateOf(initialExpanded ?: true) }
|
||||||
val descriptor: MetaDescriptor? = remember(rootDescriptor, name) { rootDescriptor?.get(name) }
|
val descriptor: MetaDescriptor? = remember(rootDescriptor, name) { rootDescriptor?.get(name) }
|
||||||
var property: MutableMeta by remember { mutableStateOf(meta.getOrCreate(name)) }
|
var property: MutableMeta by remember { mutableStateOf(rootMeta.getOrCreate(name)) }
|
||||||
var editorPropertyState: EditorPropertyState by remember { mutableStateOf(getPropertyState(name)) }
|
var editorPropertyState: EditorPropertyState by remember { mutableStateOf(getPropertyState(name)) }
|
||||||
|
|
||||||
|
|
||||||
val keys = remember(descriptor) {
|
val keys by derivedStateOf {
|
||||||
buildSet {
|
buildSet {
|
||||||
descriptor?.children?.filterNot {
|
descriptor?.children?.filterNot {
|
||||||
it.key.startsWith("@") || it.value.hidden
|
it.key.startsWith("@") || it.value.hidden
|
||||||
@ -68,11 +68,11 @@ public fun PropertyEditor(
|
|||||||
val token = name.lastOrNull()?.toString() ?: "Properties"
|
val token = name.lastOrNull()?.toString() ?: "Properties"
|
||||||
|
|
||||||
fun update() {
|
fun update() {
|
||||||
property = meta.getOrCreate(name)
|
property = rootMeta.getOrCreate(name)
|
||||||
editorPropertyState = getPropertyState(name)
|
editorPropertyState = getPropertyState(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
LaunchedEffect(meta) {
|
LaunchedEffect(rootMeta) {
|
||||||
updates.collect { updatedName ->
|
updates.collect { updatedName ->
|
||||||
if (updatedName == name) {
|
if (updatedName == name) {
|
||||||
update()
|
update()
|
||||||
@ -116,20 +116,11 @@ public fun PropertyEditor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Button({
|
CloseButton(editorPropertyState != EditorPropertyState.Defined){
|
||||||
classes(TreeStyles.propertyEditorButton)
|
rootMeta.remove(name)
|
||||||
if (editorPropertyState != EditorPropertyState.Defined) {
|
|
||||||
disabled()
|
|
||||||
} else {
|
|
||||||
onClick {
|
|
||||||
meta.remove(name)
|
|
||||||
update()
|
update()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}) {
|
|
||||||
Text("\u00D7")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (expanded) {
|
if (expanded) {
|
||||||
FlexColumn({
|
FlexColumn({
|
||||||
@ -139,7 +130,7 @@ public fun PropertyEditor(
|
|||||||
Div({
|
Div({
|
||||||
classes(TreeStyles.treeItem)
|
classes(TreeStyles.treeItem)
|
||||||
}) {
|
}) {
|
||||||
PropertyEditor(scope, meta, getPropertyState, updates, name + token, descriptor, expanded)
|
PropertyEditor(scope, rootMeta, getPropertyState, updates, name + token, rootDescriptor, expanded)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -155,7 +146,7 @@ public fun PropertyEditor(
|
|||||||
) {
|
) {
|
||||||
PropertyEditor(
|
PropertyEditor(
|
||||||
scope = scope,
|
scope = scope,
|
||||||
meta = properties,
|
rootMeta = properties,
|
||||||
getPropertyState = { name ->
|
getPropertyState = { name ->
|
||||||
if (properties[name] != null) {
|
if (properties[name] != null) {
|
||||||
EditorPropertyState.Defined
|
EditorPropertyState.Defined
|
||||||
@ -172,9 +163,7 @@ public fun PropertyEditor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
invokeOnClose {
|
awaitClose { properties.removeListener(scope) }
|
||||||
properties.removeListener(scope)
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
name = Name.EMPTY,
|
name = Name.EMPTY,
|
||||||
rootDescriptor = descriptor,
|
rootDescriptor = descriptor,
|
||||||
|
@ -4,6 +4,7 @@ import androidx.compose.runtime.*
|
|||||||
import app.softwork.bootstrapcompose.Card
|
import app.softwork.bootstrapcompose.Card
|
||||||
import app.softwork.bootstrapcompose.NavbarLink
|
import app.softwork.bootstrapcompose.NavbarLink
|
||||||
import app.softwork.bootstrapcompose.Styling
|
import app.softwork.bootstrapcompose.Styling
|
||||||
|
import org.jetbrains.compose.web.css.overflowY
|
||||||
import org.jetbrains.compose.web.dom.*
|
import org.jetbrains.compose.web.dom.*
|
||||||
import org.w3c.dom.HTMLAnchorElement
|
import org.w3c.dom.HTMLAnchorElement
|
||||||
import org.w3c.dom.HTMLDivElement
|
import org.w3c.dom.HTMLDivElement
|
||||||
@ -51,6 +52,11 @@ public fun Tabs(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
bodyAttrs = {
|
||||||
|
style {
|
||||||
|
overflowY("auto")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
activeTab?.content?.invoke(this)
|
activeTab?.content?.invoke(this)
|
||||||
|
@ -4,7 +4,6 @@ import androidx.compose.runtime.*
|
|||||||
import org.jetbrains.compose.web.css.Color
|
import org.jetbrains.compose.web.css.Color
|
||||||
import org.jetbrains.compose.web.css.color
|
import org.jetbrains.compose.web.css.color
|
||||||
import org.jetbrains.compose.web.css.cursor
|
import org.jetbrains.compose.web.css.cursor
|
||||||
import org.jetbrains.compose.web.css.textDecorationLine
|
|
||||||
import org.jetbrains.compose.web.dom.Div
|
import org.jetbrains.compose.web.dom.Div
|
||||||
import org.jetbrains.compose.web.dom.Span
|
import org.jetbrains.compose.web.dom.Span
|
||||||
import org.jetbrains.compose.web.dom.Text
|
import org.jetbrains.compose.web.dom.Text
|
||||||
@ -15,8 +14,6 @@ import space.kscience.dataforge.names.startsWith
|
|||||||
import space.kscience.visionforge.Vision
|
import space.kscience.visionforge.Vision
|
||||||
import space.kscience.visionforge.VisionGroup
|
import space.kscience.visionforge.VisionGroup
|
||||||
import space.kscience.visionforge.asSequence
|
import space.kscience.visionforge.asSequence
|
||||||
import space.kscience.visionforge.compose.TreeStyles.hover
|
|
||||||
import space.kscience.visionforge.compose.TreeStyles.invoke
|
|
||||||
import space.kscience.visionforge.isEmpty
|
import space.kscience.visionforge.isEmpty
|
||||||
|
|
||||||
|
|
||||||
@ -35,10 +32,6 @@ private fun TreeLabel(
|
|||||||
style {
|
style {
|
||||||
color(Color("#069"))
|
color(Color("#069"))
|
||||||
cursor("pointer")
|
cursor("pointer")
|
||||||
hover.invoke {
|
|
||||||
textDecorationLine("underline")
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
onClick { clickCallback(name) }
|
onClick { clickCallback(name) }
|
||||||
}) {
|
}) {
|
||||||
|
@ -4,14 +4,10 @@ package space.kscience.visionforge.compose
|
|||||||
|
|
||||||
import androidx.compose.runtime.*
|
import androidx.compose.runtime.*
|
||||||
import org.jetbrains.compose.web.attributes.*
|
import org.jetbrains.compose.web.attributes.*
|
||||||
import org.jetbrains.compose.web.css.percent
|
|
||||||
import org.jetbrains.compose.web.css.px
|
|
||||||
import org.jetbrains.compose.web.css.width
|
|
||||||
import org.jetbrains.compose.web.dom.Input
|
import org.jetbrains.compose.web.dom.Input
|
||||||
import org.jetbrains.compose.web.dom.Option
|
import org.jetbrains.compose.web.dom.Option
|
||||||
import org.jetbrains.compose.web.dom.Select
|
import org.jetbrains.compose.web.dom.Select
|
||||||
import org.jetbrains.compose.web.dom.Text
|
import org.jetbrains.compose.web.dom.Text
|
||||||
import org.w3c.dom.HTMLInputElement
|
|
||||||
import org.w3c.dom.HTMLOptionElement
|
import org.w3c.dom.HTMLOptionElement
|
||||||
import org.w3c.dom.asList
|
import org.w3c.dom.asList
|
||||||
import space.kscience.dataforge.meta.*
|
import space.kscience.dataforge.meta.*
|
||||||
@ -29,20 +25,16 @@ public fun StringValueChooser(
|
|||||||
value: Value?,
|
value: Value?,
|
||||||
onValueChange: (Value?) -> Unit,
|
onValueChange: (Value?) -> Unit,
|
||||||
) {
|
) {
|
||||||
var stringValue by remember { mutableStateOf(value?.string ?: "") }
|
var stringValue by remember(value, descriptor) { mutableStateOf(value?.string ?: "") }
|
||||||
Input(type = InputType.Text) {
|
Input(type = InputType.Text) {
|
||||||
style {
|
classes("w-100")
|
||||||
width(100.percent)
|
|
||||||
}
|
|
||||||
value(stringValue)
|
value(stringValue)
|
||||||
onKeyDown { event ->
|
onChange { event ->
|
||||||
if (event.type == "keydown" && event.asDynamic().key == "Enter") {
|
stringValue = event.value
|
||||||
stringValue = (event.target as HTMLInputElement).value
|
|
||||||
onValueChange(stringValue.asValue())
|
|
||||||
}
|
}
|
||||||
}
|
onInput { event ->
|
||||||
onChange {
|
stringValue = event.value
|
||||||
stringValue = it.target.value
|
onValueChange(event.value.asValue())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -55,16 +47,18 @@ public fun BooleanValueChooser(
|
|||||||
value: Value?,
|
value: Value?,
|
||||||
onValueChange: (Value?) -> Unit,
|
onValueChange: (Value?) -> Unit,
|
||||||
) {
|
) {
|
||||||
Input(type = InputType.Checkbox) {
|
var innerValue by remember(value, descriptor) {
|
||||||
style {
|
mutableStateOf(
|
||||||
width(100.percent)
|
value?.boolean ?: descriptor?.defaultValue?.boolean
|
||||||
|
)
|
||||||
}
|
}
|
||||||
//this.attributes["indeterminate"] = (props.item == null).toString()
|
Input(type = InputType.Checkbox) {
|
||||||
checked(value?.boolean ?: false)
|
classes("w-100")
|
||||||
|
checked(innerValue ?: false)
|
||||||
|
|
||||||
onChange {
|
onInput { event ->
|
||||||
val newValue = it.target.checked
|
innerValue = event.value
|
||||||
onValueChange(newValue.asValue())
|
onValueChange(event.value.asValue())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -76,25 +70,18 @@ public fun NumberValueChooser(
|
|||||||
value: Value?,
|
value: Value?,
|
||||||
onValueChange: (Value?) -> Unit,
|
onValueChange: (Value?) -> Unit,
|
||||||
) {
|
) {
|
||||||
var innerValue by remember { mutableStateOf(value?.string ?: "") }
|
var innerValue by remember(value, descriptor) { mutableStateOf(value?.number) }
|
||||||
Input(type = InputType.Number) {
|
Input(type = InputType.Number) {
|
||||||
style {
|
classes("w-100")
|
||||||
width(100.percent)
|
|
||||||
|
value(innerValue ?: descriptor?.defaultValue?.number ?: 0.0)
|
||||||
|
|
||||||
|
onChange { event ->
|
||||||
|
innerValue = event.value
|
||||||
}
|
}
|
||||||
value(innerValue)
|
onInput { event ->
|
||||||
onKeyDown { event ->
|
innerValue = event.value
|
||||||
if (event.type == "keydown" && event.asDynamic().key == "Enter") {
|
onValueChange(event.value?.asValue())
|
||||||
innerValue = (event.target as HTMLInputElement).value
|
|
||||||
val number = innerValue.toDoubleOrNull()
|
|
||||||
if (number == null) {
|
|
||||||
console.error("The input value $innerValue is not a number")
|
|
||||||
} else {
|
|
||||||
onValueChange(number.asValue())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
onChange {
|
|
||||||
innerValue = it.target.value
|
|
||||||
}
|
}
|
||||||
descriptor?.attributes?.get("step").number?.let {
|
descriptor?.attributes?.get("step").number?.let {
|
||||||
step(it)
|
step(it)
|
||||||
@ -116,11 +103,10 @@ public fun ComboValueChooser(
|
|||||||
value: Value?,
|
value: Value?,
|
||||||
onValueChange: (Value?) -> Unit,
|
onValueChange: (Value?) -> Unit,
|
||||||
) {
|
) {
|
||||||
var selected by remember { mutableStateOf(value?.string ?: "") }
|
var selected by remember(value, descriptor) { mutableStateOf(value?.string ?: "") }
|
||||||
Select({
|
Select({
|
||||||
style {
|
classes("w-100")
|
||||||
width(100.percent)
|
|
||||||
}
|
|
||||||
onChange {
|
onChange {
|
||||||
selected = it.target.value
|
selected = it.target.value
|
||||||
onValueChange(selected.asValue())
|
onValueChange(selected.asValue())
|
||||||
@ -142,11 +128,11 @@ public fun ColorValueChooser(
|
|||||||
value: Value?,
|
value: Value?,
|
||||||
onValueChange: (Value?) -> Unit,
|
onValueChange: (Value?) -> Unit,
|
||||||
) {
|
) {
|
||||||
|
var innerValue by remember { mutableStateOf<String?>(value?.string ?: descriptor?.defaultValue?.string) }
|
||||||
|
|
||||||
Input(type = InputType.Color) {
|
Input(type = InputType.Color) {
|
||||||
style {
|
classes("w-100")
|
||||||
width(100.percent)
|
|
||||||
marginAll(0.px)
|
|
||||||
}
|
|
||||||
value(
|
value(
|
||||||
value?.let { value ->
|
value?.let { value ->
|
||||||
if (value.type == ValueType.NUMBER) Colors.rgbToString(value.int)
|
if (value.type == ValueType.NUMBER) Colors.rgbToString(value.int)
|
||||||
@ -154,8 +140,12 @@ public fun ColorValueChooser(
|
|||||||
//else "#" + Color(value.string).getHexString()
|
//else "#" + Color(value.string).getHexString()
|
||||||
} ?: "#000000"
|
} ?: "#000000"
|
||||||
)
|
)
|
||||||
onChange {
|
onChange { event ->
|
||||||
onValueChange(it.target.value.asValue())
|
innerValue = event.value
|
||||||
|
}
|
||||||
|
onInput { event ->
|
||||||
|
innerValue = event.value
|
||||||
|
onValueChange(event.value.asValue())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -194,7 +184,7 @@ public fun RangeValueChooser(
|
|||||||
value: Value?,
|
value: Value?,
|
||||||
onValueChange: (Value?) -> Unit,
|
onValueChange: (Value?) -> Unit,
|
||||||
) {
|
) {
|
||||||
var innerValue by remember { mutableStateOf(value?.double) }
|
var innerValue by remember(value, descriptor) { mutableStateOf(value?.double) }
|
||||||
var rangeDisabled: Boolean by remember { mutableStateOf(state != EditorPropertyState.Defined) }
|
var rangeDisabled: Boolean by remember { mutableStateOf(state != EditorPropertyState.Defined) }
|
||||||
|
|
||||||
|
|
||||||
@ -219,9 +209,8 @@ public fun RangeValueChooser(
|
|||||||
}
|
}
|
||||||
|
|
||||||
Input(type = InputType.Range) {
|
Input(type = InputType.Range) {
|
||||||
style {
|
classes("w-100")
|
||||||
width(100.percent)
|
|
||||||
}
|
|
||||||
if (rangeDisabled) disabled()
|
if (rangeDisabled) disabled()
|
||||||
value(innerValue?.toString() ?: "")
|
value(innerValue?.toString() ?: "")
|
||||||
onChange {
|
onChange {
|
||||||
|
@ -14,7 +14,6 @@ import space.kscience.dataforge.context.Context
|
|||||||
import space.kscience.dataforge.context.request
|
import space.kscience.dataforge.context.request
|
||||||
import space.kscience.dataforge.names.Name
|
import space.kscience.dataforge.names.Name
|
||||||
import space.kscience.dataforge.names.isEmpty
|
import space.kscience.dataforge.names.isEmpty
|
||||||
import space.kscience.visionforge.Vision
|
|
||||||
import space.kscience.visionforge.compose.*
|
import space.kscience.visionforge.compose.*
|
||||||
import space.kscience.visionforge.root
|
import space.kscience.visionforge.root
|
||||||
import space.kscience.visionforge.solid.Solid
|
import space.kscience.visionforge.solid.Solid
|
||||||
@ -81,15 +80,6 @@ public fun ThreeView(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val selectedVision: Vision? by derivedStateOf {
|
|
||||||
selected?.let {
|
|
||||||
when {
|
|
||||||
it.isEmpty() -> solid
|
|
||||||
else -> (solid as? SolidGroup)?.get(it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (optionsSnapshot.controls.enabled) {
|
if (optionsSnapshot.controls.enabled) {
|
||||||
|
|
||||||
Row(
|
Row(
|
||||||
@ -147,7 +137,13 @@ public fun ThreeView(
|
|||||||
SimpleThreeView(solids.context, optionsSnapshot, solid, selected)
|
SimpleThreeView(solids.context, optionsSnapshot, solid, selected)
|
||||||
}
|
}
|
||||||
|
|
||||||
selectedVision?.let { vision ->
|
key(selected) {
|
||||||
|
selected?.let {
|
||||||
|
when {
|
||||||
|
it.isEmpty() -> solid
|
||||||
|
else -> (solid as? SolidGroup)?.get(it)
|
||||||
|
}
|
||||||
|
}?.let { vision ->
|
||||||
Card(
|
Card(
|
||||||
attrs = {
|
attrs = {
|
||||||
style {
|
style {
|
||||||
@ -155,10 +151,13 @@ public fun ThreeView(
|
|||||||
top(5.px)
|
top(5.px)
|
||||||
right(5.px)
|
right(5.px)
|
||||||
width(450.px)
|
width(450.px)
|
||||||
|
overflowY("auto")
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
headerAttrs = {
|
headerAttrs = {
|
||||||
// border = true
|
style {
|
||||||
|
alignItems(AlignItems.Center)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
header = {
|
header = {
|
||||||
NameCrumbs(selected) { selected = it }
|
NameCrumbs(selected) { selected = it }
|
||||||
@ -174,7 +173,7 @@ public fun ThreeView(
|
|||||||
) {
|
) {
|
||||||
PropertyEditor(
|
PropertyEditor(
|
||||||
scope = solids.context,
|
scope = solids.context,
|
||||||
meta = vision.properties.root(),
|
rootMeta = vision.properties.root(),
|
||||||
getPropertyState = { name ->
|
getPropertyState = { name ->
|
||||||
if (vision.properties.own?.get(name) != null) {
|
if (vision.properties.own?.get(name) != null) {
|
||||||
EditorPropertyState.Defined
|
EditorPropertyState.Defined
|
||||||
@ -191,6 +190,7 @@ public fun ThreeView(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Column(
|
Column(
|
||||||
auto = true,
|
auto = true,
|
||||||
@ -204,7 +204,6 @@ public fun ThreeView(
|
|||||||
paddingAll(4.px)
|
paddingAll(4.px)
|
||||||
minWidth(400.px)
|
minWidth(400.px)
|
||||||
height(100.percent)
|
height(100.percent)
|
||||||
overflowY("auto")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
|
Loading…
Reference in New Issue
Block a user