question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

How to pass custom metadata to decorator strategy?

See original GitHub issue

Let’s say my wrapper component that renders Draft Editor has property wordsToHighlight. Basing on that I want Draft strategy to use custom element to highlight selected words. List may change over time.

How could I access this property inside Decorator strategy function?

Is it possible to pass some metadata to contentState? (contentState is one of arguments passed to startegy function)

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Comments:7

github_iconTop GitHub Comments

9reactions
AlexandreKiliancommented, May 2, 2019

@roundrobin not yet, but here’s the code

You can use it exactly like the CompositeDecorator, just with he added third argument in the callback: callback(start, end, props).

Will put this into a repo when I have time, and post it here, this is in ES6-Syntax, you might have to adapt it.



import Immutable from 'immutable';

const { List } = Immutable;

const DELIMITER = '.';


function canOccupySlice(
    decorations,
    start,
    end,
) {
    for (let ii = start; ii < end; ii++) {
        if (decorations[ii] !== null) {
            return false;
        }
    }
    return true;
}

/**
 * Splice the specified component into our decoration array at the desired
 * range.
 */
function occupySlice(
    targetArr,
    start,
    end,
    componentKey,
) {
    for (let ii = start; ii < end; ii++) {
        targetArr[ii] = componentKey;
    }
}

/**
 * A CompositeDraftDecorator traverses through a list of DraftDecorator
 * instances to identify sections of a ContentBlock that should be rendered
 * in a "decorated" manner. For example, hashtags, mentions, and links may
 * be intended to stand out visually, be rendered as anchors, etc.
 *
 * The list of decorators supplied to the constructor will be used in the
 * order they are provided. This allows the caller to specify a priority for
 * string matching, in case of match collisions among decorators.
 *
 * For instance, I may have a link with a `#` in its text. Though this section
 * of text may match our hashtag decorator, it should not be treated as a
 * hashtag. I should therefore list my link DraftDecorator
 * before my hashtag DraftDecorator when constructing this composite
 * decorator instance.
 *
 * Thus, when a collision like this is encountered, the earlier match is
 * preserved and the new match is discarded.
 */
class ProppableCompositeDraftDecorator {
    constructor(decorators) {
        this._decorators = decorators.slice();
        this._props = [];
    }

    getDecorations(
        contentBlock,
        contentState,
    ) {
        const decorations = Array(contentBlock.getText().length).fill(null);

        this._decorators.forEach((/* object*/ decorator, /* number*/ ii) => {
            let counter = 0;
            const strategy = decorator.strategy;
            const callback = (/* number*/ start, /* number*/ end, props) => {
                // Find out if any of our matching range is already occupied
                // by another decorator. If so, try to wrap around it. Otherwise, store
                // the component key for rendering.
                if (canOccupySlice(decorations, start, end)) {
                    const key = ii + DELIMITER + counter + DELIMITER + contentBlock.getKey();
                    occupySlice(decorations, start, end, key);
                    this._props[key] = props;
                    counter++;
                } 
            };
            strategy(contentBlock, callback, contentState);
        });
        return List(decorations);
    }

    getComponentForKey(key) {
        const componentKey = parseInt(key.split(DELIMITER)[0], 10);
        return this._decorators[componentKey].component;
    }

    getPropsForKey(key) {
        const propsForKey = this._props[key];
        const componentKey = parseInt(key.split(DELIMITER)[0], 10);
        return { ...this._decorators[componentKey].props, ...propsForKey };
    }
}


export default ProppableCompositeDraftDecorator;

PS: I removed the “wrapping” logic I had additionally since I haven’t tested it on other usecases yet and it might conflict with whatever you’re trying to do…

0reactions
roundrobincommented, May 1, 2019

@AlexandreKilian would love to take a look at your custom decorator. Do you have a repo for it?

Read more comments on GitHub >

github_iconTop Results From Across the Web

Defining Metadata with a Decorator in Angular | Pluralsight
In this guide, you will learn about different decorators and their corresponding properties to understand how Angular identifies a simple ...
Read more >
Use decorator to add meta data to interface properties
Is it possible to use decorators to mark certain properties of an interface with some custom info. No. Interfaces cannot be used with...
Read more >
Use change sets to deploy custom metadata types and ...
Select the Custom Metadata Type component type. · Select the custom metadata type you want to add to your outbound change set. ·...
Read more >
Custom decorators | NestJS - A progressive Node.js framework
Passing data# ... Let's define a decorator that takes a property name as key, and returns the associated value if it exists (or...
Read more >
Decorators - Draft.js
The decorator concept is based on scanning the contents of a given ContentBlock for ranges of text that match a defined strategy, then...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found