npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

mycrossword

v1.4.0

Published

React crossword component

Downloads

148

Readme

MyCrossword

React crossword component built to work with Guardian crossword data.

image

Features

  • Displays crossword grid and list of clues
  • Displays separators in the grid for hyphenated and multi-word solutions
  • Responsive to different screen sizes
  • Clue selection highlights relevant cells
  • Grouped clues span multiple columns or rows
  • Tab key cycles between clues
  • Arrow keys navigate between cells
  • Displays attempted clues as greyed out
  • Autosaves progress to local storage
  • Smart clearing only removes cells not part of other completed solutions
  • Check and reveal solution functions (provided solutionsAvailable: true )
  • Anagram helper

Install

npm

npm install mycrossword --save

yarn

yarn add mycrossword

Usage

import MyCrossword from 'mycrossword';
import 'mycrossword/dist/index.css';
import React from 'react';

const data = {
  /* ... crossword data (see below) ... */
};

export default function MyPage() {
  return <MyCrossword id="crossword-1" data={data} />;
}

Props

| Property | Description | | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | allowedHtmlTags | string[] = ['b', 'strong', 'i', 'em', 'sub', 'sup']Optional list of HTML tags allowed within the clues. Use [] to prevent all HTML tags. Defaults to ['b', 'strong', 'i', 'em', 'sub', 'sup']. | | allowMissingSolutions | boolean = falseOptional flag to relax grid validation. This will allow the data prop to have missing or incomplete solutions in its entries. | | cellMatcher | RegExp = '/[A-Z]/'Optional regular expression to match against entered cell characters. Defaults to /[A-Z]/. | | className | stringOptional string to apply a space-delimited list of class names. | | data | GuardianCrosswordRequired object that contains crossword clues, solutions and other information needed to draw the grid. See crossword data below for more information. | | id | stringRequired string to uniquely identify the crossword. | | loadGrid | GuessGrid \| undefinedOptional object to override storage mechanism. Called when the component is initialized with the ID of the crossword. Should return an array-based representation of the crossword grid. See guess grid below for more information. | | onCellChange | (cellChange: CellChange) => void \| undefinedOptional function. Called after a grid cell has changed its guess. The object contains the properties pos, guess and previousGuess. | | onCellFocus | (cellFocus: CellFocus) => void \| undefinedOptional function. Called after the focus switches to a new cell. The object returned contains the properties pos and clueId. | | saveGrid | (value: GuessGrid \| ((val: GuessGrid) => GuessGrid)) => void \| undefinedOptional function to override storage mechanism. Called after the grid has changed with the ID of the crossword and array-based representation of the grid. See guess grid below for more information. | | stickyClue | 'always' \| 'never' \| 'auto' = 'auto'Optional value to define when to show the sticky clue above the grid. Defaults to 'auto' (shown on xs and sm breakpoints). | | theme | 'red' \| 'pink' \| 'purple' \| 'deepPurple' \| 'indigo' \| 'blue' \| 'lightBlue' \| 'cyan' \| 'teal' \| 'green' \| 'deepOrange' \| 'blueGrey' = 'blue'Optional value to override the main colour applied to the highlighted cells and clues. Defaults to 'blue'. |

For more type information, see interfaces.

Crossword data

This is an example of the JSON data required to create the crossword shown above. Its structure is defined by the GuardianCrossword interface.

{
  id: 'simple/1',
  number: 1,
  name: 'Simple Crossword #1',
  date: 1542326400000,
  entries: [
    {
      id: '1-across',
      number: 1,
      humanNumber: '1',
      clue: 'Toy on a string (2-2)',
      direction: 'across',
      length: 4,
      group: ['1-across'],
      position: { x: 0, y: 0 },
      separatorLocations: {
        '-': [2],
      },
      solution: 'YOYO',
    },
    {
      id: '4-across',
      number: 4,
      humanNumber: '4',
      clue: 'Have a rest (3,4)',
      direction: 'across',
      length: 7,
      group: ['4-across'],
      position: { x: 0, y: 2 },
      separatorLocations: {
        ',': [3],
      },
      solution: 'LIEDOWN',
    },
    {
      id: '1-down',
      number: 1,
      humanNumber: '1',
      clue: 'Colour (6)',
      direction: 'down',
      length: 6,
      group: ['1-down'],
      position: { x: 0, y: 0 },
      separatorLocations: {},
      solution: 'YELLOW',
    },
    {
      id: '2-down',
      number: 2,
      humanNumber: '2',
      clue: 'Bits and bobs (4,3,4)',
      direction: 'down',
      length: 7,
      group: ['2-down', '3-down'],
      position: { x: 3, y: 0 },
      separatorLocations: {
        ',': [4, 7],
      },
      solution: 'ODDSAND',
    },
    {
      id: '3-down',
      number: 3,
      humanNumber: '3',
      clue: 'See 2',
      direction: 'down',
      length: 4,
      group: ['2-down', '3-down'],
      position: {
        x: 6,
        y: 1,
      },
      separatorLocations: {},
      solution: 'ENDS',
    },
  ],
  solutionAvailable: true,
  dateSolutionAvailable: 1542326400000,
  dimensions: {
    cols: 13,
    rows: 13,
  },
  crosswordType: 'quick',
};

Guess grid

Some functions require or return the state of the crossword grid. This is a 2-dimensional array holding the user's guess for each cell. Incomplete cells or cells that are not part of any answer are represented as the empty string (""). Note that it follows the convention of indexing by column first (x) and then row (y) so the printed array is transposed compared to how the crossword grid appears. For example, the following crossword...

...would be represented as...

{
  "value": [
    ["",  "",  "A"],
    ["D", "O", "G"],
    ["",  "",  "E"]
  ]
}

What's new?

While the project has been created from scratch, it should be considered as a continuation of @guardian/react-crossword. With that in mind, here's a list of improvements when compared to the original:

Technical improvements

  • Use of TypeScript
  • Switched to functional components
  • Better performance (memoization, useCallback etc.)
  • Simplified global state management using RTK
  • More modular component hierarchy
  • Scoped CSS
  • Full unit test coverage
  • CI using GitHub actions

Functional improvements

  • Theme styles
  • Combined buttons to use dropdown menus
  • Check/Reveal letter
  • Arrow keys can skip over dark cells
  • Backspace key moves backwards without the cell having to be empty
  • Anagram helper
    • Click clue words to add to anagram
    • Added letter to centre of word wheel
    • Character counter
    • Escape key to clear/close
    • Show missing letters from grid
  • Removed hidden input and implicitly fixed the window resize bug
  • Fixed HTML display in StickyClue and AnagramHelper
  • Better loading and error state display

Working with this project

yarn to install dependencies

yarn test to run unit tests

yarn build to package for publishing

yarn build:watch to package and watch for changes

cd example && yarn start to run the example application

Licence

MIT, © 2021 Tom Blackwell