alinea
Version:
Headless git-based CMS
141 lines (137 loc) • 5.13 kB
JavaScript
import {
dist_default
} from "../../chunks/chunk-A5O3N2GS.js";
import {
useQuery
} from "../../chunks/chunk-YWCPLD22.js";
import "../../chunks/chunk-NZLE2WMY.js";
// src/field/path/PathField.view.tsx
import { Entry } from "alinea/core/Entry";
import { pathSuffix } from "alinea/core/util/EntryFilenames";
import { isSeparator, slugify } from "alinea/core/util/Slugs";
import { useField } from "alinea/dashboard/editor/UseField";
import { useEntryEditor } from "alinea/dashboard/hook/UseEntryEditor";
import { useGraph } from "alinea/dashboard/hook/UseGraph";
import { InputLabel } from "alinea/dashboard/view/InputLabel";
import { px } from "alinea/ui";
import { IcRoundLink } from "alinea/ui/icons/IcRoundLink";
import { useRef, useState } from "react";
// src/field/path/PathField.module.scss
var PathField_module_default = {
"root-input": "alinea-PathField-input",
"rootInput": "alinea-PathField-input",
"root-input-container": "alinea-PathField-input-container",
"rootInputContainer": "alinea-PathField-input-container",
"root-suffix": "alinea-PathField-suffix",
"rootSuffix": "alinea-PathField-suffix",
"root-hidden": "alinea-PathField-hidden",
"rootHidden": "alinea-PathField-hidden"
};
// src/field/path/PathField.view.tsx
import { jsx, jsxs } from "react/jsx-runtime";
var styles = dist_default(PathField_module_default);
var INPUT_OFFSET_LEFT = 16;
var INPUT_OFFSET_RIGHT = 26;
function PathInput({ field }) {
const { value: fieldValue, mutator, options, error } = useField(field);
const graph = useGraph();
const editor = useEntryEditor();
const { from = "title" } = options;
const [focus, setFocus] = useState(false);
const hiddenRef = useRef(null);
const inputRef = useRef(null);
const suffixRef = useRef(null);
const { value: source = "" } = useField(from);
const value = fieldValue ?? slugify(source);
const [endsWithSeparator, setEndsWithSeparator] = useState(false);
const inputValue = (value ?? "") + (endsWithSeparator ? "-" : "");
const empty = value === "";
async function getConflictingPaths() {
if (!editor) return [];
return graph.find({
select: Entry.path,
root: editor.activeVersion.root,
workspace: editor.activeVersion.workspace,
locale: editor.activeVersion.locale,
parentId: editor.activeVersion.parentId ?? null,
id: { isNot: editor.entryId },
path: { or: { is: inputValue, startsWith: `${inputValue}-` } },
status: "preferPublished"
});
}
const { data: conflictingPaths } = useQuery(
["path", editor?.entryId, editor?.activeVersion.parentId, inputValue],
getConflictingPaths
);
async function applySuffix() {
const pathData = await getConflictingPaths();
const suffix = pathSuffix(inputValue, pathData);
if (!suffix) return;
mutator(slugify(`${inputValue}-${suffix}`));
}
const currentSuffix = conflictingPaths && pathSuffix(inputValue, conflictingPaths);
function getSuffixPosition() {
if (!currentSuffix) return 0;
if (!hiddenRef.current || !inputRef.current || !suffixRef.current) return 0;
if (hiddenRef.current.clientWidth + INPUT_OFFSET_LEFT + getRightInputPadding() >= inputRef.current.clientWidth)
return inputRef.current.clientWidth - getRightInputPadding();
return hiddenRef.current.clientWidth + INPUT_OFFSET_LEFT;
}
function getRightInputPadding() {
if (!currentSuffix) return INPUT_OFFSET_RIGHT;
if (!suffixRef.current) return INPUT_OFFSET_RIGHT;
if (suffixRef.current.clientWidth + 10 > INPUT_OFFSET_RIGHT)
return suffixRef.current.clientWidth + 10;
return INPUT_OFFSET_RIGHT;
}
return /* @__PURE__ */ jsxs(
InputLabel,
{
asLabel: true,
...options,
error,
focused: focus,
icon: IcRoundLink,
empty,
children: [
/* @__PURE__ */ jsxs("div", { className: styles.root.input.container(), children: [
/* @__PURE__ */ jsx(
"input",
{
ref: inputRef,
className: styles.root.input(),
type: "text",
value: inputValue,
onChange: (e) => {
const value2 = e.currentTarget.value;
setEndsWithSeparator(isSeparator(value2.charAt(value2.length - 1)));
mutator(slugify(value2));
},
onFocus: () => setFocus(true),
onBlur: () => {
setFocus(false);
applySuffix();
setEndsWithSeparator(false);
},
style: { paddingRight: px(getRightInputPadding()) },
readOnly: options.readOnly
}
),
/* @__PURE__ */ jsx(
"div",
{
ref: suffixRef,
className: styles.root.suffix(),
style: { left: px(getSuffixPosition()) },
children: currentSuffix ? `-${currentSuffix}` : null
}
)
] }),
/* @__PURE__ */ jsx("span", { ref: hiddenRef, className: styles.root.hidden(), children: inputValue })
]
}
);
}
export {
PathInput
};