Skip to content

Commit

Permalink
Merge branch 'develop' into trunk
Browse files Browse the repository at this point in the history
  • Loading branch information
fabiankaegy committed Mar 5, 2024
2 parents a386c09 + 78c2ca4 commit c20302c
Show file tree
Hide file tree
Showing 8 changed files with 140 additions and 54 deletions.
Original file line number Diff line number Diff line change
@@ -1,17 +1,54 @@
import PropTypes from 'prop-types';
import { useCopyToClipboard } from '@wordpress/compose';
import { useState, useEffect } from '@wordpress/element';
import { Button } from '@wordpress/components';
import { __ } from '@wordpress/i18n';

export const ClipboardButton = (props) => {
const { text, disabled, onSuccess, labels } = props;
interface ClipboardButtonProps {
/**
* The text to copy to the clipboard.
*/
text: string;

/**
* Boolean to disable the button.
*/
disabled: boolean;

/**
* Function to run when the text is successfully copied.
*/
onSuccess: Function;

/**
* Labels for the button.
*/
labels: ButtonLabels;
}

interface ButtonLabels {
/**
* Label for the button when it's ready to copy.
*/
copy?: string;

/**
* Label for the button when the text has been copied.
*/
copied?: string;
}

export const ClipboardButton: React.FC<ClipboardButtonProps> = ({
text,
disabled,
onSuccess,
labels,
}) => {
const [hasCopied, setHasCopied] = useState(false);
const copy = labels.copy ? labels.copy : __('Copy');
const copied = labels.copied ? labels.copied : __('Copied');

useEffect(() => {
let timerId;
let timerId: undefined | number;

if (hasCopied) {
timerId = setTimeout(() => {
Expand Down Expand Up @@ -54,10 +91,3 @@ ClipboardButton.defaultProps = {
onSuccess: () => {},
labels: {},
};

ClipboardButton.propTypes = {
text: PropTypes.string,
disabled: PropTypes.bool,
onSuccess: PropTypes.func,
labels: PropTypes.object,
};
5 changes: 5 additions & 0 deletions components/content-picker/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ const ContentPickerWrapper = styled.div`
* @param {number} props.perPage number of items to show per page
* @param {boolean} props.fetchInitialResults whether or not to fetch initial results on mount
* @param {Function} props.renderItemType callback to render the item type
* @param {Function} props.renderItem react component to render the search result item
* @returns {*} React JSX
*/
const ContentPicker = ({
Expand All @@ -74,6 +75,7 @@ const ContentPicker = ({
perPage,
fetchInitialResults,
renderItemType,
renderItem,
}) => {
const currentPostId = select('core/editor')?.getCurrentPostId();

Expand Down Expand Up @@ -141,6 +143,7 @@ const ContentPicker = ({
perPage={perPage}
fetchInitialResults={fetchInitialResults}
renderItemType={renderItemType}
renderItem={renderItem}
/>
) : (
label && (
Expand Down Expand Up @@ -205,6 +208,7 @@ ContentPicker.defaultProps = {
singlePickedLabel: __('You have selected the following item:', '10up-block-components'),
fetchInitialResults: false,
renderItemType: defaultRenderItemType,
renderItem: undefined,
};

ContentPicker.propTypes = {
Expand All @@ -225,6 +229,7 @@ ContentPicker.propTypes = {
perPage: PropTypes.number,
fetchInitialResults: PropTypes.bool,
renderItemType: PropTypes.func,
renderItem: PropTypes.func,
};

export { ContentPicker };
53 changes: 41 additions & 12 deletions components/content-search/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Spinner, NavigableMenu, Button, SearchControl } from '@wordpress/components';
import apiFetch from '@wordpress/api-fetch';
import { useState, useRef, useEffect, useCallback } from '@wordpress/element';
import { addQueryArgs } from '@wordpress/url';
import PropTypes from 'prop-types';
import { __ } from '@wordpress/i18n';
import styled from '@emotion/styled';
Expand Down Expand Up @@ -50,6 +51,7 @@ const ContentSearch = ({
queryFilter,
excludeItems,
renderItemType,
renderItem: RenderItemComponent,
fetchInitialResults,
}) => {
const [searchString, setSearchString] = useState('');
Expand Down Expand Up @@ -111,12 +113,20 @@ const ContentSearch = ({

switch (mode) {
case 'user':
searchQuery = `wp/v2/users/?search=${keyword}`;
searchQuery = addQueryArgs('wp/v2/users', {
search: keyword,
});
break;
default:
searchQuery = `wp/v2/search/?search=${keyword}&subtype=${contentTypes.join(
',',
)}&type=${mode}&_embed&per_page=${perPage}&page=${page}`;
searchQuery = addQueryArgs('wp/v2/search', {
search: keyword,
subtype: contentTypes.join(','),
type: mode,
_embed: true,
per_page: perPage,
page,
});

break;
}

Expand Down Expand Up @@ -385,6 +395,12 @@ const ContentSearch = ({
return null;
}

const isSelected = selectedItem === index + 1;

const selectItem = () => {
handleItemSelection(item);
};

return (
<li
key={item.id}
Expand All @@ -393,14 +409,25 @@ const ContentSearch = ({
marginBottom: '0',
}}
>
<SearchItem
onClick={() => handleItemSelection(item)}
searchTerm={searchString}
suggestion={item}
contentTypes={contentTypes}
isSelected={selectedItem === index + 1}
renderType={renderItemType}
/>
{RenderItemComponent ? (
<RenderItemComponent
item={item}
onSelect={selectItem}
searchTerm={searchString}
contentTypes={contentTypes}
isSelected={isSelected}
renderType={renderItemType}
/>
) : (
<SearchItem
onClick={selectItem}
searchTerm={searchString}
suggestion={item}
contentTypes={contentTypes}
isSelected={isSelected}
renderType={renderItemType}
/>
)}
</li>
);
})}
Expand Down Expand Up @@ -435,6 +462,7 @@ ContentSearch.defaultProps = {
console.log('Select!'); // eslint-disable-line no-console
},
renderItemType: defaultRenderItemType,
renderItem: undefined,
fetchInitialResults: false,
};

Expand All @@ -449,6 +477,7 @@ ContentSearch.propTypes = {
hideLabelFromVision: PropTypes.bool,
perPage: PropTypes.number,
renderItemType: PropTypes.func,
renderItem: PropTypes.func,
fetchInitialResults: PropTypes.bool,
};

Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import type { SVGProps } from 'react';

/**
* Renders an SVG drag handle.
*
* @param {object} props The prop object.
* @returns {*} React JSX
*/
export const DragHandle = (props) => (

export const DragHandle: React.FC<SVGProps<SVGSVGElement>> = (props) => (
<svg
style={{ marginRight: '10px', cursor: 'grab', flexShrink: 0 }}
width="18"
Expand Down
24 changes: 17 additions & 7 deletions components/is-admin/index.js → components/is-admin/index.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,29 @@
import { useSelect } from '@wordpress/data';

interface IsAdminProps {
/**
* Fallback component.
*/
fallback: React.ReactNode | null;

/**
* Child component.
*/
children: React.ReactNode;
}

/**
* IsAdmin
*
* A wrapper component that checks wether the current user has admin capabilities
* and only returns the child components if the user is an admin. You can pass a
* fallback component via the fallback prop.
*
* @param {object} props react props
* @param {*} props.fallback fallback component
* @param {*} props.children child components
* @returns {*}
*/
export const IsAdmin = ({ fallback = null, children }) => {
const hasAdminPermissions = useSelect(
export const IsAdmin: React.FC<IsAdminProps> = ({
fallback = null,
children,
}) => {
const hasAdminPermissions: boolean = useSelect(
(select) => select('core').canUser('read', 'users?roles=1'),
[],
);
Expand Down
20 changes: 0 additions & 20 deletions hooks/use-is-plugin-active/index.js

This file was deleted.

29 changes: 29 additions & 0 deletions hooks/use-is-plugin-active/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { useSelect } from '@wordpress/data';
import { store as coreStore } from '@wordpress/core-data';
import type { Plugin } from '@wordpress/core-data';

const ACTIVE_STATUSES = ['active', 'network-active'] as const;

/**
* Custom hook to check if a plugin is active and whether its resolution has finished.
*
* @param pluginName The name of the plugin to check.
* @returns A tuple containing two boolean values: the first indicating whether the plugin is active,
* and the second indicating whether the resolution for the plugin has finished.
*/
export const useIsPluginActive = (pluginName: string) => {
return useSelect(
(select) => {
const storeSelectors = select(coreStore);
const plugin: Plugin = (storeSelectors as any).getPlugin(pluginName);
const hasResolvedPlugins: boolean = (storeSelectors as any).hasFinishedResolution('getPlugin', [
pluginName,
]);

const isPluginActive: boolean = ACTIVE_STATUSES.includes(plugin?.status);

return [isPluginActive, hasResolvedPlugins];
},
[pluginName],
) as [boolean, boolean];
};
6 changes: 3 additions & 3 deletions hooks/use-script/index.js → hooks/use-script/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ import { useEffect, useRef, useState } from '@wordpress/element';
* @param {string} scriptSource Source URL of the script to be loaded.
* @returns {HTMLScriptElement} The script tag.
*/
export const useScript = (scriptSource) => {
const scriptElement = useRef();
const [scriptLoaded, setScriptLoaded] = useState(false);
export const useScript = (scriptSource: string): { hasLoaded: boolean, scriptElement: HTMLScriptElement | null } => {
const scriptElement = useRef<HTMLScriptElement | null>(null);
const [scriptLoaded, setScriptLoaded] = useState<boolean>(false);

useEffect(() => {
if (window) {
Expand Down

0 comments on commit c20302c

Please sign in to comment.