diff --git a/src/plugin-slots/README.md b/src/plugin-slots/README.md index 21e158f68..c693e3684 100644 --- a/src/plugin-slots/README.md +++ b/src/plugin-slots/README.md @@ -24,3 +24,6 @@ * [`org.openedx.frontend.layout.header_mobile_main_menu.v1`](./MobileMainMenuSlot/) * [`org.openedx.frontend.layout.header_mobile_user_menu.v1`](./MobileUserMenuSlot/) * [`org.openedx.frontend.layout.header_mobile_user_menu_trigger.v1`](./MobileUserMenuToggleSlot/) + +### Studio Header +* [`org.openedx.frontend.layout.studio_header_search_button_slot.v1`](./StudioHeaderSearchButtonSlot/) diff --git a/src/plugin-slots/StudioHeaderSearchButtonSlot/README.md b/src/plugin-slots/StudioHeaderSearchButtonSlot/README.md new file mode 100644 index 000000000..9b81b3c31 --- /dev/null +++ b/src/plugin-slots/StudioHeaderSearchButtonSlot/README.md @@ -0,0 +1,89 @@ +# Studio Header Search Button Slot + +### Slot ID: `org.openedx.frontend.layout.studio_header_search_button_slot.v1` + +## Description + +This slot is used to replace/modify/hide the search button in the studio header. + +## Examples + +### Replace search with custom component + +The following `env.config.jsx` will replace the search button entirely (in this case with a custom emoji icon): + +![Search button being replaced](./images/studio_header_search_button_replace.png) + +```jsx +import { + DIRECT_PLUGIN, + PLUGIN_OPERATIONS, +} from "@openedx/frontend-plugin-framework"; + +const config = { + pluginSlots: { + "org.openedx.frontend.layout.studio_header_search_button_slot.v1": { + keepDefault: false, + plugins: [ + { + op: PLUGIN_OPERATIONS.Insert, + widget: { + id: "custom_notification_tray", + type: DIRECT_PLUGIN, + RenderWidget: () => 🔔, + }, + }, + ], + }, + }, +}; + +export default config; +``` + +### Add custom component before and after search button + +The following `env.config.jsx` will insert emoji after and before the search button + +![Add custom component before and after search button](./images/studio_header_search_button_before_after.png) + +```jsx +import { + DIRECT_PLUGIN, + PLUGIN_OPERATIONS, +} from "@openedx/frontend-plugin-framework"; + +const config = { + pluginSlots: { + "org.openedx.frontend.layout.studio_header_search_button_slot.v1": { + keepDefault: true, + plugins: [ + { + op: PLUGIN_OPERATIONS.Insert, + widget: { + priority: 10, + id: 'custom_notification_tray_before', + type: DIRECT_PLUGIN, + RenderWidget: () => 🔔, + }, + }, + { + op: PLUGIN_OPERATIONS.Insert, + widget: { + priority: 90, + id: 'custom_notification_tray_after', + type: DIRECT_PLUGIN, + RenderWidget: () => 🔕, + }, + }, + ], + }, +}; + +export default config; +``` + +## API + +- **Slot ID:** `org.openedx.frontend.layout.studio_header_search_button_slot.v1` +- **Component:** Uses the [PluginSlot](https://github.com/openedx/frontend-plugin-framework#pluginslot) from the Open edX Frontend Plugin Framework for plugin injection. diff --git a/src/plugin-slots/StudioHeaderSearchButtonSlot/images/studio_header_search_button_before_after.png b/src/plugin-slots/StudioHeaderSearchButtonSlot/images/studio_header_search_button_before_after.png new file mode 100644 index 000000000..29735c79b Binary files /dev/null and b/src/plugin-slots/StudioHeaderSearchButtonSlot/images/studio_header_search_button_before_after.png differ diff --git a/src/plugin-slots/StudioHeaderSearchButtonSlot/images/studio_header_search_button_replace.png b/src/plugin-slots/StudioHeaderSearchButtonSlot/images/studio_header_search_button_replace.png new file mode 100644 index 000000000..464fbcba5 Binary files /dev/null and b/src/plugin-slots/StudioHeaderSearchButtonSlot/images/studio_header_search_button_replace.png differ diff --git a/src/plugin-slots/StudioHeaderSearchButtonSlot/index.jsx b/src/plugin-slots/StudioHeaderSearchButtonSlot/index.jsx new file mode 100644 index 000000000..4152c55c9 --- /dev/null +++ b/src/plugin-slots/StudioHeaderSearchButtonSlot/index.jsx @@ -0,0 +1,34 @@ +import React from 'react'; +import { PluginSlot } from '@openedx/frontend-plugin-framework'; +import { Nav, IconButton, Icon } from '@openedx/paragon'; +import { Search } from '@openedx/paragon/icons'; +import PropTypes from 'prop-types'; +import { useIntl } from '@edx/frontend-platform/i18n'; +import messages from '../../studio-header/messages'; + +const StudioHeaderSearchButtonSlot = ({ searchButtonAction }) => { + const intl = useIntl(); + return ( + + {searchButtonAction && ( + + )} + + ); +}; + +StudioHeaderSearchButtonSlot.propTypes = { + searchButtonAction: PropTypes.func, +}; + +export default StudioHeaderSearchButtonSlot; diff --git a/src/studio-header/HeaderBody.tsx b/src/studio-header/HeaderBody.tsx index d27615971..4037240ac 100644 --- a/src/studio-header/HeaderBody.tsx +++ b/src/studio-header/HeaderBody.tsx @@ -1,22 +1,19 @@ import React, { type ReactNode, type ComponentProps } from 'react'; -import { useIntl } from '@edx/frontend-platform/i18n'; import classNames from 'classnames'; import { ActionRow, Button, Container, - Icon, - IconButton, Nav, Row, } from '@openedx/paragon'; -import { Close, MenuIcon, Search } from '@openedx/paragon/icons'; +import { Close, MenuIcon } from '@openedx/paragon/icons'; import CourseLockUp from './CourseLockUp'; import UserMenu from './UserMenu'; import BrandNav from './BrandNav'; import NavDropdownMenu from './NavDropdownMenu'; -import messages from './messages'; +import StudioHeaderSearchButtonSlot from '../plugin-slots/StudioHeaderSearchButtonSlot'; export interface HeaderBodyProps { studioBaseUrl: string; @@ -65,7 +62,6 @@ const HeaderBody = ({ searchButtonAction, containerProps = {}, }: HeaderBodyProps) => { - const intl = useIntl(); const renderBrandNav = ( )} - {searchButtonAction && ( - - )} +