/* global wpforms_gutenberg_form_selector */ /* jshint es3: false, esversion: 6 */ /** * @param wpforms_gutenberg_form_selector.route_namespace * @param strings.theme_name * @param strings.theme_delete * @param strings.theme_delete_title * @param strings.theme_delete_confirm * @param strings.theme_delete_cant_undone * @param strings.theme_delete_yes * @param strings.theme_copy * @param strings.theme_custom * @param strings.theme_noname * @param strings.button_background * @param strings.button_text * @param strings.field_label * @param strings.field_sublabel * @param strings.field_border */ /** * Gutenberg editor block. * * Themes panel module. * * @since 1.8.8 */ export default ( function( document, window, $ ) { /** * WP core components. * * @since 1.8.8 */ const { PanelBody, ColorIndicator, TextControl, Button } = wp.components; const { __experimentalRadio: Radio, __experimentalRadioGroup: RadioGroup } = wp.components; /** * Localized data aliases. * * @since 1.8.8 */ const { isPro, isLicenseActive, strings, route_namespace: routeNamespace } = wpforms_gutenberg_form_selector; /** * Form selector common module. * * @since 1.8.8 * * @type {Object} */ let formSelectorCommon = null; /** * Runtime state. * * @since 1.8.8 * * @type {Object} */ const state = {}; /** * Themes data. * * @since 1.8.8 * * @type {Object} */ const themesData = { wpforms: null, custom: null, }; /** * Enabled themes. * * @since 1.8.8 * * @type {Object} */ let enabledThemes = null; /** * Elements holder. * * @since 1.8.8 * * @type {Object} */ const el = {}; /** * Public functions and properties. * * @since 1.8.8 * * @type {Object} */ const app = { /** * Initialize panel. * * @since 1.8.8 */ init() { el.$window = $( window ); app.fetchThemesData(); $( app.ready ); }, /** * Document ready. * * @since 1.8.8 */ ready() { app.events(); }, /** * Events. * * @since 1.8.8 */ events() { wp.data.subscribe( function() { // eslint-disable-line complexity const isSavingPost = wp.data.select( 'core/editor' )?.isSavingPost(); const isAutosavingPost = wp.data.select( 'core/editor' )?.isAutosavingPost(); const isSavingWidget = wp.data.select( 'core/edit-widgets' )?.isSavingWidgetAreas(); const currentPost = wp.data.select( 'core/editor' )?.getCurrentPost(); const isBlockOrTemplate = currentPost?.type?.includes( 'wp_template' ) || currentPost?.type?.includes( 'wp_block' ); if ( ( ! isSavingPost && ! isSavingWidget && ! isBlockOrTemplate ) || isAutosavingPost ) { return; } if ( isBlockOrTemplate ) { // Delay saving if this is FSE for better performance. _.debounce( app.saveCustomThemes, 500 )(); return; } app.saveCustomThemes(); } ); }, /** * Get all themes data. * * @since 1.8.8 * * @return {Object} Themes data. */ getAllThemes() { return { ...( themesData.custom || {} ), ...( themesData.wpforms || {} ) }; }, /** * Get theme data. * * @since 1.8.8 * * @param {string} slug Theme slug. * * @return {Object|null} Theme settings. */ getTheme( slug ) { return app.getAllThemes()[ slug ] || null; }, /** * Get enabled themes data. * * @since 1.8.8 * * @return {Object} Themes data. */ getEnabledThemes() { if ( enabledThemes ) { return enabledThemes; } const allThemes = app.getAllThemes(); if ( isPro && isLicenseActive ) { return allThemes; } enabledThemes = Object.keys( allThemes ).reduce( ( acc, key ) => { if ( allThemes[ key ].settings?.fieldSize && ! allThemes[ key ].disabled ) { acc[ key ] = allThemes[ key ]; } return acc; }, {} ); return enabledThemes; }, /** * Update enabled themes. * * @since 1.8.8 * * @param {string} slug Theme slug. * @param {Object} theme Theme settings. */ updateEnabledThemes( slug, theme ) { if ( ! enabledThemes ) { return; } enabledThemes = { ...enabledThemes, [ slug ]: theme, }; }, /** * Whether the theme is disabled. * * @since 1.8.8 * * @param {string} slug Theme slug. * * @return {boolean} True if the theme is disabled. */ isDisabledTheme( slug ) { return ! app.getEnabledThemes()?.[ slug ]; }, /** * Whether the theme is one of the WPForms themes. * * @since 1.8.8 * * @param {string} slug Theme slug. * * @return {boolean} True if the theme is one of the WPForms themes. */ isWPFormsTheme( slug ) { return Boolean( themesData.wpforms[ slug ]?.settings ); }, /** * Fetch themes data from API. * * @since 1.8.8 */ fetchThemesData() { // If a fetch is already in progress, exit the function. if ( state.isFetchingThemes || themesData.wpforms ) { return; } // Set the flag to true indicating a fetch is in progress. state.isFetchingThemes = true; try { // Fetch themes data. wp.apiFetch( { path: routeNamespace + 'themes/', method: 'GET', cache: 'no-cache', } ) .then( ( response ) => { themesData.wpforms = response.wpforms || {}; themesData.custom = response.custom || {}; } ) .catch( ( error ) => { // eslint-disable-next-line no-console console.error( error?.message ); } ) .finally( () => { state.isFetchingThemes = false; } ); } catch ( error ) { // eslint-disable-next-line no-console console.error( error ); } }, /** * Save custom themes. * * @since 1.8.8 */ saveCustomThemes() { // Custom themes do not exist. if ( state.isSavingThemes || ! themesData.custom ) { return; } // Set the flag to true indicating a saving is in progress. state.isSavingThemes = true; try { // Save themes. wp.apiFetch( { path: routeNamespace + 'themes/custom/', method: 'POST', data: { customThemes: themesData.custom }, } ) .then( ( response ) => { if ( ! response?.result ) { // eslint-disable-next-line no-console console.log( response?.error ); } } ) .catch( ( error ) => { // eslint-disable-next-line no-console console.error( error?.message ); } ) .finally( () => { state.isSavingThemes = false; } ); } catch ( error ) { // eslint-disable-next-line no-console console.error( error ); } }, /** * Get the current style attributes state. * * @since 1.8.8 * * @param {Object} props Block properties. * * @return {boolean} Whether the custom theme is created. */ getCurrentStyleAttributes( props ) { const defaultAttributes = Object.keys( themesData.wpforms.default?.settings ); const currentStyleAttributes = {}; for ( const key in defaultAttributes ) { const attr = defaultAttributes[ key ]; currentStyleAttributes[ attr ] = props.attributes[ attr ] ?? ''; } return currentStyleAttributes; }, /** * Maybe create custom theme. * * @since 1.8.8 * * @param {Object} props Block properties. * * @return {boolean} Whether the custom theme is created. */ maybeCreateCustomTheme( props ) { // eslint-disable-line complexity const currentStyles = app.getCurrentStyleAttributes( props ); const isWPFormsTheme = !! themesData.wpforms[ props.attributes.theme ]; const isCustomTheme = !! themesData.custom[ props.attributes.theme ]; let migrateToCustomTheme = false; // It is one of the default themes without any changes. if ( isWPFormsTheme && JSON.stringify( themesData.wpforms[ props.attributes.theme ]?.settings ) === JSON.stringify( currentStyles ) ) { return false; } const prevAttributes = formSelectorCommon.getBlockRuntimeStateVar( props.clientId, 'prevAttributesState' ); // It is a block added in FS 1.0, so it doesn't have a theme. // The `prevAttributes` is `undefined` means that we are in the first render of the existing block. if ( props.attributes.theme === 'default' && props.attributes.themeName === '' && ! prevAttributes ) { migrateToCustomTheme = true; } // It is a modified default theme OR unknown custom theme. if ( isWPFormsTheme || ! isCustomTheme || migrateToCustomTheme ) { app.createCustomTheme( props, currentStyles, migrateToCustomTheme ); } return true; }, /** * Create custom theme. * * @since 1.8.8 * * @param {Object} props Block properties. * @param {Object} currentStyles Current style settings. * @param {boolean} migrateToCustomTheme Whether it is needed to migrate to custom theme. * * @return {boolean} Whether the custom theme is created. */ createCustomTheme( props, currentStyles = null, migrateToCustomTheme = false ) { // eslint-disable-line complexity let counter = 0; let themeSlug = props.attributes.theme; const baseTheme = app.getTheme( props.attributes.theme ) || themesData.wpforms.default; let themeName = baseTheme.name; themesData.custom = themesData.custom || {}; if ( migrateToCustomTheme ) { themeSlug = 'custom'; themeName = strings.theme_custom; } // Determine the theme slug and the number of copies. do { counter++; themeSlug = themeSlug + '-copy-' + counter; } while ( themesData.custom[ themeSlug ] && counter < 10000 ); const copyStr = counter < 2 ? strings.theme_copy : strings.theme_copy + ' ' + counter; themeName += ' (' + copyStr + ')'; // The first migrated Custom Theme should be without `(Copy)` suffix. themeName = migrateToCustomTheme && counter < 2 ? strings.theme_custom : themeName; // Add the new custom theme. themesData.custom[ themeSlug ] = { name: themeName, settings: currentStyles || app.getCurrentStyleAttributes( props ), }; app.updateEnabledThemes( themeSlug, themesData.custom[ themeSlug ] ); // Update the block attributes with the new custom theme settings. props.setAttributes( { theme: themeSlug, themeName, } ); return true; }, /** * Maybe create custom theme by given attributes. * * @since 1.8.8 * * @param {Object} attributes Block properties. * * @return {string} New theme's slug. */ maybeCreateCustomThemeFromAttributes( attributes ) { // eslint-disable-line complexity const newThemeSlug = attributes.theme; const existingTheme = app.getTheme( attributes.theme ); const keys = Object.keys( attributes ); let isExistingTheme = Boolean( existingTheme?.settings ); // Check if the theme already exists and has the same settings. if ( isExistingTheme ) { for ( const i in keys ) { const key = keys[ i ]; if ( ! existingTheme.settings[ key ] || existingTheme.settings[ key ] !== attributes[ key ] ) { isExistingTheme = false; break; } } } // The theme exists and has the same settings. if ( isExistingTheme ) { return newThemeSlug; } // The theme doesn't exist. // Normalize the attributes to the default theme settings. const defaultAttributes = Object.keys( themesData.wpforms.default.settings ); const newSettings = {}; for ( const i in defaultAttributes ) { const attr = defaultAttributes[ i ]; newSettings[ attr ] = attributes[ attr ] ?? ''; } // Create a new custom theme. themesData.custom[ newThemeSlug ] = { name: attributes.themeName ?? strings.theme_custom, settings: newSettings, }; app.updateEnabledThemes( newThemeSlug, themesData.custom[ newThemeSlug ] ); return newThemeSlug; }, /** * Update custom theme. * * @since 1.8.8 * * @param {string} attribute Attribute name. * @param {string} value New attribute value. * @param {Object} props Block properties. */ updateCustomThemeAttribute( attribute, value, props ) { // eslint-disable-line complexity const themeSlug = props.attributes.theme; // Skip if it is one of the WPForms themes OR the attribute is not in the theme settings. if ( themesData.wpforms[ themeSlug ] || ( attribute !== 'themeName' && ! themesData.wpforms.default.settings[ attribute ] ) ) { return; } // Skip if the custom theme doesn't exist. // It should never happen, only in some unique circumstances. if ( ! themesData.custom[ themeSlug ] ) { return; } // Update theme data. if ( attribute === 'themeName' ) { themesData.custom[ themeSlug ].name = value; } else { themesData.custom[ themeSlug ].settings = themesData.custom[ themeSlug ].settings || themesData.wpforms.default.settings; themesData.custom[ themeSlug ].settings[ attribute ] = value; } // Trigger event for developers. el.$window.trigger( 'wpformsFormSelectorUpdateTheme', [ themeSlug, themesData.custom[ themeSlug ], props ] ); }, /** * Get Themes panel JSX code. * * @since 1.8.8 * * @param {Object} props Block properties. * @param {Object} formSelectorCommonModule Common module. * @param {Object} stockPhotosModule StockPhotos module. * * @return {Object} Themes panel JSX code. */ getThemesPanel( props, formSelectorCommonModule, stockPhotosModule ) { // Store common module in app. formSelectorCommon = formSelectorCommonModule; state.stockPhotos = stockPhotosModule; // If there are no themes data, it is necessary to fetch it firstly. if ( ! themesData.wpforms ) { app.fetchThemesData(); // Return empty JSX code. return ( <> ); } // Get event handlers. const handlers = app.getEventHandlers( props ); const showCustomThemeOptions = formSelectorCommonModule.isFullStylingEnabled() && app.maybeCreateCustomTheme( props ); const checked = formSelectorCommonModule.isFullStylingEnabled() ? props.attributes.theme : 'classic'; const isLeadFormsEnabled = formSelectorCommonModule.isLeadFormsEnabled( formSelectorCommonModule.getBlockContainer( props ) ); const displayLeadFormNotice = isLeadFormsEnabled ? 'block' : 'none'; const modernNoticeStyles = displayLeadFormNotice === 'block' ? { display: 'none' } : {}; let classes = formSelectorCommon.getPanelClass( props ); classes += isLeadFormsEnabled ? ' wpforms-lead-forms-enabled' : ''; classes += app.isMac() ? ' wpforms-is-mac' : ''; return (

{ strings.use_modern_notice_head } { strings.use_modern_notice_text } { strings.learn_more }

{ strings.lead_forms_panel_notice_head } { strings.lead_forms_panel_notice_text }

handlers.selectTheme( value ) } > { app.getThemesItemsJSX( props ) } { showCustomThemeOptions && ( <> handlers.changeThemeName( value ) } /> ) }
); }, /** * Get the Themes panel items JSX code. * * @since 1.8.8 * * @param {Object} props Block properties. * * @return {Array} Themes items JSX code. */ getThemesItemsJSX( props ) { // eslint-disable-line complexity const allThemesData = app.getAllThemes(); if ( ! allThemesData ) { return []; } const itemsJsx = []; const themes = Object.keys( allThemesData ); let theme, firstThemeSlug; // Display the current custom theme on the top of the list. if ( ! app.isWPFormsTheme( props.attributes.theme ) ) { firstThemeSlug = props.attributes.theme; itemsJsx.push( app.getThemesItemJSX( props.attributes.theme, app.getTheme( props.attributes.theme ) ) ); } for ( const key in themes ) { const slug = themes[ key ]; // Skip the first theme. if ( firstThemeSlug && firstThemeSlug === slug ) { continue; } // Ensure that all the theme settings are present. theme = { ...allThemesData.default, ...( allThemesData[ slug ] || {} ) }; theme.settings = { ...allThemesData.default.settings, ...( theme.settings || {} ) }; itemsJsx.push( app.getThemesItemJSX( slug, theme ) ); } return itemsJsx; }, /** * Get the Themes panel's single item JSX code. * * @since 1.8.8 * * @param {string} slug Theme slug. * @param {Object} theme Theme data. * * @return {Object|null} Themes panel single item JSX code. */ getThemesItemJSX( slug, theme ) { if ( ! theme ) { return null; } const title = theme.name?.length > 0 ? theme.name : strings.theme_noname; return (
{ title }
); }, /** * Set block theme. * * @since 1.8.8 * * @param {Object} props Block properties. * @param {string} themeSlug The theme slug. * * @return {boolean} True on success. */ setBlockTheme( props, themeSlug ) { if ( app.maybeDisplayUpgradeModal( themeSlug ) ) { return false; } const theme = app.getTheme( themeSlug ); if ( ! theme?.settings ) { return false; } const attributes = Object.keys( theme.settings ); const block = formSelectorCommon.getBlockContainer( props ); const container = block.querySelector( `#wpforms-${ props.attributes.formId }` ); // Overwrite block attributes with the new theme settings. // It is needed to rely on the theme settings only. const newProps = { ...props, attributes: { ...props.attributes, ...theme.settings } }; // Update the preview with the new theme settings. for ( const key in attributes ) { const attr = attributes[ key ]; theme.settings[ attr ] = theme.settings[ attr ] === '0' ? '0px' : theme.settings[ attr ]; formSelectorCommon.updatePreviewCSSVarValue( attr, theme.settings[ attr ], container, newProps ); } // Prepare the new attributes to be set. const setAttributes = { theme: themeSlug, themeName: theme.name, ...theme.settings, }; if ( props.setAttributes ) { // Update the block attributes with the new theme settings. props.setAttributes( setAttributes ); } // Trigger event for developers. el.$window.trigger( 'wpformsFormSelectorSetTheme', [ block, themeSlug, props ] ); return true; }, /** * Maybe display upgrades modal in Lite. * * @since 1.8.8 * * @param {string} themeSlug The theme slug. * * @return {boolean} True if modal was displayed. */ maybeDisplayUpgradeModal( themeSlug ) { if ( ! app.isDisabledTheme( themeSlug ) ) { return false; } if ( ! isPro ) { formSelectorCommon.education.showProModal( 'themes', strings.themes ); return true; } if ( ! isLicenseActive ) { formSelectorCommon.education.showLicenseModal( 'themes', strings.themes, 'select-theme' ); return true; } return false; }, /** * Get themes panel event handlers. * * @since 1.8.8 * * @param {Object} props Block properties. * * @type {Object} */ getEventHandlers( props ) { // eslint-disable-line max-lines-per-function const commonHandlers = formSelectorCommon.getSettingsFieldsHandlers( props ); const handlers = { /** * Select theme event handler. * * @since 1.8.8 * * @param {string} value New attribute value. */ selectTheme( value ) { if ( ! app.setBlockTheme( props, value ) ) { return; } // Maybe open Stock Photo installation window. state?.stockPhotos?.onSelectTheme( value, props, app, commonHandlers ); const block = formSelectorCommon.getBlockContainer( props ); formSelectorCommon.setTriggerServerRender( false ); commonHandlers.updateCopyPasteContent(); // Trigger event for developers. el.$window.trigger( 'wpformsFormSelectorSelectTheme', [ block, props, value ] ); }, /** * Change theme name event handler. * * @since 1.8.8 * * @param {string} value New attribute value. */ changeThemeName( value ) { formSelectorCommon.setTriggerServerRender( false ); props.setAttributes( { themeName: value } ); app.updateCustomThemeAttribute( 'themeName', value, props ); }, /** * Delete theme event handler. * * @since 1.8.8 */ deleteTheme() { const deleteThemeSlug = props.attributes.theme; // Remove theme from the theme storage. delete themesData.custom[ deleteThemeSlug ]; // Open the confirmation modal window. app.deleteThemeModal( props, deleteThemeSlug, handlers ); }, }; return handlers; }, /** * Open the theme delete confirmation modal window. * * @since 1.8.8 * * @param {Object} props Block properties. * @param {string} deleteThemeSlug Theme slug. * @param {Object} handlers Block event handlers. */ deleteThemeModal( props, deleteThemeSlug, handlers ) { const confirm = strings.theme_delete_confirm.replace( '%1$s', `${ props.attributes.themeName }` ); const content = `

${ confirm } ${ strings.theme_delete_cant_undone }

`; $.confirm( { title: strings.theme_delete_title, content, icon: 'wpforms-exclamation-circle', type: 'red', buttons: { confirm: { text: strings.theme_delete_yes, btnClass: 'btn-confirm', keys: [ 'enter' ], action() { // Switch to the default theme. handlers.selectTheme( 'default' ); // Trigger event for developers. el.$window.trigger( 'wpformsFormSelectorDeleteTheme', [ deleteThemeSlug, props ] ); }, }, cancel: { text: strings.cancel, keys: [ 'esc' ], }, }, } ); }, /** * Determine if the user is on a Mac. * * @return {boolean} True if the user is on a Mac. */ isMac() { return navigator.userAgent.includes( 'Macintosh' ); }, }; app.init(); // Provide access to public functions/properties. return app; }( document, window, jQuery ) );

Oh hey, it looks like you're working on a Contact page.

$primary: #9ebaa0; // $secondary: #aa9d88; // $background: #738e96; // $text: #fff; // $menu_hover: #9ebaa0; $menu_hover_text: #fff; $header_background: #738e96; // $header_text: #fff; // $subsection_background: #627c83; // $subsection_background_hover: #627c83; // $subsection_text: #d5dde0; // $active_menu_text: #fff; $active_submenu_text: #fff; $text_shadow: 1; @import "../_admin.scss"; How to Apply Tint? - Top Lad

How to Apply Tint?

When it comes to makeup, there are a lot of different ways you can enhance your features. One popular technique is tinting. Tinting is the process of adding color to your skin, and it can be done in a variety of ways. In this blog post, we’ll explore how to apply tint in a makeup routine. We’ll also discuss the benefits of tinting and provide some tips on how to get the best results. So, if you’re interested in learning more about this makeup technique, keep reading!

Tint makeup is a type of makeup that is used to add color to the skin. It can be applied in a variety of ways, including tinted moisturizers, foundation, and even lip gloss. Tinting is a great way to enhance your features and give your skin a healthy-looking glow.

There are many benefits to tinting your skin. For one, it can help to even out your skin tone and give you a more youthful appearance. Tinting can also help to hide imperfections, such as blemishes or dark circles. Additionally, tinted products often contain SPF, which can help to protect your skin from the sun’s harmful rays.

If you’re interested in tinting your skin, there are a few things you should keep in mind.

  1. First, it’s important to choose a tinted product that matches your skin tone. You can do this by testing the product on a small area of your skin, such as your jawline, to see how it looks.
  2. It’s also important to apply tinted products evenly and avoid putting too much product on one area of your skin.
  3. Finally, be sure to remove any tinted makeup before going to bed to avoid staining your sheets.

How to apply tint makeup?

Now that you know a little bit more about tinting, let’s discuss how to apply it. As we mentioned before, tinted products can be applied in a variety of ways. Tinted moisturizers and foundations are two of the most popular options. To apply a tinted moisturizer, simply smooth it over your skin like you would any other moisturizer. To apply a tinted foundation, use a makeup brush or sponge to evenly distribute the product over your skin.

Another option for tinting your skin is lip gloss. Lip gloss can add a pop of color to your lips and also help to keep them hydrated. To apply lip gloss, start by lining your lips with a lip pencil. Then, apply the lip gloss to your lips using a lip brush or your finger.

No matter how you choose to tint your skin, the important thing is to do it evenly. Be sure to avoid putting too much-tinted product on one area of your skin. Otherwise, you may end up with an uneven complexion.

Colors in tint makeup:

When it comes to tinting your skin, there are a variety of colors you can choose from. Tinted moisturizers and foundations come in a range of shades, so you can find one that matches your skin tone perfectly. Lip gloss is also available in a variety of colors, so you can experiment until you find the perfect shade for you.

Some popular colors in tint makeup include pink, peach, and nude. These colors can help to give your skin a natural-looking glow. If you want something with more pigment, there are also tinted products available in brighter shades, such as red and orange. Experiment with different colors until you find the perfect shade for you.

With these tips in mind, tinting your skin can be a great way to enhance your appearance. Give it a try and see for yourself!

Tinting makeup tips:

Now that you know a little bit more about tinting, here are some tips to help you get the best results:

– Choose a tinted product that matches your skin tone. You can test the product on a small area of your skin, such as your jawline, to see how it looks.

– Apply tinted products evenly and avoid putting too much product on one area of your skin.

– Remove any tinted makeup before going to bed to avoid staining your sheets.

– If you’re using lip gloss, start by lining your lips with a lip pencil. Then, apply the lip gloss to your lips using a lip brush or your finger.

With these tips in mind, tinting your skin can be a great way to enhance your appearance. Give it a try and see for yourself! tinting can help you achieve a natural-looking glow and can be done in a variety of colors to suit your preference. Be sure to tint evenly and avoid putting too much product on one area, and remove any tint makeup before bedtime.

In conclusion, tint makeup can be a great way to enhance your features and add some color to your look. By following the tips we’ve provided, you should be able to apply tint in a way that looks natural and enhances your features. Have fun experimenting with different shades and colors to find the perfect look for you!

Scroll to Top