@iyulab/components 0.1.4 → 0.1.6

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 (142) hide show
  1. package/CHANGELOG.md +18 -18
  2. package/LICENSE +20 -20
  3. package/README.md +33 -33
  4. package/dist/assets/icons/arrow-clockwise.svg.js +1 -1
  5. package/dist/assets/icons/arrow-down.svg.js +1 -1
  6. package/dist/assets/icons/arrow-up.svg.js +1 -1
  7. package/dist/assets/icons/ban.svg.js +1 -1
  8. package/dist/assets/icons/bell-fill.svg.js +1 -1
  9. package/dist/assets/icons/check-circle-fill.svg.js +1 -1
  10. package/dist/assets/icons/check-lg.svg.js +1 -1
  11. package/dist/assets/icons/chevron-down.svg.js +1 -1
  12. package/dist/assets/icons/chevron-left.svg.js +1 -1
  13. package/dist/assets/icons/chevron-right.svg.js +1 -1
  14. package/dist/assets/icons/chevron-up.svg.js +1 -1
  15. package/dist/assets/icons/copy.svg.js +1 -1
  16. package/dist/assets/icons/dash-lg.svg.js +1 -1
  17. package/dist/assets/icons/exclamation-circle-fill.svg.js +1 -1
  18. package/dist/assets/icons/exclamation-triangle-fill.svg.js +1 -1
  19. package/dist/assets/icons/eye-slash.svg.js +1 -1
  20. package/dist/assets/icons/eye.svg.js +1 -1
  21. package/dist/assets/icons/info-circle-fill.svg.js +1 -1
  22. package/dist/assets/icons/layout-sidebar.svg.js +1 -1
  23. package/dist/assets/icons/lightbulb-fill.svg.js +1 -1
  24. package/dist/assets/icons/lightbulb-off.svg.js +1 -1
  25. package/dist/assets/icons/lightbulb.svg.js +1 -1
  26. package/dist/assets/icons/mic-fill.svg.js +1 -1
  27. package/dist/assets/icons/mic-mute-fill.svg.js +1 -1
  28. package/dist/assets/icons/paperclip.svg.js +1 -1
  29. package/dist/assets/icons/pencil-square.svg.js +1 -1
  30. package/dist/assets/icons/plus-lg.svg.js +1 -1
  31. package/dist/assets/icons/search.svg.js +1 -1
  32. package/dist/assets/icons/speedometer.svg.js +1 -1
  33. package/dist/assets/icons/x-lg.svg.js +1 -1
  34. package/dist/assets/styles/dark.css +129 -125
  35. package/dist/assets/styles/dark.css.js +1 -1
  36. package/dist/assets/styles/light.css +129 -126
  37. package/dist/assets/styles/light.css.js +1 -1
  38. package/dist/components/BaseElement.styles.js +2 -2
  39. package/dist/components/FloatingElement.d.ts +84 -0
  40. package/dist/components/FloatingElement.js +166 -0
  41. package/dist/components/FloatingElement.styles.js +26 -0
  42. package/dist/components/alert/Alert.d.ts +8 -4
  43. package/dist/components/alert/Alert.js +24 -15
  44. package/dist/components/alert/Alert.styles.js +32 -39
  45. package/dist/components/alert/index.js +5 -0
  46. package/dist/components/button/Button.js +4 -2
  47. package/dist/components/button/Button.styles.js +13 -20
  48. package/dist/components/button/index.js +5 -0
  49. package/dist/components/context-menu/ContextMenu.d.ts +20 -39
  50. package/dist/components/context-menu/ContextMenu.js +92 -137
  51. package/dist/components/context-menu/ContextMenu.styles.js +3 -28
  52. package/dist/components/context-menu/index.d.ts +1 -1
  53. package/dist/components/context-menu/index.js +5 -0
  54. package/dist/components/copy-button/CopyButton.d.ts +7 -3
  55. package/dist/components/copy-button/CopyButton.js +69 -0
  56. package/dist/components/copy-button/CopyButton.styles.js +17 -0
  57. package/dist/components/copy-button/index.js +5 -0
  58. package/dist/components/dialog/Dialog.d.ts +14 -7
  59. package/dist/components/dialog/Dialog.js +88 -27
  60. package/dist/components/dialog/Dialog.styles.js +60 -11
  61. package/dist/components/dialog/index.js +5 -0
  62. package/dist/components/divider/Divider.d.ts +10 -10
  63. package/dist/components/divider/Divider.js +32 -32
  64. package/dist/components/divider/Divider.styles.js +10 -10
  65. package/dist/components/divider/index.js +5 -0
  66. package/dist/components/dropdown-menu/DropdownMenu.d.ts +27 -0
  67. package/dist/components/dropdown-menu/DropdownMenu.js +135 -0
  68. package/dist/components/dropdown-menu/DropdownMenu.styles.d.ts +1 -0
  69. package/dist/components/dropdown-menu/DropdownMenu.styles.js +15 -0
  70. package/dist/components/dropdown-menu/index.d.ts +7 -0
  71. package/dist/components/dropdown-menu/index.js +5 -0
  72. package/dist/components/form/Form.d.ts +3 -1
  73. package/dist/components/form/Form.js +3 -1
  74. package/dist/components/form/Form.styles.js +1 -0
  75. package/dist/components/form/index.js +5 -0
  76. package/dist/components/icon/Icon.d.ts +6 -12
  77. package/dist/components/icon/Icon.js +15 -30
  78. package/dist/components/icon/Icon.styles.js +1 -1
  79. package/dist/components/icon/index.js +5 -0
  80. package/dist/components/icon-button/IconButton.d.ts +3 -3
  81. package/dist/components/icon-button/IconButton.js +6 -6
  82. package/dist/components/icon-button/IconButton.styles.js +14 -29
  83. package/dist/components/icon-button/index.js +5 -0
  84. package/dist/components/index.d.ts +3 -1
  85. package/dist/components/input/Input.d.ts +14 -13
  86. package/dist/components/input/Input.js +57 -56
  87. package/dist/components/input/Input.styles.js +54 -56
  88. package/dist/components/input/index.js +5 -0
  89. package/dist/components/menu/Menu.d.ts +4 -15
  90. package/dist/components/menu/Menu.js +43 -28
  91. package/dist/components/menu/Menu.styles.js +7 -19
  92. package/dist/components/menu/index.js +5 -0
  93. package/dist/components/menu-item/MenuItem.d.ts +21 -12
  94. package/dist/components/menu-item/MenuItem.js +184 -15
  95. package/dist/components/menu-item/MenuItem.styles.js +6 -0
  96. package/dist/components/menu-item/index.js +5 -0
  97. package/dist/components/progress-bar/ProgressBar.d.ts +1 -1
  98. package/dist/components/progress-bar/ProgressBar.js +2 -2
  99. package/dist/components/progress-bar/ProgressBar.styles.js +10 -10
  100. package/dist/components/progress-bar/index.js +5 -0
  101. package/dist/components/progress-ring/ProgressRing.d.ts +2 -2
  102. package/dist/components/progress-ring/ProgressRing.js +7 -6
  103. package/dist/components/progress-ring/ProgressRing.styles.js +8 -9
  104. package/dist/components/progress-ring/index.js +5 -0
  105. package/dist/components/spinner/Spinner.styles.js +5 -3
  106. package/dist/components/spinner/index.js +5 -0
  107. package/dist/components/split-panel/SplitPanel.d.ts +11 -3
  108. package/dist/components/split-panel/SplitPanel.js +44 -27
  109. package/dist/components/split-panel/SplitPanel.styles.js +1 -16
  110. package/dist/components/split-panel/index.js +5 -0
  111. package/dist/components/tooltip/Tooltip.d.ts +9 -29
  112. package/dist/components/tooltip/Tooltip.js +27 -149
  113. package/dist/components/tooltip/Tooltip.styles.js +9 -23
  114. package/dist/components/tooltip/index.js +5 -0
  115. package/dist/components/tree/index.js +5 -0
  116. package/dist/components/tree-item/index.js +5 -0
  117. package/dist/index.js +28 -5
  118. package/dist/integrations/react/UDropdownMenu.d.ts +8 -0
  119. package/dist/integrations/react/UDropdownMenu.js +10 -0
  120. package/dist/integrations/react/index.d.ts +1 -1
  121. package/dist/integrations/react/index.js +1 -1
  122. package/dist/internals/index.d.ts +0 -1
  123. package/dist/internals/node-helpers.d.ts +6 -1
  124. package/dist/internals/node-helpers.js +5 -6
  125. package/dist/utilities/decorators.js +2 -0
  126. package/dist/utilities/icons.d.ts +46 -0
  127. package/dist/utilities/icons.js +114 -0
  128. package/dist/utilities/index.d.ts +1 -0
  129. package/dist/utilities/notifier.d.ts +17 -7
  130. package/dist/utilities/notifier.js +51 -41
  131. package/dist/utilities/theme.d.ts +15 -20
  132. package/dist/utilities/theme.js +24 -20
  133. package/package.json +59 -58
  134. package/dist/components/panel/Panel.d.ts +0 -9
  135. package/dist/components/panel/Panel.js +0 -17
  136. package/dist/components/panel/Panel.styles.js +0 -12
  137. package/dist/components/panel/index.d.ts +0 -7
  138. package/dist/integrations/react/UPanel.d.ts +0 -8
  139. package/dist/integrations/react/UPanel.js +0 -10
  140. package/dist/internals/icon-helpers.d.ts +0 -32
  141. package/dist/internals/icon-helpers.js +0 -48
  142. /package/dist/components/{panel/Panel.styles.d.ts → FloatingElement.styles.d.ts} +0 -0
