Compare commits
10 Commits
e5e01610f5
...
b7bbb3155f
Author | SHA1 | Date | |
---|---|---|---|
|
b7bbb3155f | ||
|
21426a27b2 | ||
|
df1ccb783f | ||
|
79a7d4c92a | ||
|
9eeb223b97 | ||
|
9fe13bde17 | ||
|
dd4d9b67ee | ||
|
4b394f8143 | ||
|
75291cda8c | ||
|
6c81c22c72 |
@@ -17,6 +17,7 @@ interface CheckBoxProps {
|
||||
checked?: boolean;
|
||||
defaultChecked?: boolean;
|
||||
disabled?: boolean;
|
||||
readonly?: boolean;
|
||||
onChange?: (checked?: boolean) => void;
|
||||
}
|
||||
|
||||
@@ -35,6 +36,7 @@ const Check: ParentComponent<CheckBoxProps> = (props) => {
|
||||
const mProps = mergeProps<ParentProps<CheckBoxProps>[]>(
|
||||
{
|
||||
disabled: false,
|
||||
readonly: false,
|
||||
},
|
||||
props,
|
||||
);
|
||||
@@ -54,7 +56,7 @@ const Check: ParentComponent<CheckBoxProps> = (props) => {
|
||||
});
|
||||
|
||||
const handleClick = () => {
|
||||
if (mProps.disabled) {
|
||||
if (mProps.disabled || mProps.readonly) {
|
||||
return;
|
||||
}
|
||||
setInternalChecked((prev) => !prev);
|
||||
|
83
src/components/Input.tsx
Normal file
83
src/components/Input.tsx
Normal file
@@ -0,0 +1,83 @@
|
||||
import cx from 'clsx';
|
||||
import { isNotNil } from 'es-toolkit';
|
||||
import { Component, createEffect, createSignal, JSX, mergeProps, onMount, Show } from 'solid-js';
|
||||
|
||||
interface InputProps {
|
||||
name?: string;
|
||||
variant?: 'normal' | 'underlined' | 'immersive';
|
||||
left?: JSX.Element;
|
||||
right?: JSX.Element;
|
||||
value?: string;
|
||||
defaultValue?: string;
|
||||
placeholder?: string;
|
||||
disabled?: boolean;
|
||||
readonly?: boolean;
|
||||
onInput?: (value: string | null) => void;
|
||||
wrapperClass?: JSX.HTMLAttributes<HTMLDivElement>['class'];
|
||||
inputClass?: JSX.HTMLAttributes<HTMLInputElement>['class'];
|
||||
}
|
||||
|
||||
const Input: Component<InputProps> = (props) => {
|
||||
const mProps = mergeProps<InputProps[]>(
|
||||
{
|
||||
variant: 'normal',
|
||||
disabled: false,
|
||||
readonly: false,
|
||||
placeholder: '',
|
||||
},
|
||||
props,
|
||||
);
|
||||
const [internalValue, setInternalValue] = createSignal<string>('');
|
||||
onMount(() => {
|
||||
if (isNotNil(mProps.defaultValue)) {
|
||||
setInternalValue(mProps.defaultValue);
|
||||
}
|
||||
});
|
||||
createEffect(() => {
|
||||
if (isNotNil(mProps.value) && mProps.value !== internalValue()) {
|
||||
setInternalValue(mProps.value);
|
||||
}
|
||||
});
|
||||
|
||||
const handleInput: JSX.EventHandler<HTMLInputElement, InputEvent> = (evt) => {
|
||||
if (mProps.readonly || mProps.disabled) {
|
||||
return;
|
||||
}
|
||||
const value = evt.currentTarget.value;
|
||||
setInternalValue(value);
|
||||
mProps.onInput?.(value);
|
||||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
aria-disabled={mProps.disabled}
|
||||
aria-readonly={mProps.readonly}
|
||||
class={cx(
|
||||
'flex flex-row items-center gap-2 min-h-[1em] px-3 py-1.5 aria-readonly:cursor-not-allowed',
|
||||
mProps.variant === 'normal' &&
|
||||
'rounded-sm bg-neutral text-on-neutral aria-disabled:cursor-not-allowed aria-disabled:text-neutral-disabled',
|
||||
mProps.variant === 'underlined' &&
|
||||
'border-b border-solid pb-[calc(var(--spacing)*1.5-1px)] border-on-surface text-on-surface aria-disabled:border-neutral-disabled aria-disabled:text-neutral-disabled',
|
||||
mProps.variant === 'immersive' && 'text-on-surface aria-disabled:text-neutral-disabled',
|
||||
mProps.wrapperClass,
|
||||
)}>
|
||||
<Show when={isNotNil(mProps.left)}>{mProps.left}</Show>
|
||||
<input
|
||||
name={mProps.name}
|
||||
type={mProps.type}
|
||||
placeholder={mProps.placeholder}
|
||||
disabled={mProps.disabled}
|
||||
readonly={mProps.readonly}
|
||||
value={internalValue()}
|
||||
class={cx(
|
||||
'min-h-[1em] grow focus:outline-none placeholder:italic disabled:text-neutral-disabled',
|
||||
mProps.inputClass,
|
||||
)}
|
||||
onInput={handleInput}
|
||||
/>
|
||||
<Show when={isNotNil(mProps.right)}>{mProps.right}</Show>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Input;
|
@@ -17,6 +17,7 @@ interface RadioProps {
|
||||
checked?: boolean;
|
||||
defaultChecked?: boolean;
|
||||
disabled?: boolean;
|
||||
readonly?: boolean;
|
||||
onChange?: (value?: boolean) => void;
|
||||
}
|
||||
|
||||
@@ -35,6 +36,7 @@ const Radio: ParentComponent<RadioProps> = (props) => {
|
||||
const mProps = mergeProps<ParentProps<RadioProps>[]>(
|
||||
{
|
||||
disabled: false,
|
||||
readonly: false,
|
||||
},
|
||||
props,
|
||||
);
|
||||
@@ -54,7 +56,7 @@ const Radio: ParentComponent<RadioProps> = (props) => {
|
||||
});
|
||||
|
||||
const handleClick = () => {
|
||||
if (mProps.disabled) {
|
||||
if (mProps.disabled || mProps.readonly) {
|
||||
return;
|
||||
}
|
||||
setInternalChecked((prev) => !prev);
|
||||
|
@@ -23,6 +23,7 @@ interface RadioGroupProps {
|
||||
value?: Option['value'];
|
||||
defalutValue?: Option['value'];
|
||||
disabled?: boolean;
|
||||
readonly?: boolean;
|
||||
onChange?: (value?: Option['value']) => void;
|
||||
}
|
||||
|
||||
@@ -31,6 +32,7 @@ const RadioGroup: Component<RadioGroupProps> = (props) => {
|
||||
{
|
||||
options: [],
|
||||
disabled: false,
|
||||
readonly: false,
|
||||
},
|
||||
props,
|
||||
);
|
||||
@@ -50,7 +52,7 @@ const RadioGroup: Component<RadioGroupProps> = (props) => {
|
||||
});
|
||||
|
||||
const handleSelect = (value: Option['value']) => {
|
||||
if (mProps.disabled) {
|
||||
if (mProps.disabled || mProps.readonly) {
|
||||
return;
|
||||
}
|
||||
setSelectedValue(value);
|
||||
@@ -64,6 +66,7 @@ const RadioGroup: Component<RadioGroupProps> = (props) => {
|
||||
<Radio
|
||||
checked={selectedValue() === option().value}
|
||||
disabled={mProps.disabled}
|
||||
readonly={mProps.readonly}
|
||||
onChange={() => {
|
||||
handleSelect(option().value);
|
||||
}}>
|
||||
|
@@ -24,6 +24,7 @@ interface SegmentsProps {
|
||||
defaultValue?: Option['value'];
|
||||
direction?: 'horizontal' | 'vertical';
|
||||
disabled?: boolean;
|
||||
readonly?: boolean;
|
||||
onChange?: (value: Option['value'] | undefined) => void;
|
||||
}
|
||||
|
||||
@@ -32,6 +33,7 @@ const Segments: Component<SegmentsProps> = (props) => {
|
||||
{
|
||||
options: [],
|
||||
disabled: false,
|
||||
readonly: false,
|
||||
direction: 'horizontal',
|
||||
},
|
||||
props,
|
||||
@@ -69,7 +71,7 @@ const Segments: Component<SegmentsProps> = (props) => {
|
||||
});
|
||||
|
||||
const handleSelect = (value: Option['value']) => {
|
||||
if (mProps.disabled) {
|
||||
if (mProps.disabled || mProps.readonly) {
|
||||
return;
|
||||
}
|
||||
setSelected(value);
|
||||
@@ -88,8 +90,9 @@ const Segments: Component<SegmentsProps> = (props) => {
|
||||
<div
|
||||
ref={(el) => (optionRefs[index] = el)}
|
||||
aria-disabled={mProps.disabled}
|
||||
aria-readonly={mProps.readonly}
|
||||
class={cx(
|
||||
'z-[5] cursor-pointer rounded-sm px-2 py-0.5',
|
||||
'z-[5] cursor-pointer rounded-sm px-2 py-0.5 aria-readonly:cursor-not-allowed',
|
||||
selected() === option().value
|
||||
? 'not-aria-disabled:text-on-primary-surface aria-disabled:text-primary-disabled'
|
||||
: 'not-aria-disabled:text-on-surface aria-disabled:text-neutral-disabled hover:not-aria-disabled:text-primary-hover',
|
||||
|
@@ -10,6 +10,7 @@ import {
|
||||
JSX,
|
||||
Match,
|
||||
mergeProps,
|
||||
onCleanup,
|
||||
onMount,
|
||||
Show,
|
||||
Switch,
|
||||
@@ -40,7 +41,7 @@ const SimpleOptions: Component<SimpleOptionsProps> = (props) => {
|
||||
{(option) => (
|
||||
<div
|
||||
class={cx(
|
||||
'rounded-sm px-2 py-1 transition-colors duration-100',
|
||||
'rounded-sm px-2 py-1 transition-colors duration-100 cursor-pointer',
|
||||
option().value === props.active && 'bg-primary-surface text-on-primary-surface',
|
||||
option().value === props.active
|
||||
? 'hover:bg-primary-surface-hover hover:text-on-primary-surface'
|
||||
@@ -79,7 +80,7 @@ const GroupedOptions: Component<GroupedOptionsProps> = (props) => {
|
||||
{(option) => (
|
||||
<div
|
||||
class={cx(
|
||||
'rounded-sm px-2 py-1 transition-colors duration-100',
|
||||
'rounded-sm px-2 py-1 transition-colors duration-100 cursor-pointer',
|
||||
option().value === props.active &&
|
||||
'bg-primary-surface text-on-primary-surface',
|
||||
option().value === props.active
|
||||
@@ -107,6 +108,7 @@ interface SelectProps {
|
||||
value?: Option['value'];
|
||||
defaultValue?: Option['value'];
|
||||
disabled?: boolean;
|
||||
readonly?: boolean;
|
||||
onChange?: (value: Option['value']) => void;
|
||||
}
|
||||
|
||||
@@ -117,12 +119,14 @@ const Select: Component<SelectProps> = (props) => {
|
||||
placeholder: '',
|
||||
options: [],
|
||||
disabled: false,
|
||||
readonly: false,
|
||||
},
|
||||
props,
|
||||
);
|
||||
|
||||
let trigger: HTMLDivElement;
|
||||
let optionFrame: HTMLDivElement;
|
||||
let hideOptionTimer: number | undefined = undefined;
|
||||
|
||||
const [selected, setSelected] = createSignal<Option['value'] | undefined>(undefined);
|
||||
const [optionVisible, setOptionVisible] = createSignal(false);
|
||||
@@ -156,21 +160,91 @@ const Select: Component<SelectProps> = (props) => {
|
||||
return placeholderContent;
|
||||
}
|
||||
});
|
||||
const adjustPosition = () => {
|
||||
const triggerRect = trigger.getBoundingClientRect();
|
||||
const optionsRect = optionFrame.getBoundingClientRect();
|
||||
const distanceToBottom = window.innerHeight - triggerRect.bottom;
|
||||
|
||||
if (triggerRect.top < distanceToBottom) {
|
||||
optionFrame.style.top = `${triggerRect.bottom + 4}px`;
|
||||
optionFrame.style.height = `${Math.min(distanceToBottom * 0.6, window.innerHeight * 0.4)}px`;
|
||||
} else {
|
||||
optionFrame.style.top = `${triggerRect.top - optionsRect.height - 4}px`;
|
||||
optionFrame.style.height = `${Math.min(distanceToBottom * 0.6, window.innerHeight * 0.4)}px`;
|
||||
}
|
||||
optionFrame.style.left = `${triggerRect.left}px`;
|
||||
optionFrame.style.width = `clamp(${triggerRect.width}px, ${triggerRect.width * 1.5}px, ${
|
||||
triggerRect.width * 2.5
|
||||
}px)`;
|
||||
};
|
||||
const resizeObserver = new ResizeObserver(adjustPosition);
|
||||
|
||||
createEffect(() => {
|
||||
if (optionVisible()) {
|
||||
adjustPosition();
|
||||
resizeObserver.observe(trigger);
|
||||
}
|
||||
});
|
||||
onCleanup(() => {
|
||||
resizeObserver.unobserve(trigger);
|
||||
resizeObserver.disconnect();
|
||||
clearTimeout(hideOptionTimer);
|
||||
});
|
||||
|
||||
const handleMouseEnter = () => {
|
||||
if (mProps.disabled) {
|
||||
return;
|
||||
}
|
||||
clearTimeout(hideOptionTimer);
|
||||
};
|
||||
const handleMouseLeave = () => {
|
||||
if (mProps.disabled) {
|
||||
return;
|
||||
}
|
||||
clearTimeout(hideOptionTimer);
|
||||
hideOptionTimer = setTimeout(() => {
|
||||
setOptionVisible(false);
|
||||
}, 500);
|
||||
};
|
||||
const handleActivation = () => {
|
||||
if (mProps.disabled) {
|
||||
return;
|
||||
}
|
||||
clearTimeout(hideOptionTimer);
|
||||
if (!mProps.readonly) {
|
||||
setOptionVisible((prev) => !prev);
|
||||
}
|
||||
};
|
||||
const handleOptionClick = (value: Option['value']) => {
|
||||
if (selected() !== value) {
|
||||
setSelected(value);
|
||||
mProps.onChange?.(value);
|
||||
} else {
|
||||
setSelected(undefined);
|
||||
mProps.onChange?.(undefined);
|
||||
}
|
||||
setOptionVisible(false);
|
||||
clearTimeout(hideOptionTimer);
|
||||
};
|
||||
|
||||
return (
|
||||
<div class="relative inline-block">
|
||||
<div
|
||||
ref={trigger}
|
||||
aria-disabled={mProps.disabled}
|
||||
aria-readonly={mProps.readonly}
|
||||
class={cx(
|
||||
'flex items-center gap-3 min-h-[1em] px-3 py-1.5 cursor-pointer aria-disabled:cursor-not-allowed',
|
||||
'flex items-center gap-3 min-h-[1em] px-3 py-1.5 cursor-pointer aria-disabled:cursor-not-allowed aria-readonly:cursor-not-allowed',
|
||||
mProps.variant === 'normal' &&
|
||||
'rounded-sm bg-neutral text-on-neutral aria-disabled:text-neutral-disabled hover:not-aria-disabled:text-primary-hover',
|
||||
mProps.variant === 'underlined' &&
|
||||
'border-b border-solid pb-[calc(var(--spacing)*1.5-1px)] border-on-surface text-on-surface aria-disabled:border-neutral-disabled aria-disabled:text-neutral-disabled hover:not-aria-disabled:text-primary-hover hover:not-aria-disabled:border-primary-hover',
|
||||
mProps.variant === 'immersive' &&
|
||||
'text-on-surface hover:not-aria-disabled:text-primary-hover aria-disabled:text-neutral-disabled',
|
||||
)}>
|
||||
)}
|
||||
onMouseEnter={handleMouseEnter}
|
||||
onMouseLeave={handleMouseLeave}
|
||||
onClick={handleActivation}>
|
||||
<div class="flex-1 flex flex-row items-center truncate">
|
||||
<Dynamic component={displayLabel} />
|
||||
</div>
|
||||
@@ -186,11 +260,24 @@ const Select: Component<SelectProps> = (props) => {
|
||||
<Portal>
|
||||
<div
|
||||
ref={optionFrame}
|
||||
class="absolute z-[15] w-auto rounded-sm bg-surface-active px-1 py-1 elevation-1">
|
||||
class="absolute z-[15] w-auto rounded-sm bg-neutral-variant-active px-1 py-1 elevation-1"
|
||||
onMouseEnter={handleMouseEnter}
|
||||
onMouseLeave={handleMouseLeave}>
|
||||
<ScrollArea enableY fullSize>
|
||||
<Switch fallback={<GroupedOptions options={mProps.options} />}>
|
||||
<Switch
|
||||
fallback={
|
||||
<GroupedOptions
|
||||
options={mProps.options}
|
||||
active={selected()}
|
||||
onClick={handleOptionClick}
|
||||
/>
|
||||
}>
|
||||
<Match when={Array.isArray(mProps.options)}>
|
||||
<SimpleOptions options={mProps.options} />
|
||||
<SimpleOptions
|
||||
options={mProps.options}
|
||||
active={selected()}
|
||||
onClick={handleOptionClick}
|
||||
/>
|
||||
</Match>
|
||||
</Switch>
|
||||
</ScrollArea>
|
||||
|
@@ -1,8 +1,248 @@
|
||||
import { Icon } from '@iconify-icon/solid';
|
||||
import { Component } from 'solid-js';
|
||||
import Check from '../components/Check';
|
||||
import Input from '../components/Input';
|
||||
import Radio from '../components/Radio';
|
||||
import RadioGroup from '../components/RadioGroup';
|
||||
import ScrollArea from '../components/ScrollArea';
|
||||
import Segments from '../components/Segments';
|
||||
import Select from '../components/Select';
|
||||
import Switcher from '../components/Switch';
|
||||
|
||||
const ComponentsDemo: Component = () => {
|
||||
return (
|
||||
<div class="workspace flex flex-col items-stretch gap-2 rounded-sm bg-swatch-neutral-20"></div>
|
||||
<div class="workspace flex flex-col items-stretch gap-2 rounded-sm bg-swatch-neutral-20 p-4">
|
||||
<ScrollArea enableY flexExtended>
|
||||
<div class="flex flex-col items-stretch gap-2">
|
||||
<div class="flex flex-row gap-1">
|
||||
<Radio name="t_radio_1" defaultChecked>
|
||||
Test Radio button
|
||||
</Radio>
|
||||
</div>
|
||||
<div class="flex flex-row items-center gap-3">
|
||||
<RadioGroup
|
||||
name="t_radio_group_1"
|
||||
options={[
|
||||
{ label: 'Option 1', value: '1' },
|
||||
{ label: 'Option 2', value: '2' },
|
||||
{ label: 'Option 3', value: '3' },
|
||||
]}
|
||||
defalutValue="2"
|
||||
/>
|
||||
</div>
|
||||
<div class="flex flex-row gap-1">
|
||||
<Check name="t_check_1">Test Checkbox</Check>
|
||||
</div>
|
||||
<div class="flex flex-row gap-1 items-center">
|
||||
<Segments
|
||||
options={[
|
||||
{ label: 'Option 1', value: '1' },
|
||||
{ label: 'Option 2', value: '2' },
|
||||
{ label: 'Option 3', value: '3' },
|
||||
]}
|
||||
/>
|
||||
<Select
|
||||
placeholder="Select an option"
|
||||
options={[
|
||||
{ label: 'Option 1', value: '1' },
|
||||
{ label: 'Option 2', value: '2' },
|
||||
{ label: 'Option 3', value: '3' },
|
||||
]}
|
||||
/>
|
||||
<Select
|
||||
placeholder="Select an option"
|
||||
variant="underlined"
|
||||
options={[
|
||||
{ label: 'Option 1', value: '1' },
|
||||
{ label: 'Option 2', value: '2' },
|
||||
{ label: 'Option 3', value: '3' },
|
||||
]}
|
||||
/>
|
||||
<Select
|
||||
placeholder="Select an option"
|
||||
variant="immersive"
|
||||
options={[
|
||||
{ label: 'Option 1', value: '1' },
|
||||
{ label: 'Option 2', value: '2' },
|
||||
{ label: 'Option 3', value: '3' },
|
||||
{ label: 'Option 4', value: '4' },
|
||||
{ label: 'Option 5', value: '5' },
|
||||
{ label: 'Option 6', value: '6' },
|
||||
{ label: 'Option 7', value: '7' },
|
||||
{ label: 'Option 8', value: '8' },
|
||||
{ label: 'Option 9', value: '9' },
|
||||
{ label: 'Option 1', value: 'a' },
|
||||
{ label: 'Option 2', value: 'b' },
|
||||
{ label: 'Option 3', value: 'c' },
|
||||
{ label: 'Option 4', value: 'd' },
|
||||
{ label: 'Option 5', value: 'e' },
|
||||
{ label: 'Option 6', value: 'f' },
|
||||
{ label: 'Option 7', value: 'g' },
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
<div class="flex flex-row gap-1 items-center">
|
||||
<Segments
|
||||
disabled
|
||||
options={[
|
||||
{ label: 'Option 1', value: '1' },
|
||||
{ label: 'Option 2', value: '2' },
|
||||
{ label: 'Option 3', value: '3' },
|
||||
]}
|
||||
/>
|
||||
<Select
|
||||
placeholder="Select an option"
|
||||
disabled
|
||||
options={[
|
||||
{ label: 'Option 1', value: '1' },
|
||||
{ label: 'Option 2', value: '2' },
|
||||
{ label: 'Option 3', value: '3' },
|
||||
]}
|
||||
/>
|
||||
<Select
|
||||
placeholder="Select an option"
|
||||
variant="underlined"
|
||||
disabled
|
||||
options={[
|
||||
{ label: 'Option 1', value: '1' },
|
||||
{ label: 'Option 2', value: '2' },
|
||||
{ label: 'Option 3', value: '3' },
|
||||
]}
|
||||
/>
|
||||
<Select
|
||||
placeholder="Select an option"
|
||||
variant="immersive"
|
||||
disabled
|
||||
options={[
|
||||
{ label: 'Option 1', value: '1' },
|
||||
{ label: 'Option 2', value: '2' },
|
||||
{ label: 'Option 3', value: '3' },
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
<div class="flex flex-row gap-1 text-xs">
|
||||
<Segments
|
||||
direction="vertical"
|
||||
options={[
|
||||
{ label: 'Option 1', value: '1' },
|
||||
{ label: 'Option 2', value: '2' },
|
||||
{ label: 'Option 3', value: '3' },
|
||||
]}
|
||||
defaultValue="3"
|
||||
/>
|
||||
</div>
|
||||
<div class="flex flex-row gap-1">
|
||||
<Switcher />
|
||||
</div>
|
||||
<div class="flex flex-row gap-1 items-center">
|
||||
<Select
|
||||
placeholder="Select an option"
|
||||
options={[
|
||||
{ label: 'Option 1', value: '1' },
|
||||
{ label: 'Option 2', value: '2' },
|
||||
{ label: 'Option 3', value: '3' },
|
||||
{ label: 'Option 4', value: '4' },
|
||||
{ label: 'Option 5', value: '5' },
|
||||
{ label: 'Option 6', value: '6' },
|
||||
{ label: 'Option 7', value: '7' },
|
||||
{ label: 'Option 8', value: '8' },
|
||||
{ label: 'Option 9', value: '9' },
|
||||
{ label: 'Option 1', value: 'a' },
|
||||
{ label: 'Option 2', value: 'b' },
|
||||
{ label: 'Option 3', value: 'c' },
|
||||
{ label: 'Option 4', value: 'd' },
|
||||
{ label: 'Option 5', value: 'e' },
|
||||
{ label: 'Option 6', value: 'f' },
|
||||
{ label: 'Option 7', value: 'g' },
|
||||
]}
|
||||
/>
|
||||
<Input placeholder="输入一些文字内容" />
|
||||
<Input
|
||||
placeholder="搜索一些内容"
|
||||
value="comfy models"
|
||||
left={<Icon icon="hugeicons:search-01" />}
|
||||
/>
|
||||
</div>
|
||||
<div class="flex flex-row gap-1 items-center">
|
||||
<Input
|
||||
placeholder="搜索一些内容"
|
||||
value="comfy models"
|
||||
left={<Icon icon="hugeicons:search-01" />}
|
||||
/>
|
||||
<Input
|
||||
variant="underlined"
|
||||
placeholder="搜索一些内容"
|
||||
left={<Icon icon="hugeicons:search-01" />}
|
||||
/>
|
||||
<Input
|
||||
variant="immersive"
|
||||
placeholder="搜索一些内容"
|
||||
left={<Icon icon="hugeicons:search-01" />}
|
||||
/>
|
||||
</div>
|
||||
<div class="flex flex-row gap-1 items-center">
|
||||
<Input
|
||||
placeholder="搜索一些内容"
|
||||
disabled
|
||||
value="comfy models"
|
||||
left={<Icon icon="hugeicons:search-01" />}
|
||||
/>
|
||||
<Input
|
||||
variant="underlined"
|
||||
disabled
|
||||
placeholder="搜索一些内容"
|
||||
value="comfy models"
|
||||
left={<Icon icon="hugeicons:search-01" />}
|
||||
/>
|
||||
<Input
|
||||
variant="immersive"
|
||||
disabled
|
||||
placeholder="搜索一些内容"
|
||||
value="comfy models"
|
||||
left={<Icon icon="hugeicons:search-01" />}
|
||||
/>
|
||||
</div>
|
||||
<div class="flex flex-row gap-1 items-center">
|
||||
<div class="h-[6em] w-[35em] flex flex-row">
|
||||
<ScrollArea flexExtended enableY>
|
||||
<div class="flex flex-col gap-[2em]">
|
||||
<p>
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla pharetra quam
|
||||
tincidunt, ornare orci quis, commodo quam. Etiam finibus ex dolor, id feugiat
|
||||
augue porttitor eget. Morbi ornare nisl sed laoreet efficitur. Phasellus
|
||||
consectetur lacus id sem elementum dignissim. Aliquam pulvinar facilisis eros,
|
||||
eget scelerisque magna pharetra ac. Suspendisse potenti. Sed eget finibus magna,
|
||||
vitae laoreet lorem. Vestibulum gravida accumsan ipsum. Duis eget orci porta,
|
||||
fringilla velit viverra, ultricies est. Ut turpis erat, lobortis nec hendrerit
|
||||
eu, malesuada eu dui.
|
||||
</p>
|
||||
<p>
|
||||
Morbi elementum eleifend augue non ultrices. Aenean venenatis tincidunt risus,
|
||||
sit amet tincidunt dui feugiat ac. Morbi eu aliquam nisi, et ultrices tortor.
|
||||
Quisque eget faucibus lacus. Integer diam arcu, gravida in pellentesque in,
|
||||
pharetra sit amet orci. Vestibulum molestie porta lectus, ac laoreet justo
|
||||
fringilla et. Curabitur convallis ipsum erat, sed blandit lorem consequat ac.
|
||||
Maecenas aliquet lorem a tellus lacinia placerat. Donec id ante malesuada,
|
||||
rhoncus diam at, sollicitudin ante. Vivamus iaculis nisl urna.
|
||||
</p>
|
||||
<p>
|
||||
Duis sodales tempus nulla, vel accumsan ex. Curabitur sit amet auctor dolor, non
|
||||
gravida diam. Quisque ac velit felis. Proin imperdiet varius vestibulum. Mauris
|
||||
hendrerit id felis et maximus. Phasellus interdum felis sit amet urna semper,
|
||||
nec tincidunt quam molestie. Nam vitae quam laoreet, blandit velit et, molestie
|
||||
libero. Sed elit augue, convallis quis dictum vel, eleifend sed mi. In tincidunt
|
||||
sagittis sapien ac consectetur. Nulla volutpat, turpis pellentesque imperdiet
|
||||
convallis, ipsum felis pulvinar elit, nec luctus massa ipsum ut ligula. Fusce
|
||||
tristique sit amet lacus nec ullamcorper. Integer eros dolor, sodales eget
|
||||
maximus eget, efficitur quis nulla. Curabitur ac mollis elit, sed ultrices erat.
|
||||
</p>
|
||||
</div>
|
||||
</ScrollArea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ScrollArea>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
Reference in New Issue
Block a user