Skip to content

Commit

Permalink
init release (#1)
Browse files Browse the repository at this point in the history
  • Loading branch information
wiseaidev authored Jan 23, 2024
1 parent c59aaf4 commit 3afb4af
Show file tree
Hide file tree
Showing 7 changed files with 309 additions and 9 deletions.
11 changes: 11 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates

version: 2
updates:
- package-ecosystem: "cargo" # See documentation for possible values
directory: "/" # Location of package manifests
schedule:
interval: "weekly"
22 changes: 22 additions & 0 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: CI

on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]

env:
CARGO_TERM_COLOR: always

jobs:
build:

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3
- name: Build
run: cargo build --verbose
- name: Run tests
run: cargo test --verbose
8 changes: 2 additions & 6 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
# Generated by Cargo
# will have compiled files and executables
debug/
target/
/target/

# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
Cargo.lock

# These are backup files generated by rustfmt
**/*.rs.bk

# MSVC Windows builds of rustc generate these, which store debugging information
*.pdb
**/*.rs.bk
22 changes: 22 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
[package]
name = "yew-scroll"
version = "0.1.0"
description = "🔝 A sleek and customizable Yew component for effortless scroll to top functionality."
license = "MIT"
keywords = ["scroll-to-top", "yew", "rust", "yew-scroll"]
repository = "https://github.com/wiseaidev/yew-scroll"
documentation = "https://docs.rs/yew-scroll/"
authors = ["Mahmoud Harmouch <[email protected]>"]
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
gloo = { version = "0.11.0", features = ["utils"] }
yew = { version = "0.21.0", default-features = false }

[profile.release]
codegen-units = 1
opt-level = "z"
lto = "thin"
strip = "symbols"
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2024 Mahmoud
Copyright (c) 2024 Mahmoud Harmouch

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
116 changes: 114 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,114 @@
# yew-scroll
🔝 A Yew component for effortless "scroll to top" functionality.
# 🔝 Yew Scroll

