UNPKG

@stratakit/bricks

Version:

Small, modular components for StrataKit

123 lines (122 loc) 3.75 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 { useInit } from "./~utils.useInit.js"; import Description from "./Description.js"; import { FieldCollection, FieldControlTypeContext } from "./Field.internal.js"; import Label from "./Label.js"; const FieldRoot = forwardRef((props, forwardedRef) => { useInit(); const { layout, ...rest } = props; return /* @__PURE__ */ jsx(FieldCollection, { render: /* @__PURE__ */ jsx(Role.div, { ...rest, className: cx("\u{1F95D}Field", props.className), "data-_sk-layout": layout, ref: forwardedRef }) }); }); 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 }); }); 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 }); }); 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_0) => item_0.id).join(" "); return idRefList || void 0; }, [renderedItems]); const getData = React.useCallback((data) => ({ ...data, elementType: "control", controlType }), [controlType]); const invalid = React.useMemo(() => renderedItems?.some((item_1) => item_1.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 }) }); }); 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 }); }); export { FieldControl as Control, FieldDescription as Description, FieldErrorMessage as ErrorMessage, FieldLabel as Label, FieldRoot as Root };