@stratakit/bricks
Version:
Small, modular components for StrataKit
157 lines (156 loc) • 4.37 kB
JavaScript
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
}
)
}
);
});
DEV: FieldRoot.displayName = "Field.Root";
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
};