Rikka

TypeScript

/**
 * The component for highlighting lines.
 *
 * @since 0.0.1
 */
export function ActiveLines( { event, root, options }: Renderer ): void {
  const lines = ( root && parseData( root ) ) || options.activeLines;

  if ( isArray( lines ) ) {
    const activeLines = normalize( lines );

    event.on( 'gutter:row:open', ( html, classes, index ) => {
      if ( activeLines[ index ] ) {
        classes.push( activeLines[ index ] );
      }
    } );

    event.on( 'line:open', ( html, classes, index ) => {
      if ( activeLines[ index ] ) {
        classes.push( activeLines[ index ] );
      }
    } );
  }
}

/**
 * Normalizes the definition of lines to activate.
 *
 * @param lines - An array with line numbers.
 *
 * @return An array with normalized line numbers.
 */
function normalize( lines: Array<number | [ number, number ]> ): string[] {
  const numbers = [];

  lines.forEach( range => {
    if ( ! isArray( range ) ) {
      range = [ range, range ];
    }

    const start = ( +range[ 0 ] || 1 ) - 1;
    const end   = ( +range[ 1 ] || 1 ) - 1;

    for ( let i = start; i <= end; i++ ) {
      numbers[ i ] = CLASSES.active;
    }
  } );

  return numbers;
}
  

SCSS

@import url( '../reset.scss' );

/*
 * Main styles
 */
:root {
  --text-color: #333;
}

body {
  color: var( --text-color );
  padding: 0 !important;
}

#container {
  padding: 2rem 2rem 4rem;
}

@media only screen
  and ( min-width: 320px )
  and ( max-width: 480px )
  and ( resolution: 150dpi ) {
    body { line-height: 1.4; }
}

@media ( /* ( max-width: 900px ) */ max-width: calc( ( 100px ) - 10 ) ) {
  .wrapper {
    background-image: url( "wave-#{ $name }.svg" );
    #{ $border }: 2px solid #ccc;
  }
}

@mixin animation( $prefix, $duration ) {
  $animation: $prefix-#{ unique-id() };

  @keyframes #{ $animation } {
    @content;
  }

  animation-name: $animation;
  animation-duration: $duration;
}

.dialog {
  @include animation( 500ms ) {
    from {
      opacity: 0;
    }
    to {
      opacity: 1;
    }
  }
}

/*
 * Components
 */
.button {
  $root: &;
  $inner: 'inner';

  /*
    font-family: Roboto, 'Avenir Next Pro', sans-serif;
    font-size: .9rem;
  */

  &__#{ $inner } {
    padding: 1rem;
  }

  &--primary {
    color: white;

    #{$root}__inner {
      background: $main-color;
    }
  }

  &:hover {
    background: rgba( 255, 255, 0, .1 );
  }

  &:active {
    outline: 2px solid hsla( 0, 0%, 100%, .6 );
  }

  &::after {
    content: attr( data-title number, 0 );
  }
}
  

JSX

import React from 'react';
import { Splide, SplideSlide } from '../../../../src/js';
import { createSlides } from "../utils/slides";

/**
 * The class for the thumbnail slider example.
 * Need to call sync() after the component is mounted, using refs.
 */
export default class ThumbnailsExample extends React.Component {
  /**
   * ThumbnailExample constructor.
   *
   * @param {Object} props - Props.
   */
  constructor( props ) {
    super( props );

    this.primaryRef   = React.createRef();
    this.secondaryRef = React.createRef();
  }

  /**
   * Set the sync target right after the component is mounted.
   */
  componentDidMount() {
    this.primaryRef.current.sync( this.secondaryRef.current.splide );
  }

  /**
   * Render slides.
   *
   * @return {ReactNode[]}
   */
  renderSlides() {
    return createSlides().map( slide => (
      <SplideSlide key={ slide.src }>
        <img src={ slide.src } alt={ slide.alt } />
      </SplideSlide>
    ) );
  };

  /**
   * Render the component.
   *
   * @return {ReactNode} - React component.
   */
  render() {
    const primaryOptions = {
      type      : 'loop',
      perPage   : 2,
      perMove   : 1,
      gap       : '1rem',
      pagination: false,
    };

    const secondaryOptions = {
      type        : 'slide',
      rewind      : true,
      gap         : '1rem',
      pagination  : false,
      fixedWidth  : 110,
      fixedHeight : 70,
      cover       : true,
      focus       : 'center',
      isNavigation: true,
      updateOnMove: true,
    };

    return (
      <div className="wrapper">
        <h2>Thumbnail Slider</h2>

        <a
          href="https://github.com/Splidejs/react-splide/blob/master/examples/src/js/components/ThumbnailsExample.jsx"
          target="_blank"
          rel="noopener"
        >
          View Code
        </a>

        <Splide options={ primaryOptions } ref={ this.primaryRef }>
          { this.renderSlides() }
        </Splide>

        <Splide options={ secondaryOptions } ref={ this.secondaryRef }>
          { this.renderSlides() }
        </Splide>
      </div>
    );
  }
}
  

Diff

/**
 * Converts +/- symbols to spaces or removes them.
 *
 * @param remove - Whether to remove symbols or not.
 * @param tokens - Target tokens.
 */
function convertSymbols( remove: boolean, tokens: Token[] ): void {
  const [ category, text ] = tokens[ 0 ];

+ if ( remove ) {
+   if ( text.length === 1 ) {
+     tokens.shift();
+   } else {
+     tokens[ 0 ] = [ category, text.slice( 1 ) ];
+   }
+ } else {
-   const spaceToken: Token = [ CATEGORY_SPACE, ' ' ];
-
-   if ( text.length === 1 ) {
-     tokens[ 0 ] = spaceToken;
    } else {
      tokens[ 0 ] = [ category, text.slice( 1 ) ];
      tokens.unshift( spaceToken );
    }
  }
}