Skip to content

[Feature] Responsive Color Picker #48

@ryanraposo

Description

@ryanraposo

Responsive Color Picker

The color picker in the Color view should automatically resize to fit the view.

48_current

Relevant Code

The 'Color' view in CodeUI is a Webview, which is no different than an ordinary webpage.

The HTML comes from a template literal:

codeui/src/color.ts

Lines 65 to 87 in fff58bb

return `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<!--
Use a content security policy to only allow loading images from https or from our extension directory,
and only allow scripts that have a specific nonce.
-->
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; style-src ${webview.cspSource}; script-src 'nonce-${nonce}';">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="${styleColorWheel}" rel="stylesheet">
</head>
<body>
<div id="color-wheel-container"></div>
<script nonce="${nonce}" src="${colorWheel}"></script>
<script nonce="${nonce}" src="${main}"></script>
</body>
</html>`;

This is the JavaScript behind the view:

codeui/media/main.js

Lines 5 to 49 in fff58bb

(function () {
const vscode = acquireVsCodeApi();
const initialColor = '#3fdaa4';
document.addEventListener('contextmenu', function(ev) {
ev.preventDefault();
}, false);
var currentState = vscode.getState() || { color: initialColor };
function updateSelectedColor(color) {
vscode.postMessage({ type: 'updateSelectedColor', value: color });
}
function saveState(state) {
vscode.setState({ color: state.color });
currentState = state;
updateSelectedColor(state.color);
}
window.addEventListener('message', (event) => {
const message = event.data;
switch (message.type) {
case 'setSelectedColor': {
colorWheel.hex = message.value;
break;
}
}
});
var colorWheel = new ReinventedColorWheel({
appendTo: document.getElementById('color-wheel-container'),
hex: currentState.selectedColor,
wheelDiameter: 200,
wheelThickness: 20,
handleDiameter: 16,
wheelReflectsSaturation: true,
onChange: function (color) {
saveState({ color: color.hex });
},
});
saveState({ color: colorWheel.hex });
})();

Currently, there is no CSS other than the stylesheet included with the color picker package:

.reinvented-color-wheel, .reinvented-color-wheel--hue-handle, .reinvented-color-wheel--hue-wheel, .reinvented-color-wheel--sv-handle, .reinvented-color-wheel--sv-space {
touch-action: manipulation;
touch-action: none;
-webkit-touch-callout: none;
-webkit-tap-highlight-color: transparent;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none
}
.reinvented-color-wheel {
position: relative;
display: inline-block;
line-height: 0;
border-radius: 50%;
}
.reinvented-color-wheel--hue-wheel {
border-radius: 50%
}
.reinvented-color-wheel--sv-space {
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
margin: auto
}
.reinvented-color-wheel--hue-handle, .reinvented-color-wheel--sv-handle {
position: absolute;
box-sizing: border-box;
border-radius: 50%;
border: 2px solid #fff;
box-shadow: 0 0 0 1px #000 inset
}
.reinvented-color-wheel--hue-handle {
pointer-events: none
}

Note: the package, reinvented-color-picker, is located in codeui/media alongside main.js (above). It is stored locally (not via npm) in the lib folder:

media
    └main.js
    └───lib
        └ reinvented-color-wheel.min.css
        └ reinvented-color-wheel.min.js

Solution

The solve for this issue could involve:

  • CSS (./media/lib/reinvented-color-wheel.css or a new file, ex: ./media/style.css)
  • Manipulation of the ReinventedColorWheel object and it's properties. See ./media/main.js:

codeui/media/main.js

Lines 36 to 47 in fff58bb

var colorWheel = new ReinventedColorWheel({
appendTo: document.getElementById('color-wheel-container'),
hex: currentState.selectedColor,
wheelDiameter: 200,
wheelThickness: 20,
handleDiameter: 16,
wheelReflectsSaturation: true,
onChange: function (color) {
saveState({ color: color.hex });
},
});

  • The VS Code Extension API. I can help with this side of things if you are only comfortable with the 'traditional web' stuff.

    An example is the onDidChangeVisibility event of the WebviewView. For the most part, we can work within the webview--but if we want to detect open/close/collapse events for the view container itself, we need to 'ask' VS Code.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions