Compare commits
10 Commits
e5e01610f5
...
main
Author | SHA1 | Date | |
---|---|---|---|
|
b7bbb3155f | ||
|
21426a27b2 | ||
|
df1ccb783f | ||
|
79a7d4c92a | ||
|
9eeb223b97 | ||
|
9fe13bde17 | ||
|
dd4d9b67ee | ||
|
4b394f8143 | ||
|
75291cda8c | ||
|
6c81c22c72 |
@@ -17,6 +17,7 @@ interface CheckBoxProps {
|
|||||||
checked?: boolean;
|
checked?: boolean;
|
||||||
defaultChecked?: boolean;
|
defaultChecked?: boolean;
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
|
readonly?: boolean;
|
||||||
onChange?: (checked?: boolean) => void;
|
onChange?: (checked?: boolean) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -35,6 +36,7 @@ const Check: ParentComponent<CheckBoxProps> = (props) => {
|
|||||||
const mProps = mergeProps<ParentProps<CheckBoxProps>[]>(
|
const mProps = mergeProps<ParentProps<CheckBoxProps>[]>(
|
||||||
{
|
{
|
||||||
disabled: false,
|
disabled: false,
|
||||||
|
readonly: false,
|
||||||
},
|
},
|
||||||
props,
|
props,
|
||||||
);
|
);
|
||||||
@@ -54,7 +56,7 @@ const Check: ParentComponent<CheckBoxProps> = (props) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const handleClick = () => {
|
const handleClick = () => {
|
||||||
if (mProps.disabled) {
|
if (mProps.disabled || mProps.readonly) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
setInternalChecked((prev) => !prev);
|
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;
|
checked?: boolean;
|
||||||
defaultChecked?: boolean;
|
defaultChecked?: boolean;
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
|
readonly?: boolean;
|
||||||
onChange?: (value?: boolean) => void;
|
onChange?: (value?: boolean) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -35,6 +36,7 @@ const Radio: ParentComponent<RadioProps> = (props) => {
|
|||||||
const mProps = mergeProps<ParentProps<RadioProps>[]>(
|
const mProps = mergeProps<ParentProps<RadioProps>[]>(
|
||||||
{
|
{
|
||||||
disabled: false,
|
disabled: false,
|
||||||
|
readonly: false,
|
||||||
},
|
},
|
||||||
props,
|
props,
|
||||||
);
|
);
|
||||||
@@ -54,7 +56,7 @@ const Radio: ParentComponent<RadioProps> = (props) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const handleClick = () => {
|
const handleClick = () => {
|
||||||
if (mProps.disabled) {
|
if (mProps.disabled || mProps.readonly) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
setInternalChecked((prev) => !prev);
|
setInternalChecked((prev) => !prev);
|
||||||
|
@@ -23,6 +23,7 @@ interface RadioGroupProps {
|
|||||||
value?: Option['value'];
|
value?: Option['value'];
|
||||||
defalutValue?: Option['value'];
|
defalutValue?: Option['value'];
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
|
readonly?: boolean;
|
||||||
onChange?: (value?: Option['value']) => void;
|
onChange?: (value?: Option['value']) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -31,6 +32,7 @@ const RadioGroup: Component<RadioGroupProps> = (props) => {
|
|||||||
{
|
{
|
||||||
options: [],
|
options: [],
|
||||||
disabled: false,
|
disabled: false,
|
||||||
|
readonly: false,
|
||||||
},
|
},
|
||||||
props,
|
props,
|
||||||
);
|
);
|
||||||
@@ -50,7 +52,7 @@ const RadioGroup: Component<RadioGroupProps> = (props) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const handleSelect = (value: Option['value']) => {
|
const handleSelect = (value: Option['value']) => {
|
||||||
if (mProps.disabled) {
|
if (mProps.disabled || mProps.readonly) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
setSelectedValue(value);
|
setSelectedValue(value);
|
||||||
@@ -64,6 +66,7 @@ const RadioGroup: Component<RadioGroupProps> = (props) => {
|
|||||||
<Radio
|
<Radio
|
||||||
checked={selectedValue() === option().value}
|
checked={selectedValue() === option().value}
|
||||||
disabled={mProps.disabled}
|
disabled={mProps.disabled}
|
||||||
|
readonly={mProps.readonly}
|
||||||
onChange={() => {
|
onChange={() => {
|
||||||
handleSelect(option().value);
|
handleSelect(option().value);
|
||||||
}}>
|
}}>
|
||||||
|
@@ -24,6 +24,7 @@ interface SegmentsProps {
|
|||||||
defaultValue?: Option['value'];
|
defaultValue?: Option['value'];
|
||||||
direction?: 'horizontal' | 'vertical';
|
direction?: 'horizontal' | 'vertical';
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
|
readonly?: boolean;
|
||||||
onChange?: (value: Option['value'] | undefined) => void;
|
onChange?: (value: Option['value'] | undefined) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -32,6 +33,7 @@ const Segments: Component<SegmentsProps> = (props) => {
|
|||||||
{
|
{
|
||||||
options: [],
|
options: [],
|
||||||
disabled: false,
|
disabled: false,
|
||||||
|
readonly: false,
|
||||||
direction: 'horizontal',
|
direction: 'horizontal',
|
||||||
},
|
},
|
||||||
props,
|
props,
|
||||||
@@ -69,7 +71,7 @@ const Segments: Component<SegmentsProps> = (props) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const handleSelect = (value: Option['value']) => {
|
const handleSelect = (value: Option['value']) => {
|
||||||
if (mProps.disabled) {
|
if (mProps.disabled || mProps.readonly) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
setSelected(value);
|
setSelected(value);
|
||||||
@@ -88,8 +90,9 @@ const Segments: Component<SegmentsProps> = (props) => {
|
|||||||
<div
|
<div
|
||||||
ref={(el) => (optionRefs[index] = el)}
|
ref={(el) => (optionRefs[index] = el)}
|
||||||
aria-disabled={mProps.disabled}
|
aria-disabled={mProps.disabled}
|
||||||
|
aria-readonly={mProps.readonly}
|
||||||
class={cx(
|
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
|
selected() === option().value
|
||||||
? 'not-aria-disabled:text-on-primary-surface aria-disabled:text-primary-disabled'
|
? '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',
|
: 'not-aria-disabled:text-on-surface aria-disabled:text-neutral-disabled hover:not-aria-disabled:text-primary-hover',
|
||||||
|
@@ -10,6 +10,7 @@ import {
|
|||||||
JSX,
|
JSX,
|
||||||
Match,
|
Match,
|
||||||
mergeProps,
|
mergeProps,
|
||||||
|
onCleanup,
|
||||||
onMount,
|
onMount,
|
||||||
Show,
|
Show,
|
||||||
Switch,
|
Switch,
|
||||||
@@ -40,7 +41,7 @@ const SimpleOptions: Component<SimpleOptionsProps> = (props) => {
|
|||||||
{(option) => (
|
{(option) => (
|
||||||
<div
|
<div
|
||||||
class={cx(
|
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 && 'bg-primary-surface text-on-primary-surface',
|
||||||
option().value === props.active
|
option().value === props.active
|
||||||
? 'hover:bg-primary-surface-hover hover:text-on-primary-surface'
|
? 'hover:bg-primary-surface-hover hover:text-on-primary-surface'
|
||||||
@@ -79,7 +80,7 @@ const GroupedOptions: Component<GroupedOptionsProps> = (props) => {
|
|||||||
{(option) => (
|
{(option) => (
|
||||||
<div
|
<div
|
||||||
class={cx(
|
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 &&
|
option().value === props.active &&
|
||||||
'bg-primary-surface text-on-primary-surface',
|
'bg-primary-surface text-on-primary-surface',
|
||||||
option().value === props.active
|
option().value === props.active
|
||||||
@@ -107,6 +108,7 @@ interface SelectProps {
|
|||||||
value?: Option['value'];
|
value?: Option['value'];
|
||||||
defaultValue?: Option['value'];
|
defaultValue?: Option['value'];
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
|
readonly?: boolean;
|
||||||
onChange?: (value: Option['value']) => void;
|
onChange?: (value: Option['value']) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -117,12 +119,14 @@ const Select: Component<SelectProps> = (props) => {
|
|||||||
placeholder: '',
|
placeholder: '',
|
||||||
options: [],
|
options: [],
|
||||||
disabled: false,
|
disabled: false,
|
||||||
|
readonly: false,
|
||||||
},
|
},
|
||||||
props,
|
props,
|
||||||
);
|
);
|
||||||
|
|
||||||
let trigger: HTMLDivElement;
|
let trigger: HTMLDivElement;
|
||||||
let optionFrame: HTMLDivElement;
|
let optionFrame: HTMLDivElement;
|
||||||
|
let hideOptionTimer: number | undefined = undefined;
|
||||||
|
|
||||||
const [selected, setSelected] = createSignal<Option['value'] | undefined>(undefined);
|
const [selected, setSelected] = createSignal<Option['value'] | undefined>(undefined);
|
||||||
const [optionVisible, setOptionVisible] = createSignal(false);
|
const [optionVisible, setOptionVisible] = createSignal(false);
|
||||||
@@ -156,21 +160,91 @@ const Select: Component<SelectProps> = (props) => {
|
|||||||
return placeholderContent;
|
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 (
|
return (
|
||||||
<div class="relative inline-block">
|
<div class="relative inline-block">
|
||||||
<div
|
<div
|
||||||
ref={trigger}
|
ref={trigger}
|
||||||
aria-disabled={mProps.disabled}
|
aria-disabled={mProps.disabled}
|
||||||
|
aria-readonly={mProps.readonly}
|
||||||
class={cx(
|
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' &&
|
mProps.variant === 'normal' &&
|
||||||
'rounded-sm bg-neutral text-on-neutral aria-disabled:text-neutral-disabled hover:not-aria-disabled:text-primary-hover',
|
'rounded-sm bg-neutral text-on-neutral aria-disabled:text-neutral-disabled hover:not-aria-disabled:text-primary-hover',
|
||||||
mProps.variant === 'underlined' &&
|
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',
|
'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' &&
|
mProps.variant === 'immersive' &&
|
||||||
'text-on-surface hover:not-aria-disabled:text-primary-hover aria-disabled:text-neutral-disabled',
|
'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">
|
<div class="flex-1 flex flex-row items-center truncate">
|
||||||
<Dynamic component={displayLabel} />
|
<Dynamic component={displayLabel} />
|
||||||
</div>
|
</div>
|
||||||
@@ -186,11 +260,24 @@ const Select: Component<SelectProps> = (props) => {
|
|||||||
<Portal>
|
<Portal>
|
||||||
<div
|
<div
|
||||||
ref={optionFrame}
|
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>
|
<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)}>
|
<Match when={Array.isArray(mProps.options)}>
|
||||||
<SimpleOptions options={mProps.options} />
|
<SimpleOptions
|
||||||
|
options={mProps.options}
|
||||||
|
active={selected()}
|
||||||
|
onClick={handleOptionClick}
|
||||||
|
/>
|
||||||
</Match>
|
</Match>
|
||||||
</Switch>
|
</Switch>
|
||||||
</ScrollArea>
|
</ScrollArea>
|
||||||
|
@@ -1,8 +1,248 @@
|
|||||||
|
import { Icon } from '@iconify-icon/solid';
|
||||||
import { Component } from 'solid-js';
|
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 = () => {
|
const ComponentsDemo: Component = () => {
|
||||||
return (
|
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