-
Notifications
You must be signed in to change notification settings - Fork 4.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Style engine: add border to frontend #41803
Merged
Merged
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
/** | ||
* Internal dependencies | ||
*/ | ||
import type { | ||
BorderIndividualStyles, | ||
BorderIndividualProperty, | ||
GeneratedCSSRule, | ||
Style, | ||
StyleDefinition, | ||
StyleOptions, | ||
} from '../../types'; | ||
import { generateRule, generateBoxRules, upperFirst } from '../utils'; | ||
|
||
const color = { | ||
name: 'color', | ||
generate: ( | ||
style: Style, | ||
options: StyleOptions, | ||
path: string[] = [ 'border', 'color' ], | ||
ruleKey: string = 'borderColor' | ||
): GeneratedCSSRule[] => { | ||
return generateRule( style, options, path, ruleKey ); | ||
}, | ||
}; | ||
|
||
const radius = { | ||
name: 'radius', | ||
generate: ( style: Style, options: StyleOptions ): GeneratedCSSRule[] => { | ||
return generateBoxRules( | ||
style, | ||
options, | ||
[ 'border', 'radius' ], | ||
{ | ||
default: 'borderRadius', | ||
individual: 'border%sRadius', | ||
}, | ||
[ 'topLeft', 'topRight', 'bottomLeft', 'bottomRight' ] | ||
); | ||
}, | ||
}; | ||
|
||
const borderStyle = { | ||
name: 'style', | ||
generate: ( | ||
style: Style, | ||
options: StyleOptions, | ||
path: string[] = [ 'border', 'style' ], | ||
ruleKey: string = 'borderStyle' | ||
): GeneratedCSSRule[] => { | ||
return generateRule( style, options, path, ruleKey ); | ||
}, | ||
}; | ||
|
||
const width = { | ||
name: 'width', | ||
generate: ( | ||
style: Style, | ||
options: StyleOptions, | ||
path: string[] = [ 'border', 'width' ], | ||
ruleKey: string = 'borderWidth' | ||
): GeneratedCSSRule[] => { | ||
return generateRule( style, options, path, ruleKey ); | ||
}, | ||
}; | ||
|
||
const borderDefinitionsWithIndividualStyles: StyleDefinition[] = [ | ||
color, | ||
borderStyle, | ||
width, | ||
]; | ||
|
||
/** | ||
* Returns a curried generator function with the individual border property ('top' | 'right' | 'bottom' | 'left') baked in. | ||
* | ||
* @param individualProperty Individual border property ('top' | 'right' | 'bottom' | 'left'). | ||
* | ||
* @return StyleDefinition[ 'generate' ] | ||
*/ | ||
const createBorderGenerateFunction = | ||
( individualProperty: BorderIndividualProperty ) => | ||
( style: Style, options: StyleOptions ) => { | ||
const styleValue: | ||
| BorderIndividualStyles< typeof individualProperty > | ||
| undefined = style?.border?.[ individualProperty ]; | ||
|
||
if ( ! styleValue ) { | ||
return []; | ||
} | ||
|
||
return borderDefinitionsWithIndividualStyles.reduce( | ||
( | ||
acc: GeneratedCSSRule[], | ||
borderDefinition: StyleDefinition | ||
): GeneratedCSSRule[] => { | ||
const key = borderDefinition.name; | ||
if ( | ||
styleValue.hasOwnProperty( key ) && | ||
typeof borderDefinition.generate === 'function' | ||
) { | ||
const ruleKey = `border${ upperFirst( | ||
individualProperty | ||
) }${ upperFirst( key ) }`; | ||
acc.push( | ||
...borderDefinition.generate( | ||
style, | ||
options, | ||
[ 'border', individualProperty, key ], | ||
ruleKey | ||
) | ||
); | ||
} | ||
return acc; | ||
}, | ||
[] | ||
); | ||
}; | ||
|
||
const borderTop = { | ||
name: 'borderTop', | ||
generate: createBorderGenerateFunction( 'top' ), | ||
}; | ||
|
||
const borderRight = { | ||
name: 'borderRight', | ||
generate: createBorderGenerateFunction( 'right' ), | ||
}; | ||
|
||
const borderBottom = { | ||
name: 'borderBottom', | ||
generate: createBorderGenerateFunction( 'bottom' ), | ||
}; | ||
|
||
const borderLeft = { | ||
name: 'borderLeft', | ||
generate: createBorderGenerateFunction( 'left' ), | ||
}; | ||
|
||
export default [ | ||
...borderDefinitionsWithIndividualStyles, | ||
radius, | ||
borderTop, | ||
borderRight, | ||
borderBottom, | ||
borderLeft, | ||
]; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,14 @@ | ||
/** | ||
* Internal dependencies | ||
*/ | ||
import border from './border'; | ||
import color from './color'; | ||
import spacing from './spacing'; | ||
import typography from './typography'; | ||
|
||
export const styleDefinitions = [ ...color, ...spacing, ...typography ]; | ||
export const styleDefinitions = [ | ||
...border, | ||
...color, | ||
...spacing, | ||
...typography, | ||
]; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,18 @@ | ||
/** | ||
* External dependencies | ||
*/ | ||
import { get, upperFirst } from 'lodash'; | ||
import { get } from 'lodash'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import type { GeneratedCSSRule, Style, Box, StyleOptions } from '../types'; | ||
import type { | ||
CssRulesKeys, | ||
GeneratedCSSRule, | ||
Style, | ||
Box, | ||
StyleOptions, | ||
} from '../types'; | ||
import { | ||
VARIABLE_REFERENCE_PREFIX, | ||
VARIABLE_PATH_SEPARATOR_TOKEN_ATTRIBUTE, | ||
|
@@ -45,18 +51,20 @@ export function generateRule( | |
/** | ||
* Returns a JSON representation of the generated CSS rules taking into account box model properties, top, right, bottom, left. | ||
* | ||
* @param style Style object. | ||
* @param options Options object with settings to adjust how the styles are generated. | ||
* @param path An array of strings representing the path to the style value in the style object. | ||
* @param ruleKey A CSS property key. | ||
* @param style Style object. | ||
* @param options Options object with settings to adjust how the styles are generated. | ||
* @param path An array of strings representing the path to the style value in the style object. | ||
* @param ruleKeys An array of CSS property keys and patterns. | ||
* @param individualProperties The "sides" or individual properties for which to generate rules. | ||
* | ||
* @return GeneratedCSSRule[] CSS rules. | ||
* @return GeneratedCSSRule[] CSS rules. | ||
*/ | ||
export function generateBoxRules( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As a follow up, maybe this could assume the responsibility of |
||
style: Style, | ||
options: StyleOptions, | ||
path: string[], | ||
ruleKey: string | ||
ruleKeys: CssRulesKeys, | ||
individualProperties: string[] = [ 'top', 'right', 'bottom', 'left' ] | ||
): GeneratedCSSRule[] { | ||
const boxStyle: Box | string | undefined = get( style, path ); | ||
if ( ! boxStyle ) { | ||
|
@@ -67,17 +75,20 @@ export function generateBoxRules( | |
if ( typeof boxStyle === 'string' ) { | ||
rules.push( { | ||
selector: options?.selector, | ||
key: ruleKey, | ||
key: ruleKeys.default, | ||
value: boxStyle, | ||
} ); | ||
} else { | ||
const sideRules = [ 'top', 'right', 'bottom', 'left' ].reduce( | ||
const sideRules = individualProperties.reduce( | ||
( acc: GeneratedCSSRule[], side: string ) => { | ||
const value: string | undefined = get( boxStyle, [ side ] ); | ||
if ( value ) { | ||
acc.push( { | ||
selector: options?.selector, | ||
key: `${ ruleKey }${ upperFirst( side ) }`, | ||
key: ruleKeys?.individual.replace( | ||
'%s', | ||
upperFirst( side ) | ||
), | ||
value, | ||
} ); | ||
} | ||
|
@@ -111,3 +122,14 @@ export function getCSSVarFromStyleValue( styleValue: string ): string { | |
} | ||
return styleValue; | ||
} | ||
|
||
/** | ||
* Capitalizes the first letter in a string. | ||
* | ||
* @param {string} str The string whose first letter the function will capitalize. | ||
* | ||
* @return string A CSS var value. | ||
*/ | ||
export function upperFirst( [ firstLetter, ...rest ]: string ) { | ||
return firstLetter.toUpperCase() + rest.join( '' ); | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm starting to think that we could refactor the JS style engine to use properties from a master "definitions" constant, which is basically what we do in hooks/style.js anyway using __EXPERIMENTAL_STYLE_PROPERTY
It's how we approached it in the backend.
And would allow us to store custom paths and CSS rules keys such as
border-$s-color
without the need to build them on the fly.Not sure yet. I'll test it later.