LogoLogo
These products have been deprecated and are no longer being maintained. For a better experience and support, please check out our new stack Aragon OSx.
Aragon Legacy Documentation
Aragon Legacy Documentation
  • 🔷Aragon
    • Aragon Legacy Documentation
    • Aragon Values, Finances, and Legal
      • Legal and technical infrastructure
      • Financial infrastructure
      • Meet your DAO support network
    • Learn about DAOs
      • What is a DAO?
      • Why do we need DAOs?
      • What is decentralized autonomous governance?
      • What is the AN DAO?
      • TAO Voting
      • Why use Aragon to build a DAO?
  • 🌐Products
    • Prerequisites
    • Quickstart
    • Setting up a Metamask Wallet
      • Getting started with Ethereum
      • Getting started with Goerli Testnet
      • Getting started with Polygon
      • Getting started with Mumbai Testnet
      • Getting started with Harmony
      • Getting started with Harmony testnet
      • Getting started with Metis Andromeda
      • Getting started with Stardust Testnet
      • Getting started with BSC Testnet
      • How to sign a transaction?
      • Import your seed wallet to Metamask
      • Gas Tracker
    • Setting up a Frame Wallet
    • Setting up a Gnosis Safe MultiSig Wallet
    • Aragon Client
      • What is Aragon Client
      • How to create a DAO
        • Templates
        • Using the Company Template
        • Using the Membership Template
        • Use the Reputation template
      • How to create a DAO on Polygon
      • How to create a DAO on Harmony
      • How to navigate your DAO
        • Home
        • The Apps
          • Tokens App
          • Voting App
          • Finance App
          • Agent App
            • How to install the Agent App in your DAO
            • Using Agent with Frame
        • System Setting
          • Permissions Setting
          • App Center
          • Organization Setting
      • After you've started a DAO
        • How to change the Quorum of your DAO
          • Change Quorum using Aragon Console
          • Change Quorum using EVMcrispr
        • How to create a Legal Wrapper for your DAO with Otoco
        • How to Operate your DAO from your Mobile Phone
      • How to Brick your DAO 🧱
    • Aragon Govern
      • What is Aragon Govern?
      • How to create a Govern DAO
      • Navigate into your Govern DAO
        • How to mint and assign DAO tokens to others
        • How to deposit funds
        • Challenging a transaction
      • Reasons for the delay period in the transaction
      • Collateral for scheduling or challenging a transaction. Why?
      • Acting as a guardian for an Aragon Govern dispute
      • Using the Client DAO with the Govern DAO
    • Aragon Voice
      • What is Aragon Voice?
      • Creating a voting proposal
      • Creating a voting proposal using your token
      • Voting on a proposal
    • Aragon Vocdoni
      • What is Aragon Vocdoni
      • Creating a Vodconi organization
      • Accessing your Vocdoni organization
      • Navigating your Vocdoni organization
        • Creating a voting proposal
        • Voting on a proposal (anonymous voting disabled)
        • Voting on a proposal (anonymous voting enabled)
    • Aragon Court
      • What is Aragon Court
      • Court Dashboard
      • Dispute lifecycle
      • Acting as guardian for a dispute
      • Glossary
  • 🛠️Developers
    • Legacy Developer Documentation
    • General Tools
      • The Basics
        • Before starting
        • Quick start
        • Tech Stack
        • App permissions
        • Forwarding
        • Upgradeability
        • Package management
        • Templates
        • Aragon client
        • Human readable transactions
      • Guides
        • How to create your first custom DAO using Aragon CLI!
        • How to use the Agent App
          • Installing Aragon Agent from aragonCLI
          • Setting and Checking permissions
          • Interacting with Aragon Agent
        • How to build your first Aragon App!
        • How to publish an Aragon App to aragonPM
        • How to migrate existing Aragon App to Buidler plugin
        • How to change the Quorum of your DAO
          • Change Quorum using Aragon Console
          • Change Quorum using EVMcrispr
        • Deploying Aragon Client in new Chains
          • Deployments information
            • Harmony testnet
            • BSC Tesnet
            • Harmony
            • Metis stardust
            • Metis Andromeda
        • How to Brick your DAO 🧱
        • How to sign with Web3 providers
          • Setting up a Metamask Wallet
            • Import your seed phrase into Metamask
            • Import your private key into Metamask
            • Sign a transaction with Metamask
          • Setting up a Frame Wallet
            • Sign a Transaction with Frame
        • Troubleshooting
      • aragonOS
        • Introduction
        • Motivations
        • Developing with aragonOS
        • Reference documentation
        • Migrating to aragonOS 4 from aragonOS 3
        • Reference (aragonOS 3)
        • Smart Contract References
          • ACL
            • ACL
            • ACLSyntaxSugar
            • ACLHelpers
            • IACL
            • IACLOracle
          • APM
            • APMNamehash
            • APMRegistry
            • APMInternalAppNames
            • Repo
          • APPS
            • AppProxyBase
            • AppProxyPinned
            • AppProxyUpgradeable
            • AppStorage
            • AragonApp
            • UnsafeAragonApp
          • COMMON
            • Autopetrified
            • ConversionHelpers
            • DelegateProxy
            • DepositableDelegateProxy
            • DepositableStorage
            • EtherTokenConstant
            • IForwarder
            • IForwarderFee
            • IVaultRecoverable
            • Initializable
            • IsContract
            • Petrifiable
            • ReentrancyGuard
            • SafeERC20
            • TimeHelpers
            • Uint256Helpers
            • UnstructuredStorage
            • VaultRecoverable
          • ENS
            • ENSConstants
            • ENSSubdomainRegistrar
          • EVMSCRIPT
            • EVMScriptRegistry
            • EVMScriptRunner
            • IEVMScriptExecutor
            • IEVMScriptRegistry
            • EVMScriptRegistryConstants
            • ScriptHelpers
          • EVMSCRIPT/EXECUTORS
            • BaseEVMScriptExecutor
            • CallsScript
          • FACTORY
            • APMRegistryFactory
            • AppProxyFactory
            • DAOFactory
            • ENSFactory
            • EVMScriptRegistryFactory
          • KERNEL
            • IKernel
            • IKernelEvents
            • Kernel
            • KernelAppIds
            • KernelNamespaceConstants
            • KernelProxy
            • KernelStorage
      • aragonCLI
        • Introduction
        • Main commands
        • DAO commands
        • APM commands
        • IPFS commands
        • Global configuration
      • aragonPM
        • Introduction
        • Architecture
        • Reference documentation
      • aragonAPI
        • Introduction
        • Javascript
          • Quick Start
          • App API
          • React API
          • Wrapper
          • Providers
          • Architecture of apps
          • Background Scripts
      • aragonUI
        • Getting started
        • How to upgrade
        • BASE
          • Spacing
          • Colors
          • Text styles
          • Icons
          • Main
        • ACTIONS
          • Button
          • ContextMenu
        • NAVIGATION
          • Tabs
          • Pagination
          • BackButton
          • Link
          • Header
        • STRUCTURE
          • Bar
          • Box
          • Card
          • Split
          • DataView
          • Table
          • EmptyStateCard
          • IdentityBadge
          • TransactionBadge
          • Tag
          • Accordion
          • Timer
          • TokenAmount
          • EthIdenticon
          • TransactionProgress
        • DATA ENTRY
          • AutoComplete
          • DateRangePicker
          • DropDown
          • Switch
          • Radio
          • CheckBox
          • Slider
          • TextInput
          • SearchInput
          • AddressField
          • RadioGroup
          • RadioList
          • TextCopy
          • Field
        • VISUALIZATION
          • CircleGraph
          • LineChart
          • Distribution
        • FEEDBACK
          • Info
          • ProgressBar
          • LoadingRing
          • Toast
          • SyncIndicator
          • FloatIndicator
        • OVERLAYS
          • Help
          • Popover
          • Modal
          • SidePanel
        • ADVANCES
          • ButtonBase
          • FocusVisible
          • PublicUrl
          • Redraw
          • RedrawFromDate
          • Root
          • RootPortal
          • Viewport
      • aragonDS
        • Guidelines
          • Layout
          • Color
          • Iconography
          • Typography
          • Illustrations
        • Components
          • Overview
      • Aragon Connect
        • Guides
          • Aragon Basics
          • Getting started
          • Usage with React
        • Advanced
          • Custom Subgraph queries
          • Writing an App Subgraph
          • Writing an App Connector
        • Connectors
          • Organizations
          • Tokens app
          • Voting app
          • Finance app
        • API reference
          • connect()
          • App
          • Connectors
          • Organization
          • Permission
          • Repo
          • Role
          • TransactionIntent
          • TransactionPath
          • TransactionRequest
          • Types
          • Errors
      • App Center
        • App Center
        • Preparing Assets
        • Submitting Your App to the App Center
    • Product Tools
      • Aragon Govern
        • README
        • Introduction
          • Concepts and background
            • Govern Core concepts
            • ERC3000
          • Developers
            • Getting started
            • Govern.js API
            • Historical deployments
            • GraphQL API
            • Smart contracts breakdown
        • Deployments
          • Mainnet
          • Rinkeby
        • Packages
          • ERC 3k
          • Govern Console
          • Govern contract utils
          • Types
          • govern-create
          • Govern Server
          • govern-subgraph
          • govern-token
          • govern.js
      • Aragon Vocdoni
    • Aragon Client Glossary
  • THE ANT TOKEN
    • Aragon Network Token
      • About ANT
      • Historical token sale
    • ANTv1
      • Non-standard behaviours and gotchas
      • About the MiniMe token
      • The initial token sale flow
    • ANTv2
      • Upgrade portal
        • Troubleshooting
      • Contract interaction
      • Migrating on-chain liquidity
    • Developers
      • Quick start
      • Integrating ANT
      • Historical deployments
      • Security policy
  • ‼️FAQ
    • Products
      • Aragon Client
        • Where is my DAO?
        • DAO creation taking a long time to confirm
        • DAO is taking a long time to load
        • Failed DAO creation transaction
        • Why do I see a Blue Screen?
        • An unexpected error has occurred
        • App does not appear in Firefox
        • Receiving funds directly to the Agent or Vault address
        • How to Recover Funds accidentally sent to an Aragon App address
        • Depositing EURS in the Finance app
        • Which templates are available on the Ethereum Network?
        • Which templates are available on the Polygon Network?
        • Which templates are available on the Harmony Network?
        • Which templates are available on the Metis Andromeda Network?
        • How to delete a DAO
      • Aragon Govern
        • Which was the wallet address used to create the Aragon Govern DAO?
        • Where are my DAO tokens?
        • How to delete a DAO
        • How can I transfer funds to the Aragon Govern DAO?
      • Aragon Vocdoni
        • Is Vocdoni easy to use?
        • Is Vocdoni anonymous?
        • Is Vocdoni free?
        • Is my data safe with Vocdoni?
        • As an Organization, what can I do with Vocdoni?
      • Aragon Court
        • What is the current duration of the different stages of a dispute?
        • Dispute - Which fees need to be paid to create a dispute?
        • Dispute - Do I need to put collateral to create a dispute?
        • Appeals - How much money is needed to appeal a dispute? And to confirm the appeal? What is it for?
        • Appeals - If I have tokens staked or activated, can I lose them if I appeal a dispute?
        • Appeals - What happens to the collateral put up
        • Voting - Is a majority needed to win a vote?
        • Voting - What happens if there is a tie?
        • Voting - What does "Refuse to vote" mean? What happens if it's the most voted option?
        • Voting - Another guardian tried to collude. Can I punish this guardian?
        • Voting - What's the penalty for leaked votes?
        • Governance - Which parameters of Court can be changed? How?
        • Governance - Do parameter changes affect ongoing disputes?
        • Technical - Where is the Court "hosted"?
        • Technical - Where can I find the source code and technical documentation for Aragon Court?
        • ANJ conversion - What date will the lock-up period end?
        • ANJ conversion - If I have not staked my $ANJ, do I still get the lockup period price?
        • ANJ conversion - Will I get the 0.044 conversion if I convert after September 5th 2021?
        • ANJ conversion - How much will it cost to be a Guardian in Aragon Court with $ANT?
        • I can't see my tokens in the Dashboard
        • I activated my tokens but I can't see my probability of being drafted
    • Miscellaneous
      • Metamask wallet transaction alert
      • Is Aragon open source?
      • Where can I browse through the DAOs created on Aragon?
      • How to migrate from "old" DAI to "new" DAI
      • Security notice for organizations created before Aragon 0.8
      • General troubleshooting tips
    • ANT Token
      • What can I do with ANT?
      • Who holds ANT?
      • Who are the biggest ANT holders?
      • Long-term holding ANT - What benefits?
      • Can I delegate my network votes to somebody else?
      • Can I do flash loans with ANT?
      • Is there an ANT options market?
      • Are you planning to launch new network tokens?
      • My wallet isn't available on the Upgrade Portal
      • How can connect my Ledger to the Upgrade Portal?
      • I accidentally sent my "old" ANT to an exchange
      • ANJ conversion - What is the minimum number of $ANJ I need to participate in the 0.044 conversion?
      • ANJ conversion - What is the conversion rate ANJ to ANT v2?
