Skip to content

Commit

Permalink
Add Rating component v2
Browse files Browse the repository at this point in the history
  • Loading branch information
relja-rasa committed Feb 5, 2025
1 parent cb2dff6 commit f4e8558
Show file tree
Hide file tree
Showing 7 changed files with 144 additions and 41 deletions.
12 changes: 10 additions & 2 deletions packages/ui/src/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -426,11 +426,15 @@ export namespace Components {
/**
* List of rating options
*/
"options": string | { value: string; icon: string; label: string }[];
"options": string | { value: string }[];
/**
* Instructional text for the rating component
*/
"text": string;
/**
* Customizable thank-you message from Rasa
*/
"thankYouMessage": string;
}
interface RasaSessionDivider {
/**
Expand Down Expand Up @@ -1302,11 +1306,15 @@ declare namespace LocalJSX {
/**
* List of rating options
*/
"options"?: string | { value: string; icon: string; label: string }[];
"options"?: string | { value: string }[];
/**
* Instructional text for the rating component
*/
"text"?: string;
/**
* Customizable thank-you message from Rasa
*/
"thankYouMessage"?: string;
}
interface RasaSessionDivider {
/**
Expand Down
70 changes: 52 additions & 18 deletions packages/ui/src/components/rating/rating.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,70 +2,104 @@
border-radius: 12px;
background-color: var(--rating-background-color, #fff);
color: var(--rating-text-color, #333);
margin: 0;
padding: 8px 16px 12px;
margin: 0 auto;
padding: 8px;
text-align: center;
max-width: 400px;

&__text {
margin: 0 0 12px;
font-size: 1rem;
font-weight: 200;
font-weight: 500;
color: var(--rating-instruction-color, #333);
}

&__thank-you {
margin: 0;
font-size: 1rem; /* Slightly larger for emphasis */
font-weight: 600; /* Bolder for prominence */
color: var(--rating-thank-you-color, #4CAF50); /* Match success color */
text-align: center;
animation: fadeIn 0.3s ease-in-out; /* Smooth fade-in animation */
}

&__options {
display: flex;
justify-content: center;
flex-wrap: wrap;
gap: 12px;
justify-content: space-between;
align-items: center;
gap: 8px;
flex-wrap: nowrap;
}

&__option {
background: var(--rating-option-background-color, #f9f9f9);
flex: 1 1 0;
max-width: 100px;
background: var(--rating-option-background-color, #fff);
border: 1px solid var(--rating-option-border-color, #ddd);
border-radius: 8px;
padding: 8px 12px;
padding: 8px;
cursor: pointer;
display: flex;
flex-direction: column;
align-items: center;
transition: transform 0.2s ease, background-color 0.3s, box-shadow 0.3s;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);

&:hover {
background: var(--rating-option-hover-color, #f0f0f0);
transform: translateY(-1px) scale(1.02);
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.15);
background: var(--rating-option-hover-color, #f9f9f9);
transform: scale(1.05);
box-shadow: 0 3px 6px rgba(0, 0, 0, 0.15);
}

&--selected {
border-color: var(--rating-option-selected-border-color, #007bff);
background: var(--rating-option-selected-background-color, #e9f5ff);
color: var(--rating-option-selected-text-color, #007bff);
box-shadow: 0 4px 6px rgba(0, 123, 255, 0.2);
box-shadow: 0 4px 8px rgba(0, 123, 255, 0.2);
}
}

&__icon {
font-size: 1.25rem;
width: 40px;
height: 40px;
margin-bottom: 4px;

svg {
width: 100%;
height: 100%;
display: block;
}
}

&__label {
font-size: 0.875rem;
font-weight: 500;
color: var(--rating-option-label-color, #444);
text-align: center;
}
}

@media (max-width: 768px) {
.rasa-rating__options {
gap: 8px;
gap: 6px;
}

.rasa-rating__option {
flex: 1 1 calc(33% - 16px);
max-width: 100px;
padding: 6px 10px;
max-width: 80px;
padding: 6px;
}

.rasa-rating__thank-you {
font-size: 1rem;
}
}

/* Fade-in animation for the thank-you message */
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
83 changes: 63 additions & 20 deletions packages/ui/src/components/rating/rating.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,12 @@ export class RasaRating {
/**
* List of rating options
*/
@Prop() options: string | { value: string; icon: string; label: string }[] = [];
@Prop() options: string | { value: string }[] = [];

/**
* Customizable thank-you message from Rasa
*/
@Prop() thankYouMessage: string = "Thank you for your feedback!";

/**
* Event emitted when a rating is selected
Expand All @@ -27,16 +32,22 @@ export class RasaRating {
*/
@State() selectedOption: string | null = null;

/**
* State to track if the user has voted
*/
@State() hasVoted: boolean = false;

componentDidLoad() {
messageQueueService.completeRendering();
}

private handleOptionClick(optionValue: string) {
this.selectedOption = optionValue; // Update the selected option
this.ratingSelected.emit({ value: optionValue }); // Emit the event
this.selectedOption = optionValue;
this.hasVoted = true;
this.ratingSelected.emit({ value: optionValue });
}

private getParsedOptions(): { value: string; icon: string; label: string }[] {
private getParsedOptions(): { value: string }[] {
if (typeof this.options === 'string') {
try {
return JSON.parse(this.options);
Expand All @@ -48,27 +59,59 @@ export class RasaRating {
return this.options;
}

private getIconForValue(value: string): string {
switch (value) {
case 'positive':
return `<svg width="40" height="40" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="12" cy="12" r="10" fill="white" stroke="#4CAF50" stroke-width="2"/>
<circle cx="9" cy="10" r="1.5" fill="#4CAF50"/>
<circle cx="15" cy="10" r="1.5" fill="#4CAF50"/>
<path d="M8.5 14.5c1.75 2 5.25 2 7 0" stroke="#4CAF50" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>`;
case 'neutral':
return `<svg width="40" height="40" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="12" cy="12" r="10" fill="white" stroke="#FFEB3B" stroke-width="2"/>
<circle cx="9" cy="10" r="1.5" fill="#FFEB3B"/>
<circle cx="15" cy="10" r="1.5" fill="#FFEB3B"/>
<path d="M8.5 14h7" stroke="#FFEB3B" stroke-width="2" stroke-linecap="round"/>
</svg>`;
case 'negative':
return `<svg width="40" height="40" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="12" cy="12" r="10" fill="white" stroke="#F44336" stroke-width="2"/>
<circle cx="9" cy="10" r="1.5" fill="#F44336"/>
<circle cx="15" cy="10" r="1.5" fill="#F44336"/>
<path d="M8.5 15.5c1.75-2 5.25-2 7 0" stroke="#F44336" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>`;
default:
return '';
}
}

render() {
const parsedOptions = this.getParsedOptions();

return (
<div class="rasa-rating">
<p class="rasa-rating__text">{this.text}</p>
<div class="rasa-rating__options">
{parsedOptions.map((option) => (
<button
key={option.value}
class={{
'rasa-rating__option': true,
'rasa-rating__option--selected': this.selectedOption === option.value,
}}
onClick={() => this.handleOptionClick(option.value)}
>
<span class="rasa-rating__icon">{option.icon}</span>
<span class="rasa-rating__label">{option.label}</span>
</button>
))}
</div>
{this.hasVoted ? (
<p class="rasa-rating__thank-you">{this.thankYouMessage}</p> // Thank-you message from Rasa
) : (
<div>
<p class="rasa-rating__text">{this.text}</p>
<div class="rasa-rating__options">
{parsedOptions.map((option) => (
<button
key={option.value}
class={{
'rasa-rating__option': true,
'rasa-rating__option--selected': this.selectedOption === option.value,
}}
onClick={() => this.handleOptionClick(option.value)}
innerHTML={this.getIconForValue(option.value)} // Injecting the SVG directly into the button
></button>
))}
</div>
</div>
)}
</div>
);
}
Expand Down
6 changes: 6 additions & 0 deletions packages/ui/src/icons/happy.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions packages/ui/src/icons/neutral.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions packages/ui/src/icons/sad.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion packages/ui/src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@
<link rel="icon" type="image/png" sizes="16x16" href="https://rasa.com/favicon-16x16.png?v=210226" />
</head>
<body>
<rasa-chatbot-widget></rasa-chatbot-widget>
<rasa-chatbot-widget server-url="https://3f5f-109-245-194-87.ngrok-free.app" rest-enabled="true"></rasa-chatbot-widget>
</body>
</html>

0 comments on commit f4e8558

Please sign in to comment.