Remove 2 suffix for ui, storybook, text
Co-authored-by: Mikayla <mikayla@zed.dev>
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
# Building UI with GPUI
|
||||
|
||||
## Common patterns
|
||||
|
||||
### Method ordering
|
||||
|
||||
- id
|
||||
- Flex properties
|
||||
- Position properties
|
||||
- Size properties
|
||||
- Style properties
|
||||
- Handlers
|
||||
- State properties
|
||||
|
||||
### Using the Label Component to Create UI Text
|
||||
|
||||
The `Label` component helps in displaying text on user interfaces. It creates an interface where specific parameters such as label color, line height style, and strikethrough can be set.
|
||||
|
||||
Firstly, to create a `Label` instance, use the `Label::new()` function. This function takes a string that will be displayed as text in the interface.
|
||||
|
||||
```rust
|
||||
Label::new("Hello, world!");
|
||||
```
|
||||
|
||||
Now let's dive a bit deeper into how to customize `Label` instances:
|
||||
|
||||
- **Setting Color:** To set the color of the label using various predefined color options such as `Default`, `Muted`, `Created`, `Modified`, `Deleted`, etc, the `color()` function is called on the `Label` instance:
|
||||
|
||||
```rust
|
||||
Label::new("Hello, world!").color(LabelColor::Default);
|
||||
```
|
||||
|
||||
- **Setting Line Height Style:** To set the line height style, the `line_height_style()` function is utilized:
|
||||
|
||||
```rust
|
||||
Label::new("Hello, world!").line_height_style(LineHeightStyle::TextLabel);
|
||||
```
|
||||
|
||||
- **Adding a Strikethrough:** To add a strikethrough in a `Label`, the `set_strikethrough()` function is used:
|
||||
|
||||
```rust
|
||||
Label::new("Hello, world!").set_strikethrough(true);
|
||||
```
|
||||
|
||||
That's it! Now you can use the `Label` component to create and customize text on your application's interface.
|
||||
|
||||
## Building a new component
|
||||
|
||||
TODO
|
||||
@@ -0,0 +1,160 @@
|
||||
# Hello World
|
||||
|
||||
Let's work through the prototypical "Build a todo app" example to showcase how we might build a simple component from scratch.
|
||||
|
||||
## Setup
|
||||
|
||||
We'll create a headline, a list of todo items, and a form to add new items.
|
||||
|
||||
~~~rust
|
||||
struct TodoList<V: 'static> {
|
||||
headline: SharedString,
|
||||
items: Vec<TodoItem>,
|
||||
submit_form: ClickHandler<V>
|
||||
}
|
||||
|
||||
struct TodoItem<V: 'static> {
|
||||
text: SharedString,
|
||||
completed: bool,
|
||||
delete: ClickHandler<V>
|
||||
}
|
||||
|
||||
impl<V: 'static> TodoList<V> {
|
||||
pub fn new(
|
||||
// Here we impl Into<SharedString>
|
||||
headline: impl Into<SharedString>,
|
||||
items: Vec<TodoItem>,
|
||||
submit_form: ClickHandler<V>
|
||||
) -> Self {
|
||||
Self {
|
||||
// and here we call .into() so we can simply pass a string
|
||||
// when creating the headline. This pattern is used throughout
|
||||
// outr components
|
||||
headline: headline.into(),
|
||||
items: Vec::new(),
|
||||
submit_form,
|
||||
}
|
||||
}
|
||||
}
|
||||
~~~
|
||||
|
||||
All of this is relatively straightforward.
|
||||
|
||||
We use [gpui::SharedString] in components instead of [std::string::String]. This allows us to [TODO: someone who actually knows please explain why we use SharedString].
|
||||
|
||||
When we want to pass an action we pass a `ClickHandler`. Whenever we want to add an action, the struct it belongs to needs to be generic over the view type `V`.
|
||||
|
||||
~~~rust
|
||||
use gpui::hsla
|
||||
|
||||
impl<V: 'static> TodoList<V> {
|
||||
// ...
|
||||
fn render(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Element<V> {
|
||||
div().size_4().bg(hsla(50.0/360.0, 1.0, 0.5, 1.0))
|
||||
}
|
||||
}
|
||||
~~~
|
||||
|
||||
Every component needs a render method, and it should return `impl Element<V>`. This basic component will render a 16x16px yellow square on the screen.
|
||||
|
||||
A couple of questions might come to mind:
|
||||
|
||||
**Why is `size_4()` 16px, not 4px?**
|
||||
|
||||
gpui's style system is based on conventions created by [Tailwind CSS](https://tailwindcss.com/). Here is an example of the list of sizes for `width`: [Width - TailwindCSS Docs](https://tailwindcss.com/docs/width).
|
||||
|
||||
I'll quote from the Tailwind [Core Concepts](https://tailwindcss.com/docs/utility-first) docs here:
|
||||
|
||||
> Now I know what you’re thinking, “this is an atrocity, what a horrible mess!”
|
||||
> and you’re right, it’s kind of ugly. In fact it’s just about impossible to
|
||||
> think this is a good idea the first time you see it —
|
||||
> you have to actually try it.
|
||||
|
||||
As you start using the Tailwind-style conventions you will be surprised how quick it makes it to build out UIs.
|
||||
|
||||
**Why `50.0/360.0` in `hsla()`?**
|
||||
|
||||
gpui [gpui::Hsla] use `0.0-1.0` for all it's values, but it is common for tools to use `0-360` for hue.
|
||||
|
||||
This may change in the future, but this is a little trick that let's you use familiar looking values.
|
||||
|
||||
## Building out the container
|
||||
|
||||
Let's grab our [theme2::colors::ThemeColors] from the theme and start building out a basic container.
|
||||
|
||||
We can access the current theme's colors like this:
|
||||
|
||||
~~~rust
|
||||
impl<V: 'static> TodoList<V> {
|
||||
// ...
|
||||
fn render(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Element<V> {
|
||||
let color = cx.theme().colors()
|
||||
|
||||
div().size_4().hsla(50.0/360.0, 1.0, 0.5, 1.0)
|
||||
}
|
||||
}
|
||||
~~~
|
||||
|
||||
Now we have access to the complete set of colors defined in the theme.
|
||||
|
||||
~~~rust
|
||||
use gpui::hsla
|
||||
|
||||
impl<V: 'static> TodoList<V> {
|
||||
// ...
|
||||
fn render(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Element<V> {
|
||||
let color = cx.theme().colors()
|
||||
|
||||
div().size_4().bg(color.surface)
|
||||
}
|
||||
}
|
||||
~~~
|
||||
|
||||
Let's finish up some basic styles for the container then move on to adding the other elements.
|
||||
|
||||
~~~rust
|
||||
use gpui::hsla
|
||||
|
||||
impl<V: 'static> TodoList<V> {
|
||||
// ...
|
||||
fn render(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Element<V> {
|
||||
let color = cx.theme().colors()
|
||||
|
||||
div()
|
||||
// Flex properties
|
||||
.flex()
|
||||
.flex_col() // Stack elements vertically
|
||||
.gap_2() // Add 8px of space between elements
|
||||
// Size properties
|
||||
.w_96() // Set width to 384px
|
||||
.p_4() // Add 16px of padding on all sides
|
||||
// Color properties
|
||||
.bg(color.surface) // Set background color
|
||||
.text_color(color.text) // Set text color
|
||||
// Border properties
|
||||
.rounded_md() // Add 4px of border radius
|
||||
.border() // Add a 1px border
|
||||
.border_color(color.border)
|
||||
.child(
|
||||
"Hello, world!"
|
||||
)
|
||||
}
|
||||
}
|
||||
~~~
|
||||
|
||||
### Headline
|
||||
|
||||
TODO
|
||||
|
||||
### List of todo items
|
||||
|
||||
TODO
|
||||
|
||||
### Input
|
||||
|
||||
TODO
|
||||
|
||||
|
||||
### End result
|
||||
|
||||
TODO
|
||||
@@ -0,0 +1,25 @@
|
||||
## Documentation priorities:
|
||||
|
||||
These are the priorities to get documented, in a rough stack rank order:
|
||||
|
||||
- [ ] label
|
||||
- [ ] button
|
||||
- [ ] icon_button
|
||||
- [ ] icon
|
||||
- [ ] list
|
||||
- [ ] avatar
|
||||
- [ ] panel
|
||||
- [ ] modal
|
||||
- [ ] palette
|
||||
- [ ] input
|
||||
- [ ] facepile
|
||||
- [ ] player
|
||||
- [ ] stacks
|
||||
- [ ] context menu
|
||||
- [ ] input
|
||||
- [ ] textarea/multiline input (not built - not an editor)
|
||||
- [ ] indicator
|
||||
- [ ] public actor
|
||||
- [ ] keybinding
|
||||
- [ ] tab
|
||||
- [ ] toast
|
||||
Reference in New Issue
Block a user