Powered by GitBook
On this page
  • Getting started
  • Quick setup
  • A typical Aragon app
  • Overview
  • Header
  • SidePanel
  • Split
  • DataView
  • Box and useTheme()
  • Distribution
  • Wrapping up

Was this helpful?

  1. Developers
  2. General Tools
  3. aragonUI

Getting started

PreviousaragonUINextHow to upgrade

Last updated 1 year ago

Was this helpful?

Getting started

aragonUI is a React library based on aragonDS, the Aragon design system. It aims to provide the elements needed to build Aragon apps that feel native to the Aragon ecosystem.

Quick setup

This tutorial doesn’t cover the creation of your React app nor the way you bundle it, but we recommend

Install aragonUI alongside styled-components in your project:

npm install --save @aragon/ui styled-components

Note: while not required, we strongly recommend adding in your build configuration. It provides, amongst other things, that we use widely to.

Copy the aragonUI assets into your assets directory (assuming ./public):

npx copy-aragon-ui-assets ./public

Note: doing this step ensures that any assets required by aragonUI, like fonts and illustrations, can be served properly in any environment. Most apps built with aragonUI will be served in a decentralized manner (generally through an IPFS gateway), so using services like Google Fonts is not an option.

The only mandatory component that you need to define is . This component sets up the global styles and providers used by other components. We recommend wrapping your entire app with Main:

