// packages/block-library/src/latest-posts/edit.js
import clsx from "clsx";
import {
  Placeholder,
  QueryControls,
  RadioControl,
  RangeControl,
  Spinner,
  ToggleControl,
  ToolbarGroup,
  __experimentalToggleGroupControl as ToggleGroupControl,
  __experimentalToggleGroupControlOptionIcon as ToggleGroupControlOptionIcon,
  __experimentalToolsPanel as ToolsPanel,
  __experimentalToolsPanelItem as ToolsPanelItem
} from "@wordpress/components";
import { __, _x, sprintf } from "@wordpress/i18n";
import { dateI18n, format, getSettings } from "@wordpress/date";
import {
  InspectorControls,
  BlockControls,
  __experimentalImageSizeControl as ImageSizeControl,
  useBlockProps,
  store as blockEditorStore
} from "@wordpress/block-editor";
import { useSelect, useDispatch } from "@wordpress/data";
import {
  pin,
  list,
  grid,
  alignNone,
  positionLeft,
  positionCenter,
  positionRight
} from "@wordpress/icons";
import { store as coreStore } from "@wordpress/core-data";
import { store as noticeStore } from "@wordpress/notices";
import { useInstanceId } from "@wordpress/compose";
import { createInterpolateElement } from "@wordpress/element";
import {
  MIN_EXCERPT_LENGTH,
  MAX_EXCERPT_LENGTH,
  MAX_POSTS_COLUMNS,
  DEFAULT_EXCERPT_LENGTH
} from "./constants.mjs";
import { useToolsPanelDropdownMenuProps } from "../utils/hooks.mjs";
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
var CATEGORIES_LIST_QUERY = {
  per_page: -1,
  _fields: "id,name",
  context: "view"
};
var USERS_LIST_QUERY = {
  per_page: -1,
  has_published_posts: ["post"],
  context: "view"
};
var imageAlignmentOptions = [
  {
    value: "none",
    icon: alignNone,
    label: __("None")
  },
  {
    value: "left",
    icon: positionLeft,
    label: __("Left")
  },
  {
    value: "center",
    icon: positionCenter,
    label: __("Center")
  },
  {
    value: "right",
    icon: positionRight,
    label: __("Right")
  }
];
function getFeaturedImageDetails(post, size) {
  const image = post._embedded?.["wp:featuredmedia"]?.["0"];
  return {
    url: image?.media_details?.sizes?.[size]?.source_url ?? image?.source_url,
    alt: image?.alt_text
  };
}
function getCurrentAuthor(post) {
  return post._embedded?.author?.[0];
}
function Controls({ attributes, setAttributes, postCount }) {
  const {
    postsToShow,
    order,
    orderBy,
    categories,
    selectedAuthor,
    displayFeaturedImage,
    displayPostContentRadio,
    displayPostContent,
    displayPostDate,
    displayAuthor,
    postLayout,
    columns,
    excerptLength,
    featuredImageAlign,
    featuredImageSizeSlug,
    featuredImageSizeWidth,
    featuredImageSizeHeight,
    addLinkToFeaturedImage
  } = attributes;
  const {
    imageSizes,
    defaultImageWidth,
    defaultImageHeight,
    categoriesList,
    authorList
  } = useSelect(
    (select) => {
      const { getEntityRecords, getUsers } = select(coreStore);
      const settings = select(blockEditorStore).getSettings();
      return {
        defaultImageWidth: settings.imageDimensions?.[featuredImageSizeSlug]?.width ?? 0,
        defaultImageHeight: settings.imageDimensions?.[featuredImageSizeSlug]?.height ?? 0,
        imageSizes: settings.imageSizes,
        categoriesList: getEntityRecords(
          "taxonomy",
          "category",
          CATEGORIES_LIST_QUERY
        ),
        authorList: getUsers(USERS_LIST_QUERY)
      };
    },
    [featuredImageSizeSlug]
  );
  const dropdownMenuProps = useToolsPanelDropdownMenuProps();
  const imageSizeOptions = imageSizes.filter(({ slug }) => slug !== "full").map(({ name, slug }) => ({
    value: slug,
    label: name
  }));
  const categorySuggestions = categoriesList?.reduce(
    (accumulator, category) => ({
      ...accumulator,
      [category.name]: category
    }),
    {}
  ) ?? {};
  const selectCategories = (tokens) => {
    const hasNoSuggestion = tokens.some(
      (token) => typeof token === "string" && !categorySuggestions[token]
    );
    if (hasNoSuggestion) {
      return;
    }
    const allCategories = tokens.map((token) => {
      return typeof token === "string" ? categorySuggestions[token] : token;
    });
    if (allCategories.includes(null)) {
      return false;
    }
    setAttributes({ categories: allCategories });
  };
  return /* @__PURE__ */ jsxs(Fragment, { children: [
    /* @__PURE__ */ jsxs(
      ToolsPanel,
      {
        label: __("Post content"),
        resetAll: () => setAttributes({
          displayPostContent: false,
          displayPostContentRadio: "excerpt",
          excerptLength: DEFAULT_EXCERPT_LENGTH
        }),
        dropdownMenuProps,
        children: [
          /* @__PURE__ */ jsx(
            ToolsPanelItem,
            {
              hasValue: () => !!displayPostContent,
              label: __("Display post content"),
              onDeselect: () => setAttributes({ displayPostContent: false }),
              isShownByDefault: true,
              children: /* @__PURE__ */ jsx(
                ToggleControl,
                {
                  label: __("Display post content"),
                  checked: displayPostContent,
                  onChange: (value) => setAttributes({ displayPostContent: value })
                }
              )
            }
          ),
          displayPostContent && /* @__PURE__ */ jsx(
            ToolsPanelItem,
            {
              hasValue: () => displayPostContentRadio !== "excerpt",
              label: __("Content length"),
              onDeselect: () => setAttributes({
                displayPostContentRadio: "excerpt"
              }),
              isShownByDefault: true,
              children: /* @__PURE__ */ jsx(
                RadioControl,
                {
                  label: __("Content length"),
                  selected: displayPostContentRadio,
                  options: [
                    { label: __("Excerpt"), value: "excerpt" },
                    {
                      label: __("Full post"),
                      value: "full_post"
                    }
                  ],
                  onChange: (value) => setAttributes({
                    displayPostContentRadio: value
                  })
                }
              )
            }
          ),
          displayPostContent && displayPostContentRadio === "excerpt" && /* @__PURE__ */ jsx(
            ToolsPanelItem,
            {
              hasValue: () => excerptLength !== DEFAULT_EXCERPT_LENGTH,
              label: __("Max number of words"),
              onDeselect: () => setAttributes({
                excerptLength: DEFAULT_EXCERPT_LENGTH
              }),
              isShownByDefault: true,
              children: /* @__PURE__ */ jsx(
                RangeControl,
                {
                  __next40pxDefaultSize: true,
                  label: __("Max number of words"),
                  value: excerptLength,
                  onChange: (value) => setAttributes({ excerptLength: value }),
                  min: MIN_EXCERPT_LENGTH,
                  max: MAX_EXCERPT_LENGTH
                }
              )
            }
          )
        ]
      }
    ),
    /* @__PURE__ */ jsxs(
      ToolsPanel,
      {
        label: __("Post meta"),
        resetAll: () => setAttributes({
          displayAuthor: false,
          displayPostDate: false
        }),
        dropdownMenuProps,
        children: [
          /* @__PURE__ */ jsx(
            ToolsPanelItem,
            {
              hasValue: () => !!displayAuthor,
              label: __("Display author name"),
              onDeselect: () => setAttributes({ displayAuthor: false }),
              isShownByDefault: true,
              children: /* @__PURE__ */ jsx(
                ToggleControl,
                {
                  label: __("Display author name"),
                  checked: displayAuthor,
                  onChange: (value) => setAttributes({ displayAuthor: value })
                }
              )
            }
          ),
          /* @__PURE__ */ jsx(
            ToolsPanelItem,
            {
              hasValue: () => !!displayPostDate,
              label: __("Display post date"),
              onDeselect: () => setAttributes({ displayPostDate: false }),
              isShownByDefault: true,
              children: /* @__PURE__ */ jsx(
                ToggleControl,
                {
                  label: __("Display post date"),
                  checked: displayPostDate,
                  onChange: (value) => setAttributes({ displayPostDate: value })
                }
              )
            }
          )
        ]
      }
    ),
    /* @__PURE__ */ jsxs(
      ToolsPanel,
      {
        label: __("Featured image"),
        resetAll: () => setAttributes({
          displayFeaturedImage: false,
          featuredImageAlign: void 0,
          featuredImageSizeSlug: "thumbnail",
          featuredImageSizeWidth: null,
          featuredImageSizeHeight: null,
          addLinkToFeaturedImage: false
        }),
        dropdownMenuProps,
        children: [
          /* @__PURE__ */ jsx(
            ToolsPanelItem,
            {
              hasValue: () => !!displayFeaturedImage,
              label: __("Display featured image"),
              onDeselect: () => setAttributes({ displayFeaturedImage: false }),
              isShownByDefault: true,
              children: /* @__PURE__ */ jsx(
                ToggleControl,
                {
                  label: __("Display featured image"),
                  checked: displayFeaturedImage,
                  onChange: (value) => setAttributes({ displayFeaturedImage: value })
                }
              )
            }
          ),
          displayFeaturedImage && /* @__PURE__ */ jsxs(Fragment, { children: [
            /* @__PURE__ */ jsx(
              ToolsPanelItem,
              {
                hasValue: () => featuredImageSizeSlug !== "thumbnail" || featuredImageSizeWidth !== null || featuredImageSizeHeight !== null,
                label: __("Image size"),
                onDeselect: () => setAttributes({
                  featuredImageSizeSlug: "thumbnail",
                  featuredImageSizeWidth: null,
                  featuredImageSizeHeight: null
                }),
                isShownByDefault: true,
                children: /* @__PURE__ */ jsx(
                  ImageSizeControl,
                  {
                    onChange: (value) => {
                      const newAttrs = {};
                      if (value.hasOwnProperty("width")) {
                        newAttrs.featuredImageSizeWidth = value.width;
                      }
                      if (value.hasOwnProperty("height")) {
                        newAttrs.featuredImageSizeHeight = value.height;
                      }
                      setAttributes(newAttrs);
                    },
                    slug: featuredImageSizeSlug,
                    width: featuredImageSizeWidth,
                    height: featuredImageSizeHeight,
                    imageWidth: defaultImageWidth,
                    imageHeight: defaultImageHeight,
                    imageSizeOptions,
                    imageSizeHelp: __(
                      "Select the size of the source image."
                    ),
                    onChangeImage: (value) => setAttributes({
                      featuredImageSizeSlug: value,
                      featuredImageSizeWidth: void 0,
                      featuredImageSizeHeight: void 0
                    })
                  }
                )
              }
            ),
            /* @__PURE__ */ jsx(
              ToolsPanelItem,
              {
                hasValue: () => !!featuredImageAlign,
                label: __("Image alignment"),
                onDeselect: () => setAttributes({
                  featuredImageAlign: void 0
                }),
                isShownByDefault: true,
                children: /* @__PURE__ */ jsx(
                  ToggleGroupControl,
                  {
                    className: "editor-latest-posts-image-alignment-control",
                    __next40pxDefaultSize: true,
                    label: __("Image alignment"),
                    value: featuredImageAlign || "none",
                    onChange: (value) => setAttributes({
                      featuredImageAlign: value !== "none" ? value : void 0
                    }),
                    children: imageAlignmentOptions.map(
                      ({ value, icon, label }) => {
                        return /* @__PURE__ */ jsx(
                          ToggleGroupControlOptionIcon,
                          {
                            value,
                            icon,
                            label
                          },
                          value
                        );
                      }
                    )
                  }
                )
              }
            ),
            /* @__PURE__ */ jsx(
              ToolsPanelItem,
              {
                hasValue: () => !!addLinkToFeaturedImage,
                label: __("Add link to featured image"),
                onDeselect: () => setAttributes({
                  addLinkToFeaturedImage: false
                }),
                isShownByDefault: true,
                children: /* @__PURE__ */ jsx(
                  ToggleControl,
                  {
                    label: __("Add link to featured image"),
                    checked: addLinkToFeaturedImage,
                    onChange: (value) => setAttributes({
                      addLinkToFeaturedImage: value
                    })
                  }
                )
              }
            )
          ] })
        ]
      }
    ),
    /* @__PURE__ */ jsxs(
      ToolsPanel,
      {
        label: __("Sorting and filtering"),
        resetAll: () => setAttributes({
          order: "desc",
          orderBy: "date",
          postsToShow: 5,
          categories: void 0,
          selectedAuthor: void 0,
          columns: 3
        }),
        dropdownMenuProps,
        children: [
          /* @__PURE__ */ jsx(
            ToolsPanelItem,
            {
              hasValue: () => order !== "desc" || orderBy !== "date" || postsToShow !== 5 || categories?.length > 0 || !!selectedAuthor,
              label: __("Sort and filter"),
              onDeselect: () => setAttributes({
                order: "desc",
                orderBy: "date",
                postsToShow: 5,
                categories: void 0,
                selectedAuthor: void 0
              }),
              isShownByDefault: true,
              children: /* @__PURE__ */ jsx(
                QueryControls,
                {
                  ...{ order, orderBy },
                  numberOfItems: postsToShow,
                  onOrderChange: (value) => setAttributes({ order: value }),
                  onOrderByChange: (value) => setAttributes({ orderBy: value }),
                  onNumberOfItemsChange: (value) => setAttributes({ postsToShow: value }),
                  categorySuggestions,
                  onCategoryChange: selectCategories,
                  selectedCategories: categories,
                  onAuthorChange: (value) => setAttributes({
                    selectedAuthor: "" !== value ? Number(value) : void 0
                  }),
                  authorList: authorList ?? [],
                  selectedAuthorId: selectedAuthor
                }
              )
            }
          ),
          postLayout === "grid" && /* @__PURE__ */ jsx(
            ToolsPanelItem,
            {
              hasValue: () => columns !== 3,
              label: __("Columns"),
              onDeselect: () => setAttributes({
                columns: 3
              }),
              isShownByDefault: true,
              children: /* @__PURE__ */ jsx(
                RangeControl,
                {
                  __next40pxDefaultSize: true,
                  label: __("Columns"),
                  value: columns,
                  onChange: (value) => setAttributes({ columns: value }),
                  min: 2,
                  max: !postCount ? MAX_POSTS_COLUMNS : Math.min(MAX_POSTS_COLUMNS, postCount),
                  required: true
                }
              )
            }
          )
        ]
      }
    )
  ] });
}
function LatestPostsEdit({ attributes, setAttributes }) {
  const instanceId = useInstanceId(LatestPostsEdit);
  const {
    postsToShow,
    order,
    orderBy,
    categories,
    selectedAuthor,
    displayFeaturedImage,
    displayPostContentRadio,
    displayPostContent,
    displayPostDate,
    displayAuthor,
    postLayout,
    columns,
    excerptLength,
    featuredImageAlign,
    featuredImageSizeSlug,
    featuredImageSizeWidth,
    featuredImageSizeHeight,
    addLinkToFeaturedImage
  } = attributes;
  const { latestPosts } = useSelect(
    (select) => {
      const { getEntityRecords } = select(coreStore);
      const catIds = categories && categories.length > 0 ? categories.map((cat) => cat.id) : [];
      const latestPostsQuery = Object.fromEntries(
        Object.entries({
          categories: catIds,
          author: selectedAuthor,
          order,
          orderby: orderBy,
          per_page: postsToShow,
          _embed: "author,wp:featuredmedia",
          ignore_sticky: true
        }).filter(([, value]) => typeof value !== "undefined")
      );
      return {
        latestPosts: getEntityRecords(
          "postType",
          "post",
          latestPostsQuery
        )
      };
    },
    [postsToShow, order, orderBy, categories, selectedAuthor]
  );
  const { createWarningNotice } = useDispatch(noticeStore);
  const showRedirectionPreventedNotice = (event) => {
    event.preventDefault();
    createWarningNotice(__("Links are disabled in the editor."), {
      id: `block-library/core/latest-posts/redirection-prevented/${instanceId}`,
      type: "snackbar"
    });
  };
  const hasPosts = !!latestPosts?.length;
  const inspectorControls = /* @__PURE__ */ jsx(InspectorControls, { children: /* @__PURE__ */ jsx(
    Controls,
    {
      attributes,
      setAttributes,
      postCount: latestPosts?.length ?? 0
    }
  ) });
  const blockProps = useBlockProps({
    className: clsx({
      "wp-block-latest-posts__list": true,
      "is-grid": postLayout === "grid",
      "has-dates": displayPostDate,
      "has-author": displayAuthor,
      [`columns-${columns}`]: postLayout === "grid"
    })
  });
  if (!hasPosts) {
    return /* @__PURE__ */ jsxs("div", { ...blockProps, children: [
      inspectorControls,
      /* @__PURE__ */ jsx(Placeholder, { icon: pin, label: __("Latest Posts"), children: !Array.isArray(latestPosts) ? /* @__PURE__ */ jsx(Spinner, {}) : __("No posts found.") })
    ] });
  }
  const displayPosts = latestPosts.length > postsToShow ? latestPosts.slice(0, postsToShow) : latestPosts;
  const layoutControls = [
    {
      icon: list,
      title: _x("List view", "Latest posts block display setting"),
      onClick: () => setAttributes({ postLayout: "list" }),
      isActive: postLayout === "list"
    },
    {
      icon: grid,
      title: _x("Grid view", "Latest posts block display setting"),
      onClick: () => setAttributes({ postLayout: "grid" }),
      isActive: postLayout === "grid"
    }
  ];
  const dateFormat = getSettings().formats.date;
  return /* @__PURE__ */ jsxs(Fragment, { children: [
    inspectorControls,
    /* @__PURE__ */ jsx(BlockControls, { children: /* @__PURE__ */ jsx(ToolbarGroup, { controls: layoutControls }) }),
    /* @__PURE__ */ jsx("ul", { ...blockProps, children: displayPosts.map((post) => {
      const titleTrimmed = post.title.rendered.trim();
      let excerpt = post.excerpt.rendered;
      const currentAuthor = getCurrentAuthor(post);
      const excerptElement = document.createElement("div");
      excerptElement.innerHTML = excerpt;
      excerpt = excerptElement.textContent || excerptElement.innerText || "";
      const { url: imageSourceUrl, alt: featuredImageAlt } = getFeaturedImageDetails(post, featuredImageSizeSlug);
      const imageClasses = clsx({
        "wp-block-latest-posts__featured-image": true,
        [`align${featuredImageAlign}`]: !!featuredImageAlign
      });
      const renderFeaturedImage = displayFeaturedImage && imageSourceUrl;
      const featuredImage = renderFeaturedImage && /* @__PURE__ */ jsx(
        "img",
        {
          src: imageSourceUrl,
          alt: featuredImageAlt,
          style: {
            maxWidth: featuredImageSizeWidth,
            maxHeight: featuredImageSizeHeight
          }
        }
      );
      const needsReadMore = excerptLength < excerpt.trim().split(" ").length && post.excerpt.raw === "";
      const postExcerpt = needsReadMore ? /* @__PURE__ */ jsxs(Fragment, { children: [
        excerpt.trim().split(" ", excerptLength).join(" "),
        createInterpolateElement(
          sprintf(
            /* translators: 1: Hidden accessibility text: Post title */
            __(
              "… <a>Read more<span>: %1$s</span></a>"
            ),
            titleTrimmed || __("(no title)")
          ),
          {
            a: (
              // eslint-disable-next-line jsx-a11y/anchor-has-content
              /* @__PURE__ */ jsx(
                "a",
                {
                  className: "wp-block-latest-posts__read-more",
                  href: post.link,
                  rel: "noopener",
                  onClick: showRedirectionPreventedNotice
                }
              )
            ),
            span: /* @__PURE__ */ jsx("span", { className: "screen-reader-text" })
          }
        )
      ] }) : excerpt;
      return /* @__PURE__ */ jsxs("li", { children: [
        renderFeaturedImage && /* @__PURE__ */ jsx("div", { className: imageClasses, children: addLinkToFeaturedImage ? /* @__PURE__ */ jsx(
          "a",
          {
            href: post.link,
            onClick: showRedirectionPreventedNotice,
            children: featuredImage
          }
        ) : featuredImage }),
        /* @__PURE__ */ jsx(
          "a",
          {
            className: "wp-block-latest-posts__post-title",
            href: post.link,
            dangerouslySetInnerHTML: !!titleTrimmed ? {
              __html: titleTrimmed
            } : void 0,
            onClick: showRedirectionPreventedNotice,
            children: !titleTrimmed ? __("(no title)") : null
          }
        ),
        displayAuthor && currentAuthor && /* @__PURE__ */ jsx("div", { className: "wp-block-latest-posts__post-author", children: sprintf(
          /* translators: byline. %s: author. */
          __("by %s"),
          currentAuthor.name
        ) }),
        displayPostDate && post.date_gmt && /* @__PURE__ */ jsx(
          "time",
          {
            dateTime: format("c", post.date_gmt),
            className: "wp-block-latest-posts__post-date",
            children: dateI18n(dateFormat, post.date_gmt)
          }
        ),
        displayPostContent && displayPostContentRadio === "excerpt" && /* @__PURE__ */ jsx("div", { className: "wp-block-latest-posts__post-excerpt", children: postExcerpt }),
        displayPostContent && displayPostContentRadio === "full_post" && /* @__PURE__ */ jsx(
          "div",
          {
            className: "wp-block-latest-posts__post-full-content",
            dangerouslySetInnerHTML: {
              __html: post.content.raw.trim()
            }
          }
        )
      ] }, post.id);
    }) })
  ] });
}
export {
  LatestPostsEdit as default
};
//# sourceMappingURL=edit.mjs.map
