@airplane/views
Version:
A React library for building Airplane views. Views components are optimized in style and functionality to produce internal apps that are easy to build and maintain.
170 lines (169 loc) • 4.92 kB
JavaScript
import { jsx, jsxs } from "react/jsx-runtime";
import { createStyles, Radio } from "@mantine/core";
import { useState } from "react";
import { ComponentErrorBoundary } from "../errorBoundary/ComponentErrorBoundary.js";
import { useSetLatestRunInTaskQuery } from "../errorBoundary/LatestRunDetails.js";
import { useCommonLayoutStyle } from "../layout/useCommonLayoutStyle.js";
import { Text } from "../text/Text.js";
import { displayTaskBackedError } from "../../errors/displayTaskBackedError.js";
import { useRegisterFormInput } from "../../state/components/form/useRegisterFormInput.js";
import { useInput } from "../../state/components/input/useInput.js";
import { useRadioGroupState } from "../../state/components/radio-group/useRadioGroupState.js";
import { useComponentId } from "../../state/components/useId.js";
import { useTaskQuery } from "../../state/tasks/useTaskQuery.js";
const useStyles = createStyles((theme) => {
const focusRingRGB = theme.fn.variant({
variant: "filled",
color: "primary"
}).background;
return {
radio: {
"&:focus": {
...theme.fn.focusStyles()["&:focus"],
outline: `2px solid ${focusRingRGB}`
},
"&:focus:not(:focus-visible)": {
...theme.fn.focusStyles()["&:focus"],
outline: `2px solid ${focusRingRGB}`
}
},
label: {
color: theme.colors.gray[7]
}
};
});
const RadioGroup = (props) => {
const [latestRun, setLatestRun] = useState();
if (doesUseTask(props)) {
return /* @__PURE__ */ jsx(ComponentErrorBoundary, { componentName: RadioGroup.displayName, latestRun, children: /* @__PURE__ */ jsx(RadioGroupWithTask, { ...props, setLatestRun }) });
} else {
return /* @__PURE__ */ jsxs(ComponentErrorBoundary, { componentName: RadioGroup.displayName, children: [
/* @__PURE__ */ jsx(ConnectedRadioGroup, { ...props }),
" "
] });
}
};
RadioGroup.displayName = "RadioGroup";
const RadioGroupWithTask = ({
task,
outputTransform,
setLatestRun,
...restProps
}) => {
const fullQuery = useSetLatestRunInTaskQuery(task, setLatestRun);
const {
error,
loading,
output,
runID
} = useTaskQuery(fullQuery);
const data = output ? outputToData(output, outputTransform) : [];
if (error) {
return displayTaskBackedError({
error,
taskSlug: fullQuery.slug,
runID,
componentName: "RadioGroup"
});
} else {
return /* @__PURE__ */ jsx(ConnectedRadioGroup, { ...restProps, loading, data });
}
};
const ConnectedRadioGroup = (props) => {
const id = useComponentId(props.id);
const {
state,
dispatch
} = useRadioGroupState(id, {
initialState: {
disabled: props.disabled ?? props.defaultDisabled,
value: props.value ?? props.defaultValue
}
});
const {
inputProps
} = useInput(props, state, dispatch, (v) => v);
useRegisterFormInput(id, "radio-group");
const {
validate: _,
onChange: __,
defaultDisabled: ___,
defaultValue: ____,
...restProps
} = props;
return /* @__PURE__ */ jsx(RadioGroupComponent, { ...inputProps, ...restProps });
};
const RadioGroupComponent = ({
loading,
data,
disabled,
className,
style,
width,
height,
grow,
...restProps
}) => {
const {
classes
} = useStyles();
const {
classes: layoutClasses,
cx
} = useCommonLayoutStyle({
width,
height,
grow
});
if (loading) {
return /* @__PURE__ */ jsx(Text, { disableMarkdown: true, children: "Loading..." });
}
const radioGroupData = data.map((datum) => {
if (typeof datum === "string") {
return {
value: datum
};
}
return datum;
});
return /* @__PURE__ */ jsx(Radio.Group, { className: cx(layoutClasses.style, className), style, ...restProps, children: radioGroupData.map((item, idx) => {
return /* @__PURE__ */ jsx(Radio, { classNames: classes, value: item.value, label: item.label ?? item.value, disabled: disabled || item.disabled }, idx);
}) });
};
function outputToData(output, dataTransform) {
if (!output) {
return [];
}
if (dataTransform) {
return dataTransform(output);
}
if (Array.isArray(output)) {
return output;
}
const unwrappedOutput = unwrapOutput(output);
if (unwrappedOutput) {
return unwrappedOutput;
}
return [];
}
function doesUseTask(props) {
return Boolean(props.task);
}
const unwrapOutput = (data) => {
if (data && !Array.isArray(data) && typeof data === "object") {
const keys = Object.keys(data);
if (keys.length === 1) {
const value = data[keys[0]];
if (Array.isArray(value) && value.every((item) => typeof item === "string" || isRadio(item))) {
return value;
}
}
}
return null;
};
const isRadio = (item) => !Array.isArray(item) && typeof item === "object" && typeof item.value === "string";
export {
RadioGroup,
useStyles
};
//# sourceMappingURL=RadioGroup.js.map