Giter VIP home page Giter VIP logo

sanity-plugin-icon-picker's Introduction

sanity-plugin-icon-picker

This is a Sanity Studio v3 plugin.

Icon picker for Sanity which let you select icons from a set of icon providers.

image

Installation

npm install sanity-plugin-icon-picker

Usage

Add it as a plugin in sanity.config.ts (or .js):

import { defineConfig } from 'sanity';
import { iconPicker } from 'sanity-plugin-icon-picker';

export default defineConfig({
  //...
  plugins: [iconPicker()],
});

Use the type in your schemas.

{
    title: "Icon",
    name: "icon",
    type: "iconPicker"
}

Options

Providers

Define which icon providers you want to use by providing their provider id in the providers array. If not defined, the Icon Picker defaults to display all providers and icons.

{
    title: "Icon",
    name: "icon",
    type: "iconPicker",
    options: {
        providers: ["f7", "fa", "mdi", "sa", "hi", "fi", "si"]
    }
}

Output Format

Format the output data in accordance with your front-end project. If you're using React you can set the outputFormat to react. If you ommit this option, the output format will be in accordance with every single provider's icon naming convention.

{
    title: "Icon",
    name: "icon",
    type: "iconPicker",
    options: {
        outputFormat: 'react',
    }
}

Filter

Filter out a subset of icons to be used by specifying a filter. A filter can be either an exact match of a string (case insensitive) or a regular expression. Supports both the react naming convention of an icon name as well as default naming conventions for each icon provider. This means that defining for instance the Font Awesome icon arrow-circle-up is equal to defining the react version FaArrowCircleUp.

{
    title: "Icon",
    name: "icon",
    type: "iconPicker",
    options: {
        filter: ['FaBeer', 'FaDocker', /^arrow/i],
    }
}

Store SVG

If you don't want to dynamically generate the icons in your front-end as described in this example, you can opt in to storing the selected SVG icon as a string in your data (usage example here).

{
    title: "Icon",
    name: "icon",
    type: "iconPicker",
    options: {
        storeSvg: true
    }
}

Configurations

Extend the built in provider configurations by adding your own. Note that if you want to mix built-in provider configurations with your own, you need to specify them manually since all will not be used automatically if a configuration is available.

Key Type Description
title String The title of the icon set which will be displayed in the UI.
provider String Stored as icon picker data upon selection.
icons Function A function that returns an array of Icon Object.
Icon Object
name String Stored as icon picker data upon selection.
component Function A function that returns a React component. This function, when called, renders the icon in the UI.
tags Array of Strings An array containing the tags for the icon. This can be used for filtering.
import React from 'react'
import * as CarbonIcons from '@carbon/icons-react'
...
...
{
  title: 'Icon',
  name: 'icon',
  type: 'iconPicker',
  options: {
    configurations: [
      {
        title: 'Carbon Icons',
        provider: 'ci',
        icons: (options) =>
          Object.entries(CarbonIcons).map(([name, Component]) => ({
            name,
            component: () => <Component width="1.5em" height="1em" />,
            tags: [name],
          })),
      },
    ],
  },
},

Supported Icon Providers

Provider Prefix Homepage
Framework7 f7 https://framework7.io/icons/
Font Awesome fa https://fontawesome.com/
Material Design Icons mdi http://google.github.io/material-design-icons/
Sanity Icons sa https://www.sanity.io/
Hero Icons hi https://github.com/tailwindlabs/heroicons
Feather Icons fi https://feathericons.com/
Simple Icons si https://simpleicons.org/

Helper functions

Preview

In order to render the icon component as preview media, we can import a helper method.

import { preview } from 'sanity-plugin-icon-picker';

We can then render the icon by passing the selected name and provider to this method which will return an icon component.

{
...
    preview: {
        select: {
          provider: "icon.provider",
          name: "icon.name",
        },
        prepare(icon) {
          return {
            title: icon.provider,
            subtitle: icon.name,
            media: preview(icon),
          };
        },
      }
}

Preview with configurations

If you're using your own configurations you need to pass the options object to the preview parameters. Here's an example:

import React from 'react';
import { preview } from 'sanity-plugin-icon-picker';
import * as CarbonIcons from '@carbon/icons-react';

