Skip to content

Commit

Permalink
marquee + review card wip
Browse files Browse the repository at this point in the history
  • Loading branch information
nhobes committed Nov 11, 2024
1 parent 104c5bd commit 829b7b4
Show file tree
Hide file tree
Showing 4 changed files with 224 additions and 0 deletions.
121 changes: 121 additions & 0 deletions assets/default.css
Original file line number Diff line number Diff line change
Expand Up @@ -1595,6 +1595,127 @@
display: none;
}

/* Marquee Container */
.pc-marquee-container {
@apply relative flex p-2 overflow-hidden;
gap: var(--gap);
}

.pc-marquee-container.pc-vertical {
@apply flex-col;
}

/* Max width variants */
.pc-marquee-container[max-width="sm"] {
@apply max-w-sm;
}

.pc-marquee-container[max-width="md"] {
@apply max-w-md;
}

.pc-marquee-container[max-width="lg"] {
@apply max-w-lg;
}

.pc-marquee-container[max-width="xl"] {
@apply max-w-xl;
}

.pc-marquee-container[max-width="2xl"] {
@apply max-w-2xl;
}

/* Max height variants */
.pc-marquee-container[max-height="sm"] {
@apply max-h-[24rem];
}

.pc-marquee-container[max-height="md"] {
@apply max-h-[28rem];
}

.pc-marquee-container[max-height="lg"] {
@apply max-h-[32rem];
}

.pc-marquee-container[max-height="xl"] {
@apply max-h-[36rem];
}

.pc-marquee-container[max-height="2xl"] {
@apply max-h-[42rem];
}

/* Marquee Content */
.pc-marquee-content {
@apply flex justify-around shrink-0;
gap: var(--gap);
}

.pc-marquee-horizontal {
@apply flex-row;
animation: marquee var(--duration) linear infinite;
}

.pc-marquee-vertical {
@apply flex-col;
animation: marquee-vertical var(--duration) linear infinite;
}

.pc-pause-on-hover {
@apply group-hover:[animation-play-state:paused];
}

.pc-review-card {
@apply relative md:w-64 cursor-pointer overflow-hidden rounded-xl border p-4
border-black/10 bg-black/[0.01] hover:bg-black/[0.05]
dark:border-white/10 dark:bg-white/10 dark:hover:bg-white/[0.15];
}

.pc-review-header {
@apply flex items-center gap-2;
}

.pc-review-meta {
@apply flex flex-col;
}

.pc-review-username {
@apply text-xs text-black/40 dark:text-white/40;
}

.pc-review-body {
@apply mt-2;
}

/* Animations */
@keyframes marquee {
from { transform: translateX(0); }
to { transform: translateX(calc(-100% - var(--gap))); }
}

@keyframes marquee-vertical {
from { transform: translateY(0); }
to { transform: translateY(calc(-100% - var(--gap))); }
}

.pc-gradient-overlay-left {
@apply absolute top-0 bottom-0 left-0 w-1/3 pointer-events-none bg-gradient-to-r from-white to-white/0 dark:from-gray-900 dark:to-gray-900/0;
}

.pc-gradient-overlay-right {
@apply absolute top-0 bottom-0 right-0 w-1/3 pointer-events-none bg-gradient-to-r from-white/0 to-white dark:from-gray-900/0 dark:to-gray-900;
}

.pc-gradient-overlay-top {
@apply absolute top-0 left-0 right-0 pointer-events-none h-1/3 bg-gradient-to-b from-white to-white/0 dark:from-gray-900 dark:to-gray-900/0;
}

.pc-gradient-overlay-bottom {
@apply absolute bottom-0 left-0 right-0 pointer-events-none h-1/3 bg-gradient-to-t from-white to-white/0 dark:from-gray-900 dark:to-gray-900/0;
}

