@stratakit/bricks
Version:
Small, modular components for StrataKit
123 lines (122 loc) • 3.75 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
})
});
});
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
};