diff --git a/components/x-teaser/readme.md b/components/x-teaser/readme.md index 1f75c7348..ad1e7b9ba 100644 --- a/components/x-teaser/readme.md +++ b/components/x-teaser/readme.md @@ -38,22 +38,24 @@ Teasers display _content_ but our content items are also decorated with hints an ### Rules -Because there are so many [teaser properties](#properties) some options can conflict. In these cases one option must take precedence over the others. These sitations are resolved by using a _ruleset_. A ruleset is an array of functions ordered by importance. The first function in the array to return a truthy value wins and the name of the matching function will be returned. +Because there are so many [teaser properties](#properties) some options can conflict. In these cases one option must take precedence over the others. These sitations are resolved by using a _ruleset_. A ruleset is a function which implements a series of conditions in order of precedence. When a condition evaluates to true it must return. For example to decide which media type to display (a video, headshot, or image) we define the following ruleset: ```js -const media = [ - function video(props) { - return props.showVideo && props.video; - }, - function headshot(props) { - return props.showHeadshot && props.headshot && props.indicators.isColumn; - }, - function image(props) { - return props.showImage && props.image; - } -]; +const media = (props) => { + if (props.showVideo && props.video && props.video.url) { + return 'video'; + } + + if (props.showHeadshot && props.headshot && props.headshot.url && props.indicators.isColumn) { + return 'headshot'; + } + + if (props.showImage && props.image && props.image.url) { + return 'image'; + } +}; ``` ## Usage diff --git a/components/x-teaser/src/concerns/rules.js b/components/x-teaser/src/concerns/rules.js index efde3a5e7..ad2665097 100644 --- a/components/x-teaser/src/concerns/rules.js +++ b/components/x-teaser/src/concerns/rules.js @@ -1,33 +1,35 @@ /** - * Rules are collections of exclusive properties. They are declared in a ruleset - * (an array of functions) in order of precedence. Each value returned by a rule - * will evaluated as a boolean and the name of any matching rule returned. + * Rules are sets of exclusive properties. + * They are used to ensure that only one property can take precedence. */ const rulesets = { - media: [ - function video(props) { - return props.showVideo && props.video && props.video.url; - }, - function headshot(props) { - return ( - props.showHeadshot && props.headshot && props.headshot.url && props.indicators.isColumn - ); - }, - function image(props) { - return props.showImage && props.image && props.image.url; + media: (props) => { + // If this condition evaluates to true then no headshot nor image will be displayed. + if (props.showVideo && props.video && props.video.url) { + return 'video'; } - ], - theme: [ - function live(props) { - return props.status && props.status === 'inprogress'; - }, - function opinion(props) { - return props.indicators && props.indicators.isOpinion; - }, - function highlight(props) { - return props.indicators && props.indicators.isEditorsChoice; + + if (props.showHeadshot && props.headshot && props.headshot.url && props.indicators.isColumn) { + return 'headshot'; + } + + if (props.showImage && props.image && props.image.url) { + return 'image'; } - ] + }, + theme: (props) => { + if (props.status && props.status === 'inprogress') { + return 'live' + } + + if (props.indicators && props.indicators.isOpinion) { + return 'opinion' + } + + if (props.indicators && props.indicators.isEditorsChoice) { + return 'highlight' + } + } }; /** @@ -38,8 +40,7 @@ const rulesets = { */ export default function rules(rule, props) { if (rulesets.hasOwnProperty(rule)) { - const index = rulesets[rule].findIndex((rule) => rule(props)); - return index !== -1 ? rulesets[rule][index].name : null; + return rulesets[rule](props); } else { throw Error(`No ruleset available named ${rule}`); }