button colors are working
This commit is contained in:
parent
47943ef8aa
commit
5e0aaf5222
3 changed files with 94 additions and 37 deletions
70
src/follow-me/button-style.js
Normal file
70
src/follow-me/button-style.js
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
function presetVarColorCss( color ) {
|
||||||
|
return `var(--wp--preset--color--${ color })`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getBackgroundColor( color ) {
|
||||||
|
// if color is a string, it's a var like this.
|
||||||
|
if ( typeof color === 'string' ) {
|
||||||
|
return presetVarColorCss( color );
|
||||||
|
}
|
||||||
|
|
||||||
|
return color?.color?.background || null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getLinkColor( text ) {
|
||||||
|
// if it starts with a hash, leave it be
|
||||||
|
if ( typeof text === 'string' && text.match( /^#/ ) ) {
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
// var:preset|color|luminous-vivid-amber
|
||||||
|
// var(--wp--preset--color--luminous-vivid-amber)
|
||||||
|
// we will receive the top format, we need to output the bottom format
|
||||||
|
const [ , , color ] = text.split( '|' );
|
||||||
|
return presetVarColorCss( color );
|
||||||
|
}
|
||||||
|
|
||||||
|
function generateSelector( selector, prop, value = null, pseudo = '' ) {
|
||||||
|
if ( ! value ) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
return `${ selector }${ pseudo } { ${ prop }: ${ value }; }\n`;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const BODY_CLASS = 'activitypub-follow-modal-active';
|
||||||
|
|
||||||
|
function getBlockStyles( id, style, backgroundColor ) {
|
||||||
|
const selector = `#${ id } .components-button`;
|
||||||
|
// we grab the background color if set as a good color for our button text
|
||||||
|
const buttonTextColor = getBackgroundColor( backgroundColor )
|
||||||
|
// bg might be in this form.
|
||||||
|
|| style?.color?.background;
|
||||||
|
// we misuse the link color for the button background
|
||||||
|
const buttonColor = getLinkColor( style?.elements?.link?.color?.text );
|
||||||
|
// hover!
|
||||||
|
const buttonHoverColor = getLinkColor( style?.elements?.link?.[':hover']?.color?.text );
|
||||||
|
|
||||||
|
return generateSelector( selector, 'color', buttonTextColor )
|
||||||
|
+ generateSelector( selector, 'background-color', buttonColor )
|
||||||
|
+ generateSelector( selector, 'background-color', buttonHoverColor, ':hover' )
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getPopupStyles( style ) {
|
||||||
|
const base = `.${ BODY_CLASS } .components-modal__content .components-button`;
|
||||||
|
const primary = `${ base }.is-primary`;
|
||||||
|
const secondary = `${ base }.is-tertiary`;
|
||||||
|
// we misuse the link color for the button background
|
||||||
|
const buttonColor = getLinkColor( style?.elements?.link?.color?.text );
|
||||||
|
// hover!
|
||||||
|
const buttonHoverColor = getLinkColor( style?.elements?.link?.[':hover']?.color?.text );
|
||||||
|
|
||||||
|
return generateSelector( primary, 'background-color', buttonColor )
|
||||||
|
+ generateSelector( primary, 'background-color', buttonHoverColor, ':hover' )
|
||||||
|
+ generateSelector( secondary, 'color', buttonColor )
|
||||||
|
}
|
||||||
|
|
||||||
|
export function ButtonStyle( { id, style, backgroundColor } ) {
|
||||||
|
const css = getBlockStyles( id, style, backgroundColor );
|
||||||
|
return (
|
||||||
|
<style>{ css }</style>
|
||||||
|
);
|
||||||
|
}
|
|
@ -7,6 +7,7 @@ import {
|
||||||
__experimentalConfirmDialog as ConfirmDialog
|
__experimentalConfirmDialog as ConfirmDialog
|
||||||
} from '@wordpress/components';
|
} from '@wordpress/components';
|
||||||
import { useUserOptions } from '../shared/use-user-options';
|
import { useUserOptions } from '../shared/use-user-options';
|
||||||
|
import { ButtonStyle, BODY_CLASS, getPopupStyles } from './button-style';
|
||||||
import apiFetch from '@wordpress/api-fetch';
|
import apiFetch from '@wordpress/api-fetch';
|
||||||
import { useEffect, useState } from '@wordpress/element';
|
import { useEffect, useState } from '@wordpress/element';
|
||||||
const { namespace } = window._activityPubOptions;
|
const { namespace } = window._activityPubOptions;
|
||||||
|
@ -40,36 +41,14 @@ function getNormalizedProfile( profile ) {
|
||||||
|
|
||||||
function generateHandle( profile ) {
|
function generateHandle( profile ) {
|
||||||
try {
|
try {
|
||||||
const urlObject = new URL( profile.url );
|
const { host, pathname } = new URL( profile.url )
|
||||||
const { host, pathname } = urlObject;
|
const first = profile.preferredUsername ?? pathname.replace( /^\//, '' );
|
||||||
const first = pathname.replace( /^\//, '' );
|
|
||||||
return `${ first }@${ host }`;
|
return `${ first }@${ host }`;
|
||||||
} catch ( e ) {
|
} catch ( e ) {
|
||||||
return '@error@error';
|
return '@error@error';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function styleToVar( text ) {
|
|
||||||
// if it starts with a hash, leave it be
|
|
||||||
if ( text.match( /^#/ ) ) {
|
|
||||||
return text;
|
|
||||||
}
|
|
||||||
// var:preset|color|luminous-vivid-amber
|
|
||||||
// var(--wp--preset--color--luminous-vivid-amber)
|
|
||||||
// we will receive the top format, we need to output the bottom format
|
|
||||||
const [ , , color ] = text.split( '|' );
|
|
||||||
return `var(--wp--preset--color--${ color })`;
|
|
||||||
}
|
|
||||||
|
|
||||||
function styleToButtonStyle( style ) {
|
|
||||||
if ( ! style ) {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
backgroundColor: styleToVar( style.color.text )
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function Edit( { attributes, setAttributes } ) {
|
export default function Edit( { attributes, setAttributes } ) {
|
||||||
const [ profile, setProfile ] = useState( getNormalizedProfile() );
|
const [ profile, setProfile ] = useState( getNormalizedProfile() );
|
||||||
const { selectedUser } = attributes;
|
const { selectedUser } = attributes;
|
||||||
|
@ -83,7 +62,7 @@ export default function Edit( { attributes, setAttributes } ) {
|
||||||
|
|
||||||
const blockProps = useBlockProps();
|
const blockProps = useBlockProps();
|
||||||
const usersOptions = useUserOptions();
|
const usersOptions = useUserOptions();
|
||||||
const style = styleToButtonStyle( attributes?.style?.elements?.link );
|
const popupStyles = getPopupStyles( attributes.style );
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div { ...blockProps }>
|
<div { ...blockProps }>
|
||||||
|
@ -97,40 +76,47 @@ export default function Edit( { attributes, setAttributes } ) {
|
||||||
/>
|
/>
|
||||||
</PanelBody>
|
</PanelBody>
|
||||||
</InspectorControls>
|
</InspectorControls>
|
||||||
<Profile { ...profile } style={ style } />
|
<ButtonStyle id={ blockProps.id } style={ attributes.style } backgroundColor={ attributes.backgroundColor } />
|
||||||
|
<Profile profile={ profile } popupStyles={ popupStyles } />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function Profile( profile ) {
|
function Profile( { profile, popupStyles } ) {
|
||||||
const { handle, avatar, name, style } = profile;
|
const { handle, avatar, name } = profile;
|
||||||
return (
|
return (
|
||||||
<div className="activitypub-profile">
|
<div className="activitypub-profile">
|
||||||
<img className="activitypub-profile__avatar" src={ avatar } />
|
<img className="activitypub-profile__avatar" src={ avatar } />
|
||||||
<div className="activitypub-profile__content">
|
<div className="activitypub-profile__content">
|
||||||
<div className="activitpub-profile__name">{ name }</div>
|
<div className="activitypub-profile__name">{ name }</div>
|
||||||
<div className="activitypub-profile__handle">{ handle }</div>
|
<div className="activitypub-profile__handle">{ handle }</div>
|
||||||
</div>
|
</div>
|
||||||
<Follow profile={ profile } style={ style } />
|
<Follow profile={ profile } popupStyles={ popupStyles } />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function Follow( { profile, style } ) {
|
function Follow( { profile, popupStyles } ) {
|
||||||
const [ isOpen, setIsOpen ] = useState( false );
|
const [ isOpen, setIsOpen ] = useState( false );
|
||||||
|
// a function that adds/removes the activitypub-follow-modal-active class to the body
|
||||||
|
function setModalIsOpen( value ) {
|
||||||
|
const method = value ? 'add' : 'remove';
|
||||||
|
document.body.classList[ method ]( BODY_CLASS );
|
||||||
|
setIsOpen( value );
|
||||||
|
}
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Button style={ style } className="activitypub-profile__follow" onClick={ () => setIsOpen( true ) } >
|
<Button className="activitypub-profile__follow" onClick={ () => setModalIsOpen( true ) } >
|
||||||
{ __( 'Follow', 'fediverse' ) }
|
{ __( 'Follow', 'fediverse' ) }
|
||||||
</Button>
|
</Button>
|
||||||
<ConfirmDialog
|
<ConfirmDialog
|
||||||
className="activitypub-profile__confirm"
|
className="activitypub-profile__confirm"
|
||||||
isOpen={ isOpen }
|
isOpen={ isOpen }
|
||||||
onConfirm={ () => setIsOpen( false ) }
|
onConfirm={ () => setModalIsOpen( false ) }
|
||||||
onCancel={ () => setIsOpen( false ) }
|
onCancel={ () => setModalIsOpen( false ) }
|
||||||
>
|
>
|
||||||
Todo: put the follow layout in here.
|
<p>Howdy let's put some dialogs here</p>
|
||||||
|
<style>{ popupStyles }</style>
|
||||||
</ConfirmDialog>
|
</ConfirmDialog>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
.activitypub-profile__name {
|
.activitypub-profile__name {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
|
font-size: var( --wp--preset--font-size--large );
|
||||||
}
|
}
|
||||||
.activitypub-profile__follow {
|
.activitypub-profile__follow {
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
|
|
Loading…
Reference in a new issue