import React from 'react'
import { Main } from '@aragon/ui'

function App() {
  return (
    <Main>
      <div>Your app goes here</div>
    </Main>
  )
}

From that point on, you are ready to start building your app! Let’s go through a simple app to get an overview of the components that are often used in Aragon apps.

A typical Aragon app

Aragon apps can take many shapes, but most tend to follow similar patterns. aragonUI provides components that can be used to build apps that are responsive, accessible, and theme-able by default.

This is how it looks:

The Tokens app and its layout variations.

Overview

Let’s start by defining what constitutes an Aragon app.

The Aragon client 1 displaying the Tokens app, in the app area 2.

As you can see, the app is only a part of what a user sees when interacting with the Aragon client, in a way that the app can not interfere with the interface of the client or the other apps.

The Tokens app, featuring the Header 1 and the Split 2 components.

Header

This is how Header can be used inside an app.

// App.js
import React from 'react'
import { Main, Header, Button, IconPlus, Tag } from '@aragon/ui'

function App() {
  return (
    <Main>
      <Header
        primary={
          <>
            Tokens
            <Tag mode="identifier">PTO</Tag>
          </>
        }
        secondary={
          <Button mode="strong" label="Add tokens" icon={<IconPlus />} />
        }
      />
    </Main>
  )
}

