├── .npmrc ├── cypress.json ├── postcss.config.js ├── public ├── favicon.png └── index.html ├── .gitignore ├── src ├── components │ ├── components.module.js │ └── Cursor.svelte ├── main.js └── App.svelte ├── cypress ├── fixtures │ └── example.json ├── integration │ └── Cursor.spec.js ├── support │ ├── index.js │ └── commands.js └── plugins │ └── index.js ├── .eslintrc.json ├── babel.config.js ├── LICENSE ├── README.md ├── package.json └── rollup.config.js /.npmrc: -------------------------------------------------------------------------------- 1 | save-exact=true -------------------------------------------------------------------------------- /cypress.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: [require('autoprefixer')] 3 | } 4 | -------------------------------------------------------------------------------- /public/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YerkoPalma/cursor/master/public/favicon.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | **/dist/** 3 | **/node_modules/** 4 | **/public/bundle.* 5 | 6 | cypress/videos 7 | cypress/screenshots -------------------------------------------------------------------------------- /src/components/components.module.js: -------------------------------------------------------------------------------- 1 | export { default as Cursor } from './Cursor.svelte' 2 | export { plainCursor, crossCursor } from './Cursor.svelte' 3 | -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | import App from './App.svelte' 2 | 3 | const app = new App({ 4 | target: document.body, 5 | props: {} 6 | }) 7 | 8 | export default app 9 | -------------------------------------------------------------------------------- /cypress/fixtures/example.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Using fixtures to represent data", 3 | "email": "hello@cypress.io", 4 | "body": "Fixtures are a great way to mock data for responses to routes" 5 | } -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": [ 3 | "cypress", "svelte3" 4 | ], 5 | "overrides": [ 6 | { 7 | "files": ["**/*.svelte"], 8 | "processor": "svelte3/svelte3" 9 | } 10 | ] 11 | } -------------------------------------------------------------------------------- /cypress/integration/Cursor.spec.js: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | context('Actions', () => { 4 | beforeEach(() => { 5 | cy.visit('http://localhost:5000') 6 | }) 7 | 8 | it('Should render cursor', () => { 9 | cy.get('.cursor-wrapper').should('exist') 10 | }) 11 | }) 12 | -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Svelte component 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | include: ['**/**/*.js', '**/**/*.mjs', '**/**/*.html', '**/**/*.svelte'], 3 | plugins: [ 4 | '@babel/plugin-syntax-dynamic-import', 5 | [ 6 | '@babel/plugin-transform-runtime', 7 | { 8 | useESModules: true 9 | } 10 | ] 11 | ], 12 | presets: ['@babel/preset-env'], 13 | ignore: ['node_modules/**'] 14 | } 15 | -------------------------------------------------------------------------------- /cypress/support/index.js: -------------------------------------------------------------------------------- 1 | // *********************************************************** 2 | // This example support/index.js is processed and 3 | // loaded automatically before your test files. 4 | // 5 | // This is a great place to put global configuration and 6 | // behavior that modifies Cypress. 7 | // 8 | // You can change the location of this file or turn off 9 | // automatically serving support files with the 10 | // 'supportFile' configuration option. 11 | // 12 | // You can read more here: 13 | // https://on.cypress.io/configuration 14 | // *********************************************************** 15 | 16 | // Import commands.js using ES2015 syntax: 17 | import './commands' 18 | 19 | // Alternatively you can use CommonJS syntax: 20 | // require('./commands') 21 | -------------------------------------------------------------------------------- /cypress/plugins/index.js: -------------------------------------------------------------------------------- 1 | // *********************************************************** 2 | // This example plugins/index.js can be used to load plugins 3 | // 4 | // You can change the location of this file or turn off loading 5 | // the plugins file with the 'pluginsFile' configuration option. 6 | // 7 | // You can read more here: 8 | // https://on.cypress.io/plugins-guide 9 | // *********************************************************** 10 | 11 | // This function is called when a project is opened or re-opened (e.g. due to 12 | // the project's config changing) 13 | 14 | // eslint-disable-next-line no-unused-vars 15 | module.exports = (on, config) => { 16 | // `on` is used to hook into various events Cypress emits 17 | // `config` is the resolved Cypress config 18 | } 19 | -------------------------------------------------------------------------------- /cypress/support/commands.js: -------------------------------------------------------------------------------- 1 | // *********************************************** 2 | // This example commands.js shows you how to 3 | // create various custom commands and overwrite 4 | // existing commands. 5 | // 6 | // For more comprehensive examples of custom 7 | // commands please read more here: 8 | // https://on.cypress.io/custom-commands 9 | // *********************************************** 10 | // 11 | // 12 | // -- This is a parent command -- 13 | // Cypress.Commands.add("login", (email, password) => { ... }) 14 | // 15 | // 16 | // -- This is a child command -- 17 | // Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... }) 18 | // 19 | // 20 | // -- This is a dual command -- 21 | // Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... }) 22 | // 23 | // 24 | // -- This will overwrite an existing command -- 25 | // Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... }) 26 | 27 | // For Cypress Testing Library 28 | import '@testing-library/cypress/add-commands' 29 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Yerko Palma 2020 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # @yerkopalma/cursor 2 | 3 | Custom cursor component 4 | 5 | ## Usage 6 | 7 | ```svelte 8 | 11 | 12 | 13 | ``` 14 | 15 | ## Install 16 | 17 | ```bash 18 | npm install --save-dev @yerkopalma/cursor 19 | ``` 20 | 21 | ## API 22 | 23 | ### `Cursor` component 24 | 25 | The default export is the svelte component adding it into your 26 | page will affect the your whole site. You can also set the following properties: 27 | 28 | - `global: boolean = true` => Set to false to change the cursor element only on the parent component. 29 | - `type: ['dot', 'spot', 'ring', 'circle', 'cross', 'minus']` => Predefined types of cursor, defaults to dot. 30 | - `color: string` => A valid css color for the cursor. 31 | 32 | ### actions 33 | 34 | If you want a different cursor on hover for specific elements, you should 35 | use predefined actions on those elements, example: 36 | 37 | ```svelte 38 | 41 | 42 | magnetic 43 | ``` 44 | 45 | Availaible actions are: 46 | 47 | - magneticCursor 48 | - dotCursor 49 | - crossCursor 50 | - minusCursor 51 | - borderCursor 52 | 53 | Also, you can define custom actions for custom hovers 54 | 55 | TODO: Document custom actions 56 | 57 | ## License 58 | MIT -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "browserslist": [ 3 | "defaults" 4 | ], 5 | "description": "Custom cursor component", 6 | "devDependencies": { 7 | "@babel/core": "7.8.4", 8 | "@babel/plugin-syntax-dynamic-import": "7.8.3", 9 | "@babel/plugin-transform-runtime": "7.8.3", 10 | "@babel/preset-env": "7.8.4", 11 | "@testing-library/cypress": "5.3.0", 12 | "autoprefixer": "9.7.4", 13 | "cypress": "3.8.3", 14 | "eslint": "6.8.0", 15 | "eslint-plugin-cypress": "2.9.0", 16 | "eslint-plugin-svelte3": "2.7.3", 17 | "paper": "0.12.4", 18 | "postcss": "7.0.26", 19 | "postcss-load-config": "2.1.0", 20 | "rollup": "1.31.0", 21 | "rollup-plugin-babel": "4.3.3", 22 | "rollup-plugin-commonjs": "10.1.0", 23 | "rollup-plugin-livereload": "1.0.4", 24 | "rollup-plugin-node-resolve": "5.2.0", 25 | "rollup-plugin-svelte": "5.1.1", 26 | "rollup-plugin-terser": "5.2.0", 27 | "sirv-cli": "0.4.5", 28 | "snazzy": "8.0.0", 29 | "standard": "14.3.1", 30 | "start-server-and-test": "1.10.7", 31 | "svelte": "3.18.2", 32 | "svelte-css-vars": "0.0.1", 33 | "svelte-preprocess": "3.4.0" 34 | }, 35 | "files": [ 36 | "src", 37 | "dist" 38 | ], 39 | "keywords": [ 40 | "svelte" 41 | ], 42 | "standard": { 43 | "env": [ 44 | "browser", 45 | "mocha" 46 | ], 47 | "globals": [ 48 | "cy", 49 | "Cypress", 50 | "expect", 51 | "assert" 52 | ] 53 | }, 54 | "license": "MIT", 55 | "main": "dist/index.min.js", 56 | "module": "dist/index.min.mjs", 57 | "name": "@yerkopalma/cursor", 58 | "repository": "Custom cursor component", 59 | "scripts": { 60 | "build": "rollup -c", 61 | "cy:open": "cypress open", 62 | "cy:run": "cypress run", 63 | "dev": "rollup -c -w", 64 | "lint": "standard --fix", 65 | "prepublishOnly": "npm run build", 66 | "start": "sirv public", 67 | "test": "standard --verbose | snazzy && start-server-and-test dev http://localhost:5000 cy:run" 68 | }, 69 | "svelte": "src/components/components.module.js", 70 | "version": "1.1.0" 71 | } 72 | -------------------------------------------------------------------------------- /src/App.svelte: -------------------------------------------------------------------------------- 1 | 49 | 50 | 65 | 66 | 67 | 68 | 69 | 70 |
71 |
72 | Cursor color: 73 | 74 | 75 | 76 | Cursor type: 77 | 85 |
86 | {@html body} 87 |
88 | 89 | 90 | -------------------------------------------------------------------------------- /rollup.config.js: -------------------------------------------------------------------------------- 1 | import { terser } from 'rollup-plugin-terser' 2 | import autoPreprocess from 'svelte-preprocess' 3 | import babel from 'rollup-plugin-babel' 4 | import commonjs from 'rollup-plugin-commonjs' 5 | import livereload from 'rollup-plugin-livereload' 6 | import pkg from './package.json' 7 | import resolve from 'rollup-plugin-node-resolve' 8 | import svelte from 'rollup-plugin-svelte' 9 | 10 | const production = !process.env.ROLLUP_WATCH 11 | const name = pkg.name 12 | .replace(/^(@\S+\/)?(svelte-)?(\S+)/, '$3') 13 | .replace(/^\w/, (m) => m.toUpperCase()) 14 | .replace(/-\w/g, (m) => m[1].toUpperCase()) 15 | 16 | export default { 17 | input: !production ? 'src/main.js' : 'src/components/components.module.js', 18 | output: !production 19 | ? { 20 | sourcemap: true, 21 | format: 'iife', 22 | name: 'app', 23 | file: 'public/bundle.js' 24 | } 25 | : [ 26 | { 27 | file: pkg.module, 28 | format: 'es', 29 | sourcemap: true, 30 | name 31 | }, 32 | { 33 | file: pkg.main, 34 | format: 'umd', 35 | sourcemap: true, 36 | name 37 | } 38 | ], 39 | plugins: [ 40 | babel({ 41 | runtimeHelpers: true 42 | }), 43 | svelte({ 44 | // enable run-time checks when not in production 45 | dev: !production, 46 | // we'll extract any component CSS out into 47 | // a separate file — better for performance 48 | css: (css) => { 49 | css.write('public/bundle.css') 50 | }, 51 | 52 | /** 53 | * Auto preprocess supported languages with 54 | * '