etherpad-webcomponents 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/LICENSE +21 -0
  2. package/dist/EpButton.d.ts +16 -0
  3. package/dist/EpButton.d.ts.map +1 -0
  4. package/dist/EpButton.js +148 -0
  5. package/dist/EpButton.js.map +1 -0
  6. package/dist/EpCard.d.ts +15 -0
  7. package/dist/EpCard.d.ts.map +1 -0
  8. package/dist/EpCard.js +126 -0
  9. package/dist/EpCard.js.map +1 -0
  10. package/dist/EpChatMessage.d.ts +15 -0
  11. package/dist/EpChatMessage.d.ts.map +1 -0
  12. package/dist/EpChatMessage.js +86 -0
  13. package/dist/EpChatMessage.js.map +1 -0
  14. package/dist/EpCheckbox.d.ts +15 -0
  15. package/dist/EpCheckbox.d.ts.map +1 -0
  16. package/dist/EpCheckbox.js +122 -0
  17. package/dist/EpCheckbox.js.map +1 -0
  18. package/dist/EpColorPicker.d.ts +16 -0
  19. package/dist/EpColorPicker.d.ts.map +1 -0
  20. package/dist/EpColorPicker.js +188 -0
  21. package/dist/EpColorPicker.js.map +1 -0
  22. package/dist/EpColorWheel.d.ts +61 -0
  23. package/dist/EpColorWheel.d.ts.map +1 -0
  24. package/dist/EpColorWheel.js +428 -0
  25. package/dist/EpColorWheel.js.map +1 -0
  26. package/dist/EpDropdown.d.ts +41 -0
  27. package/dist/EpDropdown.d.ts.map +1 -0
  28. package/dist/EpDropdown.js +272 -0
  29. package/dist/EpDropdown.js.map +1 -0
  30. package/dist/EpDropdownItem.d.ts +16 -0
  31. package/dist/EpDropdownItem.d.ts.map +1 -0
  32. package/dist/EpDropdownItem.js +88 -0
  33. package/dist/EpDropdownItem.js.map +1 -0
  34. package/dist/EpInput.d.ts +20 -0
  35. package/dist/EpInput.d.ts.map +1 -0
  36. package/dist/EpInput.js +149 -0
  37. package/dist/EpInput.js.map +1 -0
  38. package/dist/EpModal.d.ts +45 -0
  39. package/dist/EpModal.d.ts.map +1 -0
  40. package/dist/EpModal.js +210 -0
  41. package/dist/EpModal.js.map +1 -0
  42. package/dist/EpNotification.d.ts +32 -0
  43. package/dist/EpNotification.d.ts.map +1 -0
  44. package/dist/EpNotification.js +215 -0
  45. package/dist/EpNotification.js.map +1 -0
  46. package/dist/EpTheme.d.ts +33 -0
  47. package/dist/EpTheme.d.ts.map +1 -0
  48. package/dist/EpTheme.js +109 -0
  49. package/dist/EpTheme.js.map +1 -0
  50. package/dist/EpToast.d.ts +37 -0
  51. package/dist/EpToast.d.ts.map +1 -0
  52. package/dist/EpToast.js +220 -0
  53. package/dist/EpToast.js.map +1 -0
  54. package/dist/EpToolbarSelect.d.ts +24 -0
  55. package/dist/EpToolbarSelect.d.ts.map +1 -0
  56. package/dist/EpToolbarSelect.js +138 -0
  57. package/dist/EpToolbarSelect.js.map +1 -0
  58. package/dist/EpUserBadge.d.ts +15 -0
  59. package/dist/EpUserBadge.d.ts.map +1 -0
  60. package/dist/EpUserBadge.js +90 -0
  61. package/dist/EpUserBadge.js.map +1 -0
  62. package/dist/index.d.ts +17 -0
  63. package/dist/index.d.ts.map +1 -0
  64. package/dist/index.js +16 -0
  65. package/dist/index.js.map +1 -0
  66. package/package.json +43 -0