There are a few things to note, the first one being the way these props are named. primary and secondary are names used by aragonUI components for “slots”. Slots don’t really exist in a technical sense: this is only a name for props that are expecting a subtree to be passed, similar to the way children works in components accepting a single tree.

SidePanel

// App.js
import React, { useState } from 'react'
import { Main, Header, Button, IconPlus, Tag, SidePanel } from '@aragon/ui'

function App() {
  const [sidePanelOpened, setSidePanelOpened] = useState(false)
  return (
    <Main>
      <Header
        primary={
          <>
            Tokens
            <Tag mode="identifier">PTO</Tag>
          </>
        }
        secondary={
          <Button
            mode="strong"
            label="Add tokens"
            icon={<IconPlus />}
            onClick={() => setSidePanelOpened(true)}
          />
        }
      />
      <SidePanel
        title="Add tokens"
        opened={sidePanelOpened}
        onClose={() => setSidePanelOpened(false)}
      >
        {/* SidePanel content goes here */}
      </SidePanel>
    </Main>
  )
}

That’s pretty much it! We now have a drawer that opens from the right side of the screen (with left to right languages), that can be closed by the user. We’re ready to move to the next part of the app.

Three components used in this app: DataView 1, a Box 2, and another Box with Distribution 3.

Split

// App.js
import React, { useState } from 'react'
import { Main, Header, Split, DataView, Box } from '@aragon/ui'

