# DAOhaus Component Library Spec ## Goals: - Components are readable - Components are reliable - Components are lightweight - Components are useful and convenient - Components are simple ### Guidelines (How We Achieve These Goals) **Minimal JSX:** Spamming a React Component with CSS style props is an antipattern. It makes components less readable, harder to debug, and ensures that UI is rarely consistent. While customization is necessary, we'll use fallbacks for every prop we can. That way, the developer is always passing the minimum data required to render UI. **Low Custom Styling** We are not Bootstrap or Material UI. We do not need to make our library 100% customizable. In fact, doing so would eliminate the value-add we offer developers. Devs use this library to: - Build DAOhaus UI quickly and easily - Build UI that is consistent with DAOhaus's other apps. Devs do not use this library to: - Create their own style from scratch The DAOhaus UI will offer a minimal API for custom theming (color etc), but the scope will be strictly limited. For styles that are completely custom, community devs will be encouraged to write their own UI instead. This prevents us from reinventing the wheel and frees us to provide value in ways that are the most common and immediate. It also considers the community developer's time, as overwriting styles, especially for components with an opinionated pattern will be pretty costly. Keeping styles consistent also helps reinforce the DAOhaus meme and brand, while ensuring components are interchangeable and reusable. **Functional and Declarative:** In keeping with nature of React and modern JS, we style our code to be as declarative as possible. Our functions are tiny, simple, and often handle one operation. In doing so, our code becomes self-documenting and is easy on the eyes. We should be able to understand what a function or component is doing from a glance, instead of trying to follow the thread of execution through hundreds of lines of code. With this comes many of principles found in writing modern JS: - minimal state - top-down (tree-shaped) component architecture - pure, testable functions These principles are very much in line with our existing JS style guide for V2. **Minimally Invasive** Over time, we'd like the package size to get smaller and smaller. This library strives to find the balance between package minimalism and not rewriting code. This requires us to be very diligent about what we add and why. To make sure the package is as usable as possible, we plan to bundle our UI and Web3 utils separately. Most importantly, we bundle our macro components separately so that they can import what they need and tree-shake the rest. **Maximally Useful** While the micro elements are useful for keeping elements consistent and reliable, the macro elements are here to help devs implement reliable UI systems with little headache. Here's an example of what a Macro should look like ``` js <ProposalList daoAddress={0x...} filters={[ ... ]} sort={[ ... ]} /> ``` While this Macro may look simple, there's a lot going on under the hood. Having the above component with that level of abstraction would only be possible if: a) we limit the amount devs can customize the library b) our micros are rock solid. Becuase the components are modular. Devs should also be able to compose the components in different arrangements if they want. For example, if a dev wanted to bring in a ``<CustomComponent />``, the dev would import all the subcomponents and assemble ``<PropopsalList />`` themselves. Because we build our macros out of composable building blocks, the example below is possible. ``` const HomemadeProposalList = ({proposals}) => { //example of proposal state and list hook const {filter, seacrch, sort, items} = useList(proposals) <TableLayout tableNav={ [ <DropDown options{...} selectedOption={filter}/> <DropDown options{...} selectedOption={search}/> <ProposalSearch options={...}sort={sort}/> ] } > <CustomComponent /> {items?.map(proposal => <ProposalCard {...proposal} />)} </TableLayout> } ``` ## Micros: - Micros are the primitive or micro components. They're the base building blocks of the DAOhaus UI. - Micros are dumb (stateless, simple, declarative) - Micros are indivisible, meaning that they could not be split into smaller components. - Micros easy to debug. - Micros are declarative and readable. - Micros use specialized primitives over props when feasible (generally in situations with low customizability or variance). ``` Yes <BodyMd>Your Text Here </BodyMd> No <Text variant='body' size='md'> Text Here </Text> ``` ## Macros - Macros are interlocking combinations of micros - They still strive to be stateless whenever possible. - Macros are state mgmt agnostic, meaning that they always are passed this data from props. - OR Macros fetch their data independantly - OR Macros components can fetch IF they don't receive props. - The behaviour of macros is informed by the design team - Macros use factory components to render components from static data or data from an API. - Macros should be exported seperately to prevent bloat.