@@ -1,48 +1,29 @@
1
1
  import { PropertyValues } from 'lit';
2
- import { Placement } from '@floating-ui/dom';
3
2
  import { BaseElement } from '../BaseElement.js';
4
- /**
5
- * ContextMenu 컴포넌트는 마우스 오른쪽 버튼 클릭으로 표시되는 컨텍스트 메뉴입니다.
6
- * MenuItem 컴포넌트를 자식으로 포함하여 메뉴를 구성합니다.
7
- */
8
- export declare class ContextMenu extends BaseElement {
3
+ import { FloatingElement } from '../FloatingElement.js';
4
+ export declare class ContextMenu extends FloatingElement {
9
5
  static styles: import('lit').CSSResultGroup[];
10
6
  static dependencies: Record<string, typeof BaseElement>;
11
- /** 마우스 클릭 위치 */
12
- private mouseX;
13
- private mouseY;
14
- /** 컨텍스트 메뉴가 연결될 대상 엘리먼트입니다. 지정하지 않으면 부모 엘리먼트가 대상이 됩니다. */
15
- trigger?: HTMLElement;
16
- /** 현재 메뉴가 열려있는지 여부입니다. */
17
- open: boolean;
18
- /** 'fixed' 위치에서 포지션을 계산할지 여부를 설정합니다. 기본값은 true입니다. */
19
- hoist: boolean;
20
- /** 메뉴가 나타날 위치를 설정합니다. */
21
- placement?: Placement;
22
- /** 메뉴의 위치에서 마우스 포인터까지의 거리를 픽셀단위로 설정합니다. 기본값은 2입니다. */
23
- distance: number;
7
+ preventNative: boolean;
8
+ closeOnSelect: boolean;
9
+ closeOnCheck: boolean;
10
+ private get menu();
24
11
  connectedCallback(): void;
25
12
  disconnectedCallback(): void;
26
- protected updated(changedProperties: PropertyValues): void;
13
+ protected updated(changed: PropertyValues): void;
27
14
  render(): import('lit-html').TemplateResult<1>;
28
- /** 컨텍스트 메뉴를 표시합니다. */
29
- show: (x?: number, y?: number) => Promise<void>;
30
- /** 컨텍스트 메뉴를 숨깁니다. */
15
+ /** 컨텍스트 메뉴는 Virtual anchor를 쓰므로 autoUpdate는 꺼버림 */
16
+ protected autoPosition(_enable: boolean): void;
17
+ private attachAnchor;
18
+ private detachAnchor;
19
+ private onContextMenu;
31
20
  hide: () => Promise<void>;
32
- /**
33
- * 메뉴가 나타날 위치에 따라 transform-origin 값을 반환합니다.
34
- */
35
- private getTransformOrigin;
36
- /** 대상 엘리먼트에 컨텍스트 메뉴 이벤트를 바인딩 합니다. */
37
- private attachTrigger;
38
- /** 대상 엘리먼트에 바인딩된 컨텍스트 메뉴 이벤트를 제거합니다. */
39
- private detachTrigger;
40
- /** 컨텍스트 메뉴 이벤트를 처리합니다. */
41
- private handleContextMenu;
42
- /** 문서 클릭 이벤트를 처리합니다. */
43
- private handleDocumentClick;
44
- /** 문서 컨텍스트 메뉴 이벤트를 처리합니다. */
45
- private handleDocumentContextMenu;
46
- /** 슬롯 변경 이벤트를 처리합니다. */
47
- private handleSlotChange;
21
+ private onDocPointerDown;
22
+ private onWindowBlur;
23
+ private onWindowScrollOrResize;
24
+ private attachDismiss;
25
+ private detachDismiss;
26
+ private onSelect;
27
+ private onCheck;
28
+ private onRequestClose;
48
29
  }
@@ -1,8 +1,7 @@
1
1
  import { html } from 'lit';
2
2
  import { property } from 'lit/decorators.js';
3
- import { offset, shift, flip, autoPlacement, computePosition } from '@floating-ui/dom';
4
- import { getParentElement } from '../../internals/node-helpers.js';
5
- import { BaseElement } from '../BaseElement.js';
3
+ import { FloatingElement } from '../FloatingElement.js';
4
+ import { Menu } from '../menu/Menu.js';
6
5
  import { MenuItem } from '../menu-item/MenuItem.js';
7
6
  import { styles } from './ContextMenu.styles.js';
8
7
 
@@ -15,91 +14,58 @@ var __decorateClass = (decorators, target, key, kind) => {
15
14
  if (result) __defProp(target, key, result);
16
15
  return result;
17
16
  };
18
- class ContextMenu extends BaseElement {
17
+ class ContextMenu extends FloatingElement {
19
18
  constructor() {
20
19
  super(...arguments);
21
- /** 마우스 클릭 위치 */
22
- this.mouseX = 0;
23
- this.mouseY = 0;
24
- this.open = false;
25
- this.hoist = true;
26
- this.distance = 2;
27
- /** 컨텍스트 메뉴를 표시합니다. */
28
- this.show = async (x, y) => {
29
- if (x !== void 0) this.mouseX = x;
30
- if (y !== void 0) this.mouseY = y;
31
- await this.updateComplete;
32
- const virtualElement = {
20
+ this.preventNative = true;
21
+ this.closeOnSelect = true;
22
+ this.closeOnCheck = false;
23
+ this.onContextMenu = async (e) => {
24
+ if (this.preventNative) e.preventDefault();
25
+ this.menu && (this.menu.open = true);
26
+ const virtual = {
33
27
  getBoundingClientRect: () => ({
28
+ x: e.clientX,
29
+ y: e.clientY,
30
+ top: e.clientY,
31
+ left: e.clientX,
32
+ right: e.clientX,
33
+ bottom: e.clientY,
34
34
  width: 0,
35
35
  height: 0,
36
- x: this.mouseX,
37
- y: this.mouseY,
38
- top: this.mouseY,
39
- left: this.mouseX,
40
- right: this.mouseX,
41
- bottom: this.mouseY
36
+ toJSON() {
37
+ return {};
38
+ }
42
39
  })
43
40
  };
44
- const middleware = [
45
- offset({ mainAxis: this.distance }),
46
- shift({ padding: 8 }),
47
- flip()
48
- ];
49
- if (!this.placement) {
50
- middleware.push(autoPlacement({ allowedPlacements: ["bottom-start", "bottom-end", "top-start", "top-end"] }));
51
- }
52
- const position = await computePosition(virtualElement, this, {
53
- placement: this.placement || "bottom-start",
54
- middleware,
55
- strategy: this.hoist ? "fixed" : "absolute"
56
- });
57
- Object.assign(this.style, {
58
- left: `${position.x}px`,
59
- top: `${position.y}px`,
60
- transformOrigin: this.getTransformOrigin(position.placement)
61
- });
62
- await this.updateComplete;
63
- requestAnimationFrame(() => {
64
- this.open = true;
65
- this.emit("u-show");
66
- });
41
+ await super.show(virtual);
42
+ await this.menu?.focusFirstItem?.();
67
43
  };
68
- /** 컨텍스트 메뉴를 숨깁니다. */
69
44
  this.hide = async () => {
70
- await this.updateComplete;
71
- requestAnimationFrame(() => {
72
- this.open = false;
73
- this.emit("u-hide");
74
- });
45
+ await super.hide();
46
+ this.menu && (this.menu.open = false);
47
+ this.querySelectorAll("u-menu-item").forEach((i) => i.closeSubmenu?.());
75
48
  };
76
- /** 컨텍스트 메뉴 이벤트를 처리합니다. */
77
- this.handleContextMenu = (e) => {
78
- e.preventDefault();
79
- e.stopPropagation();
80
- this.show(e.clientX, e.clientY);
49
+ this.onDocPointerDown = (e) => {
50
+ if (!this.visible) return;
51
+ const path = e.composedPath();
52
+ if (path.includes(this)) return;
53
+ this.hide();
81
54
  };
82
- /** 문서 클릭 이벤트를 처리합니다. */
83
- this.handleDocumentClick = (e) => {
84
- if (this.open && !this.contains(e.target)) {
85
- this.hide();
86
- }
55
+ this.onWindowBlur = () => {
56
+ if (this.visible) this.hide();
87
57
  };
88
- /** 문서 컨텍스트 메뉴 이벤트를 처리합니다. */
89
- this.handleDocumentContextMenu = (e) => {
90
- if (this.open && !this.trigger?.contains(e.target)) {
91
- this.hide();
92
- }
58
+ this.onWindowScrollOrResize = () => {
59
+ if (this.visible) this.hide();
93
60
  };
94
- /** 슬롯 변경 이벤트를 처리합니다. */
95
- this.handleSlotChange = () => {
96
- const slot = this.shadowRoot?.querySelector("slot");
97
- const items = slot?.assignedElements({ flatten: true });
98
- items?.forEach((item) => {
99
- item.addEventListener("u-select", () => {
100
- this.hide();
101
- });
102
- });
61
+ this.onSelect = async () => {
62
+ if (this.closeOnSelect) await this.hide();
63
+ };
64
+ this.onCheck = async () => {
65
+ if (this.closeOnCheck) await this.hide();
66
+ };
67
+ this.onRequestClose = async () => {
68
+ await this.hide();
103
69
  };
104
70
  }
105
71
  static {
@@ -107,87 +73,76 @@ class ContextMenu extends BaseElement {
107
73
  }
108
74
  static {
109
75
  this.dependencies = {
76
+ "u-menu": Menu,
110
77
  "u-menu-item": MenuItem
111
78
  };
112
79
  }
80
+ get menu() {
81
+ return this.querySelector("u-menu");
82
+ }
113
83
  connectedCallback() {
114
84
  super.connectedCallback();
115
- this.trigger ||= getParentElement(this);
116
- this.setAttribute("role", "menu");
85
+ this.strategy = "fixed";
86
+ this.placement ||= "bottom-start";
87
+ this.distance ||= 4;
88
+ this.addEventListener("u-select", this.onSelect);
89
+ this.addEventListener("u-check", this.onCheck);
90
+ this.addEventListener("u-request-close", this.onRequestClose);
117
91
  }
118
92
  disconnectedCallback() {
119
- this.detachTrigger(this.trigger);
93
+ this.detachAnchor(this.anchor);
94
+ this.detachDismiss();
95
+ this.removeEventListener("u-select", this.onSelect);
96
+ this.removeEventListener("u-check", this.onCheck);
97
+ this.removeEventListener("u-request-close", this.onRequestClose);
120
98
  super.disconnectedCallback();
121
99
  }
122
- updated(changedProperties) {
123
- super.updated(changedProperties);
124
- if (changedProperties.has("trigger") && this.trigger) {
125
- const oldTrigger = changedProperties.get("trigger");
126
- this.detachTrigger(oldTrigger);
127
- this.attachTrigger(this.trigger);
100
+ updated(changed) {
101
+ super.updated(changed);
102
+ if (changed.has("anchor")) {
103
+ this.detachAnchor(changed.get("anchor"));
104
+ this.attachAnchor(this.anchor);
105
+ }
106
+ if (changed.has("visible")) {
107
+ if (this.visible) this.attachDismiss();
108
+ else this.detachDismiss();
128
109
  }
129
110
  }
130
111
  render() {
131
- return html`
132
- <div class="container">
133
- <slot @slotchange=${this.handleSlotChange}></slot>
134
- </div>
135
- `;
112
+ return html`<slot></slot>`;
136
113
  }
137
- /**
138
- * 메뉴가 나타날 위치에 따라 transform-origin 값을 반환합니다.
139
- */
140
- getTransformOrigin(placement) {
141
- switch (placement) {
142
- case "top":
143
- case "top-start":
144
- case "top-end":
145
- return "center bottom";
146
- case "bottom":
147
- case "bottom-start":
148
- case "bottom-end":
149
- return "center top";
150
- case "left":
151
- case "left-start":
152
- case "left-end":
153
- return "right center";
154
- case "right":
155
- case "right-start":
156
- case "right-end":
157
- return "left center";
158
- default:
159
- return "top left";
160
- }
114
+ /** 컨텍스트 메뉴는 Virtual anchor를 쓰므로 autoUpdate는 꺼버림 */
115
+ autoPosition(_enable) {
161
116
  }
162
- /** 대상 엘리먼트에 컨텍스트 메뉴 이벤트를 바인딩 합니다. */
163
- attachTrigger(trigger) {
164
- if (!trigger) return;
165
- trigger.addEventListener("contextmenu", this.handleContextMenu);
166
- document.addEventListener("click", this.handleDocumentClick);
167
- document.addEventListener("contextmenu", this.handleDocumentContextMenu);
117
+ attachAnchor(target) {
118
+ if (!target) return;
119
+ target.addEventListener("contextmenu", this.onContextMenu);
168
120
  }
169
- /** 대상 엘리먼트에 바인딩된 컨텍스트 메뉴 이벤트를 제거합니다. */
170
- detachTrigger(trigger) {
171
- if (!trigger) return;
172
- trigger.removeEventListener("contextmenu", this.handleContextMenu);
173
- document.removeEventListener("click", this.handleDocumentClick);
174
- document.removeEventListener("contextmenu", this.handleDocumentContextMenu);
121
+ detachAnchor(target) {
122
+ if (!target) return;
123
+ target.removeEventListener("contextmenu", this.onContextMenu);
124
+ }
125
+ attachDismiss() {
126
+ document.addEventListener("pointerdown", this.onDocPointerDown, true);
127
+ window.addEventListener("blur", this.onWindowBlur);
128
+ window.addEventListener("scroll", this.onWindowScrollOrResize, true);
129
+ window.addEventListener("resize", this.onWindowScrollOrResize);
130
+ }
131
+ detachDismiss() {
132
+ document.removeEventListener("pointerdown", this.onDocPointerDown, true);
133
+ window.removeEventListener("blur", this.onWindowBlur);
134
+ window.removeEventListener("scroll", this.onWindowScrollOrResize, true);
135
+ window.removeEventListener("resize", this.onWindowScrollOrResize);
175
136
  }
176
137
  }
177
138
  __decorateClass([
178
- property({ attribute: false })
179
- ], ContextMenu.prototype, "trigger");
180
- __decorateClass([
181
- property({ type: Boolean, reflect: true })
182
- ], ContextMenu.prototype, "open");
183
- __decorateClass([
184
- property({ type: Boolean, reflect: true })
185
- ], ContextMenu.prototype, "hoist");
139
+ property({ type: Boolean })
140
+ ], ContextMenu.prototype, "preventNative");
186
141
  __decorateClass([
187
- property({ type: String })
188
- ], ContextMenu.prototype, "placement");
142
+ property({ type: Boolean })
143
+ ], ContextMenu.prototype, "closeOnSelect");
189
144
  __decorateClass([
190
- property({ type: Number })
191
- ], ContextMenu.prototype, "distance");
145
+ property({ type: Boolean })
146
+ ], ContextMenu.prototype, "closeOnCheck");
192
147
 
193
148
  export { ContextMenu };
@@ -2,38 +2,13 @@ import { css } from 'lit';
2
2
 
3
3
  const styles = css`
4
4
  :host {
5
- position: absolute;
6
- z-index: 1000;
7
- top: 0;
8
- left: 0;
9
- display: block;
10
- width: max-content;
11
- min-width: 180px;
12
-
13
5
  opacity: 0;
14
- pointer-events: none;
15
- transform: scale(0.95);
16
- transition: opacity 0.2s ease, transform 0.2s ease;
6
+ transform: scale(0.98);
7
+ transition: opacity 0.12s ease, transform 0.12s ease;
17
8
  }
18
- :host([open]) {
9
+ :host([visible]) {
19
10
  opacity: 1;
20
11
  transform: scale(1);
21
- pointer-events: auto;
22
- }
23
- :host([hoist]) {
24
- position: fixed;
25
- }
26
-
27
- .container {
28
- display: flex;
29
- flex-direction: column;
30
- gap: 2px;
31
- padding: 4px;
32
- border: 1px solid var(--u-border-color, #ddd);
33
- border-radius: 8px;
34
- background-color: var(--u-bg-color, #fff);
35
- box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2);
36
- overflow: hidden;
37
12
  }
38
13
  `;
39
14
 
@@ -1,7 +1,7 @@
1
1
  import { ContextMenu } from './ContextMenu.js';
2
2
  declare global {
3
3
  interface HTMLElementTagNameMap {
4
- 'u-context-menu': ContextMenu;
4
+ "u-context-menu": ContextMenu;
5
5
  }
6
6
  }
7
7
  export { ContextMenu };
@@ -0,0 +1,5 @@
1
+ import { ContextMenu } from './ContextMenu.js';
2
+
3
+ ContextMenu.define("u-context-menu");
4
+
5
+ export { ContextMenu };
@@ -5,11 +5,15 @@ import { BaseElement } from '../BaseElement.js';
5
5
  export declare class CopyButton extends BaseElement {
6
6
  static styles: import('lit').CSSResultGroup[];
7
7
  static dependencies: Record<string, typeof BaseElement>;
8
- /** 버튼의 테두리 유무를 설정합니다. 기본값은 true로, 테두리가 없습니다. */
8
+ /** 버튼의 복사 상태를 설정합니다. 복사가 완료되면 true 변경됩니다. */
9
+ copied: boolean;
10
+ /** 버튼의 테두리 유무를 설정합니다. 기본값은 false입니다. */
9
11
  borderless: boolean;
10
12
  /** 버튼이 비활성화 상태인지 여부를 설정합니다. 비활성화된 버튼은 클릭할 수 없습니다. */
11
13
  disabled: boolean;
12
- /** 버튼의 복사 상태를 설정합니다. 복사가 완료되면 true로 변경됩니다. */
13
- copied: boolean;
14
+ /** 복사할 텍스트를 설정합니다. */
15
+ value: string;
14
16
  render(): import('lit-html').TemplateResult<1>;
17
+ /** 복사 버튼 클릭 핸들러 */
18
+ private handleButtonClick;
15
19
  }
@@ -0,0 +1,69 @@
1
+ import { html } from 'lit';
2
+ import { state, property } from 'lit/decorators.js';
3
+ import { BaseElement } from '../BaseElement.js';
4
+ import { IconButton } from '../icon-button/IconButton.js';
5
+ import { styles } from './CopyButton.styles.js';
6
+
7
+ var __defProp = Object.defineProperty;
8
+ var __decorateClass = (decorators, target, key, kind) => {
9
+ var result = void 0 ;
10
+ for (var i = decorators.length - 1, decorator; i >= 0; i--)
11
+ if (decorator = decorators[i])
12
+ result = (decorator(target, key, result) ) || result;
13
+ if (result) __defProp(target, key, result);
14
+ return result;
15
+ };
16
+ class CopyButton extends BaseElement {
17
+ constructor() {
18
+ super(...arguments);
19
+ this.copied = false;
20
+ this.borderless = false;
21
+ this.disabled = false;
22
+ this.value = "";
23
+ /** 복사 버튼 클릭 핸들러 */
24
+ this.handleButtonClick = async () => {
25
+ try {
26
+ await navigator.clipboard.writeText(this.value);
27
+ this.copied = true;
28
+ this.emit("u-copy", { value: this.value });
29
+ setTimeout(() => this.copied = false, 2e3);
30
+ } catch (error) {
31
+ console.error("Failed to copy text: ", error);
32
+ }
33
+ };
34
+ }
35
+ static {
36
+ this.styles = [super.styles, styles];
37
+ }
38
+ static {
39
+ this.dependencies = {
40
+ "u-icon-button": IconButton
41
+ };
42
+ }
43
+ render() {
44
+ return html`
45
+ <u-icon-button part="base"
46
+ ?copied=${this.copied}
47
+ .borderless=${this.borderless}
48
+ .disabled=${this.disabled || this.copied}
49
+ .library=${"internal"}
50
+ .name=${this.copied ? "check-lg" : "copy"}
51
+ @click=${this.handleButtonClick}>
52
+ </u-icon-button>
53
+ `;
54
+ }
55
+ }
56
+ __decorateClass([
57
+ state()
58
+ ], CopyButton.prototype, "copied");
59
+ __decorateClass([
60
+ property({ type: Boolean })
61
+ ], CopyButton.prototype, "borderless");
62
+ __decorateClass([
63
+ property({ type: Boolean })
64
+ ], CopyButton.prototype, "disabled");
65
+ __decorateClass([
66
+ property({ type: String })
67
+ ], CopyButton.prototype, "value");
68
+
69
+ export { CopyButton };
@@ -0,0 +1,17 @@
1
+ import { css } from 'lit';
2
+
3
+ const styles = css`
4
+ :host {
5
+ display: inline-block;
6
+ font-size: 16px;
7
+ }
8
+
9
+ u-icon-button {
10
+ font-size: inherit;
11
+ }
12
+ u-icon-button[copied] {
13
+ color: var(--u-green-600, #16a34a);
14
+ }
15
+ `;
16
+
17
+ export { styles };
@@ -0,0 +1,5 @@
1
+ import { CopyButton } from './CopyButton.js';
2
+
3
+ CopyButton.define("u-copy-button");
4
+
5
+ export { CopyButton };
@@ -7,13 +7,15 @@ import { BaseElement } from '../BaseElement.js';
7
7
  export declare class Dialog extends BaseElement {
8
8
  static styles: import('lit').CSSResultGroup[];
9
9
  static dependencies: Record<string, typeof BaseElement>;
10
- overlayEl: HTMLDivElement;
10
+ dialogEl: HTMLDivElement;
11
+ /** 모달 모드 활성화 (배경 차단 및 포커스 트랩) */
12
+ modal: boolean;
11
13
  /** 다이얼로그가 열려있는지 여부 */
12
14
  open: boolean;
13
- /** 오버레이 클릭 닫기 활성화 여부 */
14
- closeOnOverlayClick: boolean;
15
- /** ESC 키로 닫기 활성화 여부 */
16
- closeOnEscape: boolean;
15
+ /** 이벤트에 의한 다이얼로그 닫기 허용 여부 */
16
+ closable: boolean;
17
+ /** 타이틀 텍스트 */
18
+ heading: string;
17
19
  connectedCallback(): void;
18
20
  disconnectedCallback(): void;
19
21
  protected updated(changedProperties: PropertyValues): void;
@@ -22,9 +24,14 @@ export declare class Dialog extends BaseElement {
22
24
  show: () => Promise<void>;
23
25
  /** 다이얼로그를 숨깁니다 */
24
26
  hide: () => Promise<void>;
27
+ /** 패널을 흔드는 애니메이션을 재생합니다 */
28
+ private shake;
25
29
  /** 오버레이 클릭 핸들러 */
26
- private handleOverlayClick;
30
+ private handleBackdropClick;
27
31
  /** 키보드 이벤트 핸들러 */
28
- private handleKeyDown;
32
+ private handleKeydown;
33
+ /** 포커스 트랩 핸들러 */
34
+ private handleFocusin;
29
35
  private updateOpenState;
36
+ private updateModalState;
30
37
  }