UNPKG

@stratakit/bricks

Version:

Small, modular components for StrataKit

155 lines (154 loc) 4.31 kB
import { jsx } from "react/jsx-runtime"; import * as React from "react"; import { CollectionItem, useCollectionContext } from "@ariakit/react/collection"; import { Role } from "@ariakit/react/role"; import { useStoreState } from "@ariakit/react/store"; import { forwardRef } from "@stratakit/foundations/secret-internals"; import cx from "classnames"; import Description from "./Description.js"; import { FieldCollection, FieldControlTypeContext } from "./Field.internal.js"; import Label from "./Label.js"; const FieldRoot = forwardRef((props, forwardedRef) => { const { layout, ...rest } = props; return /* @__PURE__ */ jsx( FieldCollection, { render: /* @__PURE__ */ jsx( Role.div, { ...rest, className: cx("\u{1F95D}-field", props.className), "data-kiwi-layout": layout, ref: forwardedRef } ) } ); }); DEV: FieldRoot.displayName = "Field"; const FieldLabel = forwardRef( (props, forwardedRef) => { const store = useCollectionContext(); const renderedItems = useStoreState(store, "renderedItems"); const fieldId = React.useMemo( () => renderedItems?.find((item) => item.elementType === "control")?.id, [renderedItems] ); const getData = React.useCallback( (data) => ({ ...data, elementType: "label" }), [] ); return /* @__PURE__ */ jsx( CollectionItem, { getItem: getData, render: /* @__PURE__ */ jsx(Label, { ...props, htmlFor: fieldId }), ref: forwardedRef } ); } ); DEV: FieldLabel.displayName = "Field.Label"; const FieldDescription = forwardRef((props, forwardedRef) => { const generatedId = React.useId(); const { id = generatedId, ...rest } = props; const getData = React.useCallback( (data) => ({ ...data, elementType: "description" }), [] ); return /* @__PURE__ */ jsx( CollectionItem, { getItem: getData, id, render: /* @__PURE__ */ jsx(Description, { ...rest }), ref: forwardedRef } ); }); DEV: FieldDescription.displayName = "Field.Description"; const FieldControl = forwardRef( (props, forwardedRef) => { const [controlType, setControlType] = React.useState(); const store = useCollectionContext(); const generatedId = React.useId(); const { id = store ? generatedId : void 0, ...rest } = props; const renderedItems = useStoreState(store, "renderedItems"); const describedBy = React.useMemo(() => { const idRefList = renderedItems?.filter( (item) => item.elementType === "description" || item.elementType === "error" )?.map((item) => item.id).join(" "); return idRefList || void 0; }, [renderedItems]); const getData = React.useCallback( (data) => ({ ...data, elementType: "control", controlType }), [controlType] ); const invalid = React.useMemo( () => renderedItems?.some( (item) => item.elementType === "error" ), [renderedItems] ); return /* @__PURE__ */ jsx(FieldControlTypeContext.Provider, { value: setControlType, children: /* @__PURE__ */ jsx( CollectionItem, { id, getItem: getData, render: /* @__PURE__ */ jsx( Role, { ...rest, "aria-invalid": invalid ? "true" : void 0, "aria-describedby": describedBy } ), ref: forwardedRef } ) }); } ); DEV: FieldControl.displayName = "Field.Control"; const FieldErrorMessage = forwardRef( (props, forwardedRef) => { const generatedId = React.useId(); const { id = generatedId, ...rest } = props; const getData = React.useCallback( (data) => ({ ...data, elementType: "error" }), [] ); return /* @__PURE__ */ jsx( CollectionItem, { id, getItem: getData, render: /* @__PURE__ */ jsx(Description, { ...rest, tone: "critical" }), ref: forwardedRef } ); } ); DEV: FieldErrorMessage.displayName = "Field.ErrorMessage"; export { FieldControl as Control, FieldDescription as Description, FieldErrorMessage as ErrorMessage, FieldLabel as Label, FieldRoot as Root };