CSE provides a set of React hooks and components to consume the extensions registered for a given extension point. These hooks and components will receive an optional context, and validate the resulting attributes against the provided schema.
Take for example the following schema file:
schema.cse.graphql
1 2""" --- extensionPoint: example.extension-point --- """ type Schema { type: LinkExtension! label: string! url: string! } type ContextSchema { issueKey: String }
You can import the hooks and components directly from the schema file, and the loader will transform the file into a module that contains all the hooks and components already configured to use the schema provided.
Receives an optional context object, retrieves the extensions registered for the extension point declared in the schema, validates them and return an array of only valid extensions.
1 2import type { ExtensionDescriptor, Context } from '@atlassian/clientside-extensions-registry'; type useExtensions = (context: Context<{}>) => ExtensionDescriptor[];
1 2import React from "react"; import { useExtensions } from "./schema.cse.graphql"; const ExampleExtensionPoint = ({ context }) => { const extensions = useExtensions(context); return ( <> {extensions.map(({ attributes }) => ( <a href={attributes.url} key={attributes.key}>{attributes.label}</a> )} </> ) } export default ExampleExtensionPoint;
Use this hooks in order to indicate the users that the extensions are loading.
1 2import type { Context } from '@atlassian/clientside-extensions-registry'; type useExtensionsLoadingState = (context: Context<{}>) => boolean;
1 2import React from "react"; import { useExtensions, useExtensionsLoadingState } from "./schema.cse.graphql"; const ExampleExtensionPoint = ({ context }) => { const extensions = useExtensions(context); const loading = useExtensionsLoadingState(context); return ( <> {loading ? "loading..." : extensions.map(({ attributes }) => ( <a href={attributes.url} key={attributes.key}>{attributes.label}</a> )} </> ) } export default ExampleExtensionPoint;
Receives an optional context object, retrieves the extensions registered for the extension point and return a list of all the extensions that don't pass the validation against the schema.
This is particularly useful in case you need to support legacy WebItems
that are created only using XML definitions
inside atlassian-plugin.xml
.
1 2import type { ExtensionDescriptor, Context } from '@atlassian/clientside-extensions-registry'; type useExtensionsUnsupported = (context: Context<{}>) => ExtensionDescriptor[];
1 2import React from "react"; import { useExtensionsUnsupported } from "./schema.cse.graphql"; const ExampleExtensionPoint = () => { const extensions = useExtensionsUnsupported(null); return ( <> {extensions.map((extension) => ( <a href={extension.url} key={extension.key}>{extension.label}</a> )} </> ) } export default ExampleExtensionPoint;
You can use useExtensionsAll
in case you need all the results from useExtensions
, useExtensionsLoadingState
and useExtensionsLoadingState
and prefer to get the results with a single hook.
1 2import type { ExtensionDescriptor, Context } from '@atlassian/clientside-extensions-registry'; /** * @return [extensions, unsupported extensions, loading state] */ type useExtensionsAll = (context: Context<{}>) => [ExtensionDescriptor[], ExtensionDescriptor[], boolean];
1 2import React from "react"; import { useExtensionsAll } from "./schema.cse.graphql"; const ExampleExtensionPoint = ({context}) => { const [extensions, unsupportedExtensions, loading] = useExtensionsAll(context); return ( <> <h2>Extensions</h2> {loading ? "loading..." : extensions.map((extension) => ( {/*...render as needed*/} )} <h2>Unsupported Extensions</h2> {loading ? "loading..." : unsupportedExtensions.map((extension) => ( {/*...render as needed*/} )} </> ) } export default ExampleExtensionPoint;
You can use the ExtensionPoint
component in case you prefer it over hooks. Keep in mind that it is using the
hook internally, so you will need a compatible React version.
The component provides the same information as useExtensionsAll
.
1 2import type { ExtensionDescriptor, Context } from '@atlassian/clientside-extensions-registry'; type ExtensionPoint = (props: { context: Context<{}> }) => ( ExtensionDescriptor[], ExtensionDescriptor[], boolean, ) => JSX.Element;
1 2import React from "react"; import { ExtensionPoint } from "./schema.cse.graphql"; const ExampleExtensionPoint = ({context}) => { return ( <ExtensionPoint context={context}> {(extensions, unsupportedExtensions, loading) => ( <> <h2>Extensions</h2> {loading ? "loading..." : extensions.map((extension) => ( {/*...render as needed*/} )} <h2>Unsupported Extensions</h2> {loading ? "loading..." : unsupportedExtensions.map((extension) => ( {/*...render as needed*/} )} </> )} </ExtensionPoint> ) } export default ExampleExtensionPoint;
You can add this component to share with extension developers the schema of your extension points and highlight their locations in the current screen.
The information will only be available if the product has enabled their display in development mode.
1 2import React from "react"; import { useExtensions, useExtensionsLoadingState, ExtensionPointInfo } from "./schema.cse.graphql"; const ExampleExtensionPoint = ({ context }) => { const extensions = useExtensions(context); const loading = useExtensionsLoadingState(context); return ( <> <h2>Example extension point <ExtensionPointInfo /></h2> {loading ? "loading..." : extensions.map(({ attributes }) => ( <a href={attributes.url} key={attributes.key}>{attributes.label}</a> )} </> ) } export default ExampleExtensionPoint;
Rate this page: