Skip to content

Commit

Permalink
feat: expose form field context with id and skin
Browse files Browse the repository at this point in the history
  • Loading branch information
abelflopes committed Jun 23, 2024
1 parent 86f9287 commit 7143b75
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 54 deletions.
69 changes: 69 additions & 0 deletions packages/components/form-field/src/FormField.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import React, { useMemo } from "react";
import styles from "./styles/index.module.scss";
import classNames from "classnames";
import { Text } from "@react-ck/text";
import { FormFieldContext, FormFieldContextProps } from "./context";

export interface FormFieldProps
extends Pick<React.HTMLAttributes<HTMLDivElement>, "children" | "className"> {
/** Specifies the visual style of the form-field */
skin?: FormFieldContextProps["skin"];
/** The main label for the form field */
label?: React.ReactNode;
/** The description text for the form field */
description?: React.ReactNode;
/** The validation message text */
validationMessage?: React.ReactNode;
}

/**
* FormField is a component that provides a consistent layout and input peripherals.
*
* **WARNING**: This component is used as an internal utility - if you want to render an element such as an input, use its component directly
* @param props - {@link FormFieldProps}
* @returns a React element
*/

export const FormField = ({
skin = "default",
label,
description,
validationMessage,
children,
className,
...otherProps
}: Readonly<FormFieldProps>): React.ReactElement => {
const id = React.useId();

const context = useMemo<FormFieldContextProps>(
() => ({
skin,
id,
}),
[id, skin],
);

return (
<FormFieldContext.Provider value={context}>
<div {...otherProps} className={classNames(styles.root, styles[skin], className)}>
{label ? (
<Text variation="small" margin="none" as={<label htmlFor={id}>{label}</label>} />
) : null}

<div className={styles.content}>{children}</div>

{description ? (
<Text variation="small" margin="none">
{description}
</Text>
) : null}

{validationMessage ? (
<Text className={styles.validation_message} variation="small" margin="none">
{validationMessage}
</Text>
) : null}
</div>
</FormFieldContext.Provider>
);
};
13 changes: 13 additions & 0 deletions packages/components/form-field/src/context.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import React from "react";

export interface FormFieldContextProps {
skin: "default" | "negative" | "average" | "positive" | "ghost";
id: string;
}

export const FormFieldContext = React.createContext<FormFieldContextProps>({
id: "",
skin: "default",
});

export const useFormFieldContext = (): FormFieldContextProps => React.useContext(FormFieldContext);
3 changes: 3 additions & 0 deletions packages/components/form-field/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export * from "./FormField";

export { useFormFieldContext } from "./context";
54 changes: 0 additions & 54 deletions packages/components/form-field/src/index.tsx

This file was deleted.

4 changes: 4 additions & 0 deletions packages/components/form-field/src/styles/_variables.scss
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ $form-field-styles: (
border-color: get-color(neutral-light-2),
color: get-color(neutral-dark-4),
),
ghost: (
border-color: transparent,
color: get-color(neutral-dark-4),
),
negative: (
border-color: get-color(status-negative-dark),
color: get-color(status-negative-dark),
Expand Down

0 comments on commit 7143b75

Please sign in to comment.