mirror of
https://github.com/webstudio-is/webstudio.git
synced 2026-11-07 20:44:05 +09:00
Improve types and add more examples for refs
This commit is contained in:
1 parent
ebd952492a
commit
2a4cd84e10
2 files changed
+82
-53
No files matched your search
@@ -1,6 +1,7 @@
|
||||
import React from "react";
|
||||
import { ComponentStory } from "@storybook/react";
|
||||
import { BrushIcon, ChevronDownIcon } from "@webstudio-is/icons";
|
||||
import { Button } from "./button";
|
||||
import { Flex } from "./flex";
|
||||
import { IconButton } from "./icon-button";
|
||||
import { TextField } from "./text-field";
|
||||
@@ -94,3 +95,30 @@ export const PrefixSuffix: ComponentStory<typeof TextField> = () => {
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
|
||||
export const Interactive: ComponentStory<typeof TextField> = () => {
|
||||
const [value, setValue] = React.useState("");
|
||||
const wrapperRef = React.useRef<HTMLDivElement>(null);
|
||||
const inputRef = React.useRef<HTMLInputElement>(null);
|
||||
|
||||
return (
|
||||
<Flex direction="column" gap={3}>
|
||||
<TextField ref={wrapperRef} inputRef={inputRef} value={value} readOnly />
|
||||
<Button
|
||||
onClick={() => {
|
||||
// eslint-disable-next-line no-console
|
||||
setValue(JSON.stringify(wrapperRef.current?.getBoundingClientRect()));
|
||||
}}
|
||||
>
|
||||
Measure TextField
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() => {
|
||||
inputRef.current?.focus();
|
||||
}}
|
||||
>
|
||||
Focus TextField
|
||||
</Button>
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
@@ -146,67 +146,68 @@ const TextFieldBase = styled("div", {
|
||||
},
|
||||
});
|
||||
|
||||
type TextFieldProps = Omit<
|
||||
type TextFieldProps = Pick<
|
||||
React.ComponentProps<typeof TextFieldBase>,
|
||||
"onChange" | "onFocus" | "onBlur" | "prefix"
|
||||
"size" | "variant" | "state" | "css"
|
||||
> &
|
||||
React.ComponentProps<"input"> & {
|
||||
Omit<React.ComponentProps<"input">, "prefix" | "children"> & {
|
||||
inputRef?: React.Ref<HTMLInputElement>;
|
||||
prefix?: React.ReactNode;
|
||||
suffix?: React.ReactNode;
|
||||
};
|
||||
|
||||
export const TextField = React.forwardRef<
|
||||
React.ElementRef<typeof TextFieldBase>,
|
||||
TextFieldProps
|
||||
>((props, forwardedRef) => {
|
||||
const {
|
||||
prefix,
|
||||
suffix,
|
||||
css,
|
||||
disabled,
|
||||
inputRef,
|
||||
size,
|
||||
state,
|
||||
variant,
|
||||
...textFieldProps
|
||||
} = props;
|
||||
return (
|
||||
<TextFieldBase
|
||||
aria-disabled={disabled}
|
||||
ref={forwardedRef}
|
||||
size={size}
|
||||
state={state}
|
||||
variant={variant}
|
||||
css={css}
|
||||
>
|
||||
{prefix && (
|
||||
<Flex
|
||||
css={{
|
||||
alignItems: "center",
|
||||
flexShrink: 0,
|
||||
order: 0,
|
||||
}}
|
||||
>
|
||||
{prefix}
|
||||
</Flex>
|
||||
)}
|
||||
export const TextField = React.forwardRef<HTMLDivElement, TextFieldProps>(
|
||||
(props, forwardedRef) => {
|
||||
const {
|
||||
prefix,
|
||||
suffix,
|
||||
css,
|
||||
disabled,
|
||||
inputRef,
|
||||
size,
|
||||
state,
|
||||
variant,
|
||||
...textFieldProps
|
||||
} = props;
|
||||
|
||||
<InputBase disabled={disabled} {...textFieldProps} ref={inputRef} />
|
||||
return (
|
||||
<TextFieldBase
|
||||
aria-disabled={disabled}
|
||||
ref={forwardedRef}
|
||||
size={size}
|
||||
state={state}
|
||||
variant={variant}
|
||||
css={css}
|
||||
>
|
||||
{/* We want input to be the first element in DOM so it receives the focus first */}
|
||||
<InputBase disabled={disabled} {...textFieldProps} ref={inputRef} />
|
||||
|
||||
{suffix && (
|
||||
<Flex
|
||||
css={{
|
||||
alignItems: "center",
|
||||
flexShrink: 0,
|
||||
order: 2,
|
||||
}}
|
||||
>
|
||||
{suffix}
|
||||
</Flex>
|
||||
)}
|
||||
</TextFieldBase>
|
||||
);
|
||||
});
|
||||
{prefix && (
|
||||
<Flex
|
||||
css={{
|
||||
alignItems: "center",
|
||||
flexShrink: 0,
|
||||
order: 0,
|
||||
}}
|
||||
>
|
||||
{prefix}
|
||||
</Flex>
|
||||
)}
|
||||
|
||||
{suffix && (
|
||||
<Flex
|
||||
css={{
|
||||
alignItems: "center",
|
||||
flexShrink: 0,
|
||||
order: 2,
|
||||
}}
|
||||
>
|
||||
{suffix}
|
||||
</Flex>
|
||||
)}
|
||||
</TextFieldBase>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
TextField.displayName = "TextField";
|
||||
Reference in new issue
Block a user