const options = {
  configurations: [
    {
      title: 'Carbon Icons',
      provider: 'ci',
      icons: (options) =>
        Object.entries(CarbonIcons).map(([name, Component]) => ({
          name,
          component: () => <Component width="1.5em" height="1em" />,
          tags: [name],
        })),
    },
  ],
};

export const schemaTypes = [
  {
    title: 'Icons',
    name: 'icons',
    type: 'document',
    fields: [
      {
        title: 'Icon',
        name: 'icon',
        type: 'iconPicker',
        options,
      },
    ],
    preview: {
      select: {
        provider: 'icon.provider',
        name: 'icon.name',
      },
      prepare(icon) {
        return {
          title: icon.provider,
          subtitle: icon.name,
          media: preview({ ...icon, options }),
        };
      },
    },
  },
];

Migrations

import { migrateIconName } from 'sanity-plugin-icon-picker';

We can use this function to migrate the name to a new outputFormat. This can be useful if you added icons in your studio and later decide that you want to use another outputFormat. Pass the third parameter react if you want to convert the name to options.outputFormat: 'react' naming convention. If you want to convert from react to default simply leave out the third parameter. Here's an example of a migration script where this function might come in handy.

migrateIconName('alert-circle', 'fi', 'react');

FAQ

Can I use this plugin for Sanity Studio v2?

Yes you can! Simply install the older version of this plugin

npm install [email protected]

Then refer to the old documentation and follow everything except the install step.

How can I consume the data returned from Sanity Studio in my React app?

Example 1: Dynamically generating icon

Here's a really simple example of how you could consume the data to render a Font Awesome icon from it. Note that in this example I'm using the option outputFormat: 'react' for the icon picker in the studio as mentioned here.

import * as Icons from 'react-icons/fa';

// Sanity data mock
const data = {
  _type: 'iconPicker',
  name: 'FaBeer',
  provider: 'fa',
  _updatedAt: '2021-07-25T02:30:43.141Z',
};

const DynamicFontAwesomeIcon = ({ name }) => Icons[name];

export default function App() {
  const Icon = DynamicFontAwesomeIcon(data);
  return (
    <div className="App">
      <Icon />
    </div>
  );
}

Example 2: Stored SVG

If you've opted in to store SVGs in your data (options.storeSvg), you could present them in various ways:

// Sanity data mock
const data = {
  _type: 'iconPicker',
  name: 'alert-circle',
  provider: 'fi',
  svg: '<svg stroke="currentColor" fill="none" stroke-width="2" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg" style="width: 1.5em; height: 1em;"><circle cx="12" cy="12" r="10"></circle><line x1="12" y1="8" x2="12" y2="12"></line><line x1="12" y1="16" x2="12.01" y2="16"></line></svg>',
};

export default function App() {
  const encodedSvg = encodeURIComponent(data.svg);
  const imgSrc = `data:image/svg+xml,${encodedSvg}`;

  return (
    <div className="App">
      <img src={imgSrc} />
    </div>
  );
}
import SVG from 'react-inlinesvg';

// Sanity data mock
const data = {
  _type: 'iconPicker',
  name: 'alert-circle',
  provider: 'fi',
  svg: '<svg fill="none" height="1em" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" viewBox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><circle cx="12" cy="12" r="10" /><line x1="12" x2="12" y1="8" y2="12" /><line x1="12" x2="12.01" y1="16" y2="16" /></svg>',
};

export default function App() {
  return (
    <div className="App">
      <SVG src={data.svg} />
    </div>
  );
}
Changing output format doesn't change the data

If you start adding icons to your data with for instance no options.outputFormat (default) set and then later decide that you want to use options.outputFormat: true, your data will not automagically update. You will either have to re-select each icon in your Studio or run a migration script to update all the icons to the correct output format. Here's an example of such a migration script.

Deploying NextJS embedded studio breaks studio

It's been reported several times that in some cases when deploying a studio that uses this plugin breaks the studio. The quick fix for that is to use swcMinify: false in your NextJS config.

License

MIT © Christopher Af Bjur

Develop & test