[![Crates.io](https://img.shields.io/crates/v/yew-scroll)](https://crates.io/crates/yew-scroll)
[![Crates.io Downloads](https://img.shields.io/crates/d/yew-scroll)](https://crates.io/crates/yew-scroll)
![Crates.io License](https://img.shields.io/crates/l/yew-scroll)
![Rust](https://img.shields.io/badge/rust-stable-orange)

![demo](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3wyypvi0bgxwsr0i146j.gif)

## 📜 Introduction

This component is designed to provide a convenient and customizable solution for implementing a "scroll to top" button in your Yew applications. Enhance user experience by allowing them to easily navigate to the top of the page with a single click.

## 🤔 Why is this Component Useful?

This component comes with several benefits that make it an essential addition to your Yew projects:

1. 🔄 Scroll Navigation: Simplify user navigation by adding a convenient button to scroll smoothly to the top of the page.

1. 🎨 Customization: Tailor the appearance of the "scroll to top" button using custom CSS classes, and provide a personalized SVG icon.

1. 📏 Customizable Offset: Define a custom vertical offset (Y position) to trigger the visibility of the button, ensuring a seamless user experience.

## ⚙️ Installation

Integrating this component into your Yew project is a straightforward process. Follow these simple steps:

1. Make sure you have Yew set up in your project. If not, refer to the [Yew documentation](https://yew.rs/docs/getting-started/introduction) for installation instructions.

2. Install the component package using your preferred package manager:

```bash
$ cargo add yew-scroll
```

3. Import the component into your Yew application and start using it to improve user navigation.

## 🛠️ Usage

Incorporating this component into your application is easy. Follow these steps:

1. Import the component and its required dependencies:

```rust
use yew-scroll::{ScrollToTop, ScrollToTopProps};
```

1. Set up the props for the `ScrollToTop` component:

```rust
// Custom SVG content for the scroll-to-top button (an arrow).
fn custom_svg() -> Html {
html! {
<svg
class="w-6 h-6"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M5 10l7-7m0 0l7 7m-7-7v18"
/>
</svg>
}
}

// Custom SVG content for the scroll-to-top button (an arrow).
#[function_component(MyComponent)]
pub fn my_component() -> Html {

// Set props for the `ScrollToTop` component
let custom_props = ScrollToTopProps {
css: "custom-css", // Add any custom CSS classes
top_offset: 0.0, // Set the desired top offset value to show the button
svg_content: custom_svg(), // Provide custom SVG content
};

// Render the `ScrollToTop` component with the specified props
html! {
<>
// Other content in your component
<p>{"Scroll down to see the button"}</p>

// Use the scroll_to_top component
<ScrollToTop ..custom_props />

// Default Usage
<ScrollToTop />
</>
}
}
```

1. Customize the appearance and behavior of the "scroll to top" button based on your project requirements.

## 🔧 Props

| Name | Type | Description | Example | Default Value |
| --- | --- | --- | --- | --- |
| `css` | `&'static str` | Custom CSS classes for styling the button. | "custom-scroll-button", "highlight-button". | "fixed bottom-4 right-4 bg-blue-500 text-white p-3 rounded-full cursor-pointer hover:bg-blue-600 transition duration-300 ease-in-out" |
| `top_offset` | `f64` | The vertical offset value (Y position) to trigger button visibility. | 200.0, 300.0 | 500.0 |
| `svg_content` | `Html` | Custom SVG content for the button. | `custom_svg()` | `default_svg()` |

## 🤝 Contribution

We encourage contributions from the community to enhance this Yew component. Feel free to open issues, submit pull requests, or provide feedback. Let's collaborate and make this component even more powerful!

## 📜 License

The Scroll To Top Yew component is licensed under the `MIT` License, allowing you to use, modify, and distribute it freely. Refer to the [`LICENSE`](LICENSE) file for more details.
137 changes: 137 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
use gloo::events::EventListener;
use gloo::utils::window;
use yew::prelude::*;

/// Constant defining default Tailwind CSS classes for the scroll-to-top button.
const SCROLL_TO_TOP_CLASSES: &'static str =
"fixed bottom-4 right-4 bg-blue-500 text-white p-3 rounded-full cursor-pointer hover:bg-blue-600 transition duration-300 ease-in-out";

#[derive(Properties, Clone, PartialEq)]
pub struct ScrollToTopProps {
/// Custom CSS classes for styling the scroll-to-top button.
#[prop_or(SCROLL_TO_TOP_CLASSES)]
pub css: &'static str,

/// The vertical offset value (Y position) to show the button.
#[prop_or(500.0)]
pub top_offset: f64,

/// Custom SVG content for the scroll-to-top button.
#[prop_or_else(default_svg)]
pub svg_content: Html,
}

/// scroll_to_top
/// A Yew component that provides a button to scroll to the top of the page when clicked.
///
/// # Arguments
/// * `props` - The properties of the component.
/// - `css` - Custom CSS classes for styling the scroll-to-top button. Defaults to predefined Tailwind classes.
/// - `top_offset` - The vertical offset value (Y position) to show the button. Defaults to 500.0 pixels.
/// - `svg_content` - Custom SVG content for the scroll-to-top button. Defaults to a default arrow SVG.
///
/// # Returns
/// (Html): An HTML representation of the scroll-to-top button.
///
/// # Examples
/// ```
/// // Example of using the scroll_to_top component
/// use yew::prelude::*;
/// use yew_scroll::{ScrollToTop, ScrollToTopProps};
///
/// // Custom SVG content for the scroll-to-top button (an arrow).
/// fn custom_svg() -> Html {
/// html! {
/// <svg
/// class="w-6 h-6"
/// fill="none"
/// stroke="currentColor"
/// viewBox="0 0 24 24"
/// xmlns="http://www.w3.org/2000/svg"
/// >
/// <path
/// stroke-linecap="round"
/// stroke-linejoin="round"
/// stroke-width="2"
/// d="M5 10l7-7m0 0l7 7m-7-7v18"
/// />
/// </svg>
/// }
/// }
///
/// #[function_component(MyComponent)]
/// pub fn my_component() -> Html {
/// // Set props for the scroll_to_top component
/// let scroll_to_top_props = ScrollToTopProps {
/// css: "custom-css", // Add any custom CSS classes
/// top_offset: 0.0, // Set the desired top offset value to show the button
/// svg_content: custom_svg(), // Provide custom SVG content
/// };
///
/// // Render the scroll_to_top component with the specified props
/// html! {
/// <>
/// // Other content in your component
/// <p>{"Scroll down to see the button"}</p>
///
/// // Use the scroll_to_top component
/// <ScrollToTop ..scroll_to_top_props />
///
/// // Default Usage
/// <ScrollToTop />
/// </>
/// }
/// }
/// ```
#[function_component(ScrollToTop)]
pub fn scroll_to_top(props: &ScrollToTopProps) -> Html {
// State handle to track the visibility of the scroll-to-top button.
let visible_handle = use_state(|| false);
let visible = *visible_handle;
let top_offset = props.top_offset.clone();

// Effect to add a scroll event listener and update the visibility state.
use_effect(move || {
let listener = EventListener::new(&window(), "scroll", move |_| {
let scroll_position = window().scroll_y().unwrap_or_default();
visible_handle.set(scroll_position > top_offset);
});

// Cleanup when the component is unmounted.
move || {
drop(listener);
}
});

// Callback for the button click event to scroll to the top.
let on_click = Callback::from(|_| {
let win = window();
win.scroll_to_with_x_and_y(0.0, 0.0);
});

html! {
if visible {
<div class={SCROLL_TO_TOP_CLASSES} onclick={on_click}>{ props.svg_content.clone() }</div>
}
}
}

/// Default SVG content for the scroll-to-top button (an arrow).
fn default_svg() -> Html {
html! {
<svg
class="w-6 h-6"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M5 10l7-7m0 0l7 7m-7-7v18"
/>
</svg>
}
}

0 comments on commit 3afb4af

Please sign in to comment.