diff --git a/packages/components/src/index.ts b/packages/components/src/index.ts index 3dde605808..fcae5e5602 100644 --- a/packages/components/src/index.ts +++ b/packages/components/src/index.ts @@ -142,6 +142,8 @@ export { default as RadioGroup, RadioOption } from './molecules/RadioGroup' export type { RadioGroupProps, RadioOptionProps } from './molecules/RadioGroup' export { default as Rating } from './molecules/Rating' export type { RatingProps } from './molecules/Rating' +export { default as RatingField } from './molecules/RatingField' +export type { RatingFieldProps } from './molecules/RatingField' export { default as RegionBar } from './molecules/RegionBar' export type { RegionBarProps } from './molecules/RegionBar' diff --git a/packages/components/src/molecules/RatingField/RatingField.tsx b/packages/components/src/molecules/RatingField/RatingField.tsx new file mode 100644 index 0000000000..0d2e5a8ed5 --- /dev/null +++ b/packages/components/src/molecules/RatingField/RatingField.tsx @@ -0,0 +1,71 @@ +import React from 'react' +import type { MutableRefObject } from 'react' +import { Label, Rating, type RatingProps } from '../..' + +interface DefaultProps { + /** + * ID to find this component in testing tools (e.g.: cypress, testing library, and jest). + */ + testId?: string + /** + * ID to identify input and corresponding label. + */ + id: string + /** + * The text displayed to identify the input rating. + */ + label: string + /** + * The error message displayed when an error occurs. + */ + error?: string + /** + * Component's ref. + */ + ratingRef?: MutableRefObject +} + +export type RatingFieldProps = DefaultProps & RatingProps + +const RatingField = ({ + id, + label, + error, + disabled, + length = 5, + value = 0, + onChange, + ratingRef, + testId = 'fs-rating-field', + ...otherProps +}: RatingFieldProps) => { + const shouldDisplayError = !disabled && error && error !== '' + + return ( +
+ + + {shouldDisplayError && ( + {error} + )} +
+ ) +} + +export default RatingField diff --git a/packages/components/src/molecules/RatingField/index.ts b/packages/components/src/molecules/RatingField/index.ts new file mode 100644 index 0000000000..06749f3abe --- /dev/null +++ b/packages/components/src/molecules/RatingField/index.ts @@ -0,0 +1,2 @@ +export { default } from './RatingField' +export type { RatingFieldProps } from './RatingField' diff --git a/packages/ui/src/components/molecules/Rating/styles.scss b/packages/ui/src/components/molecules/Rating/styles.scss index ac6817361a..709699eb9b 100644 --- a/packages/ui/src/components/molecules/Rating/styles.scss +++ b/packages/ui/src/components/molecules/Rating/styles.scss @@ -18,10 +18,12 @@ --fs-rating-actionable-icon-height : var(--fs-rating-actionable-icon-width); --fs-rating-actionable-icon-color : var(--fs-rating-color-empty); --fs-rating-actionable-icon-color-selected : var(--fs-rating-color); + --fs-rating-button-min-height : var(--fs-spacing-5); // -------------------------------------------------------- // Structural Styles // -------------------------------------------------------- + display: flex; [data-fs-icon] { @@ -31,6 +33,8 @@ } [data-fs-rating-button] { + --fs-button-small-min-height: var(--fs-rating-button-min-height); + color: unset; &[disabled] [data-fs-button-wrapper] { @@ -92,6 +96,7 @@ [data-fs-icon] { width: var(--fs-rating-actionable-icon-width); height: var(--fs-rating-actionable-icon-height); + color: var(--fs-rating-actionable-color); color: var(--fs-rating-actionable-icon-color); } } diff --git a/packages/ui/src/components/molecules/RatingField/styles.scss b/packages/ui/src/components/molecules/RatingField/styles.scss new file mode 100644 index 0000000000..6daa6cccff --- /dev/null +++ b/packages/ui/src/components/molecules/RatingField/styles.scss @@ -0,0 +1,44 @@ +[data-fs-rating-field] { + // -------------------------------------------------------- + // Design Tokens for Rating Field + // -------------------------------------------------------- + + // Label + --fs-rating-field-label-color : var(--fs-color-text-light); + --fs-rating-field-label-size : var(--fs-text-size-2); + --fs-rating-field-label-line-height : var(--fs-text-size-4); + + // Error + --fs-rating-field-error-message-size : var(--fs-text-size-legend); + --fs-rating-field-error-message-line-height : 1.1; + --fs-rating-field-error-message-color : var(--fs-color-danger-text); + + // -------------------------------------------------------- + // Structural Styles + // -------------------------------------------------------- + display: flex; + flex-direction: column; + + [data-fs-rating-field-label] { + margin-bottom: var(--fs-spacing-0); + font-size: var(--fs-rating-field-label-size); + line-height: var(--fs-rating-field-label-line-height); + color: var(--fs-rating-field-label-color); + } + + [data-fs-rating-field-error-message] { + margin-top: var(--fs-spacing-0); + font-size: var(--fs-rating-field-error-message-size); + line-height: var(--fs-rating-field-error-message-line-height); + color: var(--fs-rating-field-error-message-color); + } + + // -------------------------------------------------------- + // Variants Styles + // -------------------------------------------------------- + &[data-fs-rating-field-error="true"] { + [data-fs-rating-item="empty"] [data-fs-icon] { + color: var(--fs-rating-field-error-message-color); + } + } +} diff --git a/packages/ui/src/styles/components.scss b/packages/ui/src/styles/components.scss index e5be295692..431a094e8b 100644 --- a/packages/ui/src/styles/components.scss +++ b/packages/ui/src/styles/components.scss @@ -41,6 +41,7 @@ @import "../components/molecules/QuantitySelector/styles"; @import "../components/molecules/RadioField/styles"; @import "../components/molecules/Rating/styles"; +@import "../components/molecules/RatingField/styles"; @import "../components/molecules/RegionBar/styles"; @import "../components/molecules/SearchAutoComplete/styles"; @import "../components/molecules/SearchDropdown/styles";