├── style └── index.css ├── .gitignore ├── tsconfig.json ├── schema └── plugin.json ├── package.json ├── src └── index.ts ├── README.md └── yarn.lock /style/index.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.bundle.* 2 | lib/ 3 | node_modules/ 4 | *.egg-info/ 5 | .ipynb_checkpoints 6 | tsconfig.tsbuildinfo 7 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "allowSyntheticDefaultImports": true, 4 | "composite": true, 5 | "declaration": true, 6 | "esModuleInterop": true, 7 | "incremental": true, 8 | "jsx": "react", 9 | "module": "esnext", 10 | "moduleResolution": "node", 11 | "noEmitOnError": true, 12 | "noImplicitAny": true, 13 | "noUnusedLocals": true, 14 | "preserveWatchOutput": true, 15 | "resolveJsonModule": true, 16 | "outDir": "lib", 17 | "rootDir": "src", 18 | "strict": true, 19 | "strictNullChecks": false, 20 | "target": "es2017", 21 | "types": [] 22 | }, 23 | "include": ["src/*"] 24 | } 25 | -------------------------------------------------------------------------------- /schema/plugin.json: -------------------------------------------------------------------------------- 1 | { 2 | "jupyter.lab.setting-icon-class": "jp-SettingsIcon", 3 | "jupyter.lab.setting-icon-label": "Custom CSS", 4 | "title": "Custom CSS", 5 | "description": "Custom CSS settings", 6 | "properties": { 7 | "rules": { 8 | "title": "CSS rules", 9 | "description": "CSS rules to be inserted into the HTML page", 10 | "items": { "$ref": "#/definitions/rule" }, 11 | "type": "array", 12 | "default": [] 13 | } 14 | }, 15 | "additionalProperties": false, 16 | "type": "object", 17 | "definitions": { 18 | "rule": { 19 | "title": "Rule definition", 20 | "properties": { 21 | "selector": { 22 | "title": "CSS selector", 23 | "type": "string" 24 | }, 25 | "styles": { 26 | "title": "Style definition", 27 | "description": "Style definitions for the selector", 28 | "type": "array", 29 | "items": { "type": "string" }, 30 | "minItems": 1 31 | } 32 | }, 33 | "required": ["selector", "styles"], 34 | "type": "object" 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@wallneradam/custom_css", 3 | "version": "0.2.0", 4 | "description": "Allow to insert custom css into JupyterLab", 5 | "keywords": [ 6 | "jupyter", 7 | "jupyterlab", 8 | "jupyterlab-extension" 9 | ], 10 | "homepage": "https://github.com/wallneradam/jupyterlab-custom-css.git", 11 | "bugs": { 12 | "url": "https://github.com/wallneradam/jupyterlab-custom-css.git/issues" 13 | }, 14 | "license": "BSD-3-Clause", 15 | "author": "Adam Wallner", 16 | "files": [ 17 | "lib/**/*.{d.ts,eot,gif,html,jpg,js,js.map,json,png,svg,woff2,ttf}", 18 | "style/**/*.{css,eot,gif,html,jpg,json,png,svg,woff2,ttf}", 19 | "schema/*.json" 20 | ], 21 | "main": "lib/index.js", 22 | "types": "lib/index.d.ts", 23 | "style": "style/index.css", 24 | "repository": { 25 | "type": "git", 26 | "url": "https://github.com/wallneradam/jupyterlab-custom-css.git.git" 27 | }, 28 | "scripts": { 29 | "build": "tsc", 30 | "clean": "rimraf lib && rimraf tsconfig.tsbuildinfo", 31 | "prepare": "npm run clean && npm run build", 32 | "watch": "tsc -w" 33 | }, 34 | "dependencies": { 35 | "@jupyterlab/application": "^2.0.2" 36 | }, 37 | "devDependencies": { 38 | "rimraf": "^3.0.2", 39 | "typescript": "~3.8.3" 40 | }, 41 | "sideEffects": [ 42 | "style/*.css" 43 | ], 44 | "jupyterlab": { 45 | "extension": true, 46 | "schemaDir": "schema" 47 | } 48 | } -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | const PLUGIN_NAME = "@wallneradam/custom_css"; 2 | 3 | import { JupyterFrontEnd, JupyterFrontEndPlugin } from '@jupyterlab/application'; 4 | import { ISettingRegistry } from '@jupyterlab/settingregistry'; 5 | import { JSONObject } from '@lumino/coreutils'; 6 | 7 | 8 | interface ICSSRule extends JSONObject { 9 | selector: string; 10 | styles: string[]; 11 | } 12 | 13 | 14 | const extension: JupyterFrontEndPlugin = { 15 | id: PLUGIN_NAME, 16 | requires: [ISettingRegistry], 17 | autoStart: true, 18 | 19 | activate: (app: JupyterFrontEnd, settingRegistry: ISettingRegistry) => { 20 | console.log('JupyterLab extension custom_css is activated!'); 21 | 22 | let styleElement = document.createElement("style"); 23 | styleElement.type = "text/css"; 24 | styleElement.id = PLUGIN_NAME; 25 | document.body.appendChild(styleElement); 26 | 27 | /** 28 | * Update settings on change 29 | * @param settings The loaded settings 30 | */ 31 | function updateOptions(settings: ISettingRegistry.ISettings): void { 32 | let styles = ""; 33 | let rules = settings.composite.rules as ICSSRule[]; 34 | for (let rule of rules) { 35 | styles += `${rule.selector} \{`; 36 | styles += "\n " + rule.styles.join(";\n ") 37 | styles += "\n}\n"; 38 | } 39 | document.body.removeChild(styleElement); 40 | styleElement.innerHTML = styles; 41 | document.body.appendChild(styleElement); 42 | } 43 | 44 | // Load settings 45 | settingRegistry 46 | .load(extension.id + ':plugin') 47 | .then(settings => { 48 | // Update options 49 | updateOptions(settings); 50 | 51 | // Update options on settings changed 52 | settings.changed.connect(() => { 53 | updateOptions(settings); 54 | }); 55 | }); 56 | } 57 | }; 58 | 59 | 60 | export default extension; 61 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # custom-css 2 | 3 | Add custom CSS rules to JupyterLab 4 | 5 | ## Usage 6 | 7 | After install the plugin, you should see an item called "Custom CSS" in the settings in "Advanced Settings Editor". 8 | Here you can specify any CSS rules you want. 9 | 10 | ```javascript 11 | { 12 | "rules": [ 13 | { 14 | "selector": ".cls-parent .cls-child", 15 | "styles": [ 16 | "max-height: 100px", 17 | "font-size: 14px" 18 | ] 19 | }, 20 | ... 21 | ] 22 | } 23 | ``` 24 | 25 | This will create an inline `