ui: use css modules for TextArea and TextInput
This commit is contained in:
@@ -21,10 +21,17 @@ export type CheckboxProps = FieldProps &
|
||||
};
|
||||
|
||||
export const Checkbox = (props: CheckboxProps) => {
|
||||
const [local, other] = splitProps(
|
||||
mergeProps({ size: "default", orientation: "vertical" } as const, props),
|
||||
["size", "orientation", "inverted", "ghost", "input"],
|
||||
const withDefaults = mergeProps(
|
||||
{ size: "default", orientation: "vertical" } as const,
|
||||
props,
|
||||
);
|
||||
const [local, other] = splitProps(withDefaults, [
|
||||
"size",
|
||||
"orientation",
|
||||
"inverted",
|
||||
"ghost",
|
||||
"input",
|
||||
]);
|
||||
|
||||
const iconChecked = (
|
||||
<Icon
|
||||
@@ -66,7 +73,7 @@ export const Checkbox = (props: CheckboxProps) => {
|
||||
in={keepTruthy(
|
||||
local.orientation == "horizontal" && "Orienter-horizontal",
|
||||
)}
|
||||
{...props}
|
||||
{...withDefaults}
|
||||
/>
|
||||
<KCheckbox.Input {...local.input} />
|
||||
<KCheckbox.Control class={styles.checkboxControl}>
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
export interface FieldProps {
|
||||
class?: string;
|
||||
label?: string;
|
||||
labelWeight?: "bold" | "normal";
|
||||
description?: string;
|
||||
|
||||
@@ -11,7 +11,7 @@ import styles from "./HostFileInput.module.css";
|
||||
import { PolymorphicProps } from "@kobalte/core/polymorphic";
|
||||
import { FieldProps } from "./Field";
|
||||
import { Orienter } from "./Orienter";
|
||||
import { createSignal, splitProps } from "solid-js";
|
||||
import { createSignal, mergeProps, splitProps } from "solid-js";
|
||||
import { Tooltip } from "@kobalte/core/tooltip";
|
||||
import { Typography } from "@/src/components/Typography/Typography";
|
||||
import { keepTruthy } from "@/src/util";
|
||||
@@ -24,7 +24,14 @@ export type HostFileInputProps = FieldProps &
|
||||
};
|
||||
|
||||
export const HostFileInput = (props: HostFileInputProps) => {
|
||||
const [value, setValue] = createSignal<string>(props.value || "");
|
||||
const withDefaults = mergeProps({ value: "" } as const, props);
|
||||
const [local, other] = splitProps(withDefaults, [
|
||||
"size",
|
||||
"orientation",
|
||||
"inverted",
|
||||
"ghost",
|
||||
]);
|
||||
const [value, setValue] = createSignal<string>(other.value);
|
||||
|
||||
let actualInputElement: HTMLInputElement | undefined;
|
||||
|
||||
@@ -41,13 +48,6 @@ export const HostFileInput = (props: HostFileInputProps) => {
|
||||
}
|
||||
};
|
||||
|
||||
const [local, other] = splitProps(props, [
|
||||
"size",
|
||||
"orientation",
|
||||
"inverted",
|
||||
"ghost",
|
||||
]);
|
||||
|
||||
return (
|
||||
<TextField {...other}>
|
||||
<Orienter
|
||||
@@ -60,7 +60,7 @@ export const HostFileInput = (props: HostFileInputProps) => {
|
||||
in={keepTruthy(
|
||||
local.orientation == "horizontal" && "Orienter-horizontal",
|
||||
)}
|
||||
{...props}
|
||||
{...withDefaults}
|
||||
/>
|
||||
|
||||
<TextField.Input
|
||||
|
||||
@@ -52,7 +52,8 @@ const sortedAndUniqueOptions = (options: MachineTag[]) =>
|
||||
sortedOptions(uniqueOptions(options));
|
||||
|
||||
export const MachineTags = (props: MachineTagsProps) => {
|
||||
const [local, rest] = splitProps(props, ["defaultValue"]);
|
||||
const withDefaults = props;
|
||||
const [local, rest] = splitProps(withDefaults, ["defaultValue"]);
|
||||
|
||||
// // convert default value string[] into MachineTag[]
|
||||
const defaultValue = sortedAndUniqueOptions(
|
||||
@@ -199,7 +200,7 @@ export const MachineTags = (props: MachineTagsProps) => {
|
||||
in={keepTruthy(
|
||||
props.orientation == "horizontal" && "Orienter-horizontal",
|
||||
)}
|
||||
{...props}
|
||||
{...withDefaults}
|
||||
/>
|
||||
|
||||
<Combobox.HiddenSelect
|
||||
|
||||
@@ -121,11 +121,11 @@ export const AutoResize: Story = {
|
||||
description:
|
||||
"This textarea automatically adjusts its height based on content",
|
||||
tooltip: "Try typing multiple lines to see it grow",
|
||||
autoResize: true,
|
||||
minRows: 2,
|
||||
maxRows: 10,
|
||||
input: {
|
||||
placeholder: "Start typing to see the textarea grow...",
|
||||
autoResize: true,
|
||||
minRows: 2,
|
||||
maxRows: 10,
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -134,10 +134,10 @@ export const AutoResizeNoMax: Story = {
|
||||
args: {
|
||||
label: "Auto-resize without max height",
|
||||
description: "This textarea grows indefinitely with content",
|
||||
autoResize: true,
|
||||
minRows: 3,
|
||||
input: {
|
||||
placeholder: "This will grow as much as needed...",
|
||||
autoResize: true,
|
||||
minRows: 3,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -7,38 +7,50 @@ import {
|
||||
import cx from "classnames";
|
||||
import { Label } from "./Label";
|
||||
import { PolymorphicProps } from "@kobalte/core/polymorphic";
|
||||
import { createEffect, createSignal, splitProps } from "solid-js";
|
||||
import { createEffect, createSignal, mergeProps, splitProps } from "solid-js";
|
||||
|
||||
import "./TextInput.css";
|
||||
import styles from "./TextField.module.css";
|
||||
import { FieldProps } from "./Field";
|
||||
import { Orienter } from "./Orienter";
|
||||
import { keepTruthy } from "@/src/util";
|
||||
|
||||
export type TextAreaProps = FieldProps &
|
||||
TextFieldRootProps & {
|
||||
input: PolymorphicProps<"textarea", TextFieldTextAreaProps<"input">> & {
|
||||
autoResize?: boolean;
|
||||
minRows?: number;
|
||||
maxRows?: number;
|
||||
};
|
||||
input: PolymorphicProps<"textarea", TextFieldTextAreaProps<"input">>;
|
||||
autoResize?: boolean;
|
||||
minRows?: number;
|
||||
maxRows?: number;
|
||||
};
|
||||
|
||||
export const TextArea = (props: TextAreaProps) => {
|
||||
const withDefaults = mergeProps(
|
||||
{ size: "default", minRows: 1, maxRows: Infinity } as const,
|
||||
props,
|
||||
);
|
||||
const [local, other] = splitProps(withDefaults, [
|
||||
"autoResize",
|
||||
"minRows",
|
||||
"maxRows",
|
||||
"size",
|
||||
"orientation",
|
||||
"inverted",
|
||||
"ghost",
|
||||
"input",
|
||||
]);
|
||||
|
||||
let textareaRef: HTMLTextAreaElement;
|
||||
|
||||
const [lineHeight, setLineHeight] = createSignal(0);
|
||||
|
||||
const autoResize = () => {
|
||||
const input = props.input;
|
||||
|
||||
if (!(textareaRef && input.autoResize && lineHeight() > 0)) return;
|
||||
if (!(textareaRef && local.autoResize && lineHeight() > 0)) return;
|
||||
|
||||
// Reset height to auto to get accurate scrollHeight
|
||||
textareaRef.style.height = "auto";
|
||||
|
||||
// Calculate min and max heights based on rows
|
||||
const minHeight = (input.minRows || 1) * lineHeight();
|
||||
const maxHeight = input.maxRows ? input.maxRows * lineHeight() : Infinity;
|
||||
const minHeight = local.minRows * lineHeight();
|
||||
const maxHeight = local.maxRows * lineHeight();
|
||||
|
||||
// Set the height based on content, respecting min/max
|
||||
const newHeight = Math.min(
|
||||
@@ -53,7 +65,7 @@ export const TextArea = (props: TextAreaProps) => {
|
||||
|
||||
// Set up auto-resize effect
|
||||
createEffect(() => {
|
||||
if (textareaRef && props.input.autoResize) {
|
||||
if (textareaRef && local.autoResize) {
|
||||
// Get computed line height
|
||||
const computedStyle = window.getComputedStyle(textareaRef);
|
||||
const computedLineHeight = parseFloat(computedStyle.lineHeight);
|
||||
@@ -68,32 +80,14 @@ export const TextArea = (props: TextAreaProps) => {
|
||||
|
||||
// Watch for value changes to trigger resize
|
||||
createEffect(() => {
|
||||
if (props.input.autoResize && textareaRef) {
|
||||
if (local.autoResize && textareaRef) {
|
||||
// Access the value to create a dependency
|
||||
const _ = props.value || props.defaultValue || "";
|
||||
const _ = other.value || other.defaultValue;
|
||||
// Trigger resize on the next tick to ensure DOM is updated
|
||||
setTimeout(autoResize, 0);
|
||||
}
|
||||
});
|
||||
|
||||
const input = props.input;
|
||||
|
||||
// TextField.Textarea already has an `autoResize` prop
|
||||
// We filter our props out to avoid conflicting behaviour
|
||||
const [_, textareaProps] = splitProps(input, [
|
||||
"autoResize",
|
||||
"minRows",
|
||||
"maxRows",
|
||||
]);
|
||||
|
||||
const [styleProps, otherProps] = splitProps(props, [
|
||||
"class",
|
||||
"size",
|
||||
"orientation",
|
||||
"inverted",
|
||||
"ghost",
|
||||
]);
|
||||
|
||||
return (
|
||||
<TextField
|
||||
ref={(el: HTMLDivElement) => {
|
||||
@@ -102,46 +96,44 @@ export const TextArea = (props: TextAreaProps) => {
|
||||
textareaRef = el.querySelector("textarea")! as HTMLTextAreaElement;
|
||||
}}
|
||||
class={cx(
|
||||
styleProps.class,
|
||||
"form-field",
|
||||
"textarea",
|
||||
styleProps.size,
|
||||
styleProps.orientation,
|
||||
styles.textField,
|
||||
local.size != "default" && styles[local.size],
|
||||
local.orientation == "horizontal" && styles[local.orientation],
|
||||
{
|
||||
inverted: styleProps.inverted,
|
||||
ghost: styleProps.ghost,
|
||||
[styles.inverted]: local.inverted,
|
||||
[styles.ghost]: local.ghost,
|
||||
},
|
||||
)}
|
||||
{...otherProps}
|
||||
{...other}
|
||||
>
|
||||
<Orienter orientation={styleProps.orientation} align={"start"}>
|
||||
<Orienter orientation={local.orientation} align={"start"}>
|
||||
<Label
|
||||
labelComponent={TextField.Label}
|
||||
descriptionComponent={TextField.Description}
|
||||
in={keepTruthy(
|
||||
props.orientation == "horizontal" && "Orienter-horizontal",
|
||||
)}
|
||||
{...props}
|
||||
{...withDefaults}
|
||||
/>
|
||||
<TextField.TextArea
|
||||
class={cx(input.class, {
|
||||
"auto-resize": input.autoResize,
|
||||
class={cx({
|
||||
[styles.autoResize]: local.autoResize,
|
||||
})}
|
||||
onInput={(e) => {
|
||||
autoResize();
|
||||
|
||||
if (!input.onInput) {
|
||||
if (!local.input.onInput) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Call original onInput if it exists
|
||||
if (typeof input.onInput === "function") {
|
||||
input.onInput(e);
|
||||
} else if (Array.isArray(input.onInput)) {
|
||||
input.onInput.forEach((handler) => handler(e));
|
||||
if (typeof local.input.onInput === "function") {
|
||||
local.input.onInput(e);
|
||||
} else if (Array.isArray(local.input.onInput)) {
|
||||
local.input.onInput.forEach((handler) => handler(e));
|
||||
}
|
||||
}}
|
||||
{...textareaProps}
|
||||
{...local.input}
|
||||
/>
|
||||
</Orienter>
|
||||
</TextField>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
div.form-field {
|
||||
&.text input,
|
||||
&.textarea textarea {
|
||||
.textField {
|
||||
input,
|
||||
textarea {
|
||||
@apply w-full px-2 py-1.5 rounded-sm;
|
||||
@apply outline outline-1 outline-def-acc-1 bg-def-1 fg-def-1;
|
||||
|
||||
@@ -38,12 +38,12 @@ div.form-field {
|
||||
}
|
||||
}
|
||||
|
||||
&.textarea textarea {
|
||||
textarea {
|
||||
&[data-readonly] {
|
||||
@apply overflow-y-hidden;
|
||||
}
|
||||
|
||||
&.auto-resize {
|
||||
&.autoResize {
|
||||
@apply resize-none overflow-y-auto;
|
||||
transition: height 0.1s ease-out;
|
||||
}
|
||||
@@ -52,48 +52,15 @@ div.form-field {
|
||||
&.horizontal {
|
||||
@apply flex-row gap-2 justify-between;
|
||||
|
||||
&.text div.input-container,
|
||||
&.textarea textarea {
|
||||
.inputContainer,
|
||||
textarea {
|
||||
@apply w-1/2 grow;
|
||||
}
|
||||
}
|
||||
|
||||
&.text div.input-container {
|
||||
@apply inline-block relative w-full h-[1.875rem];
|
||||
|
||||
/* I'm unsure why I have to do this */
|
||||
@apply leading-none;
|
||||
|
||||
& > input {
|
||||
@apply w-full h-[1.875rem];
|
||||
|
||||
&.has-icon {
|
||||
@apply pl-7;
|
||||
}
|
||||
}
|
||||
|
||||
& > .icon {
|
||||
@apply absolute left-2 top-1/2 transform -translate-y-1/2;
|
||||
@apply w-[0.875rem] h-[0.875rem] pointer-events-none;
|
||||
}
|
||||
|
||||
& > .start-component {
|
||||
@apply absolute left-2 top-1/2 transform -translate-y-1/2;
|
||||
}
|
||||
|
||||
& > .end-component {
|
||||
@apply absolute right-2 top-1/2 transform -translate-y-1/2;
|
||||
}
|
||||
|
||||
& > .start-component,
|
||||
& > .end-component {
|
||||
@apply size-fit;
|
||||
}
|
||||
}
|
||||
|
||||
&.s {
|
||||
&.text input,
|
||||
&.textarea textarea {
|
||||
input,
|
||||
textarea {
|
||||
@apply px-1.5 py-1;
|
||||
font-size: 0.75rem;
|
||||
|
||||
@@ -102,26 +69,18 @@ div.form-field {
|
||||
}
|
||||
}
|
||||
|
||||
&.text div.input-container {
|
||||
.inputContainer {
|
||||
@apply h-[1.25rem];
|
||||
|
||||
input {
|
||||
@apply h-[1.25rem];
|
||||
}
|
||||
|
||||
input.has-icon {
|
||||
@apply pl-6;
|
||||
}
|
||||
|
||||
& > .icon {
|
||||
@apply w-[0.6875rem] h-[0.6875rem];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.inverted {
|
||||
&.text input,
|
||||
&.textarea textarea {
|
||||
input,
|
||||
textarea {
|
||||
@apply bg-inv-1 fg-inv-1 outline-inv-acc-1;
|
||||
|
||||
&::placeholder {
|
||||
@@ -151,13 +110,33 @@ div.form-field {
|
||||
}
|
||||
|
||||
&.ghost {
|
||||
&.text input,
|
||||
&.textarea textarea {
|
||||
input,
|
||||
textarea {
|
||||
@apply outline-none;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
@apply outline-none;
|
||||
}
|
||||
.inputContainer {
|
||||
@apply inline-block relative w-full h-[1.875rem];
|
||||
|
||||
/* I'm unsure why I have to do this */
|
||||
@apply leading-none;
|
||||
|
||||
& > input {
|
||||
@apply w-full h-[1.875rem];
|
||||
}
|
||||
|
||||
& > .startComponent {
|
||||
@apply absolute left-2 top-1/2 transform -translate-y-1/2;
|
||||
}
|
||||
|
||||
& > .endComponent {
|
||||
@apply absolute right-2 top-1/2 transform -translate-y-1/2;
|
||||
}
|
||||
|
||||
& > .startComponent,
|
||||
& > .endComponent {
|
||||
@apply size-fit;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,11 +3,10 @@ import {
|
||||
TextFieldInputProps,
|
||||
TextFieldRootProps,
|
||||
} from "@kobalte/core/text-field";
|
||||
import Icon, { IconVariant } from "@/src/components/Icon/Icon";
|
||||
|
||||
import cx from "classnames";
|
||||
import { Label } from "./Label";
|
||||
import "./TextInput.css";
|
||||
import styles from "./TextField.module.css";
|
||||
import { PolymorphicProps } from "@kobalte/core/polymorphic";
|
||||
import { FieldProps } from "./Field";
|
||||
import { Orienter } from "./Orienter";
|
||||
@@ -15,6 +14,7 @@ import {
|
||||
Component,
|
||||
createEffect,
|
||||
createSignal,
|
||||
mergeProps,
|
||||
onMount,
|
||||
splitProps,
|
||||
} from "solid-js";
|
||||
@@ -22,19 +22,21 @@ import { keepTruthy } from "@/src/util";
|
||||
|
||||
export type TextInputProps = FieldProps &
|
||||
TextFieldRootProps & {
|
||||
icon?: IconVariant;
|
||||
input?: PolymorphicProps<"input", TextFieldInputProps<"input">>;
|
||||
startComponent?: Component<Pick<FieldProps, "inverted">>;
|
||||
endComponent?: Component<Pick<FieldProps, "inverted">>;
|
||||
};
|
||||
|
||||
export const TextInput = (props: TextInputProps) => {
|
||||
const [styleProps, otherProps] = splitProps(props, [
|
||||
"class",
|
||||
const withDefaults = mergeProps({ size: "default" } as const, props);
|
||||
const [local, other] = splitProps(withDefaults, [
|
||||
"size",
|
||||
"orientation",
|
||||
"inverted",
|
||||
"ghost",
|
||||
"input",
|
||||
"startComponent",
|
||||
"endComponent",
|
||||
]);
|
||||
|
||||
let inputRef: HTMLInputElement | undefined;
|
||||
@@ -73,50 +75,35 @@ export const TextInput = (props: TextInputProps) => {
|
||||
return (
|
||||
<TextField
|
||||
class={cx(
|
||||
styleProps.class,
|
||||
"form-field",
|
||||
"text",
|
||||
styleProps.size,
|
||||
styleProps.orientation,
|
||||
styles.textField,
|
||||
local.size != "default" && styles[local.size],
|
||||
local.orientation == "horizontal" && styles[local.orientation],
|
||||
{
|
||||
inverted: styleProps.inverted,
|
||||
ghost: styleProps.ghost,
|
||||
[styles.inverted]: local.inverted,
|
||||
[styles.ghost]: local.ghost,
|
||||
},
|
||||
)}
|
||||
{...otherProps}
|
||||
{...other}
|
||||
>
|
||||
<Orienter orientation={styleProps.orientation}>
|
||||
<Orienter orientation={local.orientation}>
|
||||
<Label
|
||||
labelComponent={TextField.Label}
|
||||
descriptionComponent={TextField.Description}
|
||||
in={keepTruthy(
|
||||
props.orientation == "horizontal" && "Orienter-horizontal",
|
||||
)}
|
||||
{...props}
|
||||
{...withDefaults}
|
||||
/>
|
||||
<div class="input-container">
|
||||
{props.startComponent && !props.readOnly && (
|
||||
<div ref={startComponentRef} class="start-component">
|
||||
{props.startComponent({ inverted: props.inverted })}
|
||||
<div class={styles.inputContainer}>
|
||||
{local.startComponent && !other.readOnly && (
|
||||
<div ref={startComponentRef} class={styles.startComponent}>
|
||||
{local.startComponent({ inverted: local.inverted })}
|
||||
</div>
|
||||
)}
|
||||
{props.icon && !props.readOnly && (
|
||||
<Icon
|
||||
icon={props.icon}
|
||||
inverted={styleProps.inverted}
|
||||
color={props.disabled ? "tertiary" : "quaternary"}
|
||||
/>
|
||||
)}
|
||||
<TextField.Input
|
||||
ref={inputRef}
|
||||
{...props.input}
|
||||
class={cx({
|
||||
"has-icon": props.icon && !props.readOnly,
|
||||
})}
|
||||
/>
|
||||
{props.endComponent && !props.readOnly && (
|
||||
<div ref={endComponentRef} class="end-component">
|
||||
{props.endComponent({ inverted: props.inverted })}
|
||||
<TextField.Input ref={inputRef} {...local.input} />
|
||||
{local.endComponent && !other.readOnly && (
|
||||
<div ref={endComponentRef} class={styles.endComponent}>
|
||||
{local.endComponent({ inverted: local.inverted })}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import cx from "classnames";
|
||||
import styles from "./ClanSettingsModal.module.css";
|
||||
import { Modal } from "@/src/components/Modal/Modal";
|
||||
import { ClanDetails } from "@/src/hooks/queries";
|
||||
@@ -104,7 +103,7 @@ export const ClanSettingsModal = (props: ClanSettingsModalProps) => {
|
||||
|
||||
return (
|
||||
<Modal
|
||||
class={cx(styles.modal)}
|
||||
class={styles.modal}
|
||||
open
|
||||
title="Settings"
|
||||
onClose={props.onClose}
|
||||
@@ -112,7 +111,7 @@ export const ClanSettingsModal = (props: ClanSettingsModalProps) => {
|
||||
<Form onSubmit={handleSubmit}>{props.children}</Form>
|
||||
)}
|
||||
metaHeader={() => (
|
||||
<div class={cx(styles.header)}>
|
||||
<div class={styles.header}>
|
||||
<Typography
|
||||
hierarchy="label"
|
||||
family="mono"
|
||||
@@ -127,7 +126,7 @@ export const ClanSettingsModal = (props: ClanSettingsModalProps) => {
|
||||
</div>
|
||||
)}
|
||||
>
|
||||
<div class={cx(styles.content)}>
|
||||
<div class={styles.content}>
|
||||
<Show when={errorMessage()}>
|
||||
<Alert type="error" title="Error" description={errorMessage()} />
|
||||
</Show>
|
||||
@@ -164,11 +163,11 @@ export const ClanSettingsModal = (props: ClanSettingsModalProps) => {
|
||||
"A description of this Clan",
|
||||
)}
|
||||
orientation="horizontal"
|
||||
autoResize={true}
|
||||
minRows={2}
|
||||
maxRows={4}
|
||||
input={{
|
||||
...input,
|
||||
autoResize: true,
|
||||
minRows: 2,
|
||||
maxRows: 4,
|
||||
placeholder: "No description",
|
||||
}}
|
||||
/>
|
||||
@@ -176,21 +175,22 @@ export const ClanSettingsModal = (props: ClanSettingsModalProps) => {
|
||||
</Field>
|
||||
</Fieldset>
|
||||
|
||||
<div class={cx(styles.remove)}>
|
||||
<TextInput
|
||||
class={cx(styles.clanInput)}
|
||||
orientation="horizontal"
|
||||
onChange={setRemoveValue}
|
||||
input={{
|
||||
value: removeValue(),
|
||||
placeholder: "Enter the name of this Clan",
|
||||
onKeyDown: (event) => {
|
||||
if (event.key == "Enter" && !removeDisabled()) {
|
||||
onRemove();
|
||||
}
|
||||
},
|
||||
}}
|
||||
/>
|
||||
<div class={styles.remove}>
|
||||
<div class={styles.clanInput}>
|
||||
<TextInput
|
||||
orientation="horizontal"
|
||||
onChange={setRemoveValue}
|
||||
input={{
|
||||
value: removeValue(),
|
||||
placeholder: "Enter the name of this Clan",
|
||||
onKeyDown: (event) => {
|
||||
if (event.key == "Enter" && !removeDisabled()) {
|
||||
onRemove();
|
||||
}
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Button
|
||||
hierarchy="primary"
|
||||
|
||||
@@ -126,11 +126,11 @@ export const SectionGeneral = (props: SectionGeneralProps) => {
|
||||
readOnly={readOnly(editing, "description")}
|
||||
tooltip={tooltipText("description", fieldsSchema()!)}
|
||||
orientation="horizontal"
|
||||
autoResize={true}
|
||||
minRows={2}
|
||||
maxRows={4}
|
||||
input={{
|
||||
...input,
|
||||
autoResize: true,
|
||||
minRows: 2,
|
||||
maxRows: 4,
|
||||
placeholder: "No description",
|
||||
}}
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user