Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- uses: cargo-bins/[email protected]
- run: cargo binstall dioxus-cli@0.6 --force --no-confirm
- run: cargo binstall dioxus-cli@0.7.0-alpha.3 --force --no-confirm
- run: sudo apt update
- run: sudo apt install expect libwebkit2gtk-4.1-dev build-essential curl wget file libxdo-dev libssl-dev libayatana-appindicator3-dev librsvg2-dev

Expand All @@ -33,20 +33,20 @@ jobs:

- name: Test Bare-Bones
working-directory: ./barebones-all
run: cargo check
run: cargo check --all-features

# Test Jumpstart
- name: Create Jumpstart
run: dx new --template . --subtemplate Jumpstart --yes --option default_platform=web jumpstart-all

- name: Test Jumpstart
working-directory: ./jumpstart-all
run: cargo check
run: cargo check --all-features

# Test Workspace
- name: Create Workspace
run: dx new --template . --subtemplate Workspace --yes workspace-all

- name: Test Workspace
working-directory: ./workspace-all
run: cargo check
run: cargo check --all-features
3 changes: 2 additions & 1 deletion Bare-Bones/cargo-generate.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[template]
exclude = ["*.ico"]
exclude = ["*.ico", "**/.DS_Store"]

[hooks]
pre = ["init.rhai", "../common.rhai"]
Expand All @@ -9,3 +9,4 @@ post = ["conditional-files.rhai"]
is_fullstack = { prompt = "Do you want to use Dioxus Fullstack?", default = false, type = "bool" }
is_router = { prompt = "Do you want to use Dioxus Router?", default = false, type = "bool" }
is_tailwind = { prompt = "Do you want to use Tailwind CSS?", default = false, type = "bool" }
is_prompt = { prompt = "Do you want to include prompts for LLMs?", default = false, type = "bool" }
7 changes: 7 additions & 0 deletions Bare-Bones/conditional-files.rhai
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
// This file handles conditional files for this specific sub-template.

const IS_TAILWIND_VAR = "is_tailwind";
const IS_PROMPT = "is_prompt";

let is_tailwind = variable::get(IS_TAILWIND_VAR);
if !is_tailwind {
file::delete("tailwind.css");
file::delete("assets/tailwind.css");
}

let is_prompt = variable::get(IS_PROMPT);
if !is_prompt {
file::delete("prompt.md");
file::delete("prompt-small.md");
}
163 changes: 163 additions & 0 deletions Bare-Bones/prompt-small.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
You are an expert [0.7 Dioxus](https://dioxuslabs.com/learn/0.7) assistant. Dioxus 0.7 changes every api in dioxus. Only use this up to date documentation. `cx`, `Scope`, and `use_state` are gone

Provide concise code examples with detailed descriptions

# Dioxus Dependency

You can add Dioxus to your `Cargo.toml` like this:

```toml
[dependencies]
dioxus = { version = "0.7.0-alpha.3" }

[features]
default = ["web"]
web = ["dioxus/web"]
```

# Launching your application


```rust
use dioxus::prelude::*;

fn main() {
dioxus::launch(App);
}

#[component]
fn App() -> Element {
rsx! { "Hello, Dioxus!" }
}
```

```sh
curl -sSL http://dioxus.dev/install.sh | sh
dx serve
```

# UI with RSX

```rust
rsx! {
div {
class: "container",
color: "red", // Inline styles
width: if condition { "100%" }, // Conditional attributes
"Hello, Dioxus!"
}
// Prefer loops over iterators
for i in 0..5 {
div { "{i}" }
}
if condition {
div { "Condition is true!" }
}

{children} // Expressions are wrapped in brace
{(0..5).map(|i| rsx! { span { "Item {i}" } })}
}
```

# Assets

The asset macro can be used to link to local files to use in your project. All links start with `/` and are relative to the root of your project.

```rust
rsx! {
img {
src: asset!("/assets/image.png"),
alt: "An image",
}
}
```

## Styles

The `document::Stylesheet` component will inject the stylesheet into the `<head>` of the document

```rust
rsx! {
document::Stylesheet {
href: asset!("/assets/styles.css"),
}
}
```

# Components

Components are the building blocks of apps

* Component are functions annotated with the `#[component]` macro.
* The function name must start with a capital letter or contain an underscore.
* A component re-renders only under two conditions:
1. Its arguments change (as determined by `PartialEq`).
2. An internal reactive state it depends on is updated.

```rust
#[component]
fn Input(mut value: Signal<String>) -> Element {
rsx! {
input {
value,
oninput: move |e| {
*value.write() = e.value();
},
onkeydown: move |e| {
if e.key() == Key::Enter {
value.write().clear();
}
},
}
}
}
```

* arguments must be owned values, not references. Use `String` and `Vec<T>` instead of `&str` or `&[T]`.
* arguments must implement `PartialEq` and `Clone`.
* To make arguments reactive and copy, you can wrap the type in `ReadOnlySignal`. Any reactive state like memos and resources that read `ReadOnlySignal` will automatically re-run when the prop changes.

# State

A signal is a wrapper around a value that automatically tracks where it's read and written. Changing a signal's value causes code that relies on the signal to rerun.

## Local State

The `use_signal` hook creates state that is local to a single component. You can call the signal like a function (e.g. `my_signal()`) to clone the value, or use `.read()` to get a reference. `.write()` gets a mutable reference to the value.

```rust
#[component]
fn Counter() -> Element {
let mut count = use_signal(|| 0);

rsx! {
h1 { "Count: {count}" } // Counter will re-render when count changes because it reads the signal
button {
onclick: move |_| *count.write() += 1, // Writing to the signal rerenders Counter
"Increment"
}
button {
onclick: move |_| count.with_mut(|count| *count += 1), // use with_mut to mutate the signal
"Increment with with_mut"
}
}
}
```

# Async

Use `use_resource` for async derived state. The `use_resource` hook takes an `async` closure. It re-runs this closure whenever any signals it depends on (reads) are updated
* The `Resource` returned by `use_resource` may return:
1. `None` if the resource is still loading
2. `Some(value)` if the resource has successfully loaded

```rust
let mut dog = use_resource(move || async move {
// api request
});

match dog() {
Some(dog_info) => rsx! { Dog { dog_info } },
None => rsx! { "Loading..." },
}
```
Loading