feat(input): data management improved

This commit is contained in:
Junior Garcia 2023-04-15 16:03:49 -03:00
parent da5aa53a6c
commit 8ce412c508
4 changed files with 59 additions and 54 deletions

View File

@ -5,7 +5,7 @@ import {AriaTextFieldProps} from "@react-types/textfield";
import {useFocusRing} from "@react-aria/focus";
import {input} from "@nextui-org/theme";
import {useDOMRef} from "@nextui-org/dom-utils";
import {usePress} from "@react-aria/interactions";
import {useHover, usePress} from "@react-aria/interactions";
import {clsx, dataAttr} from "@nextui-org/shared-utils";
import {useControlledState} from "@react-stately/utils";
import {useMemo, Ref, RefObject} from "react";
@ -115,6 +115,8 @@ export function useInput(originalProps: UseInputProps) {
isTextInput: true,
});
const {isHovered, hoverProps} = useHover({isDisabled: !!originalProps?.isDisabled});
const {focusProps: clearFocusProps, isFocusVisible: isClearButtonFocusVisible} = useFocusRing();
const {pressProps: clearPressProps} = usePress({
@ -138,19 +140,9 @@ export function useInput(originalProps: UseInputProps) {
...variantProps,
isInvalid,
isClearable,
isFocusVisible,
isLabelPlaceholder: isLabelPlaceholder && !hasStartContent,
isClearButtonFocusVisible,
}),
[
...Object.values(variantProps),
isInvalid,
isClearable,
isClearButtonFocusVisible,
isLabelPlaceholder,
hasStartContent,
isFocusVisible,
],
[...Object.values(variantProps), isInvalid, isClearable, isLabelPlaceholder, hasStartContent],
);
const getBaseProps: PropGetter = (props = {}) => {
@ -159,6 +151,7 @@ export function useInput(originalProps: UseInputProps) {
"data-focus-visible": dataAttr(isFocusVisible),
"data-focused": dataAttr(isFocused),
"data-invalid": dataAttr(isInvalid),
...props,
};
};
@ -175,9 +168,6 @@ export function useInput(originalProps: UseInputProps) {
return {
ref: domRef,
className: slots.input({class: clsx(classNames?.input, !!inputValue ? "is-filled" : "")}),
"data-focus-visible": dataAttr(isFocusVisible),
"data-focused": dataAttr(isFocused),
"data-invalid": dataAttr(isInvalid),
...mergeProps(focusProps, inputProps, filterDOMProps(otherProps, {labelable: true}), props),
onChange: chain(inputProps.onChange, onChange),
};
@ -185,6 +175,7 @@ export function useInput(originalProps: UseInputProps) {
const getInputWrapperProps: PropGetter = (props = {}) => {
return {
"data-hover": dataAttr(isHovered),
className: slots.inputWrapper({
class: clsx(classNames?.inputWrapper, !!inputValue ? "is-filled" : ""),
}),
@ -193,7 +184,7 @@ export function useInput(originalProps: UseInputProps) {
domRef.current?.focus();
}
},
...props,
...mergeProps(props, hoverProps),
style: {
cursor: "text",
...props.style,
@ -231,6 +222,7 @@ export function useInput(originalProps: UseInputProps) {
role: "button",
tabIndex: 0,
className: slots.clearButton({class: classNames?.clearButton}),
"data-focus-visible": dataAttr(isClearButtonFocusVisible),
...mergeProps(clearPressProps, clearFocusProps),
};
};

View File

@ -16,7 +16,7 @@ import {modal} from "@nextui-org/theme";
import {HTMLNextUIProps, mapPropsVariants, PropGetter} from "@nextui-org/system";
import {useAriaButton} from "@nextui-org/use-aria-button";
import {useFocusRing} from "@react-aria/focus";
import {clsx, ReactRef} from "@nextui-org/shared-utils";
import {clsx, dataAttr, ReactRef} from "@nextui-org/shared-utils";
import {useOverlayTrigger} from "@react-aria/overlays";
import {createDOMRef} from "@nextui-org/dom-utils";
import {useOverlayTriggerState} from "@react-stately/overlays";
@ -148,9 +148,8 @@ export function useModal(originalProps: UseModalProps) {
() =>
modal({
...variantProps,
isCloseButtonFocusVisible,
}),
[...Object.values(variantProps), isCloseButtonFocusVisible],
[...Object.values(variantProps)],
);
const getDialogProps: PropGetter = (props = {}, ref = null) => ({
@ -158,6 +157,7 @@ export function useModal(originalProps: UseModalProps) {
...mergeProps(modalProps, otherProps, props),
className: slots.base({class: clsx(baseStyles, props.className)}),
id: dialogId,
"data-open": dataAttr(state.isOpen),
"aria-modal": true,
"aria-labelledby": headerMounted ? headerId : undefined,
"aria-describedby": bodyMounted ? bodyId : undefined,
@ -186,6 +186,7 @@ export function useModal(originalProps: UseModalProps) {
role: "button",
tabIndex: 0,
"aria-label": "Close",
"data-focus-visible": dataAttr(isCloseButtonFocusVisible),
className: slots.closeButton({class: classNames?.closeButton}),
...mergeProps(closeButtonProps, closeButtonFocusProps),
};

View File

@ -2,8 +2,6 @@ import type {VariantProps} from "tailwind-variants";
import {tv} from "tailwind-variants";
import {ringClasses} from "../utils";
/**
* Input wrapper **Tailwind Variants** component
*
@ -24,7 +22,7 @@ import {ringClasses} from "../utils";
*/
const input = tv({
slots: {
base: "flex flex-col gap-2",
base: "group flex flex-col gap-2",
label: "block text-sm font-medium text-neutral-600",
inputWrapper: "relative w-full inline-flex flex-row items-center shadow-sm px-3 gap-3",
innerWrapper: "inline-flex h-full items-center w-full gap-1.5 box-border",
@ -42,6 +40,13 @@ const input = tv({
"cursor-pointer",
"active:!opacity-70",
"rounded-full",
// focus ring
"data-[focus-visible]:outline-none",
"data-[focus-visible]:ring-2",
"data-[focus-visible]:!ring-primary",
"data-[focus-visible]:ring-offset-2",
"data-[focus-visible]:ring-offset-background",
"data-[focus-visible]:dark:ring-offset-background-dark",
],
description: "text-xs text-neutral-500",
errorMessage: "text-xs text-danger",
@ -49,21 +54,25 @@ const input = tv({
variants: {
variant: {
flat: {
inputWrapper: ["bg-neutral-100", "hover:bg-neutral-200", "focus-within:!bg-neutral-100"],
inputWrapper: [
"bg-neutral-100",
"data-[hover=true]:bg-neutral-200",
"focus-within:!bg-neutral-100",
],
},
faded: {
inputWrapper: [
"bg-neutral-100",
"border",
"border-neutral-200",
"hover:border-neutral-400",
"data-[hover=true]:border-neutral-400",
],
},
bordered: {
inputWrapper: [
"border-2",
"border-neutral-200",
"hover:border-neutral-400",
"data-[hover=true]:border-neutral-400",
"focus-within:!border-foreground",
],
},
@ -197,14 +206,6 @@ const input = tv({
base: "opacity-50 pointer-events-none",
},
},
isFocusVisible: {
true: {},
},
isClearButtonFocusVisible: {
true: {
clearButton: [...ringClasses],
},
},
isInvalid: {
true: {
label: "!text-danger",
@ -259,7 +260,7 @@ const input = tv({
class: {
inputWrapper: [
"bg-primary-50",
"hover:bg-primary-100",
"data-[hover=true]:bg-primary-100",
"text-primary",
"focus-within:!bg-primary-50",
"placeholder:text-primary",
@ -273,7 +274,7 @@ const input = tv({
class: {
inputWrapper: [
"bg-secondary-50",
"hover:bg-secondary-100",
"data-[hover=true]:bg-secondary-100",
"text-secondary",
"focus-within:!bg-secondary-50",
"placeholder:text-secondary",
@ -287,7 +288,7 @@ const input = tv({
class: {
inputWrapper: [
"bg-success-50",
"hover:bg-success-100",
"data-[hover=true]:bg-success-100",
"text-success",
"focus-within:!bg-success-50",
"placeholder:text-success",
@ -301,7 +302,7 @@ const input = tv({
class: {
inputWrapper: [
"bg-warning-50",
"hover:bg-warning-100",
"data-[hover=true]:bg-warning-100",
"text-warning",
"focus-within:!bg-warning-50",
"placeholder:text-warning",
@ -315,7 +316,7 @@ const input = tv({
class: {
inputWrapper: [
"bg-danger-50",
"hover:bg-danger-100",
"data-[hover=true]:bg-danger-100",
"text-danger",
"focus-within:!bg-danger-50",
"placeholder:text-danger",
@ -329,7 +330,7 @@ const input = tv({
color: "primary",
class: {
label: "text-primary",
inputWrapper: "hover:border-primary focus-within:border-primary",
inputWrapper: "data-[hover=true]:border-primary focus-within:border-primary",
},
},
{
@ -337,7 +338,7 @@ const input = tv({
color: "secondary",
class: {
label: "text-secondary",
inputWrapper: "hover:border-secondary focus-within:border-secondary",
inputWrapper: "data-[hover=true]:border-secondary focus-within:border-secondary",
},
},
{
@ -345,7 +346,7 @@ const input = tv({
color: "success",
class: {
label: "text-success",
inputWrapper: "hover:border-success focus-within:border-success",
inputWrapper: "data-[hover=true]:border-success focus-within:border-success",
},
},
{
@ -353,7 +354,7 @@ const input = tv({
color: "warning",
class: {
label: "text-warning",
inputWrapper: "hover:border-warning focus-within:border-warning",
inputWrapper: "data-[hover=true]:border-warning focus-within:border-warning",
},
},
{
@ -361,7 +362,7 @@ const input = tv({
color: "danger",
class: {
label: "text-danger",
inputWrapper: "hover:border-danger focus-within:border-danger",
inputWrapper: "data-[hover=true]:border-danger focus-within:border-danger",
},
},
// underlined & color
@ -480,12 +481,19 @@ const input = tv({
inputWrapper: "after:transition-width motion-reduce:after:transition-none",
},
},
// isFocusVisible & variant
// flat & faded
{
isFocusVisible: true,
variant: ["flat", "faded"],
class: {
inputWrapper: [...ringClasses],
inputWrapper: [
// focus ring
"group-data-[focus-visible]:outline-none",
"group-data-[focus-visible]:ring-2",
"group-data-[focus-visible]:!ring-primary",
"group-data-[focus-visible]:ring-offset-2",
"group-data-[focus-visible]:ring-offset-background",
"group-data-[focus-visible]:dark:ring-offset-background-dark",
],
},
},
// isInvalid & variant
@ -493,7 +501,11 @@ const input = tv({
isInvalid: true,
variant: "flat",
class: {
inputWrapper: ["bg-danger-50", "hover:bg-danger-100", "focus-within:!bg-danger-50"],
inputWrapper: [
"bg-danger-50",
"data-[hover=true]:bg-danger-100",
"focus-within:!bg-danger-50",
],
},
},
{

View File

@ -2,8 +2,6 @@ import type {VariantProps} from "tailwind-variants";
import {tv} from "tailwind-variants";
import {ringClasses} from "../utils";
/**
* Card **Tailwind Variants** component
*
@ -66,6 +64,13 @@ const modal = tv({
"rounded-full",
"hover:bg-neutral-100",
"active:bg-neutral-200",
// focus ring
"data-[focus-visible]:outline-none",
"data-[focus-visible]:ring-2",
"data-[focus-visible]:!ring-primary",
"data-[focus-visible]:ring-offset-2",
"data-[focus-visible]:ring-offset-background",
"data-[focus-visible]:dark:ring-offset-background-dark",
],
},
variants: {
@ -130,11 +135,6 @@ const modal = tv({
base: "my-16",
},
},
isCloseButtonFocusVisible: {
true: {
closeButton: [...ringClasses],
},
},
},
defaultVariants: {
size: "md",