This is a quick reference and showcase of standard UI components using the Forge UI. For complete info, see Forge UI components developer documentation.
- It's common to think your Forge apps UI in terms of standard UI components(example: Carousel, Pagination, ...), but FORGE UI has very few components. It's an attempt to build standard UI components using FORGE UI
- DON'T REINVENT THE WHEEL, use already existing standard UI pattern in your app.
- LESS IS MORE, to show Forge UI components are sufficient to create most of the standard UI components.
- Ease and speed over flexibility. Minimise options to stay lighting fast.
- Provide direction. Components are moleculer and composed and avoid minutiae
- Heading
- Link
- List
- Code
- Button
- ButtonSet
- Layout
- Image
- Icons
- Carousel
- Video
- Collapse
- Progress
- Pagination
- Chart
- Alert
- Modal
- Navbar
It's tempting to think about heading with HTML header tags (h1 to h6). But, we need to understand Forge apps are embedded in the Atlassian products (JIRA, Confluence page ..,). Consider using strong text or emphasis text for important or header content.
<Text> **It's a strong text**</Text>
<Text> __It's a strong text__</Text>
<Text> *It's a emphasis text*</Text>
<Text> _It's a emphasis text_</Text>
<Text>
[It's a link to my
project](https://github.com/anilkk/ui-component-with-forge-ui)
</Text>
<Text> - Item 1 </Text>
<Text> - Item 2 </Text>
<Text> - Item 3 </Text>
<Text> - Item 4 </Text>
<Text> 1. Item 1 </Text>
<Text> 2. Item 2 </Text>
<Text> 3. Item 3 </Text>
<Text> 4. Item 4 </Text>
<Text>{`<Text>sample text</Text>`}</Text>
<Button text="demo button" onClick={() => console.log('perform action')} />
<ButtonSet>
<Button text="demo button 1" onClick={() => console.log('perform action')} />
<Button text="demo button 2" onClick={() => console.log('perform action')} />
</ButtonSet>
<Table>
<Row>
<Cell>
<Text>Column 1</Text>
</Cell>
<Cell>
<Text>Column 2</Text>
</Cell>
</Row>
</Table>
<Table>
<Row>
<Cell>
<Text>Column 1</Text>
</Cell>
<Cell>
<Text>Column 2</Text>
</Cell>
<Cell>
<Text>Column 3</Text>
</Cell>
</Row>
</Table>
<Table>
<Row>
<Cell>
<Text>Column 1</Text>
</Cell>
<Cell>
<Text>Column 2</Text>
</Cell>
{/* Empty cells for spacing */}
<Cell></Cell>
<Cell></Cell>
<Cell></Cell>
<Cell></Cell>
<Cell>
<Text>Column 3</Text>
</Cell>
</Row>
</Table>
⚠️ Be careful while using Table cells as a column, same UI is also rendred on the mobile apps.
You don't have the option to style image(example: width and height). It's good practice to pass formatted images with right dimention and style.
<Image
src="https://images.unsplash.com/photo-1560969184-10fe8719e047?auto=format&fit=crop&w=1200&q=50"
alt="Berlin"
/>
<Image
src="https://res.cloudinary.com/anilkumark/image/upload/c_thumb,w_200,g_face/v1589315094/projects/forge/ui-components/photo-1560969184-10fe8719e047_hfksqn.jpg"
alt="Berlin"
/>
<Image
src="https://res.cloudinary.com/anilkumark/image/upload/w_1000,c_fill,ar_1:1,g_auto,r_max,bo_5px_solid_red,b_rgb:262c35/v1589315094/projects/forge/ui-components/photo-1560969184-10fe8719e047_hfksqn.jpg"
alt="Berlin"
/>
- You can't style using CSS and so use 3rd party services like cloudinary to customize your image if possible.
You can use a small Image component, or you can also use emoji as an icon with text.
<Button text="✅ button with emoji icon" />
- You can find a collection of emojis on getemoji and emojipedia.
const [images] = useState(() => {
// You can make API call here
return imageUrls;
});
const [currentIndex, setCurrentIndex] = useState(0);
return (
<Fragment>
<Text>**Carousel demo**</Text>
<Table>
<Row>
<Cell>
<Button
text="<"
onClick={() => {
setCurrentIndex(
currentIndex === 0 ? images.length - 1 : currentIndex - 1
);
}}
/>
</Cell>
<Cell>
<Image src={images[currentIndex]} />
</Cell>
<Cell>
<Button
text=">"
onClick={() => {
setCurrentIndex(
currentIndex === images.length - 1 ? 0 : currentIndex + 1
);
}}
/>
</Cell>
</Row>
</Table>
</Fragment>
);
- You may expect delay, and you don't have a smooth transition effect.
It's not a video component; it's just a fallback with image and link.
<Image
src="https://res.cloudinary.com/anilkumark/image/upload/v1589197328/projects/forge/ui-components/Group_4_3_w6zihu.png"
alt="forge tunnel debug"
/>
<Text>
[**Play Demo of Forge tunnel debug ▶️**](https://youtu.be/1AlzjCsczV4)
</Text>
- Yes, it's not a video component, it's just a fallback with image and link.
const [isOpen, setIsOpen] = useState(false);
<Button
text="Toggle text view"
onClick={() => {
setIsOpen(!isOpen);
}}
/>;
{
isOpen && <Text>It's a collapsable text content</Text>;
}
Using 3rd party service quickchart.
<Image
src="https://quickchart.io/chart?bkg=white&c={type:%27bar%27,data:{labels:[2012,2013,2014,2015,2016],datasets:[{label:%27Users%27,data:[120,60,50,180,120]}]}}"
alt="progress"
/>
- For more details refer to the documentation quickchart.
Using 3rd party service quickchart.
<Image
src="https://quickchart.io/chart?c={type:'radialGauge',data:{datasets:[{data:[70],backgroundColor:'blue'}]}}"
alt="progress"
/>
- For more details refer to the documentation quickchart.
const handleClick = (buttonPressed) => {
console.log('buttonPressed ---->', buttonPressed);
};
<ButtonSet>
<Button
text="Previous"
onClick={(event) => {
console.log('EVENT ---->', event);
handleClick('Previous');
}}
/>
<Button
text="2"
onClick={() => {
handleClick(2);
}}
/>
<Button
text="3"
onClick={() => {
handleClick(3);
}}
/>
<Button
text="4"
onClick={() => {
handleClick(4);
}}
/>
<Button
text="Next"
onClick={() => {
handleClick('Next');
}}
/>
</ButtonSet>;
Alerts are available for any length of text. For proper styling, use one of the six appearance value (e.g., .inprogress).
<Text>
<StatusLozenge text="A simple default alert" appearance="default" />
</Text>
<Text>
<StatusLozenge text="A simple primary alert" appearance="inprogress" />
</Text>
<Text>
<StatusLozenge text="A simple info alert" appearance="new" />
</Text>
<Text>
<StatusLozenge text="A simple warning alert ⚠️" appearance="moved" />
</Text>
<Text>
<StatusLozenge text="A simple danger alert ⛔" appearance="removed" />
</Text>
<Text>
<StatusLozenge text="A simple success alert ✅" appearance="success" />
</Text>
const [isOpen, setIsOpen] = useState(false);
<Button text="Show modal" onClick={() => setIsOpen(true)} />;
{
isOpen && (
<ModalDialog
header="My modal dialog"
onClose={() => setIsOpen(false)}
appearance="danger"
>
<Text>It's a ModalDialog danger on the header</Text>
</ModalDialog>
);
}
const [isOpen, setIsOpen] = useState(false);
<Button text="Show modal" onClick={() => setIsOpen(true)} />;
{
isOpen && (
<ModalDialog
header="My modal dialog"
onClose={() => setIsOpen(false)}
appearance="warning"
>
<Text>It's a ModalDialog warning on the header</Text>
</ModalDialog>
);
}
const [isOpen, setOpen] = useState(false);
<Button text="Show modal" onClick={() => setOpen(true)} />;
{
isOpen && (
<ModalDialog header="My modal dialog" onClose={() => setOpen(false)}>
<Text>It's a ModalDialog</Text>
</ModalDialog>
);
}
<Table>
<Row>
<Cell>
<Image
src="https://res.cloudinary.com/anilkumark/image/upload/c_thumb,w_200,g_face/v1589212010/projects/forge/ui-components/anil-logo_yq4vyu.png"
alt="demo logo"
/>
</Cell>
{/* Create many empty Cell for spacing */}
<Cell></Cell>
<Cell></Cell>
<Cell></Cell>
<Cell>
<ButtonSet>
<Button text="Home" />
<Button text="About" />
<Button text="Contact" />
</ButtonSet>
</Cell>
</Row>
</Table>
<Table>
<Row>
<Cell>
<Image
src="https://res.cloudinary.com/anilkumark/image/upload/c_thumb,w_200,g_face/v1589212010/projects/forge/ui-components/anil-logo_yq4vyu.png"
alt="demo logo"
/>
</Cell>
{/* Create many empty Cell for spacing */}
<Cell></Cell>
<Cell></Cell>
<Cell></Cell>
<Cell>
<Text>
[Home](https://developer.atlassian.com/platform/forge)
{' '} {/* For extra spacing */}
[Reference](https://developer.atlassian.com/platform/forge/manifest-reference/)
{' '} {/* For extra spacing */}
[Help](https://developer.atlassian.com/platform/forge/get-help/)
</Text>
</Cell>
</Row>
</Table>