diff --git a/docs/getting-started-with-react/getting-started-with-react.stories.mdx b/docs/getting-started-with-react/getting-started-with-react.stories.mdx index 2256f5bda7..08d6e0c21b 100644 --- a/docs/getting-started-with-react/getting-started-with-react.stories.mdx +++ b/docs/getting-started-with-react/getting-started-with-react.stories.mdx @@ -8,9 +8,7 @@ import { getGIF, loadingGIF } from "./getGIF"; -# Getting Started with React - -## Things to know. +# Getting started with React ## What is React @@ -18,7 +16,7 @@ At its core React is simply a JavaScript view library layer. It provides us with a way to define and render view components. It also aids with tracking and re-rendering changes to data that the components are representing. -## What is a Component +## What is a component Much as a function in programing allows you to encapsulate, test and reuse logic a React Component allows you to encapsulate, test and reuse pieces of your UI. @@ -64,7 +62,7 @@ There are a few things going on in the example above. Lets break them down: | `{ text, yell }: MessageProps` | There are two parts to this. Starting on the right `MessageProps` indicates that this funciton takes a parameter of type `MessageProps`. On the left the `{ text, yell }` unpacks the parameter into local variables. | | `return

{text}

` | Every React component will return an [element](https://reactjs.org/docs/rendering-elements.html) or [fragment](https://reactjs.org/docs/fragments.html). (Note the [fragment short hand syntax](https://reactjs.org/docs/fragments.html#short-syntax).) | -## It's Components All the Way Down +## It's components all the way down In React everything is a component. A typical page will consist of one top level component representing the main view. Then within that page you will break down @@ -79,7 +77,7 @@ smaller components. Brad Frost covers this break down very well with When you are writing a front end using React each of the levels he talks about are represented by components functions. -## Composing Components +## Composing components As mentioned above a lot of the power of React comes from being able to build components out of other components. Lets take a look at an example on how to do @@ -89,7 +87,7 @@ For this example we are going to build a card that allows you to enter a topic and then search for a related gif. - + {() => { const [topic, setTopic] = useState(); const [url, setURL] = useState(); @@ -117,7 +115,7 @@ and then search for a related gif. > `function getGIF(topic: string): Promise;` that will return a promise > resolving to a url. -### Breaking it Down +### Breaking it down ```tsx const [topic, setTopic] = useState(); @@ -183,3 +181,43 @@ The final part of our example defines the custom actions needed to power our component. In this case the action when the user clicks on the **Search** button. Here we call the `setURL` setter to show the `loadingGIF`. Then, we call `setURL` awaiting the async response of `getGIF`. + +## Types of components in Atlantis and their ability for customization + +#### 1. Primitive components: + +Examples: [Icon](..?path=/docs/components-images-and-icons-icon--docs), +[Avatar](..?path=/docs/components-images-and-icons-avatar--docs) + +These components do not accept children and have minimal customization. + +#### 2. Simple components: + +Examples: [Button](..?path=/docs/components-actions-button--docs), +[Link](..?path=/docs/components-text-and-typography-link--docs) + +These allow basic customization through props or limited children, like +`ReactNode` or specific child types. + +#### 3. Compound components: + +Examples: [Chip](..?path=/docs/components-selections-chip--docs), +[DataList](..?path=/docs/components-lists-and-tables-datalist--docs) + +These are part of larger compositions and may validate their children types to +maintain internal consistency. + +#### 4. Strict complex components: + +Example: +[Autocomplete](..?path=/docs/components-forms-and-inputs-autocomplete--docs), + +These have multiple UI pieces they are built out of but strict APIs and limited +customization. + +#### 5. Customizable complex components: + +Example: [Combobox](..?path=/docs/components-selections-combobox--docs) + +These also have multiple UI pieces they are built out of but offer options for +customization. diff --git a/docs/guides/customizing-components.stories.mdx b/docs/guides/customizing-components.stories.mdx new file mode 100644 index 0000000000..bf51731de5 --- /dev/null +++ b/docs/guides/customizing-components.stories.mdx @@ -0,0 +1,77 @@ +import { Meta } from "@storybook/addon-docs"; + + + +# Customizing components + +### Philosophy: easy to use, flexible to customize + +Atlantis is designed to make building consistent, accessible, and visually +appealing user interfaces as effortless as possible. Our goal is to create +components that work out of the box, requiring minimal setup or configuration +from consumers. + +While we strive to cover the most common design scenarios with thoughtful +defaults, we understand that unique use cases may require customization. For +these scenarios, we provide mechanisms to extend or modify our components in a +way that maintains flexibility without compromising the integrity of the +components. + +We recommend using the default implementations wherever possible to benefit from +consistency, maintainability, and built in accessibility. However, if you choose +to customize, please note that the responsibility for ensuring proper +functionality and cohesion will rest with you. + +Atlantis aims to strike a balance between simplicity, flexibility, and +consistency. + +### Primary customization approach: named render props + +In Atlantis, our primary approach to enabling customization is through named +render props, using the `customRender____` pattern. This method allows consumers +to inject their own UI logic while retaining the default behaviors and +functionality of the component. + +#### Example: customRenderItem + +Here's an example of how to use a named render prop to customize the rendering +of items in a [List](..?path=/docs/components-lists-and-tables-list--docs) +component: + +```tsx +const renderProductItem = item => ( + + {item.price} + {item.name} + +); + +export const CustomRenderExample = () => ( + +); +``` + +In this example, the default List behavior (such as the main list structure and +handling item interactions) is preserved. Only the presentation of individual +items is customized. + +### Other customization approaches + +While custom render functions are our primary approach it is not used in all +places. For simple cases where customization does not depend on internal state, +we have chosen to extend prop types to allow for a `ReactNode` to be passed in. + +#### Example: Tab component (see [Tabs](..?path=/docs/components-navigation-tabs--docs)) + +Instead of introducing `customRenderLabel`, the `Tab` component was updated to +allow the `label` prop to accept a `ReactNode`. + +```tsx +} /> +``` + +This approach was chosen to provide a simpler experience for those implementing +Atlantis components. Customizing the `label` didn’t require exposing or +interacting with the `Tab`’s internal state (e.g., active state styling). Once +the design becomes more complex a custom render function would become a better +fit.