docs: Improve docs add more details. (#1447)
- Also update "Compare to others", close #1452
This commit is contained in:
parent
4eb1ed2cfd
commit
d34ea6640a
19 changed files with 262 additions and 494 deletions
|
|
@ -114,7 +114,7 @@ Check out [CONTRIBUTING.md](CONTRIBUTING.md) for more details.
|
|||
|
||||
## Compare to others
|
||||
|
||||
| Features | GPUI Component | [Iced] | [egui] | [QT 6] |
|
||||
| Features | GPUI Component | [Iced] | [egui] | [Qt 6] |
|
||||
| --------------------- | ------------------------------ | ------------------ | --------------------- | ------------------------------------------------- |
|
||||
| Language | Rust | Rust | Rust | C++/QML |
|
||||
| Core Render | GPUI | wgpu | wgpu | QT |
|
||||
|
|
@ -135,7 +135,7 @@ Check out [CONTRIBUTING.md](CONTRIBUTING.md) for more details.
|
|||
| Markdown Rendering | Yes | Yes | Basic | No |
|
||||
| Markdown mix HTML | Yes | No | No | No |
|
||||
| HTML Rendering | Basic | No | No | Basic |
|
||||
| Text Selection | TextView | No | Any Label | No |
|
||||
| Text Selection | TextView | No | Any Label | Yes |
|
||||
| Custom Theme | Yes | Yes | Yes | Yes |
|
||||
| Built Themes | Yes | No | No | No |
|
||||
| I18n | Yes | Yes | Yes | Yes |
|
||||
|
|
|
|||
|
|
@ -93,13 +93,14 @@ const config: UserConfig = {
|
|||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
component: "GitHubStar",
|
||||
},
|
||||
],
|
||||
|
||||
sidebar: sidebar as any,
|
||||
|
||||
socialLinks: [
|
||||
{ icon: "github", link: "https://github.com/longbridge/gpui-component" },
|
||||
],
|
||||
socialLinks: null,
|
||||
editLink: {
|
||||
pattern:
|
||||
"https://github.com/longbridge/gpui-component/edit/main/docs/:path",
|
||||
|
|
|
|||
40
docs/.vitepress/theme/components/GitHubStar.vue
Normal file
40
docs/.vitepress/theme/components/GitHubStar.vue
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
<template>
|
||||
<a
|
||||
href="https://github.com/longbridge/gpui-component"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="github-star-button"
|
||||
:title="`${stargazers_count} stars on GitHub`"
|
||||
>
|
||||
<svg viewBox="0 0 438.549 438.549">
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M409.132 114.573c-19.608-33.596-46.205-60.194-79.798-79.8-33.598-19.607-70.277-29.408-110.063-29.408-39.781 0-76.472 9.804-110.063 29.408-33.596 19.605-60.192 46.204-79.8 79.8C9.803 148.168 0 184.854 0 224.63c0 47.78 13.94 90.745 41.827 128.906 27.884 38.164 63.906 64.572 108.063 79.227 5.14.954 8.945.283 11.419-1.996 2.475-2.282 3.711-5.14 3.711-8.562 0-.571-.049-5.708-.144-15.417a2549.81 2549.81 0 01-.144-25.406l-6.567 1.136c-4.187.767-9.469 1.092-15.846 1-6.374-.089-12.991-.757-19.842-1.999-6.854-1.231-13.229-4.086-19.13-8.559-5.898-4.473-10.085-10.328-12.56-17.556l-2.855-6.57c-1.903-4.374-4.899-9.233-8.992-14.559-4.093-5.331-8.232-8.945-12.419-10.848l-1.999-1.431c-1.332-.951-2.568-2.098-3.711-3.429-1.142-1.331-1.997-2.663-2.568-3.997-.572-1.335-.098-2.43 1.427-3.289 1.525-.859 4.281-1.276 8.28-1.276l5.708.853c3.807.763 8.516 3.042 14.133 6.851 5.614 3.806 10.229 8.754 13.846 14.842 4.38 7.806 9.657 13.754 15.846 17.847 6.184 4.093 12.419 6.136 18.699 6.136 6.28 0 11.704-.476 16.274-1.423 4.565-.952 8.848-2.383 12.847-4.285 1.713-12.758 6.377-22.559 13.988-29.41-10.848-1.14-20.601-2.857-29.264-5.14-8.658-2.286-17.605-5.996-26.835-11.14-9.235-5.137-16.896-11.516-22.985-19.126-6.09-7.614-11.088-17.61-14.987-29.979-3.901-12.374-5.852-26.648-5.852-42.826 0-23.035 7.52-42.637 22.557-58.817-7.044-17.318-6.379-36.732 1.997-58.24 5.52-1.715 13.706-.428 24.554 3.853 10.85 4.283 18.794 7.952 23.84 10.994 5.046 3.041 9.089 5.618 12.135 7.708 17.705-4.947 35.976-7.421 54.818-7.421s37.117 2.474 54.823 7.421l10.849-6.849c7.419-4.57 16.18-8.758 26.262-12.565 10.088-3.805 17.802-4.853 23.134-3.138 8.562 21.509 9.325 40.922 2.279 58.24 15.036 16.18 22.559 35.787 22.559 58.817 0 16.178-1.958 30.497-5.853 42.966-3.9 12.471-8.941 22.457-15.125 29.979-6.191 7.521-13.901 13.85-23.131 18.986-9.232 5.14-18.182 8.85-26.84 11.136-8.662 2.286-18.415 4.004-29.263 5.146 9.894 8.562 14.842 22.077 14.842 40.539v60.237c0 3.422 1.19 6.279 3.572 8.562 2.379 2.279 6.136 2.95 11.276 1.995 44.163-14.653 80.185-41.062 108.068-79.226 27.88-38.161 41.825-81.126 41.825-128.906-.01-39.771-9.818-76.454-29.414-110.049z"
|
||||
></path>
|
||||
</svg>
|
||||
<span>{{ starLabel }}</span>
|
||||
</a>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { data } from "../../../data/repo.data";
|
||||
let stargazers_count = data.stargazers_count;
|
||||
|
||||
const starLabel =
|
||||
stargazers_count / 1000 >= 1
|
||||
? (stargazers_count / 1000.0).toFixed(1) + "k"
|
||||
: stargazers_count.toString();
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@reference "../style.css";
|
||||
|
||||
.github-star-button {
|
||||
@apply flex w-full py-3 px-0 lg:inline-flex lg:w-auto lg:py-0 lg:px-2;
|
||||
@apply items-center text-sm gap-2 text-[var(--vp-c-text-1)] rounded hover:text-[var(--vp-c-brand-1)] no-underline;
|
||||
|
||||
svg {
|
||||
@apply w-5 h-5;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -3,7 +3,9 @@ import { h } from "vue";
|
|||
import type { Theme } from "vitepress";
|
||||
import DefaultTheme from "vitepress/theme";
|
||||
import "./style.css";
|
||||
import GitHubStar from "./components/GitHubStar.vue";
|
||||
|
||||
/** @type {import('vitepress').Theme} */
|
||||
export default {
|
||||
extends: DefaultTheme,
|
||||
Layout: () => {
|
||||
|
|
@ -13,5 +15,6 @@ export default {
|
|||
},
|
||||
enhanceApp({ app, router, siteData }) {
|
||||
// ...
|
||||
app.component("GitHubStar", GitHubStar);
|
||||
},
|
||||
} satisfies Theme;
|
||||
|
|
|
|||
|
|
@ -54,6 +54,8 @@
|
|||
--vp-custom-block-tip-text: var(--vp-c-text-1);
|
||||
--vp-custom-block-tip-bg: transparent;
|
||||
--vp-custom-block-tip-code-bg: var(--vp-c-default-soft);
|
||||
--vp-input-switch-bg-color: var(--secondary);
|
||||
--vp-input-border-color: var(--input);
|
||||
}
|
||||
|
||||
.dark {
|
||||
|
|
@ -94,6 +96,20 @@
|
|||
border-right: 1px solid var(--border);
|
||||
}
|
||||
|
||||
#app {
|
||||
.VPMenu {
|
||||
@apply p-1 rounded-md bg-[var(--popover)];
|
||||
|
||||
.link {
|
||||
@apply text-sm py-1;
|
||||
}
|
||||
}
|
||||
|
||||
.DocSearch-Button {
|
||||
@apply rounded-md py-0 px-2 h-8 lg:w-56 xl:w-64;
|
||||
}
|
||||
}
|
||||
|
||||
.vp-doc {
|
||||
[class*="language-"] pre {
|
||||
@apply rounded-md py-5 text-base font-mono;
|
||||
|
|
|
|||
|
|
@ -22,18 +22,8 @@
|
|||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted } from "vue";
|
||||
|
||||
const IGNORE_LOGINS = ["dependabot[bot]", "copilot"];
|
||||
let contributors = ref([]);
|
||||
fetch("https://api.github.com/repos/longbridge/gpui-component/contributors")
|
||||
.then((res) => res.json())
|
||||
.then((items) => {
|
||||
let filtered = items.filter(
|
||||
(item) => !IGNORE_LOGINS.includes(item.login.toLowerCase()),
|
||||
);
|
||||
contributors.value = filtered.slice(0, 24);
|
||||
});
|
||||
import { data } from "./data/contributors.data";
|
||||
const contributors = data;
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
|
|
|||
16
docs/data/contributors.data.js
Normal file
16
docs/data/contributors.data.js
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
const IGNORE_LOGINS = ["dependabot[bot]", "copilot"];
|
||||
const API_URL =
|
||||
"https://api.github.com/repos/longbridge/gpui-component/contributors";
|
||||
|
||||
export default {
|
||||
async load() {
|
||||
return await fetch(API_URL)
|
||||
.then((res) => res.json())
|
||||
.then((items) => {
|
||||
let filtered = items.filter(
|
||||
(item) => !IGNORE_LOGINS.includes(item.login.toLowerCase()),
|
||||
);
|
||||
return filtered.slice(0, 24);
|
||||
});
|
||||
},
|
||||
};
|
||||
7
docs/data/repo.data.js
Normal file
7
docs/data/repo.data.js
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
const API_URL = "https://api.github.com/repos/longbridge/gpui-component";
|
||||
|
||||
export default {
|
||||
async load() {
|
||||
return await fetch(API_URL).then((res) => res.json());
|
||||
},
|
||||
};
|
||||
|
|
@ -86,29 +86,12 @@ Accordion::new("my-accordion")
|
|||
|
||||
## API Reference
|
||||
|
||||
### Accordion
|
||||
|
||||
| Method | Description |
|
||||
| --------------------- | -------------------------------------------------------------------- |
|
||||
| `new(id)` | Create a new accordion with the given ID |
|
||||
| `multiple(bool)` | Allow multiple items to be open simultaneously |
|
||||
| `bordered(bool)` | Show borders around accordion items |
|
||||
| `disabled(bool)` | Disable all accordion items |
|
||||
| `item(fn)` | Add an accordion item using a builder function |
|
||||
| `on_toggle_click(fn)` | Callback when items are toggled, receives `&[usize]` of open indices |
|
||||
|
||||
### AccordionItem
|
||||
|
||||
| Method | Description |
|
||||
| ---------------- | --------------------------------- |
|
||||
| `header(str)` | Set the header text |
|
||||
| `child(el)` | Add content to the accordion item |
|
||||
| `open(bool)` | Set initial open state |
|
||||
| `disabled(bool)` | Disable this specific item |
|
||||
- [Accordion]
|
||||
- [AccordionItem]
|
||||
|
||||
### Sizing
|
||||
|
||||
Implements `Sizable` trait:
|
||||
Implements [Sizable] trait:
|
||||
|
||||
- `small()` - Small size
|
||||
- `medium()` - Medium size (default)
|
||||
|
|
@ -145,3 +128,7 @@ Accordion::new("outer")
|
|||
)
|
||||
})
|
||||
```
|
||||
|
||||
[Accordion]: https://docs.rs/gpui-component/latest/gpui_component/accordion/struct.Accordion.html
|
||||
[AccordionItem]: https://docs.rs/gpui-component/latest/gpui_component/accordion/struct.AccordionItem.html
|
||||
[Sizable]: https://docs.rs/gpui-component/latest/gpui_component/trait.Sizable.html
|
||||
|
|
|
|||
|
|
@ -51,25 +51,27 @@ Alert::error("error-alert", "An error occurred while processing your request.")
|
|||
### Alert Sizes
|
||||
|
||||
```rust
|
||||
Alert::info("alert", "Message content")
|
||||
.with_size(Size::XSmall) // Extra small
|
||||
.title("XSmall Alert")
|
||||
use gpui_component::{alert::Alert, Sizable as _};
|
||||
|
||||
Alert::info("alert", "Message content")
|
||||
.with_size(Size::Small) // Small
|
||||
.xsmall()
|
||||
.title("XSmall Alert")
|
||||
Alert::info("alert", "Message content")
|
||||
.small()
|
||||
.title("Small Alert")
|
||||
|
||||
Alert::info("alert", "Message content")
|
||||
.with_size(Size::Medium) // Medium (default)
|
||||
.title("Medium Alert")
|
||||
|
||||
Alert::info("alert", "Message content")
|
||||
.with_size(Size::Large) // Large
|
||||
.large()
|
||||
.title("Large Alert")
|
||||
```
|
||||
|
||||
### Closable Alerts
|
||||
|
||||
When you add an `on_close` handler, a close button appears on the alert:
|
||||
|
||||
```rust
|
||||
Alert::info("closable-alert", "This alert can be dismissed.")
|
||||
.title("Dismissible")
|
||||
|
|
@ -140,40 +142,7 @@ Alert::info("conditional-alert", "This alert may be hidden.")
|
|||
|
||||
## API Reference
|
||||
|
||||
### Alert Methods
|
||||
|
||||
| Method | Description |
|
||||
| ---------------------- | --------------------------------------------------- |
|
||||
| `new(id, message)` | Create a new alert with default (secondary) variant |
|
||||
| `info(id, message)` | Create an info alert with blue styling |
|
||||
| `success(id, message)` | Create a success alert with green styling |
|
||||
| `warning(id, message)` | Create a warning alert with yellow/orange styling |
|
||||
| `error(id, message)` | Create an error alert with red styling |
|
||||
| `title(text)` | Set the alert title (not shown in banner mode) |
|
||||
| `icon(icon)` | Set a custom icon for the alert |
|
||||
| `banner()` | Enable banner mode (full width, no title) |
|
||||
| `on_close(callback)` | Make alert closable with close button |
|
||||
| `visible(bool)` | Control alert visibility |
|
||||
| `with_size(size)` | Set alert size (XSmall, Small, Medium, Large) |
|
||||
|
||||
### Alert Variants
|
||||
|
||||
| Variant | Description | Default Icon |
|
||||
| ----------- | ----------------------------- | ------------- |
|
||||
| `Secondary` | Default gray styling | Info |
|
||||
| `Info` | Blue informational styling | Info |
|
||||
| `Success` | Green success styling | CircleCheck |
|
||||
| `Warning` | Yellow/orange warning styling | TriangleAlert |
|
||||
| `Error` | Red error styling | CircleX |
|
||||
|
||||
### Size Options
|
||||
|
||||
| Size | Padding | Gap | Border Radius |
|
||||
| -------- | --------- | ---- | ------------- |
|
||||
| `XSmall` | 12px/6px | 6px | Default |
|
||||
| `Small` | 12px/8px | 6px | Default |
|
||||
| `Medium` | 16px/10px | 12px | Default |
|
||||
| `Large` | 20px/14px | 12px | Large |
|
||||
- [Alert]
|
||||
|
||||
## Examples
|
||||
|
||||
|
|
@ -188,7 +157,6 @@ Alert::error(
|
|||
- Terms of service must be accepted"
|
||||
)
|
||||
.title("Validation Failed")
|
||||
.with_size(Size::Medium)
|
||||
```
|
||||
|
||||
### Success Notification
|
||||
|
|
@ -210,7 +178,7 @@ Alert::warning(
|
|||
Some services may be temporarily unavailable."
|
||||
)
|
||||
.banner()
|
||||
.with_size(Size::Large)
|
||||
.large()
|
||||
```
|
||||
|
||||
### Interactive Alert with Custom Action
|
||||
|
|
@ -245,3 +213,5 @@ Alert::warning(
|
|||
.title("Security Alert")
|
||||
.icon(IconName::Shield)
|
||||
```
|
||||
|
||||
[Alert]: https://docs.rs/gpui-component/latest/gpui_component/alert/struct.Alert.html
|
||||
|
|
|
|||
|
|
@ -17,11 +17,12 @@ use gpui_component::avatar::{Avatar, AvatarGroup};
|
|||
|
||||
### Basic Avatar
|
||||
|
||||
You can create an [Avatar] by providing an image source URL and a user name:
|
||||
|
||||
```rust
|
||||
// Avatar with image
|
||||
Avatar::new()
|
||||
.src("https://example.com/avatar.jpg")
|
||||
.name("John Doe")
|
||||
.src("https://example.com/avatar.jpg")
|
||||
```
|
||||
|
||||
### Avatar with Fallback Text
|
||||
|
|
@ -91,7 +92,7 @@ Avatar::new()
|
|||
|
||||
## AvatarGroup
|
||||
|
||||
Display multiple avatars in a compact, overlapping layout:
|
||||
The [AvatarGroup] component allows you to display multiple avatars in a compact, overlapping layout:
|
||||
|
||||
### Basic Group
|
||||
|
||||
|
|
@ -117,7 +118,9 @@ AvatarGroup::new()
|
|||
|
||||
### Group with Ellipsis
|
||||
|
||||
Show an ellipsis indicator when avatars are hidden due to the limit:
|
||||
Show an ellipsis indicator when avatars are hidden due to the limit.
|
||||
|
||||
In this example, only 3 avatars are shown, and "..." indicates there are more:
|
||||
|
||||
```rust
|
||||
AvatarGroup::new()
|
||||
|
|
@ -132,6 +135,8 @@ AvatarGroup::new()
|
|||
|
||||
### Group Sizes
|
||||
|
||||
The [Sizeable] trait can also be applied to AvatarGroup, and it will set the size for all contained avatars.
|
||||
|
||||
```rust
|
||||
// Extra small group
|
||||
AvatarGroup::new()
|
||||
|
|
@ -175,44 +180,8 @@ AvatarGroup::new()
|
|||
|
||||
## API Reference
|
||||
|
||||
### Avatar
|
||||
|
||||
| Method | Description |
|
||||
| ------------------- | ------------------------------------------ |
|
||||
| `new()` | Create a new avatar |
|
||||
| `src(source)` | Set image source (ImageSource) |
|
||||
| `name(name)` | Set user name (used for initials fallback) |
|
||||
| `placeholder(icon)` | Set placeholder icon (default: User icon) |
|
||||
|
||||
### Avatar Sizes (via Sizable trait)
|
||||
|
||||
| Method | Description |
|
||||
| ------------------- | --------------------- |
|
||||
| `xsmall()` | 20px avatar |
|
||||
| `small()` | 24px avatar |
|
||||
| `medium()` | 48px avatar (default) |
|
||||
| `large()` | 80px avatar |
|
||||
| `with_size(pixels)` | Custom size in pixels |
|
||||
|
||||
### AvatarGroup
|
||||
|
||||
| Method | Description |
|
||||
| ------------------- | --------------------------------------- |
|
||||
| `new()` | Create a new avatar group |
|
||||
| `child(avatar)` | Add single avatar to group |
|
||||
| `children(avatars)` | Add multiple avatars to group |
|
||||
| `limit(count)` | Maximum avatars to display (default: 3) |
|
||||
| `ellipsis()` | Show "..." when limit exceeded |
|
||||
|
||||
### AvatarGroup Sizes (via Sizable trait)
|
||||
|
||||
| Method | Description |
|
||||
| ----------------- | ------------------------------- |
|
||||
| `xsmall()` | Group of 20px avatars |
|
||||
| `small()` | Group of 24px avatars |
|
||||
| `medium()` | Group of 48px avatars (default) |
|
||||
| `large()` | Group of 80px avatars |
|
||||
| `with_size(size)` | Custom size for all avatars |
|
||||
- [Avatar]
|
||||
- [AvatarGroup]
|
||||
|
||||
## Examples
|
||||
|
||||
|
|
@ -276,3 +245,7 @@ Avatar::new().name("Alice") // Gets one color
|
|||
Avatar::new().name("Bob") // Gets a different color
|
||||
Avatar::new().name("Charlie") // Gets another color
|
||||
```
|
||||
|
||||
[Avatar]: https://docs.rs/gpui-component/latest/gpui_component/avatar/struct.Avatar.html
|
||||
[AvatarGroup]: https://docs.rs/gpui-component/latest/gpui_component/avatar/struct.AvatarGroup.html
|
||||
[Sizable]: https://docs.rs/gpui-component/latest/gpui_component/trait.Sizable.html
|
||||
|
|
|
|||
|
|
@ -15,7 +15,11 @@ use gpui_component::badge::Badge;
|
|||
|
||||
## Usage
|
||||
|
||||
### Basic Badge with Count
|
||||
### Badge with Count
|
||||
|
||||
Use `count` to display a numeric badge, if the count is greater than zero (`> 0`) the badge will be shown, otherwise it will be hidden.
|
||||
|
||||
There is a default maximum count of `99`, any count above this will be displayed as `99+`. You can customize this maximum using the [max](https://docs.rs/gpui-component/latest/gpui_component/badge/struct.Badge.html#method.max) method.
|
||||
|
||||
```rust
|
||||
Badge::new()
|
||||
|
|
@ -23,7 +27,11 @@ Badge::new()
|
|||
.child(Icon::new(IconName::Bell))
|
||||
```
|
||||
|
||||
### Badge Variants
|
||||
### Variants
|
||||
|
||||
- Default: Displays a numeric count.
|
||||
- Dot: A small dot indicator, typically used for status.
|
||||
- Icon: Displays an icon instead of a number.
|
||||
|
||||
```rust
|
||||
// Number badge (default)
|
||||
|
|
@ -44,6 +52,8 @@ Badge::new()
|
|||
|
||||
### Badge Sizes
|
||||
|
||||
The Badge is also implemented with the [Sizable] trait, allowing you to set small, medium (default), or large sizes.
|
||||
|
||||
```rust
|
||||
// Small badge
|
||||
Badge::new()
|
||||
|
|
@ -161,26 +171,7 @@ Badge::new()
|
|||
|
||||
## API Reference
|
||||
|
||||
### Badge
|
||||
|
||||
| Method | Description |
|
||||
| ---------------- | -------------------------------------------- |
|
||||
| `new()` | Create a new badge |
|
||||
| `count(usize)` | Set the count to display (0 hides the badge) |
|
||||
| `dot()` | Display as a small dot indicator |
|
||||
| `icon(icon)` | Display an icon instead of count |
|
||||
| `max(usize)` | Set maximum count to show (default: 99) |
|
||||
| `color(color)` | Set badge background color |
|
||||
| `child(element)` | Add child element to position badge on |
|
||||
|
||||
### Size Methods (from Sizable trait)
|
||||
|
||||
| Method | Description |
|
||||
| ----------------- | --------------------------------- |
|
||||
| `small()` | Small badge size (10px) |
|
||||
| `medium()` | Medium badge size (16px, default) |
|
||||
| `large()` | Large badge size (24px) |
|
||||
| `with_size(size)` | Custom size |
|
||||
- [Badge]
|
||||
|
||||
## Examples
|
||||
|
||||
|
|
@ -251,3 +242,6 @@ Badge::new().count(1000).max(999) // Shows "999+"
|
|||
// Zero count hides the badge
|
||||
Badge::new().count(0) // Badge not visible
|
||||
```
|
||||
|
||||
[Badge]: https://docs.rs/gpui_component/latest/gpui_component/badge/struct.Badge.html
|
||||
[Sizable]: https://docs.rs/gpui-component/latest/gpui_component/trait.Sizable.html
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ description: Displays a button or a component that looks like a button.
|
|||
|
||||
# Button
|
||||
|
||||
A versatile button component with multiple variants, sizes, and states. Supports icons, loading states, and can be grouped together.
|
||||
The [Button] element with multiple variants, sizes, and states. Supports icons, loading states, and can be grouped together.
|
||||
|
||||
## Import
|
||||
|
||||
|
|
@ -25,7 +25,7 @@ Button::new("my-button")
|
|||
})
|
||||
```
|
||||
|
||||
### Button Variants
|
||||
### Variants
|
||||
|
||||
```rust
|
||||
// Primary button
|
||||
|
|
@ -58,12 +58,27 @@ Button::new("btn-text").text().label("Text")
|
|||
|
||||
### Outline Buttons
|
||||
|
||||
Outline style is not a variant itself, but can be combined with other variants.
|
||||
|
||||
```rust
|
||||
Button::new("btn").primary().outline().label("Primary Outline")
|
||||
Button::new("btn").danger().outline().label("Danger Outline")
|
||||
```
|
||||
|
||||
### Button Sizes
|
||||
### Compact Button
|
||||
|
||||
The `compact` method reduces the padding of the button for a more condensed appearance.
|
||||
|
||||
```rust
|
||||
// Compact (reduced padding)
|
||||
Button::new("btn")
|
||||
.label("Compact")
|
||||
.compact()
|
||||
```
|
||||
|
||||
### Sizeable
|
||||
|
||||
The Button supports the [Sizable] trait for different sizes.
|
||||
|
||||
```rust
|
||||
Button::new("btn").xsmall().label("Extra Small")
|
||||
|
|
@ -94,6 +109,8 @@ Button::new("btn")
|
|||
|
||||
### Button States
|
||||
|
||||
There have `disabled`, `loading`, `selected` state for buttons to indicate different statuses.
|
||||
|
||||
```rust
|
||||
// Disabled
|
||||
Button::new("btn")
|
||||
|
|
@ -109,14 +126,9 @@ Button::new("btn")
|
|||
Button::new("btn")
|
||||
.label("Selected")
|
||||
.selected(true)
|
||||
|
||||
// Compact (reduced padding)
|
||||
Button::new("btn")
|
||||
.label("Compact")
|
||||
.compact()
|
||||
```
|
||||
|
||||
### Button Group
|
||||
## Button Group
|
||||
|
||||
```rust
|
||||
ButtonGroup::new("btn-group")
|
||||
|
|
@ -138,7 +150,7 @@ ButtonGroup::new("toggle-group")
|
|||
})
|
||||
```
|
||||
|
||||
### Dropdown Button
|
||||
## Dropdown Button
|
||||
|
||||
```rust
|
||||
use gpui::Corner;
|
||||
|
|
@ -160,7 +172,7 @@ DropdownButton::new("dropdown")
|
|||
})
|
||||
```
|
||||
|
||||
### Custom Variant
|
||||
## Custom Variant
|
||||
|
||||
```rust
|
||||
use gpui_component::button::ButtonCustomVariant;
|
||||
|
|
@ -179,57 +191,10 @@ Button::new("custom-btn")
|
|||
|
||||
## API Reference
|
||||
|
||||
### Button
|
||||
|
||||
| Method | Description |
|
||||
| -------------------- | ------------------------------------- |
|
||||
| `new(id)` | Create a new button with the given ID |
|
||||
| `label(str)` | Set button label text |
|
||||
| `icon(icon)` | Add icon to button (before label) |
|
||||
| `loading_icon(icon)` | Custom loading icon |
|
||||
| `child(el)` | Add custom child element |
|
||||
| `on_click(fn)` | Click event handler |
|
||||
| `on_hover(fn)` | Hover event handler |
|
||||
| `disabled(bool)` | Set disabled state |
|
||||
| `loading(bool)` | Set loading state |
|
||||
| `selected(bool)` | Set selected state |
|
||||
| `compact()` | Reduce padding |
|
||||
|
||||
### Button Variants
|
||||
|
||||
| Method | Description |
|
||||
| ----------------- | -------------------------------------- |
|
||||
| `primary()` | Primary button style |
|
||||
| `danger()` | Danger button style |
|
||||
| `warning()` | Warning button style |
|
||||
| `success()` | Success button style |
|
||||
| `info()` | Info button style |
|
||||
| `ghost()` | Ghost button style |
|
||||
| `link()` | Link button style |
|
||||
| `text()` | Text button style |
|
||||
| `outline()` | Outline style (combines with variants) |
|
||||
| `custom(variant)` | Custom variant |
|
||||
|
||||
### ButtonGroup
|
||||
|
||||
| Method | Description |
|
||||
| ---------------- | ---------------------------------- |
|
||||
| `new(id)` | Create a new button group |
|
||||
| `child(button)` | Add button to group |
|
||||
| `multiple(bool)` | Allow multiple selections |
|
||||
| `compact()` | Compact spacing |
|
||||
| `outline()` | Apply outline style to all buttons |
|
||||
| `disabled(bool)` | Disable all buttons |
|
||||
| `on_click(fn)` | Called with selected indices |
|
||||
|
||||
### DropdownButton
|
||||
|
||||
| Method | Description |
|
||||
| --------------------------------------- | ----------------------------- |
|
||||
| `new(id)` | Create a new dropdown button |
|
||||
| `button(btn)` | Set the trigger button |
|
||||
| `dropdown_menu(fn)` | Set dropdown menu builder |
|
||||
| `dropdown_menu_with_anchor(corner, fn)` | Set menu with anchor position |
|
||||
- [Button]
|
||||
- [ButtonGroup]
|
||||
- [DropdownButton]
|
||||
- [ButtonCustomVariant]
|
||||
|
||||
## Examples
|
||||
|
||||
|
|
@ -254,3 +219,9 @@ Button::new("btn")
|
|||
.child(IconName::Eye)
|
||||
)
|
||||
```
|
||||
|
||||
[Button]: https://docs.rs/gpui-component/latest/gpui_component/button/struct.Button.html
|
||||
[ButtonGroup]: https://docs.rs/gpui-component/latest/gpui_component/button/struct.ButtonGroup.html
|
||||
[DropdownButton]: https://docs.rs/gpui-component/latest/gpui_component/button/struct.DropdownButton.html
|
||||
[ButtonCustomVariant]: https://docs.rs/gpui-component/latest/gpui_component/button/struct.ButtonCustomVariant.html
|
||||
[Sizable]: https://docs.rs/gpui-component/latest/gpui_component/trait.Sizable.html
|
||||
|
|
|
|||
|
|
@ -7,6 +7,9 @@ description: A flexible calendar component for displaying months, navigating dat
|
|||
|
||||
A standalone calendar component that provides a rich interface for date selection and navigation. The Calendar component supports single date selection, date range selection, multiple month views, custom disabled dates, and comprehensive keyboard navigation.
|
||||
|
||||
- [CalendarState]: For managing calendar state and selection.
|
||||
- [Calendar]: For rendering the calendar UI.
|
||||
|
||||
## Import
|
||||
|
||||
```rust
|
||||
|
|
@ -20,9 +23,8 @@ use gpui_component::{
|
|||
### Basic Calendar
|
||||
|
||||
```rust
|
||||
let calendar = cx.new(|cx| CalendarState::new(window, cx));
|
||||
|
||||
Calendar::new(&calendar)
|
||||
let state = cx.new(|cx| CalendarState::new(window, cx));
|
||||
Calendar::new(&state)
|
||||
```
|
||||
|
||||
### Calendar with Initial Date
|
||||
|
|
@ -30,13 +32,13 @@ Calendar::new(&calendar)
|
|||
```rust
|
||||
use chrono::Local;
|
||||
|
||||
let calendar = cx.new(|cx| {
|
||||
let state = cx.new(|cx| {
|
||||
let mut state = CalendarState::new(window, cx);
|
||||
state.set_date(Local::now().naive_local().date(), window, cx);
|
||||
state
|
||||
});
|
||||
|
||||
Calendar::new(&calendar)
|
||||
Calendar::new(&state)
|
||||
```
|
||||
|
||||
### Date Range Calendar
|
||||
|
|
@ -44,7 +46,7 @@ Calendar::new(&calendar)
|
|||
```rust
|
||||
use chrono::{Local, Days};
|
||||
|
||||
let calendar = cx.new(|cx| {
|
||||
let state = cx.new(|cx| {
|
||||
let mut state = CalendarState::new(window, cx);
|
||||
let now = Local::now().naive_local().date();
|
||||
state.set_date(
|
||||
|
|
@ -55,27 +57,27 @@ let calendar = cx.new(|cx| {
|
|||
state
|
||||
});
|
||||
|
||||
Calendar::new(&calendar)
|
||||
Calendar::new(&state)
|
||||
```
|
||||
|
||||
### Multiple Months Display
|
||||
|
||||
```rust
|
||||
// Show 2 months side by side
|
||||
Calendar::new(&calendar)
|
||||
Calendar::new(&state)
|
||||
.number_of_months(2)
|
||||
|
||||
// Show 3 months
|
||||
Calendar::new(&calendar)
|
||||
Calendar::new(&state)
|
||||
.number_of_months(3)
|
||||
```
|
||||
|
||||
### Calendar Sizes
|
||||
|
||||
```rust
|
||||
Calendar::new(&calendar).large()
|
||||
Calendar::new(&calendar) // medium (default)
|
||||
Calendar::new(&calendar).small()
|
||||
Calendar::new(&state).large()
|
||||
Calendar::new(&state) // medium (default)
|
||||
Calendar::new(&state).small()
|
||||
```
|
||||
|
||||
## Date Restrictions
|
||||
|
|
@ -83,24 +85,24 @@ Calendar::new(&calendar).small()
|
|||
### Disabled Weekends
|
||||
|
||||
```rust
|
||||
let calendar = cx.new(|cx| {
|
||||
let state = cx.new(|cx| {
|
||||
CalendarState::new(window, cx)
|
||||
.disabled_matcher(vec![0, 6]) // Sunday=0, Saturday=6
|
||||
});
|
||||
|
||||
Calendar::new(&calendar)
|
||||
Calendar::new(&state)
|
||||
```
|
||||
|
||||
### Disabled Specific Weekdays
|
||||
|
||||
```rust
|
||||
// Disable Sundays, Wednesdays, and Saturdays
|
||||
let calendar = cx.new(|cx| {
|
||||
let state = cx.new(|cx| {
|
||||
CalendarState::new(window, cx)
|
||||
.disabled_matcher(vec![0, 3, 6])
|
||||
});
|
||||
|
||||
Calendar::new(&calendar)
|
||||
Calendar::new(&state)
|
||||
```
|
||||
|
||||
### Disabled Date Range
|
||||
|
|
@ -110,7 +112,7 @@ use chrono::{Local, Days};
|
|||
|
||||
let now = Local::now().naive_local().date();
|
||||
|
||||
let calendar = cx.new(|cx| {
|
||||
let state = cx.new(|cx| {
|
||||
CalendarState::new(window, cx)
|
||||
.disabled_matcher(Matcher::range(
|
||||
Some(now),
|
||||
|
|
@ -118,14 +120,14 @@ let calendar = cx.new(|cx| {
|
|||
))
|
||||
});
|
||||
|
||||
Calendar::new(&calendar)
|
||||
Calendar::new(&state)
|
||||
```
|
||||
|
||||
### Disabled Date Interval
|
||||
|
||||
```rust
|
||||
// Disable dates outside the interval (before/after specified dates)
|
||||
let calendar = cx.new(|cx| {
|
||||
let state = cx.new(|cx| {
|
||||
CalendarState::new(window, cx)
|
||||
.disabled_matcher(Matcher::interval(
|
||||
Some(now.checked_sub_days(Days::new(30)).unwrap()),
|
||||
|
|
@ -133,41 +135,41 @@ let calendar = cx.new(|cx| {
|
|||
))
|
||||
});
|
||||
|
||||
Calendar::new(&calendar)
|
||||
Calendar::new(&state)
|
||||
```
|
||||
|
||||
### Custom Disabled Dates
|
||||
|
||||
```rust
|
||||
// Disable first 5 days of each month
|
||||
let calendar = cx.new(|cx| {
|
||||
let state = cx.new(|cx| {
|
||||
CalendarState::new(window, cx)
|
||||
.disabled_matcher(Matcher::custom(|date| {
|
||||
date.day0() < 5 // day0() returns 0-based day
|
||||
}))
|
||||
});
|
||||
|
||||
Calendar::new(&calendar)
|
||||
Calendar::new(&state)
|
||||
|
||||
// Disable all Mondays
|
||||
let calendar = cx.new(|cx| {
|
||||
let state = cx.new(|cx| {
|
||||
CalendarState::new(window, cx)
|
||||
.disabled_matcher(Matcher::custom(|date| {
|
||||
date.weekday() == chrono::Weekday::Mon
|
||||
}))
|
||||
});
|
||||
|
||||
Calendar::new(&calendar)
|
||||
Calendar::new(&state)
|
||||
|
||||
// Disable past dates
|
||||
let calendar = cx.new(|cx| {
|
||||
let state = cx.new(|cx| {
|
||||
CalendarState::new(window, cx)
|
||||
.disabled_matcher(Matcher::custom(|date| {
|
||||
*date < Local::now().naive_local().date()
|
||||
}))
|
||||
});
|
||||
|
||||
Calendar::new(&calendar)
|
||||
Calendar::new(&state)
|
||||
```
|
||||
|
||||
## Month/Year Navigation
|
||||
|
|
@ -182,20 +184,20 @@ The Calendar automatically provides navigation controls:
|
|||
### Custom Year Range
|
||||
|
||||
```rust
|
||||
let calendar = cx.new(|cx| {
|
||||
let state = cx.new(|cx| {
|
||||
CalendarState::new(window, cx)
|
||||
.year_range((2020, 2030)) // Limit to specific year range
|
||||
});
|
||||
|
||||
Calendar::new(&calendar)
|
||||
Calendar::new(&state)
|
||||
```
|
||||
|
||||
## Handle Selection Events
|
||||
|
||||
```rust
|
||||
let calendar = cx.new(|cx| CalendarState::new(window, cx));
|
||||
let state = cx.new(|cx| CalendarState::new(window, cx));
|
||||
|
||||
cx.subscribe(&calendar, |view, _, event, _| {
|
||||
cx.subscribe(&state, |view, _, event, _| {
|
||||
match event {
|
||||
CalendarEvent::Selected(date) => {
|
||||
match date {
|
||||
|
|
@ -216,7 +218,7 @@ cx.subscribe(&calendar, |view, _, event, _| {
|
|||
}
|
||||
});
|
||||
|
||||
Calendar::new(&calendar)
|
||||
Calendar::new(&state)
|
||||
```
|
||||
|
||||
## Advanced Examples
|
||||
|
|
@ -226,14 +228,14 @@ Calendar::new(&calendar)
|
|||
```rust
|
||||
use chrono::Weekday;
|
||||
|
||||
let business_calendar = cx.new(|cx| {
|
||||
let state = cx.new(|cx| {
|
||||
CalendarState::new(window, cx)
|
||||
.disabled_matcher(Matcher::custom(|date| {
|
||||
matches!(date.weekday(), Weekday::Sat | Weekday::Sun)
|
||||
}))
|
||||
});
|
||||
|
||||
Calendar::new(&business_calendar)
|
||||
Calendar::new(&state)
|
||||
```
|
||||
|
||||
### Holiday Calendar
|
||||
|
|
@ -249,36 +251,36 @@ let holidays: HashSet<NaiveDate> = [
|
|||
NaiveDate::from_ymd_opt(2024, 12, 25).unwrap(), // Christmas
|
||||
].into_iter().collect();
|
||||
|
||||
let holiday_calendar = cx.new(|cx| {
|
||||
let state = cx.new(|cx| {
|
||||
CalendarState::new(window, cx)
|
||||
.disabled_matcher(Matcher::custom(move |date| {
|
||||
holidays.contains(date)
|
||||
}))
|
||||
});
|
||||
|
||||
Calendar::new(&holiday_calendar)
|
||||
Calendar::new(&state)
|
||||
```
|
||||
|
||||
### Multi-Month Range Selector
|
||||
|
||||
```rust
|
||||
let range_calendar = cx.new(|cx| {
|
||||
let state = cx.new(|cx| {
|
||||
let mut state = CalendarState::new(window, cx);
|
||||
state.set_date(Date::Range(None, None), window, cx); // Range mode
|
||||
state
|
||||
});
|
||||
|
||||
Calendar::new(&range_calendar)
|
||||
Calendar::new(&state)
|
||||
.number_of_months(3) // Show 3 months for easier range selection
|
||||
```
|
||||
|
||||
### Quarterly View Calendar
|
||||
|
||||
```rust
|
||||
let quarterly_calendar = cx.new(|cx| CalendarState::new(window, cx));
|
||||
let state = cx.new(|cx| CalendarState::new(window, cx));
|
||||
|
||||
// Update to show current quarter's months
|
||||
Calendar::new(&quarterly_calendar)
|
||||
Calendar::new(&state)
|
||||
.number_of_months(3)
|
||||
```
|
||||
|
||||
|
|
@ -299,115 +301,9 @@ Calendar::new(&calendar)
|
|||
|
||||
## API Reference
|
||||
|
||||
### CalendarState
|
||||
|
||||
| Method | Description |
|
||||
| ----------------------------------------- | ----------------------------------- |
|
||||
| `new(window, cx)` | Create a new calendar state |
|
||||
| `disabled_matcher(matcher)` | Set date disabling rules |
|
||||
| `set_date(date, window, cx)` | Set selected date programmatically |
|
||||
| `date()` | Get current selected date |
|
||||
| `set_number_of_months(count, window, cx)` | Set number of months to display |
|
||||
| `year_range(range)` | Set available year range (min, max) |
|
||||
|
||||
### Calendar
|
||||
|
||||
| Method | Description |
|
||||
| ------------------------- | ---------------------------------------- |
|
||||
| `new(state)` | Create calendar with state entity |
|
||||
| `number_of_months(count)` | Set number of months to display |
|
||||
| `with_size(size)` | Set calendar size (Small, Medium, Large) |
|
||||
| `large()` | Large size variant |
|
||||
| `small()` | Small size variant |
|
||||
|
||||
### Date
|
||||
|
||||
| Variant | Description |
|
||||
| --------------------------------------------- | -------------------------- |
|
||||
| `Single(Option<NaiveDate>)` | Single date selection mode |
|
||||
| `Range(Option<NaiveDate>, Option<NaiveDate>)` | Date range selection mode |
|
||||
|
||||
| Method | Description |
|
||||
| -------------------- | -------------------------------------- |
|
||||
| `is_active(date)` | Check if date is currently selected |
|
||||
| `is_single()` | Check if in single date mode |
|
||||
| `is_in_range(date)` | Check if date is within selected range |
|
||||
| `is_some()` | Check if any date is selected |
|
||||
| `is_complete()` | Check if selection is complete |
|
||||
| `start()` | Get start date of selection |
|
||||
| `end()` | Get end date of selection |
|
||||
| `format(format_str)` | Format date(s) using chrono format |
|
||||
|
||||
### Matcher
|
||||
|
||||
| Variant | Description |
|
||||
| ----------------------------------------- | ------------------------------------------------ |
|
||||
| `DayOfWeek(Vec<u32>)` | Disable specific weekdays (0=Sunday, 6=Saturday) |
|
||||
| `Interval(IntervalMatcher)` | Disable dates outside interval |
|
||||
| `Range(RangeMatcher)` | Disable dates within range |
|
||||
| `Custom(Box<dyn Fn(&NaiveDate) -> bool>)` | Custom disable function |
|
||||
|
||||
| Method | Description |
|
||||
| ------------------------- | -------------------------------------- |
|
||||
| `interval(before, after)` | Create interval matcher |
|
||||
| `range(from, to)` | Create range matcher |
|
||||
| `custom(fn)` | Create custom matcher |
|
||||
| `matched(date)` | Check if date matches the matcher |
|
||||
| `date_matched(date)` | Check if Date enum matches the matcher |
|
||||
|
||||
### CalendarEvent
|
||||
|
||||
| Event | Description |
|
||||
| ---------------- | ------------------------------- |
|
||||
| `Selected(Date)` | Date or range selection changed |
|
||||
|
||||
## Size Variants
|
||||
|
||||
| Size | Description | Dimensions |
|
||||
| -------- | ----------------- | -------------------------------- |
|
||||
| `Small` | Compact calendar | Smaller spacing and text |
|
||||
| `Medium` | Default size | Standard spacing and readability |
|
||||
| `Large` | Spacious calendar | Larger touch targets and text |
|
||||
|
||||
## View Modes
|
||||
|
||||
The calendar supports three view modes:
|
||||
|
||||
1. **Day View**: Default monthly calendar grid
|
||||
2. **Month View**: Grid of months for quick month selection
|
||||
3. **Year View**: Grid of years for quick year selection
|
||||
|
||||
Users can navigate between views by clicking on the month/year buttons in the header.
|
||||
|
||||
## Keyboard Navigation
|
||||
|
||||
### Day View
|
||||
|
||||
- **Arrow Keys**: Navigate between dates
|
||||
- **Enter**: Select current date
|
||||
- **Escape**: Clear selection
|
||||
- **Tab**: Navigate to header controls
|
||||
- **Page Up/Down**: Previous/next month
|
||||
- **Home**: Go to first day of month
|
||||
- **End**: Go to last day of month
|
||||
|
||||
### Month View
|
||||
|
||||
- **Arrow Keys**: Navigate between months
|
||||
- **Enter**: Select month and return to day view
|
||||
- **Escape**: Return to day view
|
||||
|
||||
### Year View
|
||||
|
||||
- **Arrow Keys**: Navigate between years
|
||||
- **Enter**: Select year and return to day view
|
||||
- **Escape**: Return to day view
|
||||
- **Page Up/Down**: Previous/next year page
|
||||
|
||||
### Header Navigation
|
||||
|
||||
- **Tab**: Navigate between prev/next buttons and month/year selectors
|
||||
- **Enter/Space**: Activate buttons or toggle view modes
|
||||
- [Calendar]
|
||||
- [CalendarState]
|
||||
- [RangeMatcher]
|
||||
|
||||
## Examples
|
||||
|
||||
|
|
@ -476,3 +372,7 @@ Calendar::new(&availability_calendar)
|
|||
```
|
||||
|
||||
The Calendar component provides a foundation for any date-related UI requirements, from simple date pickers to complex scheduling interfaces.
|
||||
|
||||
[Calendar]: https://docs.rs/gpui-component/latest/gpui_component/calendar/struct.Calendar.html
|
||||
[CalendarState]: https://docs.rs/gpui-component/latest/gpui_component/calendar/struct.CalendarState.html
|
||||
[RangeMatcher]: https://docs.rs/gpui-component/latest/gpui_component/calendar/struct.RangeMatcher.html
|
||||
|
|
|
|||
|
|
@ -82,17 +82,7 @@ Checkbox::new("checkbox")
|
|||
|
||||
## API Reference
|
||||
|
||||
### Checkbox
|
||||
|
||||
| Method | Description |
|
||||
| ------------------ | ----------------------------------------------------------- |
|
||||
| `new(id)` | Create a new checkbox with the given ID |
|
||||
| `label(text)` | Set label text |
|
||||
| `checked(bool)` | Set checked state |
|
||||
| `disabled(bool)` | Set disabled state |
|
||||
| `on_click(fn)` | Callback when clicked, receives `&bool` (new checked state) |
|
||||
| `tab_stop(bool)` | Enable/disable tab navigation (default: true) |
|
||||
| `tab_index(isize)` | Set tab order index (default: 0) |
|
||||
- [Checkbox]
|
||||
|
||||
### Styling
|
||||
|
||||
|
|
@ -145,3 +135,5 @@ v_flex()
|
|||
}))
|
||||
)
|
||||
```
|
||||
|
||||
[Checkbox]: https://docs.rs/gpui-component/latest/gpui_component/checkbox/struct.Checkbox.html
|
||||
|
|
|
|||
|
|
@ -87,86 +87,7 @@ Input::new(&url_state)
|
|||
|
||||
## API Reference
|
||||
|
||||
### Clipboard
|
||||
|
||||
| Method | Description |
|
||||
| --------------- | ------------------------------------------------------- |
|
||||
| `new(id)` | Create a new clipboard component with the given ID |
|
||||
| `value(str)` | Set static text to copy to clipboard |
|
||||
| `value_fn(fn)` | Set dynamic function that returns the value to copy |
|
||||
| `content(fn)` | Set custom content to display alongside the copy button |
|
||||
| `on_copied(fn)` | Callback executed when content is successfully copied |
|
||||
|
||||
### Method Details
|
||||
|
||||
#### `value(value: impl Into<SharedString>)`
|
||||
|
||||
Sets a static value that will be copied to the clipboard when the button is clicked.
|
||||
|
||||
```rust
|
||||
Clipboard::new("static")
|
||||
.value("Static text to copy")
|
||||
```
|
||||
|
||||
#### `value_fn(fn: impl Fn(&mut Window, &mut App) -> SharedString + 'static)`
|
||||
|
||||
Sets a function that will be called to get the value when the copy action occurs. This is useful for dynamic content that may change over time.
|
||||
|
||||
```rust
|
||||
Clipboard::new("dynamic")
|
||||
.value_fn(|_, cx| {
|
||||
format!("Current time: {}", SystemTime::now())
|
||||
})
|
||||
```
|
||||
|
||||
#### `content(fn: impl Fn(&mut Window, &mut App) -> E + 'static)`
|
||||
|
||||
Sets custom content to display before the copy button. The content can be any element that implements `IntoElement`.
|
||||
|
||||
```rust
|
||||
Clipboard::new("with-content")
|
||||
.content(|_, _| Label::new("Copy me"))
|
||||
.value("Hello")
|
||||
```
|
||||
|
||||
#### `on_copied(fn: impl Fn(SharedString, &mut Window, &mut App) + 'static)`
|
||||
|
||||
Sets a callback that is executed when content is successfully copied. Receives the copied value as the first parameter.
|
||||
|
||||
```rust
|
||||
Clipboard::new("with-callback")
|
||||
.value("Hello")
|
||||
.on_copied(|value, window, cx| {
|
||||
println!("Copied: {}", value);
|
||||
window.push_notification("Copied to clipboard!", cx);
|
||||
})
|
||||
```
|
||||
|
||||
## Behavior
|
||||
|
||||
### Visual States
|
||||
|
||||
The clipboard button has two visual states:
|
||||
|
||||
1. **Default State**: Shows a copy icon (IconName::Copy)
|
||||
2. **Copied State**: Shows a checkmark icon (IconName::Check) for 2 seconds after successful copy
|
||||
|
||||
### Copy Process
|
||||
|
||||
1. User clicks the clipboard button
|
||||
2. The component determines the value to copy:
|
||||
- If `value_fn` is set, calls the function to get the current value
|
||||
- Otherwise, uses the static `value`
|
||||
3. Writes the value to the system clipboard using `ClipboardItem::new_string()`
|
||||
4. Changes the button icon to a checkmark
|
||||
5. Calls the `on_copied` callback if provided
|
||||
6. After 2 seconds, resets the icon back to the copy icon
|
||||
|
||||
### Event Handling
|
||||
|
||||
- Click events are handled internally and call `cx.stop_propagation()` to prevent bubbling
|
||||
- The component is disabled (unclickable) while in the "copied" state
|
||||
- Uses GPUI's clipboard API (`cx.write_to_clipboard()`) for system integration
|
||||
- [Clipboard]
|
||||
|
||||
## Examples
|
||||
|
||||
|
|
@ -247,3 +168,5 @@ The Clipboard component currently supports copying text strings to the clipboard
|
|||
- Plain text strings
|
||||
- UTF-8 encoded content
|
||||
- Cross-platform clipboard integration
|
||||
|
||||
[Clipboard]: https://docs.rs/gpui-component/latest/gpui_component/clipboard/struct.Clipboard.html
|
||||
|
|
|
|||
|
|
@ -212,49 +212,9 @@ The color picker preserves alpha values when selecting colors and allows modific
|
|||
|
||||
## API Reference
|
||||
|
||||
### ColorPickerState
|
||||
|
||||
| Method | Description |
|
||||
| ------------------------------ | -------------------------------------- |
|
||||
| `new(window, cx)` | Create a new color picker state |
|
||||
| `default_value(color)` | Set the default selected color |
|
||||
| `set_value(color, window, cx)` | Programmatically set the current color |
|
||||
| `value()` | Get the currently selected color |
|
||||
|
||||
### ColorPicker
|
||||
|
||||
| Method | Description |
|
||||
| ------------------------- | -------------------------------------------------- |
|
||||
| `new(state)` | Create a new color picker with the given state |
|
||||
| `featured_colors(colors)` | Set custom featured colors array |
|
||||
| `size(size)` | Set the picker size (XSmall, Small, Medium, Large) |
|
||||
| `icon(icon)` | Display icon instead of color square |
|
||||
| `label(text)` | Add a label to the color picker |
|
||||
| `anchor(corner)` | Set dropdown anchor position |
|
||||
|
||||
### ColorPickerEvent
|
||||
|
||||
| Event | Description |
|
||||
| ---------------------- | ------------------------------------ |
|
||||
| `Change(Option<Hsla>)` | Emitted when color selection changes |
|
||||
|
||||
### Size Options
|
||||
|
||||
| Size | Description |
|
||||
| -------------- | ------------------------------ |
|
||||
| `Size::XSmall` | Extra small picker button |
|
||||
| `Size::Small` | Small picker button |
|
||||
| `Size::Medium` | Medium picker button (default) |
|
||||
| `Size::Large` | Large picker button |
|
||||
|
||||
### Anchor Positions
|
||||
|
||||
| Corner | Description |
|
||||
| --------------------- | ------------------------------------- |
|
||||
| `Corner::TopLeft` | Dropdown opens below and to the right |
|
||||
| `Corner::TopRight` | Dropdown opens below and to the left |
|
||||
| `Corner::BottomLeft` | Dropdown opens above and to the right |
|
||||
| `Corner::BottomRight` | Dropdown opens above and to the left |
|
||||
- [ColorPicker]
|
||||
- [ColorPickerState]
|
||||
- [ColorPickerEvent]
|
||||
|
||||
## Examples
|
||||
|
||||
|
|
@ -409,3 +369,7 @@ let _subscription = cx.subscribe(&color_picker, |this, _, ev, _| match ev {
|
|||
}
|
||||
});
|
||||
```
|
||||
|
||||
[ColorPicker]: https://docs.rs/gpui-component/latest/gpui_component/color_picker/struct.ColorPicker.html
|
||||
[ColorPickerState]: https://docs.rs/gpui-component/latest/gpui_component/color_picker/struct.ColorPickerState.html
|
||||
[ColorPickerEvent]: https://docs.rs/gpui-component/latest/gpui_component/color_picker/enum.ColorPickerEvent.html
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ The Menu component provides both context menus (right-click menus) and popup men
|
|||
|
||||
```rust
|
||||
use gpui_component::{
|
||||
menu::{PopupMenu, ContextMenuExt, DropdownMenu},
|
||||
menu::{PopupMenu, PopupMenuItem, ContextMenuExt, DropdownMenu},
|
||||
Button
|
||||
};
|
||||
use gpui::{actions, Action};
|
||||
|
|
@ -19,7 +19,7 @@ use gpui::{actions, Action};
|
|||
|
||||
## Usage
|
||||
|
||||
### Context Menu
|
||||
### ContextMenu
|
||||
|
||||
Context menus appear when right-clicking on an element:
|
||||
|
||||
|
|
@ -41,18 +41,38 @@ div()
|
|||
Dropdown menus are triggered by buttons or other interactive elements:
|
||||
|
||||
```rust
|
||||
use gpui_component::menu::DropdownMenu;
|
||||
use gpui_component::popup_menu::{PopupMenuExt as _, PopupMenuItem};
|
||||
|
||||
let view = cx.entity();
|
||||
Button::new("menu-btn")
|
||||
.label("Open Menu")
|
||||
.dropdown_menu(|menu, window, cx| {
|
||||
menu.menu("New File", Box::new(NewFile))
|
||||
.menu("Open File", Box::new(OpenFile))
|
||||
.link("Documentation", "https://longbridge.github.io/gpui-component/")
|
||||
.separator()
|
||||
.item(PopupMenuItem::new("Custom Action")
|
||||
.on_click(window.listener_for(&view, |this, _, window, cx| {
|
||||
// Custom action logic here
|
||||
this.
|
||||
})
|
||||
)
|
||||
.separator()
|
||||
.menu("Exit", Box::new(Exit))
|
||||
})
|
||||
```
|
||||
|
||||
:::tip
|
||||
As you see, the each menu item is associated with an [Action],
|
||||
we choice this design to better integrate with GPUI's action and key binding system,
|
||||
allowing menu items to automatically display keyboard shortcuts when applicable.
|
||||
|
||||
So, the [Action] is the recommended way to define menu item behaviors.
|
||||
|
||||
However, if you prefer not to use [Action]s, you can create custom menu items using the `item` method along with [PopupMenuItem].
|
||||
There have a `on_click` callback to handle the click event directly.
|
||||
:::
|
||||
|
||||
### Menu with Anchor Position
|
||||
|
||||
Control where the dropdown menu appears relative to the trigger:
|
||||
|
|
@ -438,6 +458,7 @@ Button::new("settings")
|
|||
7. **Clear Labels**: Use descriptive, action-oriented labels
|
||||
8. **Reasonable Limits**: Use scrollable menus for more than 10-15 items
|
||||
|
||||
[PopupMenu]: https://docs.rs/gpui-component/latest/gpui_component/menu/popup_menu/struct.PopupMenu.html
|
||||
[PopupMenuItem]: https://docs.rs/gpui-component/latest/gpui_component/menu/popup_menu/struct.PopupMenuItem.html
|
||||
[context_menu]: https://docs.rs/gpui-component/latest/gpui_component/menu/context_menu/trait.ContextMenuExt.html#method.context_menu
|
||||
[PopupMenu]: https://docs.rs/gpui-component/latest/gpui_component/menu/struct.PopupMenu.html
|
||||
[PopupMenuItem]: https://docs.rs/gpui-component/latest/gpui_component/menu/struct.PopupMenuItem.html
|
||||
[context_menu]: https://docs.rs/gpui-component/latest/gpui_component/menu/trait.ContextMenuExt.html#method.context_menu
|
||||
[Action]: https://docs.rs/gpui/latest/gpui/trait.Action.html
|
||||
|
|
|
|||
|
|
@ -25,8 +25,8 @@ Button::new("ok")
|
|||
Add the following to your `Cargo.toml`:
|
||||
|
||||
```toml
|
||||
gpui-component = "0.2"
|
||||
gpui = "0.2"
|
||||
gpui-component = "0.3"
|
||||
```
|
||||
|
||||
## Hello World
|
||||
|
|
|
|||
Loading…
Reference in a new issue