/* Modal */
.pc-modal {
@apply relative z-50;
Expand Down
1 change: 1 addition & 0 deletions lib/petal_components.ex
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ defmodule PetalComponents do
Input,
Link,
Loading,
Marquee,
Modal,
Pagination,
Progress,
Expand Down
28 changes: 28 additions & 0 deletions lib/petal_components/card.ex
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
defmodule PetalComponents.Card do
use Phoenix.Component
import PetalComponents.Avatar
import PetalComponents.Typography

attr(:class, :any, default: nil, doc: "CSS class")
attr(:variant, :string, default: "basic", values: ["basic", "outline"])
Expand Down Expand Up @@ -71,4 +73,30 @@ defmodule PetalComponents.Card do
</div>
"""
end

attr(:name, :string, required: true, doc: "The reviewer's name")
attr(:username, :string, required: true, doc: "The reviewer's username")
attr(:img, :string, required: true, doc: "URL of the reviewer's avatar")
attr(:body, :string, required: true, doc: "The review text content")
attr(:class, :string, default: "", doc: "Additional classes")
attr(:rest, :global)

def review_card(assigns) do
~H"""
<figure class={["pc-review-card", @class]} {@rest}>
<div class="pc-review-header">
<.avatar src={@img} alt={@name} size="md" />
<div class="pc-review-meta">
<figcaption>
<.h5 no_margin class="text-sm pc-review-name"><%= @name %></.h5>
</figcaption>
<p class="pc-review-username"><%= @username %></p>
</div>
</div>
<blockquote class="pc-review-body">
<.p class="text-sm" no_margin><%= @body %></.p>
</blockquote>
</figure>
"""
end
end
74 changes: 74 additions & 0 deletions lib/petal_components/marquee.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
defmodule PetalComponents.Marquee do
use Phoenix.Component

attr(:pause_on_hover, :boolean,
default: false,
doc: "Pause the marquee when the user hovers over the cards"
)

attr(:repeat, :integer, default: 1, doc: "Number of times to repeat the content")
attr(:vertical, :boolean, default: false, doc: "Display the marquee vertically")
attr(:reverse, :boolean, default: false, doc: "Reverse the direction of the marquee")
attr(:duration, :string, default: "30s", doc: "Animation duration")
attr(:gap, :string, default: "1rem", doc: "Gap between items")
attr(:overlay_gradient, :boolean, default: true, doc: "Add gradient overlay at edges")

attr(:max_width, :string,
default: "none",
values: ["sm", "md", "lg", "xl", "2xl", "none"],
doc: "Maximum width of the marquee container"
)

attr(:max_height, :string,
default: "none",
values: ["sm", "md", "lg", "xl", "2xl", "none"],
doc: "Maximum height of the marquee container"
)

attr(:class, :string, default: "", doc: "CSS class for parent div")
attr(:rest, :global)
slot(:inner_block, required: true)

def marquee(assigns) do
~H"""
<div class="relative overflow-hidden">
<div
:if={@repeat > 0}
class={[
"pc-marquee-container group",
@vertical && "pc-vertical",
@class
]}
max-width={@max_width}
max-height={@max_height}
style={"--duration: #{@duration}; --gap: #{@gap};"}
{@rest}
>
<%= for _ <- 0..(@repeat - 1) do %>
<div
class={[
"pc-marquee-content",
@vertical && "pc-marquee-vertical",
!@vertical && "pc-marquee-horizontal",
@pause_on_hover && "pc-pause-on-hover"
]}
style={@reverse && "animation-direction: reverse;"}
>
<%= render_slot(@inner_block) %>
</div>
<% end %>
</div>
<%= if @overlay_gradient do %>
<%= if @vertical do %>
<div class="pc-gradient-overlay-top"></div>
<div class="pc-gradient-overlay-bottom"></div>
<% else %>
<div class="pc-gradient-overlay-left"></div>
<div class="pc-gradient-overlay-right"></div>
<% end %>
<% end %>
</div>
"""
end
end

0 comments on commit 829b7b4

Please sign in to comment.