| @@ -2,8 +2,9 @@ | ||
| 2 | 2 | |
| 3 | 3 | namespace FluentForm\App\Services\FormBuilder\Components; |
| 4 | 4 | |
| 5 | 5 | use FluentForm\App\Helpers\Helper; |
| 6 | +use FluentForm\App\Services\FormBuilder\RatingIcon; | |
| 6 | 7 | use FluentForm\Framework\Helpers\ArrayHelper; |
| 7 | 8 | |
| 8 | 9 | class Rating extends BaseComponent |
| 9 | 10 | { |
| @@ -35,14 +36,32 @@ | ||
| 35 | 36 | $data['attributes']['type'] = 'radio'; |
| 36 | 37 | |
| 37 | 38 | $defaultValues = (array) $this->extractValueFromAttributes($data); |
| 38 | 39 | |
| 39 | - $elMarkup = "<div class='ff-el-ratings jss-ff-el-ratings' role='radiogroup'>"; | |
| 40 | + $iconSettings = RatingIcon::resolveSettings($data); | |
| 41 | + $iconSvg = RatingIcon::getResolvedIconSvg($data, [ | |
| 42 | + 'class' => 'ff-rating-icon-svg jss-ff-svg ff-svg', | |
| 43 | + ]); | |
| 44 | + $ratingStyles = sprintf( | |
| 45 | + '--ff-rating-inactive-color: %s; --ff-rating-active-color: %s;', | |
| 46 | + esc_attr($iconSettings['inactive_color']), | |
| 47 | + esc_attr($iconSettings['active_color']) | |
| 48 | + ); | |
| 49 | + | |
| 50 | + $firstTabIndex = Helper::getNextTabIndex(); | |
| 51 | + $elMarkup = "<div class='ff-el-ratings jss-ff-el-ratings' role='radiogroup' style='" . $ratingStyles . "' data-rating-icon-source='" . esc_attr($iconSettings['icon_source']) . "' data-rating-icon-type='" . esc_attr($iconSettings['icon_type']) . "' data-base-tabindex='" . esc_attr($firstTabIndex ?: 0) . "'>"; | |
| 40 | 52 | $ratingText = ''; |
| 53 | + $selectedValues = array_filter(array_map('strval', $defaultValues), function ($value) { | |
| 54 | + return $value !== ''; | |
| 55 | + }); | |
| 56 | + $hasSelectedValue = !empty($selectedValues); | |
| 57 | + $optionIndex = 0; | |
| 41 | 58 | |
| 42 | - foreach ($data['options'] as $value => $label) { | |
| 59 | + foreach ((array) ArrayHelper::get($data, 'options', []) as $value => $label) { | |
| 43 | 60 | $starred = ''; |
| 44 | - if (in_array($value, $defaultValues)) { | |
| 61 | + $isSelected = in_array((string) $value, $selectedValues, true); | |
| 62 | + | |
| 63 | + if ($isSelected) { | |
| 45 | 64 | $data['attributes']['checked'] = true; |
| 46 | 65 | $starred = 'active'; |
| 47 | 66 | } else { |
| 48 | 67 | $data['attributes']['checked'] = false; |
| @@ -47,14 +66,11 @@ | ||
| 47 | 66 | } else { |
| 48 | 67 | $data['attributes']['checked'] = false; |
| 49 | 68 | } |
| 50 | 69 | |
| 51 | - if ($tabIndex = Helper::getNextTabIndex()) { | |
| 52 | - $data['attributes']['tabindex'] = $tabIndex; | |
| 53 | - } | |
| 54 | - | |
| 70 | + $data['attributes']['tabindex'] = -1; | |
| 55 | 71 | $atts = $this->buildAttributes($data['attributes']); |
| 56 | - $id = esc_attr($this->getUniqueid(str_replace(['[', ']'], ['', ''], $data['attributes']['name']))); | |
| 72 | + $id = esc_attr($this->getUniqueId(str_replace(['[', ']'], ['', ''], $data['attributes']['name']))); | |
| 57 | 73 | |
| 58 | 74 | $ariaRequired = 'false'; |
| 59 | 75 | if (ArrayHelper::get($data, 'settings.validation_rules.required.value')) { |
| 60 | 76 | $ariaRequired = 'true'; |
| @@ -59,16 +75,24 @@ | ||
| 59 | 75 | if (ArrayHelper::get($data, 'settings.validation_rules.required.value')) { |
| 60 | 76 | $ariaRequired = 'true'; |
| 61 | 77 | } |
| 62 | 78 | |
| 63 | - $elMarkup .= "<label for={$id} class='{$starred}'><input {$atts} id={$id} aria-valuenow='" . esc_attr($value) . "' value='" . esc_attr($value) . "' aria-required={$ariaRequired} aria-invalid='false'>"; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- $starred, $atts, $id are escaped before being passed in. | |
| 64 | - $elMarkup .= '<?xml version="1.0" encoding="iso-8859-1"?><svg class="jss-ff-svg ff-svg" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 53.867 53.867" style="enable-background:new 0 0 53.867 53.867;" xml:space="preserve"><polygon points="26.934,1.318 35.256,18.182 53.867,20.887 40.4,34.013 43.579,52.549 26.934,43.798 10.288,52.549 13.467,34.013 0,20.887 18.611,18.182 "/><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g></svg>'; | |
| 79 | + $labelTabIndex = -1; | |
| 80 | + if ($isSelected || (!$hasSelectedValue && $optionIndex === 0)) { | |
| 81 | + $labelTabIndex = $firstTabIndex ?: 0; | |
| 82 | + } | |
| 83 | + | |
| 84 | + $checked = $isSelected ? 'true' : 'false'; | |
| 85 | + $elMarkup .= "<label for={$id} class='{$starred}' role='radio' aria-checked='{$checked}' aria-label='" . esc_attr(wp_strip_all_tags($label)) . "' tabindex='" . esc_attr($labelTabIndex) . "'><input {$atts} id={$id} aria-valuenow='" . esc_attr($value) . "' value='" . esc_attr($value) . "' aria-required={$ariaRequired} aria-invalid='false'>"; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- $starred, $atts, $id are escaped before being passed in. | |
| 86 | + $elMarkup .= "<span class='ff-rating-icon' aria-hidden='true'>{$iconSvg}</span>"; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- SVG is sanitized before output. | |
| 65 | 87 | $elMarkup .= '</label>'; |
| 66 | 88 | |
| 67 | 89 | if ('yes' == ArrayHelper::get($data, 'settings.show_text')) { |
| 68 | - $displayDefaultText = in_array($value, $defaultValues) ? 'display: inline-block' : 'display: none'; | |
| 90 | + $displayDefaultText = $isSelected ? 'display: inline-block' : 'display: none'; | |
| 69 | 91 | $ratingText .= "<span style='{$displayDefaultText}' class='ff-el-rating-text' data-id='{$id}'>" . fluentform_sanitize_html($label) . '</span>'; |
| 70 | 92 | } |
| 93 | + | |
| 94 | + $optionIndex++; | |
| 71 | 95 | }; |
| 72 | 96 | |
| 73 | 97 | $elMarkup .= '</div>' . $ratingText; |
| 74 | 98 | |