function App() {
  const [sidePanelOpened, setSidePanelOpened] = useState(false)
  return (
    <Main>
      <Header />
      <Split
        primary={<DataView />}
        secondary={
          <>
            <Box />
            <Box />
          </>
        }
      />
      <SidePanel
        title="Add tokens"
        opened={sidePanelOpened}
        onClose={() => setSidePanelOpened(false)}
      />
    </Main>
  )
}

DataView

// TokenHoldersView.js
import React from 'react'
import {
  DataView,
  IdentityBadge,
  ContextMenu,
  ContextMenuItem,
} from '@aragon/ui'

// The token holders represented as a DataView.
function TokenHoldersView({ tokenHolders }) {
  /*

  This is how tokenHolders could look like:

  tokenHolders = [
    ['0xcafe…', 3],
    ['0xbeef…', 2],
    …
  ]

  */
  return (
    <DataView
      display="table"
      fields={['Holder', 'Balance']}
      items={tokenHolders}
      renderEntry={entryParts}
      renderEntryActions={entryActions}
    />
  )
}

// Return the parts (table cells) corresponding to an entry.
function entryParts([account, balance]) {
  return [<LocalIdentityBadge entity={account} />, balance]
}

// Return the contextual menu for an entry (no interaction behavior defined).
function entryActions([account, balance]) {
  return (
    <ContextMenu>
      <ContextMenuItem>Add tokens</ContextMenuItem>
      <ContextMenuItem>Remove tokens</ContextMenuItem>
    </ContextMenu>
  )
}

export default TokenHoldersView

Box and useTheme()

Box is a straightforward component that renders as a surface (as defined by aragonDS) which can optionally have a heading. It is commonly used in either slot of Split.

To implement the “Token info” component, we are going to define some custom styles and use some specific text colors. To ensure your app is compatible with any aragonUI theme, make sure you always use colors from the useTheme() hook.

// TokenInfoBox.js
import React from 'react'
import { Box, TokenBadge, useTheme } from '@aragon/ui'

// TokenInfoBox is making use of the Box with some custom content.
function TokenInfoBox({ supply, transferable, token }) {
  return (
    <Box heading="Token info">
      <TokenInfoBoxRow primary="Total supply" secondary={supply} />
      <TokenInfoBoxRow
        primary="Transferable"
        secondary={transferable ? 'YES' : 'NO'}
      />
      <TokenInfoBoxRow
        primary="Token"
        secondary={
          <TokenBadge
            address={token.address}
            name={token.name}
            symbol={token.symbol}
          />
        }
      />
    </Box>
  )
}

