diff --git a/assets/core/scss/tokens/_colors.scss b/assets/core/scss/tokens/_colors.scss index e7c9db010a..b0bec1be0c 100644 --- a/assets/core/scss/tokens/_colors.scss +++ b/assets/core/scss/tokens/_colors.scss @@ -6,16 +6,16 @@ // ============================================================================= // Brand Colors -$tutor-brand-100: #f6f8fe; -$tutor-brand-200: #e4ebfc; -$tutor-brand-300: #dbe4fa; -$tutor-brand-400: #a4bcf4; -$tutor-brand-500: #4979e8; -$tutor-brand-600: #3e64de; -$tutor-brand-700: #2b49ca; -$tutor-brand-800: #293da4; -$tutor-brand-900: #263782; -$tutor-brand-950: #1c234f; +$tutor-brand-100: var(--tutor-brand-100, #f6f8fe); +$tutor-brand-200: var(--tutor-brand-200, #e4ebfc); +$tutor-brand-300: var(--tutor-brand-300, #dbe4fa); +$tutor-brand-400: var(--tutor-brand-400, #a4bcf4); +$tutor-brand-500: var(--tutor-brand-500, #4979e8); +$tutor-brand-600: var(--tutor-brand-600, #3e64de); +$tutor-brand-700: var(--tutor-brand-700, #2b49ca); +$tutor-brand-800: var(--tutor-brand-800, #293da4); +$tutor-brand-900: var(--tutor-brand-900, #263782); +$tutor-brand-950: var(--tutor-brand-950, #1c234f); // Gray Colors $tutor-gray-1: #ffffff; diff --git a/assets/images/images-v2/default-theme/auto.webp b/assets/images/images-v2/default-theme/auto.webp new file mode 100644 index 0000000000..4c5fc4fcb6 Binary files /dev/null and b/assets/images/images-v2/default-theme/auto.webp differ diff --git a/assets/images/images-v2/default-theme/dark.webp b/assets/images/images-v2/default-theme/dark.webp new file mode 100644 index 0000000000..e3c95d9f60 Binary files /dev/null and b/assets/images/images-v2/default-theme/dark.webp differ diff --git a/assets/images/images-v2/default-theme/light.webp b/assets/images/images-v2/default-theme/light.webp new file mode 100644 index 0000000000..5e49c25a42 Binary files /dev/null and b/assets/images/images-v2/default-theme/light.webp differ diff --git a/assets/images/images-v2/learning-mode/kids.svg b/assets/images/images-v2/learning-mode/kids.svg new file mode 100644 index 0000000000..8752560621 --- /dev/null +++ b/assets/images/images-v2/learning-mode/kids.svg @@ -0,0 +1,33 @@ + diff --git a/assets/images/images-v2/learning-mode/legacy.svg b/assets/images/images-v2/learning-mode/legacy.svg new file mode 100644 index 0000000000..1b786171a5 --- /dev/null +++ b/assets/images/images-v2/learning-mode/legacy.svg @@ -0,0 +1,11 @@ + diff --git a/assets/images/images-v2/learning-mode/modern.svg b/assets/images/images-v2/learning-mode/modern.svg new file mode 100644 index 0000000000..c3bd6d0a76 --- /dev/null +++ b/assets/images/images-v2/learning-mode/modern.svg @@ -0,0 +1,4 @@ + diff --git a/assets/images/vision/deuteranomaly.webp b/assets/images/vision/deuteranomaly.webp index 64e3b90100..4773fdc0a8 100644 Binary files a/assets/images/vision/deuteranomaly.webp and b/assets/images/vision/deuteranomaly.webp differ diff --git a/assets/images/vision/deuteranopia.webp b/assets/images/vision/deuteranopia.webp index cfebb3dbcd..d6c3b9ace4 100644 Binary files a/assets/images/vision/deuteranopia.webp and b/assets/images/vision/deuteranopia.webp differ diff --git a/assets/images/vision/normal.webp b/assets/images/vision/normal.webp index 8bd0e0c5d2..766ffa3bfa 100644 Binary files a/assets/images/vision/normal.webp and b/assets/images/vision/normal.webp differ diff --git a/assets/images/vision/protanopia.webp b/assets/images/vision/protanopia.webp index cfc82a2842..f45cf387e2 100644 Binary files a/assets/images/vision/protanopia.webp and b/assets/images/vision/protanopia.webp differ diff --git a/assets/src/js/admin-dashboard/segments/reset.js b/assets/src/js/admin-dashboard/segments/reset.js index cdd8aab5ba..0ee942f629 100644 --- a/assets/src/js/admin-dashboard/segments/reset.js +++ b/assets/src/js/admin-dashboard/segments/reset.js @@ -47,7 +47,7 @@ const resetConfirmation = () => { if (xhttp.readyState === 4) { let pageData = JSON.parse(xhttp.response).data; pageData.forEach((item) => { - const field_types_associate = ['color_preset', 'upload_full', 'checkbox_notification', 'checkgroup', 'group_radio_full_3', 'group_radio', 'radio_vertical', 'checkbox_horizontal', 'radio_horizontal', 'radio_horizontal_full', 'checkbox_vertical', 'toggle_switch', 'toggle_switch_button', 'text', 'textarea', 'email', 'hidden', 'select', 'number']; + const field_types_associate = ['color_field', 'upload_full', 'checkbox_notification', 'checkgroup', 'group_radio_full_3', 'group_radio', 'radio_vertical', 'checkbox_horizontal', 'radio_horizontal', 'radio_horizontal_full', 'radio_horizontal_image', 'checkbox_vertical', 'toggle_switch', 'toggle_switch_button', 'text', 'textarea', 'email', 'hidden', 'select', 'number']; if (field_types_associate.includes(item.type)) { let itemName = 'tutor_option[' + item.key + ']'; @@ -60,36 +60,14 @@ const resetConfirmation = () => { elementOption.selected = typeof item.default === 'number' ? elementOption.value === item.default : item.default.includes(elementOption.value); }); - } else if (item.type == 'color_preset') { - - let presetItems = elementByName(itemName); - presetItems.forEach((presetItem) => { - let labelClasses = presetItem.parentElement.classList; - item.default.includes(presetItem.value) ? labelClasses.add('is-checked') : labelClasses.remove('is-checked'); - presetItem.checked = item.default.includes(presetItem.value) ? true : false; - }) - - item.fields.forEach((fields) => { - if (fields.key === item.default) { - fields.colors.forEach((picker) => { - let pickerName = 'tutor_option[' + picker.slug + ']'; - let pickerItem = elementByName(pickerName)[0]; - let pickerItemParent = pickerItem.parentElement; - pickerItem.value = picker.value; - pickerItem.nextElementSibling.innerText = picker.value; - - pickerItemParent.style.borderColor = picker.value; - pickerItemParent.style.boxShadow = `inset 0 0 0 1px ${picker.value}`; - - setTimeout(() => { - pickerItemParent.style.borderColor = '#cdcfd5'; - pickerItemParent.style.boxShadow = 'none'; - }, 5000); - }) - } - }) - - } else if (item.type == 'checkbox_horizontal' || item.type == 'checkbox_vertical' || item.type == 'radio_horizontal' || item.type == 'radio_horizontal_full' || item.type == 'radio_vertical' || item.type == 'group_radio' || item.type == 'group_radio_full_3') { + } else if (item.type == 'color_field') { + let pickerName = 'tutor_option[' + item.key + ']'; + let pickerItem = elementByName(pickerName)[0]; + if (pickerItem) { + pickerItem.value = item.default; + pickerItem.nextElementSibling.innerText = item.default; + } + } else if (item.type == 'checkbox_horizontal' || item.type == 'checkbox_vertical' || item.type == 'radio_horizontal' || item.type == 'radio_horizontal_full' || item.type == 'radio_horizontal_image' || item.type == 'radio_vertical' || item.type == 'group_radio' || item.type == 'group_radio_full_3') { if (item.type == 'checkbox_horizontal') { Object.keys(item.options).forEach((optionKeys) => { diff --git a/assets/src/scss/admin-dashboard/v2/components/_custom-input-field.scss b/assets/src/scss/admin-dashboard/v2/components/_custom-input-field.scss index 97a974d1aa..a9f905879c 100644 --- a/assets/src/scss/admin-dashboard/v2/components/_custom-input-field.scss +++ b/assets/src/scss/admin-dashboard/v2/components/_custom-input-field.scss @@ -71,6 +71,60 @@ } } } + + &.radio-thumbnail-image { + display: flex; + align-items: center; + justify-content: end; + gap: 16px; + + label { + display: flex; + flex-direction: column; + align-items: center; + justify-self: center; + padding-block: 8px; + position: relative; + border: 1px solid #c0c3cb; + border-radius: 6px; + height: 90px; + width: 88px; + + img { + max-width: 100%; + } + + &:before { + content: ""; + position: absolute; + right: -8px; + top: -8px; + height: 16px; + width: 16px; + border-radius: 50%; + background-size: 8px; + background-color: transparent; + background-repeat: no-repeat; + background-position: 50%; + transition: 0.3s; + } + + &:has(input[type="radio"]:checked) { + border-color: var(--tutor-color-primary); + + &:before { + background-color: var(--tutor-color-primary); + @include svg-check-icon-2; + } + } + + .image-title { + color: #262626; + font-size: 13px; + line-height: 18px; + } + } + } } .items-per-row-label { diff --git a/assets/src/scss/frontend/dashboard/settings/_social-accounts.scss b/assets/src/scss/frontend/dashboard/settings/_social-accounts.scss index 7fa6ef399f..bd40e94c4e 100644 --- a/assets/src/scss/frontend/dashboard/settings/_social-accounts.scss +++ b/assets/src/scss/frontend/dashboard/settings/_social-accounts.scss @@ -24,6 +24,6 @@ &-icon { position: relative; color: $tutor-icon-idle; - top: 38px; + top: 37px; } } \ No newline at end of file diff --git a/assets/src/scss/frontend/kids/_dashboard.scss b/assets/src/scss/frontend/kids/_dashboard.scss index ba6506599a..8874cc1206 100644 --- a/assets/src/scss/frontend/kids/_dashboard.scss +++ b/assets/src/scss/frontend/kids/_dashboard.scss @@ -179,6 +179,10 @@ border-radius: $tutor-radius-5xl; } + .tutor-account-section .tutor-account-cover-photo { + border-radius: $tutor-radius-4xl; + } + .tutor-review-card { .tutor-review-form { border-radius: $tutor-radius-6xl; diff --git a/classes/Assets.php b/classes/Assets.php index c575b56891..8653bc9360 100644 --- a/classes/Assets.php +++ b/classes/Assets.php @@ -571,11 +571,25 @@ private function load_color_palette() { 'tutor_gray_color' => '#CDCFD5', ); + $brand_color = tutor_utils()->get_brand_color(); + $color_string = ''; foreach ( $colors as $key => $property ) { $fallback_color = isset( $fallback_colors[ $key ] ) ? $fallback_colors[ $key ] : '#212327'; - $color = tutor_utils()->get_option( $key, $fallback_color ); - $color_rgb = tutor_utils()->hex2rgb( $color ); + $color = $fallback_color; + + if ( Options_V2::DEFAULT_BRAND_COLOR !== $brand_color ) { + if ( 'tutor_primary_color' === $key ) { + $color = $brand_color; + } + + if ( 'tutor_primary_hover_color' === $key ) { + $palette = $this->generate_color_palette( $brand_color ); + $color = $palette[700]; + } + } + + $color_rgb = tutor_utils()->hex2rgb( $color ); if ( is_admin() && isset( $admin_colors[ $property ] ) ) { $color = $admin_colors[ $property ]; @@ -594,6 +608,81 @@ private function load_color_palette() { return ':root{' . $color_string . '}'; } + /** + * Generate color palette + * + * @since 4.0.0 + * + * @param string $base_hex HEX color code. + * + * @return array + */ + private function generate_color_palette( $base_hex ) { + $base = tutor_utils()->hex_to_hsl( $base_hex ); + + // Mapping of [Hue-Shift, Saturation-Shift, Target-Lightness]. + $rules = array( + 100 => array( -1, 3, 97.5 ), + 200 => array( -3, 1, 94.1 ), + 300 => array( -3, -2, 92.2 ), + 400 => array( -4, 0, 79.6 ), + 500 => array( -4, 5, 59.8 ), + 600 => array( 0, 0, $base['l'] ), + 700 => array( 3, -7, 48.0 ), + 800 => array( 4, -12, 40.2 ), + 900 => array( 5, -17, 33.1 ), + 950 => array( 6, -24, 20.8 ), + ); + + $palette = array(); + foreach ( $rules as $weight => $modifier ) { + if ( 600 === $weight ) { + $palette[ $weight ] = strtolower( $base_hex ); + continue; + } + + $new_h = fmod( ( $base['h'] + $modifier[0] + 360 ), 360 ); + $new_s = max( 0, min( 100, $base['s'] + $modifier[1] ) ); + $new_l = max( 0, min( 100, $modifier[2] ) ); + + $palette[ $weight ] = tutor_utils()->hsl_to_hex( $new_h, $new_s, $new_l ); + } + + return $palette; + } + + /** + * Load core color palette + * + * @since 4.0.0 + * + * @param string $brand_color Base color code. + * + * @return string + */ + private function load_core_color_palette( $brand_color ) { + if ( empty( $brand_color ) ) { + return ''; + } + + $palette = $this->generate_color_palette( $brand_color ); + + return " + :root { + --tutor-brand-100: {$palette[100]}; + --tutor-brand-200: {$palette[200]}; + --tutor-brand-300: {$palette[300]}; + --tutor-brand-400: {$palette[400]}; + --tutor-brand-500: {$palette[500]}; + --tutor-brand-600: {$palette[600]}; + --tutor-brand-700: {$palette[700]}; + --tutor-brand-800: {$palette[800]}; + --tutor-brand-900: {$palette[900]}; + --tutor-brand-950: {$palette[950]}; + } + "; + } + /** * Add Tinymce button for placing shortcode * @@ -847,6 +936,12 @@ public function enqueue_scripts() { wp_localize_script( 'tutor-core', '_tutorobject', $localize_data ); + // Generate color palette from user selected brand color and add to the root. + $brand_color = tutor_utils()->get_brand_color(); + if ( Options_V2::DEFAULT_BRAND_COLOR !== $brand_color ) { + wp_add_inline_style( 'tutor-core', $this->load_core_color_palette( $brand_color ) ); + } + if ( $is_dashboard ) { wp_enqueue_style( 'tutor-dashboard', $dashboard_css_url, array(), $version ); wp_enqueue_script( 'tutor-dashboard', $dashboard_js_url, array( 'tutor-core', 'wp-i18n' ), $version, true ); diff --git a/classes/Options_V2.php b/classes/Options_V2.php index eb4aec57ec..517bc1da15 100644 --- a/classes/Options_V2.php +++ b/classes/Options_V2.php @@ -36,6 +36,22 @@ class Options_V2 { const LEARNING_MODE_KIDS = 'kids'; const LEARNING_MODE_LEGACY = 'legacy'; + /** + * Default theme. + * + * @since 4.0.0 + */ + const DEFAULT_THEME_LIGHT = 'light'; + const DEFAULT_THEME_DARK = 'dark'; + const DEFAULT_THEME_SYSTEM = 'system'; + + /** + * Brand color. + * + * @since 4.0.0 + */ + const DEFAULT_BRAND_COLOR = '#3e64de'; + /** * Undocumented variable * @@ -1246,15 +1262,54 @@ public function get_setting_fields() { 'fields' => array( array( 'key' => 'learning_mode', - 'type' => 'radio_horizontal_full', + 'type' => 'radio_horizontal_image', 'label' => __( 'Learning Mode', 'tutor' ), + 'desc' => __( 'Decide how students will experience the courses you create.', 'tutor' ), 'default' => self::LEARNING_MODE_MODERN, 'options' => array( - self::LEARNING_MODE_MODERN => __( 'Modern', 'tutor' ), - self::LEARNING_MODE_KIDS => __( 'Kids', 'tutor' ), - self::LEARNING_MODE_LEGACY => __( 'Legacy', 'tutor' ), + self::LEARNING_MODE_MODERN => array( + 'title' => __( 'Modern', 'tutor' ), + 'image' => 'learning-mode/modern.svg', + ), + self::LEARNING_MODE_KIDS => array( + 'title' => __( 'Kids', 'tutor' ), + 'image' => 'learning-mode/kids.svg', + ), + self::LEARNING_MODE_LEGACY => array( + 'title' => __( 'Legacy', 'tutor' ), + 'image' => 'learning-mode/legacy.svg', + ), + ), + ), + array( + 'key' => 'default_theme', + 'type' => 'radio_horizontal_image', + 'label' => __( 'Default Theme', 'tutor' ), + 'desc' => __( 'Set the default appearance for learners across your platform. Learners can switch between dark and light mode if enabled.', 'tutor' ), + 'default' => self::DEFAULT_THEME_SYSTEM, + 'options' => array( + self::DEFAULT_THEME_LIGHT => array( + 'title' => __( 'Light', 'tutor' ), + 'image' => 'default-theme/light.webp', + ), + self::DEFAULT_THEME_DARK => array( + 'title' => __( 'Dark', 'tutor' ), + 'image' => 'default-theme/dark.webp', + ), + self::DEFAULT_THEME_SYSTEM => array( + 'title' => __( 'Auto', 'tutor' ), + 'image' => 'default-theme/auto.webp', + ), ), - 'desc' => __( 'Decide how students will experience the courses you create.', 'tutor' ), + ), + array( + 'key' => 'brand_color', + 'preset_name' => 'brand_color', + 'type' => 'color_field', + 'label' => __( 'Brand Color', 'tutor' ), + 'desc' => __( 'Customize the primary accent color used across your learning platform to match your brand identity.', 'tutor' ), + 'class' => 'color-picker-wrapper', + 'default' => tutor_utils()->get_brand_color(), ), ), ), @@ -1563,199 +1618,6 @@ public function get_setting_fields() { ), ), ), - 'colors' => array( - 'label' => __( 'Colors', 'tutor' ), - 'slug' => 'colors', - 'block_type' => 'color_picker', - 'fields_group' => array( - array( - 'key' => 'color_preset_type', - 'type' => 'color_preset', - 'label' => __( 'Preset Colors', 'tutor' ), - 'desc' => __( 'These colors will be used throughout your website. Choose between these presets or create your own custom palette.', 'tutor' ), - 'default' => 'default', - 'fields' => array( - /* First 4 preset_name should be same as color_fields */ - array( - 'key' => 'default', - 'label' => __( 'Default', 'tutor' ), - 'colors' => array( - array( - 'slug' => 'tutor_primary_color', - 'preset_name' => 'primary', - 'value' => '#3E64DE', - ), - array( - 'slug' => 'tutor_primary_hover_color', - 'preset_name' => 'hover', - 'value' => '#395BCA', - ), - array( - 'slug' => 'tutor_text_color', - 'preset_name' => 'text', - 'value' => '#212327', - ), - array( - 'slug' => 'tutor_gray_color', - 'preset_name' => 'gray', - 'value' => '#E3E5EB', - ), - array( - 'slug' => 'tutor_border_color', - 'preset_name' => 'border', - 'value' => '#CDCFD5', - ), - ), - ), - array( - 'key' => 'landscape', - 'label' => __( 'Landscape', 'tutor' ), - 'colors' => array( - array( - 'slug' => 'tutor_primary_color', - 'preset_name' => 'primary', - 'value' => '#239371', - ), - array( - 'slug' => 'tutor_primary_hover_color', - 'preset_name' => 'hover', - 'value' => '#117D5D', - ), - array( - 'slug' => 'tutor_text_color', - 'preset_name' => 'text', - 'value' => '#212327', - ), - array( - 'slug' => 'tutor_gray_color', - 'preset_name' => 'gray', - 'value' => '#E3E5EB', - ), - array( - 'slug' => 'tutor_border_color', - 'preset_name' => 'border', - 'value' => '#CDCFD5', - ), - ), - ), - array( - 'key' => 'ocean', - 'label' => __( 'Ocean', 'tutor' ), - 'colors' => array( - array( - 'slug' => 'tutor_primary_color', - 'preset_name' => 'primary', - 'value' => '#5A18C2', - ), - array( - 'slug' => 'tutor_primary_hover_color', - 'preset_name' => 'hover', - 'value' => '#3F02A0', - ), - array( - 'slug' => 'tutor_text_color', - 'preset_name' => 'text', - 'value' => '#212327', - ), - array( - 'slug' => 'tutor_gray_color', - 'preset_name' => 'gray', - 'value' => '#E3E5EB', - ), - array( - 'slug' => 'tutor_border_color', - 'preset_name' => 'border', - 'value' => '#CDCFD5', - ), - ), - ), - array( - 'key' => 'custom', - 'label' => __( 'Custom', 'tutor' ), - 'colors' => array( - array( - 'slug' => 'tutor_primary_color', - 'preset_name' => 'primary', - 'value' => '#3E64DE', - ), - array( - 'slug' => 'tutor_primary_hover_color', - 'preset_name' => 'hover', - 'value' => '#28408E', - ), - array( - 'slug' => 'tutor_text_color', - 'preset_name' => 'text', - 'value' => '#1A1B1E', - ), - array( - 'slug' => 'tutor_gray_color', - 'preset_name' => 'gray', - 'value' => '#E3E5EB', - ), - array( - 'slug' => 'tutor_border_color', - 'preset_name' => 'border', - 'value' => '#CDCFD5', - ), - ), - ), - ), - ), - array( - 'key' => 'tutor_color_presets', - 'type' => 'color_fields', - 'label' => __( 'Preset Colors', 'tutor' ), - 'fields' => array( - array( - 'key' => 'tutor_primary_color', - 'type' => 'color_field', - 'preset_name' => 'primary', - 'preset_exist' => true, - 'label' => __( 'Primary Color', 'tutor' ), - 'default' => '#3E64DE', - 'desc' => __( 'Choose a primary color', 'tutor' ), - ), - array( - 'key' => 'tutor_primary_hover_color', - 'type' => 'color_field', - 'preset_name' => 'hover', - 'preset_exist' => true, - 'label' => __( 'Primary Hover Color', 'tutor' ), - 'default' => '#395BCA', - 'desc' => __( 'Choose a primary hover color', 'tutor' ), - ), - array( - 'key' => 'tutor_text_color', - 'type' => 'color_field', - 'preset_name' => 'text', - 'preset_exist' => true, - 'label' => __( 'Text Color', 'tutor' ), - 'default' => '#212327', - 'desc' => __( 'Choose a text color for your website', 'tutor' ), - ), - array( - 'key' => 'tutor_gray_color', - 'type' => 'color_field', - 'preset_name' => 'gray', - 'preset_exist' => false, - 'label' => __( 'Gray', 'tutor' ), - 'default' => '#E3E5EB', - 'desc' => __( 'Choose a color for elements like table, card etc', 'tutor' ), - ), - array( - 'key' => 'tutor_border_color', - 'type' => 'color_field', - 'preset_name' => 'border', - 'preset_exist' => false, - 'label' => __( 'Border', 'tutor' ), - 'default' => '#CDCFD5', - 'desc' => __( 'Choose a border color for your website', 'tutor' ), - ), - ), - ), - ), - ), ), ), 'advanced' => array( diff --git a/classes/Tutor.php b/classes/Tutor.php index 6622db1883..4fcc468caf 100644 --- a/classes/Tutor.php +++ b/classes/Tutor.php @@ -1235,7 +1235,6 @@ public static function default_options() { 'email_footer_text' => '', 'earning_admin_commission' => '20', 'earning_instructor_commission' => '80', - 'color_preset_type' => 'default', // Default options for tutor ecommerce. 'monetize_by' => Ecommerce::MONETIZE_BY, diff --git a/classes/UserPreference.php b/classes/UserPreference.php index 8ac2d69325..ee5cecc259 100644 --- a/classes/UserPreference.php +++ b/classes/UserPreference.php @@ -171,7 +171,7 @@ class UserPreference { * * @var string */ - const DEFAULT_THEME = self::THEME_LIGHT; + const DEFAULT_THEME = self::THEME_SYSTEM; /** * Available theme options. @@ -554,7 +554,7 @@ private static function get_default_preferences() { 'tutor_user_preference_defaults', array( 'auto_play_next' => (bool) tutor_utils()->get_option( 'autoload_next_course_content' ), - 'theme' => self::DEFAULT_THEME, + 'theme' => tutor_utils()->get_option( 'default_theme', Options_V2::DEFAULT_THEME_SYSTEM ), 'vision' => self::VISION_NORMAL, 'contrast' => '', 'motion_effects' => self::MOTION_EFFECTS_AUTO, diff --git a/classes/Utils.php b/classes/Utils.php index 5c23a36a21..b0e1bb45ac 100644 --- a/classes/Utils.php +++ b/classes/Utils.php @@ -25,6 +25,7 @@ use Tutor\Models\CourseModel; use Tutor\Models\EnrollmentModel; use Tutor\Models\QuizModel; +use Tutor\Options_V2; use Tutor\Traits\JsonResponse; /** @@ -9191,6 +9192,110 @@ public function hex2rgb( string $color ) { return implode( ', ', $rgb ); } + /** + * Convert HEX to HSL + * + * @since 4.0.0 + * + * @param string $hex HEX color code. + * + * @return array + */ + public function hex_to_hsl( $hex ) { + $hex = ltrim( $hex, '#' ); + if ( strlen( $hex ) == 3 ) { + $hex = $hex[0] . $hex[0] . $hex[1] . $hex[1] . $hex[2] . $hex[2]; + } + $r = hexdec( substr( $hex, 0, 2 ) ) / 255; + $g = hexdec( substr( $hex, 2, 2 ) ) / 255; + $b = hexdec( substr( $hex, 4, 2 ) ) / 255; + + $max = max( $r, $g, $b ); + $min = min( $r, $g, $b ); + $l = ( $max + $min ) / 2; + + if ( $min === $max ) { + $h = $s = 0; //phpcs:ignore + } else { + $d = $max - $min; + $s = $l > 0.5 ? $d / ( 2 - $max - $min ) : $d / ( $max + $min ); + switch ( $max ) { + case $r: + $h = ( $g - $b ) / $d + ( $g < $b ? 6 : 0 ); + break; + case $g: + $h = ( $b - $r ) / $d + 2; + break; + case $b: + $h = ( $r - $g ) / $d + 4; + break; + } + $h /= 6; + } + return array( + 'h' => $h * 360, + 's' => $s * 100, + 'l' => $l * 100, + ); + } + + /** + * Convert HSL to HEX + * + * @since 4.0.0 + * + * @param string $h H color value. + * @param string $s S color value. + * @param string $l L color value. + * + * @return array + */ + public function hsl_to_hex( $h, $s, $l ) { + $h /= 360; + $s /= 100; + $l /= 100; + if ( 0 === $s ) { + $r = $g = $b = $l; //phpcs:ignore + } else { + $hue2rgb = function( $p, $q, $t ) { + if ( $t < 0 ) { + ++$t; + } + if ( $t > 1 ) { + --$t; + } + if ( $t < 1 / 6 ) { + return $p + ( $q - $p ) * 6 * $t; + } + if ( $t < 1 / 2 ) { + return $q; + } + if ( $t < 2 / 3 ) { + return $p + ( $q - $p ) * ( 2 / 3 - $t ) * 6; + } + return $p; + }; + $q = $l < 0.5 ? $l * ( 1 + $s ) : $l + $s - $l * $s; + $p = 2 * $l - $q; + $r = $hue2rgb( $p, $q, $h + 1 / 3 ); + $g = $hue2rgb( $p, $q, $h ); + $b = $hue2rgb( $p, $q, $h - 1 / 3 ); + } + return sprintf( '#%02x%02x%02x', round( $r * 255 ), round( $g * 255 ), round( $b * 255 ) ); + } + + /** + * Get brand color + * + * @since 4.0.0 + * + * @return string + */ + public function get_brand_color() { + $legacy_brand_color = tutor_utils()->get_option( 'tutor_primary_color' ); + return $legacy_brand_color ? $legacy_brand_color : tutor_utils()->get_option( 'brand_color', Options_V2::DEFAULT_BRAND_COLOR ); + } + /** * Get course builder screen. * diff --git a/v2-library/src/scss/mixins/_svg-icons-static.scss b/v2-library/src/scss/mixins/_svg-icons-static.scss index 50c8c3aeaf..3bf742f387 100644 --- a/v2-library/src/scss/mixins/_svg-icons-static.scss +++ b/v2-library/src/scss/mixins/_svg-icons-static.scss @@ -3,6 +3,10 @@ background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg width='14' height='10' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M.922 5.7a.627.627 0 01-.127-.194.72.72 0 010-.5.6.6 0 01.127-.195l.905-.867a.562.562 0 01.425-.195.592.592 0 01.25.05.665.665 0 01.207.145l2.73 2.734L11.295.82a.658.658 0 01.202-.145.613.613 0 01.484.002.568.568 0 01.191.143l.905.88a.6.6 0 01.127.195.72.72 0 010 .5.628.628 0 01-.127.194l-7.2 7.163a.575.575 0 01-.195.147.655.655 0 01-.5 0 .575.575 0 01-.195-.147L.922 5.7z' fill='%23fff'/%3E%3C/svg%3E"); } +@mixin svg-check-icon-2 { + background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg width='8' height='6' viewBox='0 0 8 6' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M2.28439 4.52415L0.748725 2.97262C0.577523 2.79965 0.298069 2.79965 0.126867 2.97262C-0.0418637 3.1431 -0.0418638 3.41765 0.126867 3.58812L2.00578 5.48644C2.15918 5.64144 2.40959 5.64144 2.563 5.48645L7.25576 0.745191C7.42449 0.574717 7.42449 0.300168 7.25576 0.129694C7.08456 -0.0432773 6.8051 -0.0432774 6.6339 0.129693L2.28439 4.52415Z' fill='%23fff'/%3E%3C/svg%3E"); +} + @mixin svg-delete-icon { background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='14' viewBox='0 0 12 14' fill='none'%3e%3cpath d='M1.36301 12.0781C1.36301 12.3889 1.48628 12.687 1.7057 12.9068C1.92512 13.1265 2.22272 13.25 2.53302 13.25H9.55307C9.86337 13.25 10.161 13.1265 10.3804 12.9068C10.5998 12.687 10.7231 12.3889 10.7231 12.0781V3.875H1.36301V12.0781ZM7.99306 5.82813C7.99306 5.72453 8.03415 5.62517 8.10729 5.55191C8.18043 5.47866 8.27962 5.4375 8.38306 5.4375C8.48649 5.4375 8.58569 5.47866 8.65883 5.55191C8.73197 5.62517 8.77306 5.72453 8.77306 5.82813V11.2969C8.77306 11.4005 8.73197 11.4998 8.65883 11.5731C8.58569 11.6463 8.48649 11.6875 8.38306 11.6875C8.27962 11.6875 8.18043 11.6463 8.10729 11.5731C8.03415 11.4998 7.99306 11.4005 7.99306 11.2969V5.82813ZM5.65304 5.82813C5.65304 5.72453 5.69413 5.62517 5.76727 5.55191C5.84041 5.47866 5.93961 5.4375 6.04304 5.4375C6.14648 5.4375 6.24568 5.47866 6.31882 5.55191C6.39196 5.62517 6.43305 5.72453 6.43305 5.82813V11.2969C6.43305 11.4005 6.39196 11.4998 6.31882 11.5731C6.24568 11.6463 6.14648 11.6875 6.04304 11.6875C5.93961 11.6875 5.84041 11.6463 5.76727 11.5731C5.69413 11.4998 5.65304 11.4005 5.65304 11.2969V5.82813ZM3.31303 5.82813C3.31303 5.72453 3.35412 5.62517 3.42726 5.55191C3.50039 5.47866 3.59959 5.4375 3.70303 5.4375C3.80646 5.4375 3.90566 5.47866 3.9788 5.55191C4.05194 5.62517 4.09303 5.72453 4.09303 5.82813V11.2969C4.09303 11.4005 4.05194 11.4998 3.9788 11.5731C3.90566 11.6463 3.80646 11.6875 3.70303 11.6875C3.59959 11.6875 3.50039 11.6463 3.42726 11.5731C3.35412 11.4998 3.31303 11.4005 3.31303 11.2969V5.82813ZM11.1131 1.53125H8.18806L7.95893 1.07471C7.9104 0.977107 7.83563 0.895005 7.74305 0.837641C7.65046 0.780276 7.54373 0.749926 7.43487 0.750004H4.64879C4.54016 0.749586 4.43362 0.779823 4.34137 0.837251C4.24911 0.894679 4.17487 0.976976 4.12716 1.07471L3.89803 1.53125H0.97301C0.869575 1.53125 0.770377 1.57241 0.697237 1.64567C0.624097 1.71892 0.583008 1.81828 0.583008 1.92188L0.583008 2.70313C0.583008 2.80673 0.624097 2.90609 0.697237 2.97934C0.770377 3.0526 0.869575 3.09375 0.97301 3.09375H11.1131C11.2165 3.09375 11.3157 3.0526 11.3889 2.97934C11.462 2.90609 11.5031 2.80673 11.5031 2.70313V1.92188C11.5031 1.81828 11.462 1.71892 11.3889 1.64567C11.3157 1.57241 11.2165 1.53125 11.1131 1.53125Z' fill='white'/%3e%3c/svg%3e"); } diff --git a/views/options/field-types/color_field.php b/views/options/field-types/color_field.php index 178a1a8398..74afc7a817 100644 --- a/views/options/field-types/color_field.php +++ b/views/options/field-types/color_field.php @@ -16,8 +16,9 @@ $value = $field['default']; } $if_other_color = isset( $field['preset_name'] ) && 'other' == $field['preset_name'] ? ' other_color' : ''; +$wrapper_class = isset( $field['class'] ) ? $field['class'] : ''; ?> -