<commit_before>import Component from '../component/Component.js';
import isFunction from '../utils/isFunction.js';

/**
 * Represents a Link
 *
 * @class
 * @classdesc This link is picked up by the Router and
 * subsequently routed to correct path of the
 * application.
 * @augments Component
 */
export default class Link extends Component {
    /**
     * Create a Link instance
     *
     * @param {string} url
     * @param {string|Component|Node} child
     * @param {Object} [props]
     *
     */
    constructor(url, child, props) {
        super(props);
        this.url = url;
        this.child = child;
    }

    /**
     * @inheritdoc
     *
     * @throws an error if incorrect child is provided
     * @returns {Node}
     */
    create() {
        // Create root element
        const a = document.createElement('a'),
            classNames = this.props.classNames,
            classNamesLength = classNames.length;

        // Add classes
        if (classNamesLength > 0) {
            for (let i = 0; i < classNamesLength; ++i) {
                a.classList.add(classNames[i]);
            }
        }

        this.react((state) => {
            const activeClass = this.props.activeClass;
            if(state.Router.isUrl(this.url)) {
                a.classList.add(activeClass);
            } else {
                a.classList.remove(activeClass);
            }
        });

        // Set href
        a.setAttribute('href', this.url);

        // Add child
        if(typeof this.child === 'string') {
            a.appendChild(document.createTextNode(this.child));
        } else if(this.child instanceof Component) {
            this.mount(this.child);
            a.appendChild(this.child.render());
        } else if(this.child instanceof Node) {
            a.appendChild(this.child);
        } else if(isFunction(this.nest)) {
            a.appendChild(this.nest());
        } else {
            throw new Error('Child should be a string, Component, Node or a nest callback');
        }

        // Add event
        this.on(a, this.props.defaultEvent, (e, state) => {
            e.preventDefault();
            return state.Router.goTo(this.url, this.props.title, this.props.data);
        });

        return a;
    }
}

// Set default properties
Link.defaultProps = {
    classNames: [],
    data: {}, // Data to push with pushState()
    title: '',
    defaultEvent: 'click',
    activeClass: 'active'
};<commit_msg>feat: Implement onClick callback for Link class to hook custom behavior when a Link is clicked<commit_after>import Component from '../component/Component.js';
import isFunction from '../utils/isFunction.js';

/**
 * Represents a Link
 *
 * @class
 * @classdesc This link is picked up by the Router and
 * subsequently routed to correct path of the
 * application.
 * @augments Component
 */
export default class Link extends Component {
    /**
     * Create a Link instance
     *
     * @param {string} url
     * @param {string|Component|Node} child
     * @param {Object} [props]
     *
     */
    constructor(url, child, props) {
        super(props);
        this.url = url;
        this.child = child;
    }

    /**
     * @inheritdoc
     *
     * @throws an error if incorrect child is provided
     * @returns {Node}
     */
    create() {
        // Destructure props
        const { classNames, activeClass, defaultEvent, onClick, title, data } = this.props;
        // Create root element
        const a = document.createElement('a'),
            classNamesLength = classNames.length;

        // Add classes
        if (classNamesLength > 0) {
            for (let i = 0; i < classNamesLength; ++i) {
                a.classList.add(classNames[i]);
            }
        }

        this.react((state) => {
            if(state.Router.isUrl(this.url)) {
                a.classList.add(activeClass);
            } else {
                a.classList.remove(activeClass);
            }
        });

        // Set href
        a.setAttribute('href', this.url);

        // Add child
        if(typeof this.child === 'string') {
            a.appendChild(document.createTextNode(this.child));
        } else if(this.child instanceof Component) {
            this.mount(this.child);
            a.appendChild(this.child.render());
        } else if(this.child instanceof Node) {
            a.appendChild(this.child);
        } else if(isFunction(this.nest)) {
            a.appendChild(this.nest());
        } else {
            throw new Error('Child should be a string, Component, Node or a nest callback');
        }

        // Add event
        this.on(a, defaultEvent, (e, state, ChildComponent) => {
            e.preventDefault();
            if(isFunction(onClick)) {
                onClick.call(this, e, state, ChildComponent);
            }
            return state.Router.goTo(this.url, title, data);
        });

        return a;
    }
}

// Set default properties
Link.defaultProps = {
    classNames: [],
    data: {}, // Data to push with pushState()
    title: '',
    defaultEvent: 'click',
    activeClass: 'active',
    onClick: null
};
{'fraction_non_alphanumeric': 0.12539001560062402, 'fraction_numerical': 0.00078003120124805, 'mean_word_length': 1.8510283490828239, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5659679', 'n_tokens_mistral': 1423, 'n_tokens_neox': 1403, 'n_words': 366}