// TokenInfoBoxRow is relying on useTheme() to get a specific text color.
function TokenInfoBoxRow({ primary, secondary }) {
  const theme = useTheme()
  return (
    <div
      css={`
        display: flex;
        justify-content: space-between;
      `}
    >
      <div
        css={`
          color: ${theme.surfaceContentSecondary};
        `}
      >
        {primary}
      </div>
      <div>{secondary}</div>
    </div>
  )
}

export default TokenInfoBox

Distribution

// OwnershipDistributionBox.js
import React from 'react'
import { Box, Distribution } from '@aragon/ui'

// OwnershipDistributionBox combines Box
// and Distribution into a single component.
function OwnershipDistributionBox({ supply, tokenHolders }) {
  const distributionItems = tokenHolders.map(([account, balance]) => ({
    item: account,
    percentage: (balance / supply) * 100,
  }))

  return (
    <Box heading="Ownership Distribution">
      <Distribution heading="Token holder stakes" items={distributionItems} />
    </Box>
  )
}

export default OwnershipDistributionBox

Wrapping up

Now that we implemented the different parts of the app, this is how the main component would look like in its final state:

// App.js
import React, { useState } from 'react'
import { Main, Header, Button, SidePanel } from '@aragon/ui'

import TokenHoldersView from './TokenHoldersView'
import TokenInfoBox from './TokenInfoBox'
import OwnershipDistributionBox from './OwnershipDistributionBox'

// Some demo data
const token = {
  name: 'My Organization Token',
  symbol: 'MOT',
  address: '0x…',
  transferable: true,
  supply: 8,
  holders: [
    ['0xcafe…', 3],
    ['0xbeef…', 2],
    ['0xfeed…', 1],
    ['0xface…', 1],
    ['0xbead…', 1],
  ],
}

function App() {
  const [sidePanelOpened, setSidePanelOpened] = useState(false)
  return (
    <Main>
      <Header />
      <Split
        primary={<TokenHoldersView tokenHolders={token.holders} />}
        secondary={
          <>
            <TokenInfoBox supply={token.supply} />
            <OwnershipDistributionBox
              supply={token.supply}
              tokenHolders={token.holders}
            />
          </>
        }
      />
      <SidePanel
        title="Add tokens"
        opened={sidePanelOpened}
        onClose={() => setSidePanelOpened(false)}
      />
    </Main>
  )
}

And this is it for the tutorial. Of course, many components were not covered here, the idea being to provide an overview of an Aragon app's structure when it uses aragonUI.

This section takes the to illustrate the different elements that constitute a typical Aragon app and how they might be put together. Rather than implementing every behaviour in the Tokens app, we are going to focus on the structure of the app and its main components. To get an idea of what the final app looks like, you can visit the .

Two components that are commonly used in Aragon apps are and . Header handles the main title of an app and its main action. Split creates a two column layout when the available horizontal space allows it. On smaller screens, it renders as a single column. As we continue, we will also be using the and the components.

If you run this app, you might also notice that the component displays either a text label or an icon, adapting to the viewport size automatically. Some components adapt to where they are, which is the case here. , being in follows the behavior defined by aragonDS about how it should adapt to different viewport sizes. These variations make it easy to follow the patterns defined by aragonDS, and are always documented and overridable.

To make things a bit more interesting, we are going to add a that opens from the “Add tokens” header button. The SidePanel component can be inserted anywhere, as long as it is inside the Main tree.

Let’s define the layout, right after the Header, to get an idea of what the structure will look like:

Like , the component defines two slots using the same primary and secondary names.

is a powerful component that can be used to represent data in various ways, adapting itself to the available space. We are going to use it for the “holders” table.

To get more details about DataView and how it works, please have a look at its

Now that TokenInfoBox is done, there is one last bit remaining, which is the “ownership distribution” box. Luckily for us, the component will do most of the work.

🛠️
using Parcel.
the styled-components Babel plugin
the css prop
Main
Tokens app
full source code
Header
Split
DataView
SidePanel
Button
Button
Header,
SidePanel
Split
Header
Split
DataView
documentation page.
Distribution