Skip to content

Commit

Permalink
[PBNTR-285] Star Rating kit: interactive form variant (Rails) (#3523)
Browse files Browse the repository at this point in the history
[PBNTR-285
](https://runway.powerhrg.com/backlog_items/PBNTR-285)

This PR adds a new interactive variant for the star rating kit.

![Screenshot 2024-07-11 at 4 13 27
PM](https://github.com/user-attachments/assets/3a708fa9-a697-454b-ab7e-22e5b7d8f30b)

![Screenshot 2024-07-11 at 4 13 46
PM](https://github.com/user-attachments/assets/0799b777-859e-46aa-a8c2-08315ef1cb16)


**How to test?** Steps to confirm the desired behavior:
1. Go to the star rating kit
2. click to see the interactive functionally 

#### Checklist:
- [x] **LABELS** Add a label: `enhancement`, `bug`, `improvement`, `new
kit`, `deprecated`, or `breaking`. See [Changelog &
Labels](https://github.com/powerhome/playbook/wiki/Changelog-&-Labels)
for details.
- [x] **DEPLOY** I have added the `milano` label to show I'm ready for a
review.
- [ ] **TESTS** I have added test coverage to my code.
  • Loading branch information
nickamantia authored Jul 19, 2024
1 parent 5e47c64 commit a07c7f8
Show file tree
Hide file tree
Showing 10 changed files with 118 additions and 8 deletions.
13 changes: 11 additions & 2 deletions playbook/app/pb_kits/playbook/pb_star_rating/_star_rating.scss
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@


$star-styles: (
yellow_star: (color: #F9BB00),
primary_star: (color: #0056CF),
yellow_star: (color: $yellow),
primary_star: (color: $royal),
suble_star_light: (color: $text_lt_default),
suble_star_dark: (color: $text_dk_default),
empty_star_dark: (color: $border_dark),
Expand Down Expand Up @@ -111,4 +111,13 @@
}
}
}
.yellow-star-selected {
color: $yellow;
}
.primary-star-selected {
color: $royal
}
.suble-star-selected {
color: $text_lt_default;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<%= pb_rails("star_rating", props: { padding_bottom: "xs", variant: "interactive" }) %>
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@ examples:
- star_rating_background_options: Background Options
- star_rating_hide: Layout Options
- star_rating_number_config: Number Config
- star_rating_size_options: Size Options
- star_rating_size_options: Size Options
50 changes: 50 additions & 0 deletions playbook/app/pb_kits/playbook/pb_star_rating/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import PbEnhancedElement from "../pb_enhanced_element";

const STAR_RATING_SELECTOR = "[data-pb-star-rating]";
const STAR_RATING_INPUT_ID = "star-rating-input";

export default class PbStarRating extends PbEnhancedElement {
static get selector() {
return STAR_RATING_SELECTOR;
}

connect() {
this.element.addEventListener("click", (event) => {
const clickedStarId = event.currentTarget.id;
this.updateStarColors(clickedStarId);
this.updateHiddenInputValue(clickedStarId);
});
}

updateStarColors(clickedStarId) {
const allStars = document.querySelectorAll(STAR_RATING_SELECTOR);

allStars.forEach(star => {
const starId = star.id;
const icon = star.querySelector(".interactive-star-icon");

if (icon) {
if (starId <= clickedStarId) {
if (star.classList.contains("yellow_star")) {
icon.classList.add("yellow-star-selected");
} else if (star.classList.contains("primary_star")) {
icon.classList.add("primary-star-selected");
} else if (star.classList.contains("suble_star_light")) {
icon.classList.add("suble-star-selected");
} else {
icon.classList.add("yellow-star-selected");
}
} else {
icon.classList.remove("yellow-star-selected", "primary-star-selected", "suble-star-selected");
}
}
});
}

updateHiddenInputValue(value) {
const hiddenInput = document.getElementById(STAR_RATING_INPUT_ID);
if (hiddenInput) {
hiddenInput.value = value;
}
}
}
30 changes: 25 additions & 5 deletions playbook/app/pb_kits/playbook/pb_star_rating/star_rating.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,33 @@
<% end %>
<% end %>
<%= pb_rails("flex", props: { }) do %>
<% object.star_count.times do %>
<%= pb_rails("icon", props: { classname: "#{star_color} pb_star_#{size}" , custom_icon: Playbook::Engine.root.join(star_svg_path) } ) %>
<% end %>
<% object.empty_stars.times do %>
<%= pb_rails("icon", props: { classname: "#{background_star_color} pb_star_#{size}", custom_icon: Playbook::Engine.root.join(background_star_path) } ) %>

<% if object.variant == "display" %>

<% object.star_count.times do %>
<%= pb_rails("icon", props: { classname: "#{star_color} pb_star_#{size}" , custom_icon: Playbook::Engine.root.join(star_svg_path) } ) %>
<% end %>
<% object.empty_stars.times do %>
<%= pb_rails("icon", props: { classname: "#{background_star_color} pb_star_#{size}", custom_icon: Playbook::Engine.root.join(background_star_path) } ) %>
<% end %>

<% else %>
<%= pb_rails("flex", props: { orientation: "column" }) do %>
<% if object.label.present? %>
<%= pb_rails("caption", props: {text: object.label, margin_bottom:"xs"}) %>
<% end %>
<input type="hidden" id="star-rating-input" value="" name="<%= object.name %>"/>
<%= pb_rails("flex", props: { orientation: "row" }) do %>
<% object.denominator.times do |index| %>
<div data-pb-star-rating id="<%= index + 1 %>" class="<%= star_color %>">
<%= pb_rails("icon", props: { classname: "#{background_star_color} pb_star_#{size} interactive-star-icon", custom_icon: Playbook::Engine.root.join(background_star_path)} ) %>
</div>
<% end %>
<% end %>
<% end %>
<% end %>
<% end %>

<% if layout_option == "onestar" %>
<%= content_tag(:div, class: "pb_star_rating_number_#{size}") do %>
<% case object.size %>
Expand Down
6 changes: 6 additions & 0 deletions playbook/app/pb_kits/playbook/pb_star_rating/star_rating.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@ class StarRating < Playbook::KitBase
values: %w[fill outline],
default: "fill"

prop :variant, type: Playbook::Props::Enum,
values: %w[display interactive],
default: "display"
prop :label, type: Playbook::Props::String
prop :name, type: Playbook::Props::String

def one_decimal_rating
rating.to_f.round(1)
end
Expand Down
3 changes: 3 additions & 0 deletions playbook/app/pb_kits/playbook/playbook-rails.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ PbDropdown.start()
import PbAdvancedTable from './pb_advanced_table'
PbAdvancedTable.start()

import PbStarRating from './pb_star_rating'
PbStarRating.start()

import 'flatpickr'

// React-Rendered Rails Kits =====
Expand Down
1 change: 1 addition & 0 deletions playbook/lib/playbook/forms/builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ class Builder < ::ActionView::Helpers::FormBuilder
require_relative "builder/multi_level_select_field"
require_relative "builder/phone_number_field"
require_relative "builder/dropdown_field"
require_relative "builder/star_rating_field"

prepend(FormFieldBuilder.new(:email_field, kit_name: "text_input"))
prepend(FormFieldBuilder.new(:number_field, kit_name: "text_input"))
Expand Down
14 changes: 14 additions & 0 deletions playbook/lib/playbook/forms/builder/star_rating_field.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# frozen_string_literal: true

module Playbook
module Forms
class Builder
def star_rating_field(name, props: {})
props[:name] = name
props[:margin_bottom] = "sm"
props[:label] = @template.label(@object_name, name) if props[:label] == true
@template.pb_rails("star_rating", props: props)
end
end
end
end
6 changes: 6 additions & 0 deletions playbook/spec/pb_kits/playbook/kits/star_rating_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,12 @@
.with_values("xs", "sm", "md", "lg")
}

it {
is_expected.to define_enum_prop(:variant)
.with_default("display")
.with_values("display", "interactive")
}

describe "#classname" do
it "returns namespaced class name", :aggregate_failures do
expect(subject.new({}).classname).to eq "pb_star_rating_kit"
Expand Down

0 comments on commit a07c7f8

Please sign in to comment.