@infinite-canvas-tutorial/webcomponents
Version:
WebComponents UI implementation
371 lines (356 loc) • 12.5 kB
JavaScript
;
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.InputGradient = void 0;
const lit_1 = require("lit");
const decorators_js_1 = require("lit/decorators.js");
const map_js_1 = require("lit/directives/map.js");
const overlay_1 = require("@spectrum-web-components/overlay");
const ecs_1 = require("@infinite-canvas-tutorial/ecs");
const color_picker_1 = require("./color-picker");
let InputGradient = class InputGradient extends lit_1.LitElement {
updated(changedProperties) {
if (changedProperties.has('value')) {
this.gradients = (0, ecs_1.parseGradient)(this.value) || [];
}
}
triggerGradientChangeEvent() {
const event = new CustomEvent('color-change', {
detail: {
type: 'gradient',
value: convertGradientsToCSSValue(this.gradients),
opacity: this.opacity,
},
bubbles: true,
composed: true,
});
this.dispatchEvent(event);
}
addGradient() {
this.gradients = [
...this.gradients,
{
type: 'linear-gradient',
angle: 0,
steps: [
{
offset: {
type: '%',
value: 0,
},
color: '#fff',
},
{
offset: {
type: '%',
value: 100,
},
color: '#000',
},
],
},
];
this.triggerGradientChangeEvent();
}
removeGradient(index) {
this.gradients = this.gradients.filter((_, i) => i !== index);
this.triggerGradientChangeEvent();
}
addStop(index) {
this.gradients[index].steps.push({
offset: {
type: '%',
value: 0,
},
color: 'white',
});
this.triggerGradientChangeEvent();
}
removeStop(index, stopIndex) {
this.gradients[index].steps = this.gradients[index].steps.filter((_, i) => i !== stopIndex);
this.triggerGradientChangeEvent();
}
handleOpacityChange(e) {
const opacity = e.target.value;
this.opacity = opacity;
this.triggerGradientChangeEvent();
}
handleAngleChange(index, e) {
const angle = e.target.value;
if (this.gradients[index].type === 'linear-gradient') {
this.gradients[index].angle = angle;
this.triggerGradientChangeEvent();
}
}
handleGradientTypeChange(index, e) {
const type = e.target.value;
this.gradients[index].type = type;
this.triggerGradientChangeEvent();
}
handleColorChange(index, stopIndex, e) {
e.stopPropagation();
const color = e.detail.value;
this.gradients[index].steps[stopIndex].color = color;
this.triggerGradientChangeEvent();
}
handleOffsetChange(index, stopIndex, e) {
const offset = e.target.value * 100;
this.gradients[index].steps[stopIndex].offset.value = offset;
this.triggerGradientChangeEvent();
}
render() {
return (0, lit_1.html) `
<sp-action-button quiet size="s" @click="${this.addGradient}">
<sp-tooltip self-managed placement="bottom"> Add gradient </sp-tooltip>
<sp-icon-add slot="icon"></sp-icon-add>
</sp-action-button>
<div class="gradient-list">
${(0, map_js_1.map)(this.gradients, (gradient, index) => {
const renderOverlayContent = () => (0, lit_1.html) `
<sp-popover class="gradient-settings-popover" dialog>
<h4>Gradient settings</h4>
${gradient.type === 'linear-gradient'
? (0, lit_1.html) `
<div class="angle-field"
<sp-field-label for="angle" side-aligned="start"
>Angle</sp-field-label
>
<sp-number-field
id="angle"
size="s"
min="0"
max="360"
step="1"
value=${gradient.angle}
@input=${this.handleAngleChange.bind(this, index)}
></sp-number-field></div>`
: ''}
<div class="gradient-stops-header">
Stops
<sp-action-button
quiet
size="s"
@click="${this.addStop.bind(this, index)}"
>
<sp-tooltip self-managed placement="bottom">
Add stop
</sp-tooltip>
<sp-icon-add slot="icon"></sp-icon-add>
</sp-action-button>
</div>
<div class="gradient-stops">
${gradient.steps.map((step, stopIndex) => {
return (0, lit_1.html) `
<div class="gradient-stop">
<div>
<sp-number-field
id="angle"
size="s"
min="0"
max="1"
step="0.1"
format-options='{
"style": "percent"
}'
value=${step.offset.value / 100}
@input=${this.handleOffsetChange.bind(this, index, stopIndex)}
></sp-number-field>
<sp-swatch
id=${`stop-color-${index}-${stopIndex}`}
color=${step.color}
size="s"
></sp-swatch>
<sp-overlay
type="auto"
trigger=${`stop-color-${index}-${stopIndex}@click`}
placement="bottom"
>
<sp-popover class="stop-color-popover" dialog>
<ic-spectrum-color-picker
.types=${[color_picker_1.ColorType.Solid]}
value=${step.color}
@color-change=${this.handleColorChange.bind(this, index, stopIndex)}
></ic-spectrum-color-picker>
</sp-popover>
</sp-overlay>
</div>
<sp-action-button
quiet
size="s"
@click="${this.removeStop.bind(this, index, stopIndex)}"
>
<sp-tooltip self-managed placement="bottom">
Remove stop
</sp-tooltip>
<sp-icon-remove slot="icon"></sp-icon-remove>
</sp-action-button>
</div>
`;
})}
</div>
</sp-popover>
`;
return (0, lit_1.html) `<div class="gradient-item">
<div>
<sp-swatch
color=${convertGradientsToCSSValue([gradient])}
size="s"
></sp-swatch>
<sp-picker
label="Gradient type"
size="s"
value=${gradient.type}
@change=${this.handleGradientTypeChange.bind(this, index)}
>
<sp-menu-item value="linear-gradient">Linear</sp-menu-item>
<sp-menu-item value="radial-gradient">Radial</sp-menu-item>
<sp-menu-item value="conic-gradient">Conic</sp-menu-item>
</sp-picker>
</div>
<div>
<sp-action-button
quiet
size="s"
${(0, overlay_1.trigger)(renderOverlayContent, {
triggerInteraction: 'click',
overlayOptions: {
placement: 'bottom',
offset: 6,
},
})}
>
<sp-icon-settings slot="icon"></sp-icon-settings>
<sp-tooltip self-managed placement="bottom">
Gradient settings
</sp-tooltip>
</sp-action-button>
<sp-action-button
quiet
size="s"
@click="${this.removeGradient.bind(this, index)}"
>
<sp-tooltip self-managed placement="bottom">
Remove gradient
</sp-tooltip>
<sp-icon-remove slot="icon"></sp-icon-remove>
</sp-action-button>
</div>
</div>`;
})}
</div>
`;
}
};
exports.InputGradient = InputGradient;
InputGradient.styles = (0, lit_1.css) `
.gradient-actions {
display: flex;
align-items: center;
justify-content: end;
gap: 8px;
}
.gradient-list {
display: flex;
flex-direction: column;
gap: 4px;
overflow-y: auto;
overflow-x: hidden;
height: 114px;
}
.gradient-item {
display: flex;
align-items: center;
justify-content: space-between;
> div {
display: flex;
align-items: center;
gap: 8px;
}
sp-picker {
width: 100px;
}
}
sp-popover {
padding: 0;
}
sp-swatch {
transform: rotate(90deg);
}
.gradient-settings-popover {
display: flex;
flex-direction: column;
gap: 8px;
padding: 8px;
h4 {
margin: 0;
}
.angle-field {
display: flex;
align-items: center;
}
sp-number-field {
width: 100px;
}
}
.gradient-stops-header {
display: flex;
align-items: center;
justify-content: space-between;
}
.gradient-stops {
display: flex;
flex-direction: column;
gap: 4px;
overflow: auto;
}
.gradient-stop {
display: flex;
align-items: center;
justify-content: space-between;
> div {
display: flex;
align-items: center;
gap: 8px;
}
}
`;
__decorate([
(0, decorators_js_1.property)()
], InputGradient.prototype, "value", void 0);
__decorate([
(0, decorators_js_1.property)()
], InputGradient.prototype, "opacity", void 0);
__decorate([
(0, decorators_js_1.state)()
], InputGradient.prototype, "gradients", void 0);
exports.InputGradient = InputGradient = __decorate([
(0, decorators_js_1.customElement)('ic-spectrum-input-gradient')
], InputGradient);
function convertGradientsToCSSValue(gradients) {
return gradients
.map((gradient) => {
if (gradient.type === 'linear-gradient') {
return `linear-gradient(${gradient.angle || 0}deg, ${gradient.steps
.map((step) => `${step.color} ${step.offset.value}%`)
.join(', ')})`;
}
else if (gradient.type === 'radial-gradient') {
return `radial-gradient(${gradient.steps
.map((step) => `${step.color} ${step.offset.value}%`)
.join(', ')})`;
}
else if (gradient.type === 'conic-gradient') {
return `conic-gradient(${gradient.steps
.map((step) => `${step.color} ${step.offset.value}%`)
.join(', ')})`;
}
return '';
})
.join(', ');
}
//# sourceMappingURL=input-gradient.js.map