This plugin uses @sanity/plugin-kit with default configuration for build & watch scripts.

See Testing a plugin in Sanity Studio on how to run this plugin with hotreload in the studio.

sanity-plugin-icon-picker's People

Contributors

blueputty01 avatar christopherafbjur avatar geball avatar heggemsnes avatar jjk801 avatar loremipson avatar luizhop avatar tobiaswild avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

sanity-plugin-icon-picker's Issues

Large front-end bundles?

Hello!

First, this is an amazing package, and makes the CMS work so much easier!

This could be a misconfiguration on my end, but it looks like the bundle sizes of the react code from the example are very large. It looks like the entire icon package is served.

Perhaps a version of this lazy loading code may be suggested instead?

          const ComponentA = dynamic(() => {
            switch (icon.provider) {
              case 'mdi':
                return import(`react-icons/md`).then((mod) => mod[icon.name!]);
              case 'fa':
                return import(`react-icons/fa`).then((mod) => mod[icon.name!]);
              default:
                return import(`react-icons/fa`).then(
                  (mod) => mod.FaMapMarkerAlt
                );
            }
          });

Thank you for writing this plugin :)

Support for font awesome 6

Hello,

This plugin is very helpfull, is there a way to add support for font awesome 6?, I notice that some icons are not there like Xmark.

I think you use react icons, I'm not sure where to add the library for font awesome 6.

Regards
Miguel Angel

Icons are a bit cut of

I noticed that the Icons are always a bit cut off (see 1 and 2).
I don't know how to fix this, but this only applies to icons that use this return (3) instead of this (4).
Because these look normal (5).

  1. image
  2. image
  3. image
  4. image
  5. image

Consuming the icon in a React app

Hello! Thanks for this great plugin, it looks really nice so far in the studio.
I was just wondering how one would go ahead by converting the received data to an icon component in e.g. React?

I saw a reference to icon.component in the source code, but I cannot find anything like that in the retrieved data from Sanity. Is that unrelated or have I misconfigured something and should have access to icon.component?

Error on production and built but not on development

Hi I keep getting this error: Uncaught (in promise) ReferenceError: create$5 is not defined, I used the plugin for the simplest icon picker in an array. Installed the plugin and set it up in the plugins section of the sanity config object. And everything works on development mode but not after building. I have a nextjs site with the studio embedded into it, Maybe that has something to do with it.

Read-only field

Hello 👋

First of all, thanks for this great plugin!

I am trying to disable the iconPicker field for certain user roles, but not being able to do that.

Tried to use readOnly property on iconPicker field schema, like on other primitive fields, but apparently is not working.
Just to be sure I've tested adding it to other primitive fields like string and it worked.

{
   name: 'icon',
   title: 'Icon',
   type: 'iconPicker',
   readOnly: ({currentUser}) => {
      return !(currentUser.roles.find(({name}) => name === 'administrator'))
   }
}

The HTML output I was expecting is something like this:

<button data-ui="MenuButton" id="menu-button-example" aria-haspopup="true" aria-expanded="false" disabled aria-disabled="true" data-disabled="true" type="button" class="sc-brSaZW gFytae">...</button>

And the expected behaviour is the button to select the icon to be grey out and not clickable:
image

Is there another way to achieve that, or this is something not supported currently?

Thank you!

Add custom provider/lib

Could be beneficial for users to be able to inject custom icons via schema options.

Need to decide how we handle this.

Proposal A
A custom property that takes an object of custom library/provider as well as a render callback method which will pass the current icon iteration of injected lib as a parameter and expects the method to return a proper icon component/element?

Proposal B
Similar to A but the user has to format the custom icons to a controlled structure before passing them to the custom object.

Global css cannot be imported from within node_modules error

Hi! Getting this error after installing the sanity-plugin-icon-picker package:

error - ./node_modules/framework7-icons/css/framework7-icons.css
Global css cannot be imported from within node_modules.

Is there a compiled version of this dependency or other way to work around this issue?

Icons are cut off in MenuButton

MenuButtons in Sanity studio are cutting off the icons:

image

^^ That's supposed to be a Television, ha.

If I remove overflow: hidden; from the span that directly wraps the svg I can see them, but not sure how to do that in the lib itself. I have a fork here (needed to remove the default imported icons to reduce bundle size), would definitely be willing to make the PR myself if someone can point me in the right direction. :)

Sanity V3 Upgrade?

Hello, are there any plans to upgrade this plugin to work with Sanity v3? Thanks!

Optimize icon provider structure

Encapsulate current icon generators, preferably in a class that contain a render method for the indivudal icon element correctly as the process might/will be provider specific

Question: How to render returned values as React component?

I've got the component integrated and working correct but how are the returned values used to render a react icon component on the frontend? The values returned for FA for example are not title cased and contain hyphens so can't directly associate to font-awesome icons (i'm using react-icons/fa).

Sanity Schema

const iconPicker = {
  title: 'Icon',
  name: 'icon',
  type: 'iconPicker',
  options: {
    providers: ["f7", "fa", "mdi", "sa", "hi", "fi"],
    outputFormat: 'react'
  }
}

Usage

import * as Icons from 'react-icons/fa'

const DynamicFaIcon = ({ name }) => {
    const IconComponent = Icons[name]
    if (!IconComponent) {
      // Return a default one
      return <Icons.FaBeer className="h-6 w-6" aria-hidden="true" />
    }
    return <IconComponent className="h-6 w-6" aria-hidden="true" />
  }

And usage in a react component
<DynamicFaIcon name={blurb.icon.name} />

Translate the strings

Hi,
Are there any way of translate the plugin in strings without modify the package itself?

Tree shaking is not possible

Tree-shaking is not possible due to the fact that react-icons libraries are hardcoded on the plugin and activated by a string.

It would be a breaking change, but I think the way icons are enabled should be refactored:

Current implementation ( bundle will include all the other libraries even if not used) :

options: {
        providers: ["fa"]
    }

Tree-shaking friendly ( bundle will only contain fa )

import * as fa from 'react-icons/fa';

// ...

options: {
        providers: {fa:fa}
    }

Add spinner on icon load

Edit: Would be better to implement #6

When loading all icons there's quite a bit to render in the SearchResults component. Add a loading state to the component for now. Going forward we should use lazy load/rendering

Feature request: access to icons from Sanity or other React project

Hi, thanks for this plugin!

I was thinking of using the selected icon as a media item in the preview of a Sanity document.

However, in order to retrieve the icon I would need to have access to your getIcons utility method (or even better, a dedicated helper function). It should return the React component based on the data stored as the field value.

Could you please export such a function for external use?

Using custom provider breaks sanity codegen

I installed this plugin in my project and added some custom configuration to get my Icons to work, the field looks like so:

import { icons } from '..'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'


  defineField({
    title: 'Icon',
    name: 'icon',
    type: 'iconPicker',
    validation: (Rule) =>
      required ? Rule.required().error('This field is required') : Rule,
    options: {
      configurations: [
        {
          title: 'FA Solid Icons',
          provider: 'fa-pro',
          icons: () =>
            Object.entries(icons).map(([name, Component]) => {
              return {
                name,
                component: () => (
                  <div
                    style={{
                      display: 'flex',
                      alignItems: 'center',
                      justifyContent: 'center',
                      width: '25px',
                      height: '25px',
                    }}
                  >
                    <FontAwesomeIcon icon={Component} />
                  </div>
                ),
                tags: [name],
              }
            }),
        },
      ],
    },
  })

With the icons object being setup like so:

import {
  faSquareFacebook,
  faInstagram,
  faLinkedin,
  faTwitter,
} from '@fortawesome/free-brands-svg-icons'

export const icons = {
  squareFacebook: faSquareFacebook,
  instagram: faInstagram,
  linkedin: faLinkedin,
  twitter: faTwitter,
}

This worked fantastically well as it allowed me limit the icon options in the CMS to the same icons that my user facing ui Icon component was setup to use and I didn't have to worry about updating them in more then one place.

I also have the sanity-codegen plugin installed to generate typescript types based on my schema and the only issue I have had with this approach, is now when I try run npx sanity-codegen I get the following errors:

$ npx sanity-codegen
Error: matchMedia not present, legacy browsers require a polyfill
    at new MediaQueryDispatch (/Users/griz/Repos/ongava-website/node_modules/enquire.js/src/MediaQueryDispatch.js:15:15)
    at Object.<anonymous> (/Users/griz/Repos/ongava-website/node_modules/enquire.js/src/index.js:2:18)
    at Module._compile (node:internal/modules/cjs/loader:1159:14)
    at Module._compile (/Users/griz/Repos/ongava-website/node_modules/pirates/lib/index.js:136:24)
    at Module._extensions..js (node:internal/modules/cjs/loader:1213:10)
    at Object.newLoader [as .js] (/Users/griz/Repos/ongava-website/node_modules/pirates/lib/index.js:141:7)
    at Module.load (node:internal/modules/cjs/loader:1037:32)
    at Function.Module._load (node:internal/modules/cjs/loader:878:12)
    at Module.require (node:internal/modules/cjs/loader:1061:19)
    at require (node:internal/modules/cjs/helpers:103:18)
    at Object.<anonymous> (/Users/griz/Repos/ongava-website/node_modules/react-slick/lib/slider.js:50:53)
    at Module._compile (node:internal/modules/cjs/loader:1159:14)
    at Module._compile (/Users/griz/Repos/ongava-website/node_modules/pirates/lib/index.js:136:24)
    at Module._extensions..js (node:internal/modules/cjs/loader:1213:10)
    at Object.newLoader [as .js] (/Users/griz/Repos/ongava-website/node_modules/pirates/lib/index.js:141:7)
    at Module.load (node:internal/modules/cjs/loader:1037:32)
    at Function.Module._load (node:internal/modules/cjs/loader:878:12)
    at Module.require (node:internal/modules/cjs/loader:1061:19)
    at require (node:internal/modules/cjs/helpers:103:18)
    at Object.<anonymous> (/Users/griz/Repos/ongava-website/node_modules/react-slick/lib/index.js:8:38)
    at Module._compile (node:internal/modules/cjs/loader:1159:14)
    at Module._compile (/Users/griz/Repos/ongava-website/node_modules/pirates/lib/index.js:136:24)
    at Module._extensions..js (node:internal/modules/cjs/loader:1213:10)
    at Object.newLoader [as .js] (/Users/griz/Repos/ongava-website/node_modules/pirates/lib/index.js:141:7)
    at Module.load (node:internal/modules/cjs/loader:1037:32)
    at Function.Module._load (node:internal/modules/cjs/loader:878:12)
    at Module.require (node:internal/modules/cjs/loader:1061:19)
    at require (node:internal/modules/cjs/helpers:103:18)
    at Object.<anonymous> (/Users/griz/Repos/ongava-website/packages/ui/components/SliderEditorial/SliderEditorial.tsx:2:1)
    at Module._compile (node:internal/modules/cjs/loader:1159:14)
    at Module._compile (/Users/griz/Repos/ongava-website/node_modules/pirates/lib/index.js:136:24)
    at Module._extensions..js (node:internal/modules/cjs/loader:1213:10)
    at Object.newLoader [as .tsx] (/Users/griz/Repos/ongava-website/node_modules/pirates/lib/index.js:141:7)
    at Module.load (node:internal/modules/cjs/loader:1037:32)
    at Function.Module._load (node:internal/modules/cjs/loader:878:12)
    at Module.require (node:internal/modules/cjs/loader:1061:19)
    at require (node:internal/modules/cjs/helpers:103:18)
    at Object.<anonymous> (/Users/griz/Repos/ongava-website/packages/ui/components/SliderEditorial/index.ts:1:1)
    at Module._compile (node:internal/modules/cjs/loader:1159:14)
    at Module._compile (/Users/griz/Repos/ongava-website/node_modules/pirates/lib/index.js:136:24)
    at Module._extensions..js (node:internal/modules/cjs/loader:1213:10)
    at Object.newLoader [as .ts] (/Users/griz/Repos/ongava-website/node_modules/pirates/lib/index.js:141:7)
    at Module.load (node:internal/modules/cjs/loader:1037:32)
    at Function.Module._load (node:internal/modules/cjs/loader:878:12)
    at Module.require (node:internal/modules/cjs/loader:1061:19)
    at require (node:internal/modules/cjs/helpers:103:18)
    at Object.<anonymous> (/Users/griz/Repos/ongava-website/packages/ui/index.tsx:16:1)
    at Module._compile (node:internal/modules/cjs/loader:1159:14)
    at Module._compile (/Users/griz/Repos/ongava-website/node_modules/pirates/lib/index.js:136:24)
    at Module._extensions..js (node:internal/modules/cjs/loader:1213:10)
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

I tried installing:

matchmedia-polyfill

and importing it in the file, which did work for the codegen but then had a bunch of other issues with the project, and either way this doesnt seem like a good solution.

If anyone has any insight that would be much appreciated

Application error: a client-side exception has occurred (see the browser console for more information).

I'm trying to use the icon picker with my v3 studio. It works on localhost but when deployed to Vercel crashes the studio with error message: Application error: a client-side exception has occurred (see the browser console for more information).

Using a basic Vercel + Sanity blog starter. Here is my package.json

  "private": true,
  "scripts": {
    "build": "next build",
    "dev": "next",
    "format": "npx prettier --write . --ignore-path .gitignore --cache",
    "lint": "next lint -- --ignore-path .gitignore",
    "lint:fix": "npm run format && npm run lint -- --fix",
    "start": "next start",
    "type-check": "tsc --noEmit"
  },
  "prettier": {
    "semi": false,
    "singleQuote": true
  },
  "dependencies": {
    "@fortawesome/fontawesome-free": "^6.4.0",
    "@fortawesome/fontawesome-svg-core": "^6.4.0",
    "@fortawesome/free-brands-svg-icons": "^6.4.0",
    "@fortawesome/free-solid-svg-icons": "^6.4.0",
    "@fortawesome/react-fontawesome": "^0.2.0",
    "@material-tailwind/react": "^2.0.4",
    "@portabletext/react": "3.0.2",
    "@sanity/code-input": "^4.1.1",
    "@sanity/color-input": "^3.1.0",
    "@sanity/image-url": "1.0.2",
    "@sanity/table": "^1.0.1",
    "@sanity/vision": "3.12.0",
    "@sendgrid/mail": "^7.7.0",
    "@typeform/embed-react": "^2.22.0",
    "@vercel/og": "0.5.7",
    "classnames": "^2.3.2",
    "date-fns": "^2.30.0",
    "font-awesome": "^4.7.0",
    "framer-motion": "^10.12.17",
    "intl-segmenter-polyfill": "0.4.4",
    "next": "13.4.4",
    "next-sanity": "4.3.3",
    "nextjs-google-analytics": "^2.3.3",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-fast-marquee": "^1.6.0",
    "react-intersection-observer": "^9.5.1",
    "react-lowlight": "^3.0.0",
    "react-refractor": "^2.1.7",
    "react-string-replace": "^1.1.1",
    "react-syntax-highlighter": "^15.5.0",
    "sanity": "3.12.0",
    "sanity-plugin-asset-source-unsplash": "1.1.0",
    "sanity-plugin-icon-picker": "^3.2.1",
    "suspend-react": "0.0.10",
    "swiper": "^9.4.1",
    "swr": "2.1.5",
    "tailwind-fontawesome": "^0.5.0"
  },
  "devDependencies": {
    "@types/react": "^18.2.1",
    "autoprefixer": "^10.4.14",
    "eslint": "^8.39.0",
    "eslint-config-next": "13.4.4",
    "eslint-plugin-simple-import-sort": "^10.0.0",
    "postcss": "^8.4.23",
    "prettier": "^2.8.8",
    "prettier-plugin-packagejson": "^2.4.3",
    "prettier-plugin-tailwindcss": "^0.3.0",
    "tailwindcss": "3.3.2",
    "typescript": "5.1.3"
  },
  "engines": {
    "node": ">=16"
  }
}

DeprecationWarning: Invalid `main` field

When running sanity graphql deploy:

DeprecationWarning: Invalid 'main' field in '../node_modules/sanity-plugin-icon-picker/node_modules/react-icons/package.json' of 'lib'. Please either fix that or report it to the module author

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.