@@ -0,0 +1,188 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ 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;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ import { LitElement, html, css } from 'lit';
8
+ import { customElement, property } from 'lit/decorators.js';
9
+ const isLightColor = (color) => {
10
+ try {
11
+ const ctx = document.createElement('canvas').getContext('2d');
12
+ if (!ctx)
13
+ return false;
14
+ ctx.fillStyle = color;
15
+ const resolved = ctx.fillStyle;
16
+ let r = 0, g = 0, b = 0;
17
+ if (resolved.startsWith('#')) {
18
+ const hex = resolved.slice(1);
19
+ r = parseInt(hex.slice(0, 2), 16);
20
+ g = parseInt(hex.slice(2, 4), 16);
21
+ b = parseInt(hex.slice(4, 6), 16);
22
+ }
23
+ else {
24
+ const match = resolved.match(/\d+/g);
25
+ if (match) {
26
+ r = parseInt(match[0], 10);
27
+ g = parseInt(match[1], 10);
28
+ b = parseInt(match[2], 10);
29
+ }
30
+ }
31
+ return (0.299 * r + 0.587 * g + 0.114 * b) / 255 > 0.6;
32
+ }
33
+ catch {
34
+ return false;
35
+ }
36
+ };
37
+ const DEFAULT_COLORS = [
38
+ 'black', 'red', 'green', 'blue', 'yellow', 'orange',
39
+ 'purple', 'pink', 'brown', 'gray', 'white', 'cyan',
40
+ ];
41
+ let EpColorPicker = class EpColorPicker extends LitElement {
42
+ constructor() {
43
+ super(...arguments);
44
+ this.colors = DEFAULT_COLORS;
45
+ this.value = '';
46
+ }
47
+ render() {
48
+ return html `
49
+ <div class="grid" role="listbox" aria-label="Color picker">
50
+ ${this.colors.map((color, i) => this._renderSwatch(color, i))}
51
+ </div>
52
+ `;
53
+ }
54
+ _renderSwatch(color, index) {
55
+ const isSelected = this.value === color;
56
+ const light = isLightColor(color);
57
+ const checkColor = light ? '#000' : '#fff';
58
+ return html `
59
+ <button class="swatch"
60
+ role="option"
61
+ aria-selected="${isSelected}"
62
+ aria-label="${color}"
63
+ tabindex="${index === 0 ? '0' : '-1'}"
64
+ @click="${() => this._selectColor(color, index)}"
65
+ @keydown="${(e) => this._handleKeydown(e)}">
66
+ <div class="swatch-inner" style="background:${color}">
67
+ <svg class="check" viewBox="0 0 14 14" fill="${checkColor}">
68
+ <path d="M11.5 3.5L5.5 10.5L2.5 7.5" stroke="${checkColor}" stroke-width="2"
69
+ fill="none" stroke-linecap="round" stroke-linejoin="round"/>
70
+ </svg>
71
+ </div>
72
+ </button>
73
+ `;
74
+ }
75
+ _selectColor(color, index) {
76
+ this.value = color;
77
+ this.dispatchEvent(new CustomEvent('ep-color-select', {
78
+ bubbles: true, composed: true,
79
+ detail: { color, index },
80
+ }));
81
+ }
82
+ _handleKeydown(e) {
83
+ const swatches = Array.from(this.renderRoot.querySelectorAll('.swatch'));
84
+ const current = e.currentTarget;
85
+ const idx = swatches.indexOf(current);
86
+ let nextIdx = -1;
87
+ switch (e.key) {
88
+ case 'ArrowRight':
89
+ case 'ArrowDown':
90
+ nextIdx = (idx + 1) % swatches.length;
91
+ break;
92
+ case 'ArrowLeft':
93
+ case 'ArrowUp':
94
+ nextIdx = (idx - 1 + swatches.length) % swatches.length;
95
+ break;
96
+ case 'Home':
97
+ nextIdx = 0;
98
+ break;
99
+ case 'End':
100
+ nextIdx = swatches.length - 1;
101
+ break;
102
+ case 'Enter':
103
+ case ' ':
104
+ e.preventDefault();
105
+ current.click();
106
+ return;
107
+ default:
108
+ return;
109
+ }
110
+ e.preventDefault();
111
+ swatches[idx].setAttribute('tabindex', '-1');
112
+ swatches[nextIdx].setAttribute('tabindex', '0');
113
+ swatches[nextIdx].focus();
114
+ }
115
+ };
116
+ EpColorPicker.styles = css `
117
+ :host {
118
+ --ep-font: var(--main-font-family, Quicksand, Cantarell, "Open Sans", "Helvetica Neue", sans-serif);
119
+ display: inline-block;
120
+ font-family: var(--ep-font);
121
+ }
122
+
123
+ .grid {
124
+ display: grid;
125
+ grid-template-columns: repeat(auto-fill, 32px);
126
+ gap: 6px;
127
+ padding: 8px;
128
+ background: var(--bg-color, white);
129
+ border: 1px solid var(--middle-color, #d2d2d2);
130
+ border-radius: 5px;
131
+ box-shadow: 0 0 0 1px rgba(99, 114, 130, 0.16), 0 8px 16px rgba(27, 39, 51, 0.08);
132
+ }
133
+
134
+ .swatch {
135
+ width: 32px;
136
+ height: 32px;
137
+ border-radius: 6px;
138
+ border: 2px solid transparent;
139
+ cursor: pointer;
140
+ position: relative;
141
+ transition: border-color 0.15s ease, transform 0.1s ease;
142
+ padding: 0;
143
+ background: none;
144
+ outline: none;
145
+ display: flex;
146
+ align-items: center;
147
+ justify-content: center;
148
+ }
149
+
150
+ .swatch:hover { transform: scale(1.1); }
151
+
152
+ .swatch:focus-visible {
153
+ outline: 2px solid var(--dark-color, #576273);
154
+ outline-offset: 2px;
155
+ }
156
+
157
+ .swatch[aria-selected="true"] {
158
+ border-color: var(--text-color, #485365);
159
+ }
160
+
161
+ .swatch-inner {
162
+ width: 100%;
163
+ height: 100%;
164
+ border-radius: 4px;
165
+ display: flex;
166
+ align-items: center;
167
+ justify-content: center;
168
+ }
169
+
170
+ .check {
171
+ display: none;
172
+ width: 14px;
173
+ height: 14px;
174
+ }
175
+
176
+ .swatch[aria-selected="true"] .check { display: block; }
177
+ `;
178
+ __decorate([
179
+ property({ type: Array })
180
+ ], EpColorPicker.prototype, "colors", void 0);
181
+ __decorate([
182
+ property()
183
+ ], EpColorPicker.prototype, "value", void 0);
184
+ EpColorPicker = __decorate([
185
+ customElement('ep-color-picker')
186
+ ], EpColorPicker);
187
+ export { EpColorPicker };
188
+ //# sourceMappingURL=EpColorPicker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EpColorPicker.js","sourceRoot":"","sources":["../src/EpColorPicker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,61 @@
1
+ import { LitElement, PropertyValues } from 'lit';
2
+ export declare class EpColorWheel extends LitElement {
3
+ static properties: {
4
+ size: {
5
+ type: NumberConstructor;
6
+ };
7
+ value: {
8
+ type: StringConstructor;
9
+ };
10
+ showInput: {
11
+ type: BooleanConstructor;
12
+ attribute: string;
13
+ };
14
+ _hsl: {
15
+ state: boolean;
16
+ };
17
+ };
18
+ static styles: import("lit").CSSResult;
19
+ size: number;
20
+ value: string;
21
+ showInput: boolean;
22
+ _hsl: [number, number, number];
23
+ private _dragging;
24
+ private _wheelWidth;
25
+ private _squareHalf;
26
+ private _mid;
27
+ private _maskDrawn;
28
+ private _ready;
29
+ private _boundMove;
30
+ private _boundUp;
31
+ constructor();
32
+ connectedCallback(): void;
33
+ protected firstUpdated(_changed: PropertyValues): void;
34
+ protected updated(changed: PropertyValues): void;
35
+ private _paint;
36
+ protected render(): import("lit").TemplateResult<1>;
37
+ private _computeGeometry;
38
+ private _syncFromValue;
39
+ private _emitColor;
40
+ private _drawWheel;
41
+ private _drawOverlay;
42
+ /** Ring marker for the hue wheel — white ring with shadow */
43
+ private _drawRingMarker;
44
+ /** Dot marker for the square — filled circle with border */
45
+ private _drawDotMarker;
46
+ private _updateSolid;
47
+ private _handleDown;
48
+ private _handleMove;
49
+ private _handleUp;
50
+ private _applyPos;
51
+ private _onHexChange;
52
+ private _onHexKeydown;
53
+ setHSL(h: number, s: number, l: number): void;
54
+ getHSL(): [number, number, number];
55
+ }
56
+ declare global {
57
+ interface HTMLElementTagNameMap {
58
+ 'ep-color-wheel': EpColorWheel;
59
+ }
60
+ }
61
+ //# sourceMappingURL=EpColorWheel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EpColorWheel.d.ts","sourceRoot":"","sources":["../src/EpColorWheel.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAa,cAAc,EAAE,MAAM,KAAK,CAAC;AAuD5D,qBAAa,YAAa,SAAQ,UAAU;IAC1C,OAAgB,UAAU;;;;;;;;;;;;;;MAKxB;IAEF,OAAgB,MAAM,0BA8DpB;IAEF,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,OAAO,CAAC;IACnB,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAE/B,OAAO,CAAC,SAAS,CAAmC;IACpD,OAAO,CAAC,WAAW,CAAK;IACxB,OAAO,CAAC,WAAW,CAAK;IACxB,OAAO,CAAC,IAAI,CAAK;IACjB,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,MAAM,CAAS;IAEvB,OAAO,CAAC,UAAU,CAA0B;IAC5C,OAAO,CAAC,QAAQ,CAAa;;IAYpB,iBAAiB;cAKP,YAAY,CAAC,QAAQ,EAAE,cAAc;cAKrC,OAAO,CAAC,OAAO,EAAE,cAAc;IAOlD,OAAO,CAAC,MAAM;cAOK,MAAM;IA2BzB,OAAO,CAAC,gBAAgB;IASxB,OAAO,CAAC,cAAc;IAOtB,OAAO,CAAC,UAAU;IAWlB,OAAO,CAAC,UAAU;IAuDlB,OAAO,CAAC,YAAY;IAkCpB,6DAA6D;IAC7D,OAAO,CAAC,eAAe;IAoBvB,4DAA4D;IAC5D,OAAO,CAAC,cAAc;IAyBtB,OAAO,CAAC,YAAY;IAepB,OAAO,CAAC,WAAW;IAgBnB,OAAO,CAAC,WAAW;IASnB,OAAO,CAAC,SAAS;IAMjB,OAAO,CAAC,SAAS;IAkBjB,OAAO,CAAC,YAAY;IAcpB,OAAO,CAAC,aAAa;IAMrB,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM;IAMtC,MAAM,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;CAGnC;AAMD,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,gBAAgB,EAAE,YAAY,CAAC;KAChC;CACF"}
@@ -0,0 +1,428 @@
1
+ import { LitElement, html, css } from 'lit';
2
+ // ---------------------------------------------------------------------------
3
+ // Color math (HSL ↔ RGB, all values 0..1)
4
+ // ---------------------------------------------------------------------------
5
+ function hueToRGB(m1, m2, h) {
6
+ if (h < 0)
7
+ h++;
8
+ if (h > 1)
9
+ h--;
10
+ if (h * 6 < 1)
11
+ return m1 + (m2 - m1) * h * 6;
12
+ if (h * 2 < 1)
13
+ return m2;
14
+ if (h * 3 < 2)
15
+ return m1 + (m2 - m1) * (2 / 3 - h) * 6;
16
+ return m1;
17
+ }
18
+ function hslToRgb(h, s, l) {
19
+ const m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s;
20
+ const m1 = l * 2 - m2;
21
+ return [hueToRGB(m1, m2, h + 1 / 3), hueToRGB(m1, m2, h), hueToRGB(m1, m2, h - 1 / 3)];
22
+ }
23
+ function rgbToHsl(r, g, b) {
24
+ const max = Math.max(r, g, b), min = Math.min(r, g, b);
25
+ const l = (max + min) / 2, d = max - min;
26
+ if (d === 0)
27
+ return [0, 0, l];
28
+ const s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
29
+ let h;
30
+ if (max === r)
31
+ h = ((g - b) / d + (g < b ? 6 : 0)) / 6;
32
+ else if (max === g)
33
+ h = ((b - r) / d + 2) / 6;
34
+ else
35
+ h = ((r - g) / d + 4) / 6;
36
+ return [h, s, l];
37
+ }
38
+ function rgbToHex(r, g, b) {
39
+ const x = (v) => Math.round(v * 255).toString(16).padStart(2, '0');
40
+ return `#${x(r)}${x(g)}${x(b)}`;
41
+ }
42
+ function hexToRgb(hex) {
43
+ let h = hex.replace('#', '');
44
+ if (h.length === 3)
45
+ h = h[0] + h[0] + h[1] + h[1] + h[2] + h[2];
46
+ return [parseInt(h.slice(0, 2), 16) / 255, parseInt(h.slice(2, 4), 16) / 255, parseInt(h.slice(4, 6), 16) / 255];
47
+ }
48
+ function luminance(r, g, b) {
49
+ return r * 0.3 + g * 0.59 + b * 0.11;
50
+ }
51
+ // Angle offset: hue 0 (red) at 12 o'clock
52
+ const ANGLE_OFFSET = -Math.PI / 2;
53
+ // ---------------------------------------------------------------------------
54
+ // Component
55
+ // ---------------------------------------------------------------------------
56
+ export class EpColorWheel extends LitElement {
57
+ constructor() {
58
+ super();
59
+ this._dragging = null;
60
+ this._wheelWidth = 0;
61
+ this._squareHalf = 0;
62
+ this._mid = 0;
63
+ this._maskDrawn = false;
64
+ this._ready = false;
65
+ this.size = 200;
66
+ this.value = '#485365';
67
+ this.showInput = true;
68
+ this._hsl = [0, 0, 0.3];
69
+ this._boundMove = this._handleMove.bind(this);
70
+ this._boundUp = this._handleUp.bind(this);
71
+ }
72
+ connectedCallback() {
73
+ super.connectedCallback();
74
+ this._syncFromValue();
75
+ }
76
+ firstUpdated(_changed) {
77
+ this._ready = true;
78
+ this._paint();
79
+ }
80
+ updated(changed) {
81
+ if (!this._ready)
82
+ return;
83
+ if (changed.has('size'))
84
+ this._maskDrawn = false;
85
+ if (changed.has('value') && !this._dragging)
86
+ this._syncFromValue();
87
+ this._paint();
88
+ }
89
+ _paint() {
90
+ this._computeGeometry();
91
+ if (!this._maskDrawn) {
92
+ this._drawWheel();
93
+ this._maskDrawn = true;
94
+ }
95
+ this._drawOverlay();
96
+ this._updateSolid();
97
+ }
98
+ render() {
99
+ const s = this.size;
100
+ return html `
101
+ <div class="wrapper">
102
+ <div class="container" style="width:${s}px;height:${s}px;"
103
+ @mousedown="${this._handleDown}">
104
+ <div class="solid"></div>
105
+ <canvas class="mask" width="${s}" height="${s}"></canvas>
106
+ <canvas class="overlay" width="${s}" height="${s}"></canvas>
107
+ </div>
108
+ ${this.showInput ? html `
109
+ <div class="preview-row">
110
+ <div class="swatch-preview" style="background:${this.value}"></div>
111
+ <input class="hex-input"
112
+ .value="${this.value}"
113
+ @change="${this._onHexChange}"
114
+ @keydown="${this._onHexKeydown}"
115
+ maxlength="7" spellcheck="false"
116
+ aria-label="Hex color value" />
117
+ </div>
118
+ ` : ''}
119
+ </div>
120
+ `;
121
+ }
122
+ // ── Geometry ─────────────────────────────────────────────
123
+ _computeGeometry() {
124
+ this._mid = this.size / 2;
125
+ this._wheelWidth = Math.round(this.size / 10);
126
+ const innerR = this._mid - this._wheelWidth - 4; // 4px gap
127
+ this._squareHalf = Math.floor(innerR * 0.7);
128
+ }
129
+ // ── Sync ─────────────────────────────────────────────────
130
+ _syncFromValue() {
131
+ try {
132
+ const [r, g, b] = hexToRgb(this.value);
133
+ this._hsl = rgbToHsl(r, g, b);
134
+ }
135
+ catch {
136
+ this._hsl = [0, 0, 0.3];
137
+ }
138
+ }
139
+ _emitColor() {
140
+ const [r, g, b] = hslToRgb(this._hsl[0], this._hsl[1], this._hsl[2]);
141
+ this.value = rgbToHex(r, g, b);
142
+ this.dispatchEvent(new CustomEvent('ep-color-change', {
143
+ bubbles: true, composed: true,
144
+ detail: { color: this.value, hsl: [this._hsl[0], this._hsl[1], this._hsl[2]] },
145
+ }));
146
+ }
147
+ // ── Draw: Hue wheel + sat/lum mask ──────────────────────
148
+ _drawWheel() {
149
+ const canvas = this.renderRoot?.querySelector('.mask');
150
+ if (!canvas)
151
+ return;
152
+ const ctx = canvas.getContext('2d');
153
+ if (!ctx)
154
+ return;
155
+ const size = this.size;
156
+ const mid = this._mid;
157
+ const ww = this._wheelWidth;
158
+ const sq = this._squareHalf;
159
+ ctx.clearRect(0, 0, size, size);
160
+ ctx.save();
161
+ ctx.translate(mid, mid);
162
+ // ── Hue ring (720 segments for smoothness) ──
163
+ const outerR = mid - 1;
164
+ const innerR = outerR - ww;
165
+ const steps = 720;
166
+ for (let i = 0; i < steps; i++) {
167
+ const hue = i / steps;
168
+ const a0 = hue * Math.PI * 2 + ANGLE_OFFSET - 0.01;
169
+ const a1 = (i + 1.5) / steps * Math.PI * 2 + ANGLE_OFFSET;
170
+ const [r, g, b] = hslToRgb(hue, 1, 0.5);
171
+ ctx.beginPath();
172
+ ctx.arc(0, 0, outerR, a0, a1);
173
+ ctx.arc(0, 0, innerR, a1, a0, true);
174
+ ctx.closePath();
175
+ ctx.fillStyle = rgbToHex(r, g, b);
176
+ ctx.fill();
177
+ }
178
+ ctx.restore();
179
+ // ── Sat/lum mask (absolute coords — putImageData ignores transform) ──
180
+ const sqSize = sq * 2;
181
+ if (sqSize <= 0)
182
+ return;
183
+ const imgData = ctx.createImageData(sqSize, sqSize);
184
+ const data = imgData.data;
185
+ for (let y = 0; y < sqSize; y++) {
186
+ const lum = 1 - y / sqSize;
187
+ for (let x = 0; x < sqSize; x++) {
188
+ const sat = 1 - x / sqSize;
189
+ const a = 1 - 2 * Math.min(lum * sat, (1 - lum) * sat);
190
+ const c = a > 0 ? ((2 * lum - 1 + a) * 0.5 / a) : 0;
191
+ const idx = (y * sqSize + x) * 4;
192
+ data[idx] = data[idx + 1] = data[idx + 2] = Math.round(c * 255);
193
+ data[idx + 3] = Math.round(a * 255);
194
+ }
195
+ }
196
+ ctx.putImageData(imgData, mid - sq, mid - sq);
197
+ }
198
+ // ── Draw: Overlay (markers) ──────────────────────────────
199
+ _drawOverlay() {
200
+ const canvas = this.renderRoot?.querySelector('.overlay');
201
+ if (!canvas)
202
+ return;
203
+ const ctx = canvas.getContext('2d');
204
+ if (!ctx)
205
+ return;
206
+ const size = this.size;
207
+ const mid = this._mid;
208
+ const ww = this._wheelWidth;
209
+ const sq = this._squareHalf;
210
+ const [h, s, l] = this._hsl;
211
+ ctx.clearRect(0, 0, size, size);
212
+ ctx.save();
213
+ ctx.translate(mid, mid);
214
+ const [cr, cg, cb] = hslToRgb(h, s, l);
215
+ const lum = luminance(cr, cg, cb);
216
+ // ── Hue marker on wheel ──
217
+ const hueAngle = h * Math.PI * 2 + ANGLE_OFFSET;
218
+ const wheelMidR = mid - 1 - ww / 2;
219
+ const hx = Math.cos(hueAngle) * wheelMidR;
220
+ const hy = Math.sin(hueAngle) * wheelMidR;
221
+ this._drawRingMarker(ctx, hx, hy, ww / 2 - 1);
222
+ // ── Square marker ──
223
+ const sx = -(s - 0.5) * sq * 2;
224
+ const sy = -(l - 0.5) * sq * 2;
225
+ this._drawDotMarker(ctx, sx, sy, lum > 0.55);
226
+ ctx.restore();
227
+ }
228
+ /** Ring marker for the hue wheel — white ring with shadow */
229
+ _drawRingMarker(ctx, x, y, r) {
230
+ // Shadow
231
+ ctx.save();
232
+ ctx.shadowColor = 'rgba(0,0,0,0.25)';
233
+ ctx.shadowBlur = 4;
234
+ ctx.beginPath();
235
+ ctx.arc(x, y, r, 0, Math.PI * 2);
236
+ ctx.strokeStyle = 'white';
237
+ ctx.lineWidth = 2.5;
238
+ ctx.stroke();
239
+ ctx.restore();
240
+ // Inner ring
241
+ ctx.beginPath();
242
+ ctx.arc(x, y, r, 0, Math.PI * 2);
243
+ ctx.strokeStyle = 'white';
244
+ ctx.lineWidth = 2.5;
245
+ ctx.stroke();
246
+ }
247
+ /** Dot marker for the square — filled circle with border */
248
+ _drawDotMarker(ctx, x, y, dark) {
249
+ const r = 7;
250
+ const border = dark ? 'rgba(0,0,0,0.6)' : 'white';
251
+ const inner = dark ? 'rgba(0,0,0,0.15)' : 'rgba(255,255,255,0.25)';
252
+ // Shadow
253
+ ctx.save();
254
+ ctx.shadowColor = 'rgba(0,0,0,0.3)';
255
+ ctx.shadowBlur = 5;
256
+ ctx.beginPath();
257
+ ctx.arc(x, y, r, 0, Math.PI * 2);
258
+ ctx.fillStyle = inner;
259
+ ctx.fill();
260
+ ctx.restore();
261
+ // Border ring
262
+ ctx.beginPath();
263
+ ctx.arc(x, y, r, 0, Math.PI * 2);
264
+ ctx.strokeStyle = border;
265
+ ctx.lineWidth = 2;
266
+ ctx.stroke();
267
+ }
268
+ // ── Update solid hue div ─────────────────────────────────
269
+ _updateSolid() {
270
+ const el = this.renderRoot?.querySelector('.solid');
271
+ if (!el)
272
+ return;
273
+ const sq = this._squareHalf;
274
+ const mid = this._mid;
275
+ const [r, g, b] = hslToRgb(this._hsl[0], 1, 0.5);
276
+ el.style.left = `${mid - sq}px`;
277
+ el.style.top = `${mid - sq}px`;
278
+ el.style.width = `${sq * 2}px`;
279
+ el.style.height = `${sq * 2}px`;
280
+ el.style.background = rgbToHex(r, g, b);
281
+ }
282
+ // ── Interaction ──────────────────────────────────────────
283
+ _handleDown(e) {
284
+ e.preventDefault();
285
+ const canvas = this.renderRoot?.querySelector('.overlay');
286
+ if (!canvas)
287
+ return;
288
+ const rect = canvas.getBoundingClientRect();
289
+ const pos = { x: e.clientX - rect.left - this._mid, y: e.clientY - rect.top - this._mid };
290
+ const sq = this._squareHalf;
291
+ // Chebyshev distance: inside square or on the wheel?
292
+ this._dragging = Math.max(Math.abs(pos.x), Math.abs(pos.y)) <= sq + 2 ? 'square' : 'wheel';
293
+ this._applyPos(pos);
294
+ document.addEventListener('mousemove', this._boundMove);
295
+ document.addEventListener('mouseup', this._boundUp);
296
+ }
297
+ _handleMove(e) {
298
+ if (!this._dragging)
299
+ return;
300
+ e.preventDefault();
301
+ const canvas = this.renderRoot?.querySelector('.overlay');
302
+ if (!canvas)
303
+ return;
304
+ const rect = canvas.getBoundingClientRect();
305
+ this._applyPos({ x: e.clientX - rect.left - this._mid, y: e.clientY - rect.top - this._mid });
306
+ }
307
+ _handleUp() {
308
+ this._dragging = null;
309
+ document.removeEventListener('mousemove', this._boundMove);
310
+ document.removeEventListener('mouseup', this._boundUp);
311
+ }
312
+ _applyPos(pos) {
313
+ const sq = this._squareHalf;
314
+ const [h, s, l] = this._hsl;
315
+ const clamp = (v) => Math.max(0, Math.min(1, v));
316
+ if (this._dragging === 'wheel') {
317
+ // atan2 gives angle from positive X axis; subtract offset to align with our wheel
318
+ const angle = Math.atan2(pos.y, pos.x) - ANGLE_OFFSET;
319
+ this._hsl = [(angle / (Math.PI * 2) + 1) % 1, s, l];
320
+ }
321
+ else {
322
+ this._hsl = [h, clamp(0.5 - pos.x / (sq * 2)), clamp(0.5 - pos.y / (sq * 2))];
323
+ }
324
+ this._emitColor();
325
+ this.requestUpdate();
326
+ }
327
+ // ── Hex input ────────────────────────────────────────────
328
+ _onHexChange(e) {
329
+ let val = e.target.value.trim();
330
+ if (!val.startsWith('#'))
331
+ val = '#' + val;
332
+ if (/^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/.test(val)) {
333
+ this.value = val;
334
+ this._syncFromValue();
335
+ this.requestUpdate();
336
+ this.dispatchEvent(new CustomEvent('ep-color-change', {
337
+ bubbles: true, composed: true,
338
+ detail: { color: this.value, hsl: [this._hsl[0], this._hsl[1], this._hsl[2]] },
339
+ }));
340
+ }
341
+ }
342
+ _onHexKeydown(e) {
343
+ if (e.key === 'Enter')
344
+ e.target.blur();
345
+ }
346
+ // ── Public API ───────────────────────────────────────────
347
+ setHSL(h, s, l) {
348
+ this._hsl = [h, s, l];
349
+ this._emitColor();
350
+ this.requestUpdate();
351
+ }
352
+ getHSL() {
353
+ return [this._hsl[0], this._hsl[1], this._hsl[2]];
354
+ }
355
+ }
356
+ EpColorWheel.properties = {
357
+ size: { type: Number },
358
+ value: { type: String },
359
+ showInput: { type: Boolean, attribute: 'show-input' },
360
+ _hsl: { state: true },
361
+ };
362
+ EpColorWheel.styles = css `
363
+ :host {
364
+ --ep-font: var(--main-font-family, Quicksand, Cantarell, "Open Sans", "Helvetica Neue", sans-serif);
365
+ display: inline-block;
366
+ font-family: var(--ep-font);
367
+ user-select: none;
368
+ -webkit-user-select: none;
369
+ }
370
+ .wrapper {
371
+ display: inline-flex;
372
+ flex-direction: column;
373
+ align-items: center;
374
+ gap: 14px;
375
+ }
376
+ .container {
377
+ position: relative;
378
+ border-radius: 50%;
379
+ box-shadow:
380
+ 0 0 0 1px rgba(99, 114, 130, 0.08),
381
+ 0 4px 20px rgba(27, 39, 51, 0.10);
382
+ cursor: crosshair;
383
+ }
384
+ canvas { position: absolute; top: 0; left: 0; pointer-events: none; }
385
+ canvas.overlay { pointer-events: none; }
386
+ .solid { position: absolute; border-radius: 3px; }
387
+ .preview-row {
388
+ display: flex;
389
+ align-items: center;
390
+ gap: 10px;
391
+ padding: 8px 12px;
392
+ background: var(--bg-color, white);
393
+ border: 1px solid var(--middle-color, #d2d2d2);
394
+ border-radius: 8px;
395
+ box-shadow: 0 1px 4px rgba(0,0,0,0.04);
396
+ }
397
+ .swatch-preview {
398
+ width: 28px;
399
+ height: 28px;
400
+ border-radius: 50%;
401
+ border: 2px solid var(--middle-color, #d2d2d2);
402
+ flex-shrink: 0;
403
+ transition: background 0.15s ease;
404
+ }
405
+ .hex-input {
406
+ font-family: var(--ep-font);
407
+ font-size: 14px;
408
+ font-weight: 600;
409
+ padding: 4px 8px;
410
+ border: 1px solid transparent;
411
+ border-radius: 4px;
412
+ background: var(--bg-soft-color, #f2f3f4);
413
+ color: var(--text-color, #485365);
414
+ width: 78px;
415
+ outline: none;
416
+ text-transform: uppercase;
417
+ letter-spacing: 0.5px;
418
+ transition: border-color 0.15s ease, background 0.15s ease;
419
+ }
420
+ .hex-input:focus {
421
+ border-color: var(--dark-color, #576273);
422
+ background: var(--bg-color, white);
423
+ }
424
+ `;
425
+ if (!customElements.get('ep-color-wheel')) {
426
+ customElements.define('ep-color-wheel', EpColorWheel);
427
+ }
428
+ //# sourceMappingURL=EpColorWheel.js.map