next-helios-fe 1.7.28 → 1.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "next-helios-fe",
3
- "version": "1.7.28",
3
+ "version": "1.8.1",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -22,6 +22,7 @@ import {
22
22
  type MultipleSelectProps,
23
23
  } from "./other/multipleSelect";
24
24
  import { Autocomplete, type AutocompleteProps } from "./other/autocomplete";
25
+ import { Rating, type RatingProps } from "./other/rating";
25
26
  import { Emoji, type EmojiProps } from "./other/emoji";
26
27
 
27
28
  interface FormProps extends React.FormHTMLAttributes<HTMLFormElement> {
@@ -48,6 +49,7 @@ interface FormComponent extends React.FC<FormProps> {
48
49
  Select: React.FC<SelectProps>;
49
50
  MultipleSelect: React.FC<MultipleSelectProps>;
50
51
  Autocomplete: React.FC<AutocompleteProps>;
52
+ Rating: React.FC<RatingProps>;
51
53
  Emoji: React.FC<EmojiProps>;
52
54
  }
53
55
 
@@ -84,4 +86,5 @@ Form.Textarea = Textarea;
84
86
  Form.Select = Select;
85
87
  Form.MultipleSelect = MultipleSelect;
86
88
  Form.Autocomplete = Autocomplete;
89
+ Form.Rating = Rating;
87
90
  Form.Emoji = Emoji;
@@ -0,0 +1,121 @@
1
+ "use client";
2
+ import React, { useState, useEffect } from "react";
3
+ import { Icon } from "@iconify/react";
4
+
5
+ export interface RatingProps extends React.InputHTMLAttributes<HTMLInputElement> {
6
+ label?: string;
7
+ description?: string;
8
+ options?: {
9
+ height?: "short" | "medium" | "high";
10
+ };
11
+ }
12
+
13
+ export const Rating: React.FC<RatingProps> = ({
14
+ options,
15
+ label,
16
+ description,
17
+ ...rest
18
+ }) => {
19
+ const [tempValue, setTempValue] = useState("");
20
+ const height =
21
+ options?.height === "short"
22
+ ? "py-1"
23
+ : options?.height === "high"
24
+ ? "py-2"
25
+ : "py-1.5";
26
+
27
+ const starHeight =
28
+ options?.height === "short"
29
+ ? "text-3xl"
30
+ : options?.height === "high"
31
+ ? "text-5xl"
32
+ : "text-4xl";
33
+
34
+ useEffect(() => {
35
+ if (rest.value || rest.value === "") {
36
+ setTempValue(rest.value as string);
37
+ return;
38
+ } else if (rest.defaultValue || rest.defaultValue === "") {
39
+ setTempValue(rest.defaultValue as string);
40
+ return;
41
+ }
42
+ }, [rest.value, rest.defaultValue]);
43
+
44
+ return (
45
+ <div className="grid gap-2 w-fit">
46
+ {(label || description) && (
47
+ <div className="flex items-center">
48
+ {label && (
49
+ <span
50
+ className={`text-sm select-none ${
51
+ rest.required &&
52
+ "after:content-['*'] after:ml-1 after:text-danger"
53
+ }`}
54
+ >
55
+ {label}
56
+ </span>
57
+ )}
58
+ {description && (
59
+ <span
60
+ title={description}
61
+ className="ms-auto text-sm text-primary-dark"
62
+ >
63
+ <Icon icon="octicon:info-16" />
64
+ </span>
65
+ )}
66
+ </div>
67
+ )}
68
+ <div className="relative">
69
+ <div className="flex items-center gap-2">
70
+ {Array.from({
71
+ length: 5,
72
+ }).map((_, index) => {
73
+ return (
74
+ <button
75
+ key={index}
76
+ type="button"
77
+ disabled={rest.disabled}
78
+ onClick={() => {
79
+ if (tempValue !== (index + 1).toString()) {
80
+ setTempValue((index + 1).toString());
81
+
82
+ if (rest.onChange) {
83
+ rest.onChange({
84
+ target: {
85
+ value: (index + 1).toString(),
86
+ } as HTMLSelectElement,
87
+ } as any);
88
+ }
89
+ } else {
90
+ setTempValue("");
91
+
92
+ if (rest.onChange) {
93
+ rest.onChange({
94
+ target: { value: "" } as HTMLSelectElement,
95
+ } as any);
96
+ }
97
+ }
98
+ }}
99
+ className={`duration-300 ease-in-out ${starHeight} ${
100
+ rest.disabled ? "text-slate-400" : "text-warning"
101
+ }`}
102
+ >
103
+ <Icon
104
+ icon={`fluent:star-12-${
105
+ parseInt(tempValue) >= index + 1 ? "filled" : "regular"
106
+ }`}
107
+ />
108
+ </button>
109
+ );
110
+ })}
111
+ </div>
112
+ <input
113
+ type="text"
114
+ className={`absolute top-0 w-full border-0 bg-transparent text-transparent caret-transparent pointer-events-none focus:ring-0 ${height}`}
115
+ value={tempValue}
116
+ required={rest.required}
117
+ />
118
+ </div>
119
+ </div>
120
+ );
121
+ };