@operato/input 8.0.0-alpha.21 → 8.0.0-alpha.27
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.
- package/CHANGELOG.md +18 -0
- package/dist/src/ox-input-signature.d.ts +4 -2
- package/dist/src/ox-input-signature.js +30 -7
- package/dist/src/ox-input-signature.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +4 -4
- package/src/ox-input-signature.ts +41 -10
- package/themes/calendar-theme.css +3 -1
package/CHANGELOG.md
CHANGED
@@ -3,6 +3,24 @@
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
5
5
|
|
6
|
+
## [8.0.0-alpha.27](https://github.com/hatiolab/operato/compare/v8.0.0-alpha.26...v8.0.0-alpha.27) (2024-10-06)
|
7
|
+
|
8
|
+
|
9
|
+
### :bug: Bug Fix
|
10
|
+
|
11
|
+
* calendar css variables ([9ea1918](https://github.com/hatiolab/operato/commit/9ea191844c72de5f920a8da85ad50209ba77cc07))
|
12
|
+
|
13
|
+
|
14
|
+
|
15
|
+
## [8.0.0-alpha.26](https://github.com/hatiolab/operato/compare/v8.0.0-alpha.25...v8.0.0-alpha.26) (2024-10-06)
|
16
|
+
|
17
|
+
|
18
|
+
### :bug: Bug Fix
|
19
|
+
|
20
|
+
* ox-input-signature ([dfd4e67](https://github.com/hatiolab/operato/commit/dfd4e67c213b33c78f6ef380fcc5e8642356e76c))
|
21
|
+
|
22
|
+
|
23
|
+
|
6
24
|
## [8.0.0-alpha.21](https://github.com/hatiolab/operato/compare/v8.0.0-alpha.20...v8.0.0-alpha.21) (2024-10-05)
|
7
25
|
|
8
26
|
|
@@ -1,4 +1,5 @@
|
|
1
1
|
import '@material/web/icon/icon.js';
|
2
|
+
import { PropertyValues } from 'lit';
|
2
3
|
import { OxFormField } from './ox-form-field.js';
|
3
4
|
export declare class OxInputSignature extends OxFormField {
|
4
5
|
static styles: import("lit").CSSResult[];
|
@@ -10,14 +11,15 @@ export declare class OxInputSignature extends OxFormField {
|
|
10
11
|
private isDrawing;
|
11
12
|
render(): import("lit-html").TemplateResult<1>;
|
12
13
|
firstUpdated(): void;
|
14
|
+
updated(changes: PropertyValues<this>): void;
|
13
15
|
openDialog(): void;
|
14
16
|
closeDialog(): void;
|
15
17
|
startDrawing(event: MouseEvent | TouchEvent): void;
|
16
|
-
stopDrawing(): void;
|
18
|
+
stopDrawing(event: MouseEvent | TouchEvent): void;
|
17
19
|
draw(event: MouseEvent | TouchEvent): void;
|
18
20
|
clearCanvas(): void;
|
19
21
|
saveSignature(): void;
|
20
|
-
loadSignature(dataUrl: string): void;
|
22
|
+
loadSignature(dataUrl: string | null): void;
|
21
23
|
getEventPosition(event: MouseEvent | TouchEvent): {
|
22
24
|
x: number;
|
23
25
|
y: number;
|
@@ -33,8 +33,6 @@ let OxInputSignature = class OxInputSignature extends OxFormField {
|
|
33
33
|
}
|
34
34
|
|
35
35
|
dialog canvas {
|
36
|
-
width: 100%;
|
37
|
-
height: 100%;
|
38
36
|
border: 1px solid var(--md-sys-color-outline);
|
39
37
|
}
|
40
38
|
|
@@ -48,6 +46,19 @@ let OxInputSignature = class OxInputSignature extends OxFormField {
|
|
48
46
|
.filler {
|
49
47
|
flex: 1;
|
50
48
|
}
|
49
|
+
|
50
|
+
/* 버튼 스타일 */
|
51
|
+
button {
|
52
|
+
background-color: var(--md-sys-color-primary);
|
53
|
+
color: var(--md-sys-color-on-primary);
|
54
|
+
padding: 10px 20px;
|
55
|
+
border: none;
|
56
|
+
border-radius: var(--spacing-small);
|
57
|
+
font-family: 'Roboto', sans-serif;
|
58
|
+
font-size: 14px;
|
59
|
+
cursor: pointer;
|
60
|
+
transition: background-color 0.3s ease;
|
61
|
+
}
|
51
62
|
`
|
52
63
|
]; }
|
53
64
|
render() {
|
@@ -84,11 +95,16 @@ let OxInputSignature = class OxInputSignature extends OxFormField {
|
|
84
95
|
this.loadSignature(this.value);
|
85
96
|
}
|
86
97
|
}
|
98
|
+
updated(changes) {
|
99
|
+
if (changes.has('value')) {
|
100
|
+
this.loadSignature(this.value);
|
101
|
+
}
|
102
|
+
}
|
87
103
|
openDialog() {
|
88
|
-
if (this.disabled)
|
104
|
+
if (this.disabled) {
|
89
105
|
return;
|
106
|
+
}
|
90
107
|
this.dialog.showModal();
|
91
|
-
// 다이아로그가 열릴 때 현재 value를 캔버스에 그리기
|
92
108
|
if (this.value) {
|
93
109
|
const img = new Image();
|
94
110
|
img.onload = () => {
|
@@ -104,17 +120,24 @@ let OxInputSignature = class OxInputSignature extends OxFormField {
|
|
104
120
|
if (this.disabled) {
|
105
121
|
return;
|
106
122
|
}
|
123
|
+
event.preventDefault();
|
124
|
+
event.stopPropagation();
|
107
125
|
this.isDrawing = true;
|
108
126
|
this.ctx.beginPath();
|
109
127
|
const position = this.getEventPosition(event);
|
110
128
|
this.ctx.moveTo(position.x, position.y);
|
111
129
|
}
|
112
|
-
stopDrawing() {
|
130
|
+
stopDrawing(event) {
|
131
|
+
event.preventDefault();
|
132
|
+
event.stopPropagation();
|
113
133
|
this.isDrawing = false;
|
114
134
|
}
|
115
135
|
draw(event) {
|
116
|
-
if (!this.isDrawing)
|
136
|
+
if (!this.isDrawing) {
|
117
137
|
return;
|
138
|
+
}
|
139
|
+
event.preventDefault();
|
140
|
+
event.stopPropagation();
|
118
141
|
const position = this.getEventPosition(event);
|
119
142
|
this.ctx.lineTo(position.x, position.y);
|
120
143
|
this.ctx.stroke();
|
@@ -129,7 +152,7 @@ let OxInputSignature = class OxInputSignature extends OxFormField {
|
|
129
152
|
this.closeDialog();
|
130
153
|
}
|
131
154
|
loadSignature(dataUrl) {
|
132
|
-
this.previewDiv.style.backgroundImage = `url(${dataUrl})
|
155
|
+
this.previewDiv.style.backgroundImage = dataUrl ? `url(${dataUrl})` : 'none';
|
133
156
|
}
|
134
157
|
getEventPosition(event) {
|
135
158
|
const rect = this.canvas.getBoundingClientRect();
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"ox-input-signature.js","sourceRoot":"","sources":["../../src/ox-input-signature.ts"],"names":[],"mappings":";AAAA,OAAO,4BAA4B,CAAA;AAEnC,OAAO,EAAE,GAAG,EAAE,IAAI,
|
1
|
+
{"version":3,"file":"ox-input-signature.js","sourceRoot":"","sources":["../../src/ox-input-signature.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/web/icon/icon.js'\n\nimport { css, html, PropertyValues } from 'lit'\nimport { customElement, property, query } from 'lit/decorators.js'\n\nimport { OxFormField } from './ox-form-field.js'\n\n@customElement('ox-input-signature')\nexport class OxInputSignature extends OxFormField {\n static styles = [\n css`\n :host {\n display: flex;\n flex-direction: column;\n min-height: var(--signature-min-height, 80px);\n min-width: var(--signature-min-width, 120px);\n\n background-color: var(--signature-background-color, white);\n\n overflow: hidden;\n }\n\n .signature-preview {\n flex: 1;\n align-self: stretch;\n\n border: 1px solid var(--md-sys-color-outline);\n background-size: contain;\n background-repeat: no-repeat;\n background-position: center;\n }\n\n dialog canvas {\n border: 1px solid var(--md-sys-color-outline);\n }\n\n .controls {\n margin-top: 10px;\n display: flex;\n flex-direction: row;\n gap: var(--spacing-medium);\n }\n\n .filler {\n flex: 1;\n }\n\n /* 버튼 스타일 */\n button {\n background-color: var(--md-sys-color-primary);\n color: var(--md-sys-color-on-primary);\n padding: 10px 20px;\n border: none;\n border-radius: var(--spacing-small);\n font-family: 'Roboto', sans-serif;\n font-size: 14px;\n cursor: pointer;\n transition: background-color 0.3s ease;\n }\n `\n ]\n\n @property({ type: String }) value: string | null = null\n\n @query('.signature-preview')\n private previewDiv!: HTMLDivElement\n @query('dialog')\n private dialog!: HTMLDialogElement\n @query('canvas')\n private canvas!: HTMLCanvasElement\n\n private ctx!: CanvasRenderingContext2D\n private isDrawing = false\n\n render() {\n return html`\n <div class=\"signature-preview\" @click=${this.openDialog}></div>\n\n <dialog>\n <canvas\n width=\"800\"\n height=\"400\"\n @mousedown=${this.startDrawing}\n @mouseup=${this.stopDrawing}\n @mousemove=${this.draw}\n @mouseleave=${this.stopDrawing}\n @touchstart=${this.startDrawing}\n @touchend=${this.stopDrawing}\n @touchmove=${this.draw}\n ></canvas>\n <div class=\"controls\">\n <button @click=\"${this.clearCanvas}\">Clear</button>\n <div class=\"filler\"></div>\n <button @click=\"${this.saveSignature}\">Save</button>\n <button @click=\"${this.closeDialog}\">Close</button>\n </div>\n </dialog>\n `\n }\n\n firstUpdated() {\n this.ctx = this.canvas.getContext('2d')!\n this.ctx.strokeStyle = '#000'\n this.ctx.lineWidth = 2\n\n // 처음 로딩 시 서명 데이터를 미리보기 div에 표시\n if (this.value) {\n this.loadSignature(this.value)\n }\n }\n\n updated(changes: PropertyValues<this>) {\n if (changes.has('value')) {\n this.loadSignature(this.value)\n }\n }\n\n openDialog() {\n if (this.disabled) {\n return\n }\n\n this.dialog.showModal()\n\n if (this.value) {\n const img = new Image()\n img.onload = () => {\n this.ctx.drawImage(img, 0, 0, this.canvas.width, this.canvas.height)\n }\n img.src = this.value\n }\n }\n\n closeDialog() {\n this.dialog.close()\n }\n\n startDrawing(event: MouseEvent | TouchEvent) {\n if (this.disabled) {\n return\n }\n\n event.preventDefault()\n event.stopPropagation()\n\n this.isDrawing = true\n this.ctx.beginPath()\n const position = this.getEventPosition(event)\n this.ctx.moveTo(position.x, position.y)\n }\n\n stopDrawing(event: MouseEvent | TouchEvent) {\n event.preventDefault()\n event.stopPropagation()\n\n this.isDrawing = false\n }\n\n draw(event: MouseEvent | TouchEvent) {\n if (!this.isDrawing) {\n return\n }\n\n event.preventDefault()\n event.stopPropagation()\n\n const position = this.getEventPosition(event)\n this.ctx.lineTo(position.x, position.y)\n this.ctx.stroke()\n }\n\n clearCanvas() {\n this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height)\n }\n\n saveSignature() {\n this.value = this.canvas.toDataURL()\n this._notifyChange()\n this.previewDiv.style.backgroundImage = `url(${this.value})`\n this.closeDialog()\n }\n\n loadSignature(dataUrl: string | null) {\n this.previewDiv.style.backgroundImage = dataUrl ? `url(${dataUrl})` : 'none'\n }\n\n getEventPosition(event: MouseEvent | TouchEvent) {\n const rect = this.canvas.getBoundingClientRect()\n\n // 캔버스의 실제 크기와 CSS 크기 간의 비율을 계산\n const scaleX = this.canvas.width / rect.width\n const scaleY = this.canvas.height / rect.height\n\n // 실제 좌표 계산\n const isTouchEvent = event instanceof TouchEvent\n const x = (isTouchEvent ? event.touches[0].clientX - rect.left : (event as MouseEvent).clientX - rect.left) * scaleX\n const y = (isTouchEvent ? event.touches[0].clientY - rect.top : (event as MouseEvent).clientY - rect.top) * scaleY\n\n return { x, y }\n }\n\n _notifyChange() {\n this.dispatchEvent(\n new CustomEvent('change', {\n bubbles: true,\n composed: true,\n detail: this.value\n })\n )\n }\n}\n"]}
|