@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,6 +1,7 @@
1
- import { html } from 'lit';
1
+ import { nothing, html } from 'lit';
2
2
  import { query, property } from 'lit/decorators.js';
3
3
  import { BaseElement } from '../BaseElement.js';
4
+ import { IconButton } from '../icon-button/IconButton.js';
4
5
  import { styles } from './Dialog.styles.js';
5
6
 
6
7
  var __defProp = Object.defineProperty;
@@ -15,30 +16,52 @@ var __decorateClass = (decorators, target, key, kind) => {
15
16
  class Dialog extends BaseElement {
16
17
  constructor() {
17
18
  super(...arguments);
19
+ this.modal = true;
18
20
  this.open = false;
19
- this.closeOnOverlayClick = true;
20
- this.closeOnEscape = true;
21
+ this.closable = true;
22
+ this.heading = "";
21
23
  /** 다이얼로그를 표시합니다 */
22
24
  this.show = async () => {
23
- this.open = true;
24
25
  await this.updateComplete;
26
+ requestAnimationFrame(() => {
27
+ this.open = true;
28
+ });
25
29
  };
26
30
  /** 다이얼로그를 숨깁니다 */
27
31
  this.hide = async () => {
28
32
  await this.updateComplete;
29
- this.open = false;
33
+ requestAnimationFrame(() => {
34
+ this.open = false;
35
+ });
30
36
  };
31
37
  /** 오버레이 클릭 핸들러 */
32
- this.handleOverlayClick = (e) => {
33
- if (this.closeOnOverlayClick && e.target === this.overlayEl) {
34
- this.hide();
38
+ this.handleBackdropClick = (e) => {
39
+ if (e.target === this) {
40
+ if (this.closable) {
41
+ this.hide();
42
+ } else {
43
+ this.shake();
44
+ }
35
45
  }
36
46
  };
37
47
  /** 키보드 이벤트 핸들러 */
38
- this.handleKeyDown = (e) => {
39
- if (this.closeOnEscape && e.key === "Escape" && this.open) {
48
+ this.handleKeydown = (e) => {
49
+ if (e.key === "Escape" && this.open) {
40
50
  e.preventDefault();
41
- this.hide();
51
+ if (this.closable) {
52
+ this.hide();
53
+ } else {
54
+ this.shake();
55
+ }
56
+ }
57
+ };
58
+ /** 포커스 트랩 핸들러 */
59
+ this.handleFocusin = (e) => {
60
+ if (!this.modal || !this.open) return;
61
+ const target = e.target;
62
+ if (!this.contains(target)) {
63
+ e.preventDefault();
64
+ this.dialogEl.focus();
42
65
  }
43
66
  };
44
67
  }
@@ -46,14 +69,17 @@ class Dialog extends BaseElement {
46
69
  this.styles = [super.styles, styles];
47
70
  }
48
71
  static {
49
- this.dependencies = {};
72
+ this.dependencies = {
73
+ "u-icon-button": IconButton
74
+ };
50
75
  }
51
76
  connectedCallback() {
52
77
  super.connectedCallback();
53
- window.addEventListener("keydown", this.handleKeyDown);
78
+ this.addEventListener("click", this.handleBackdropClick);
54
79
  }
55
80
  disconnectedCallback() {
56
- window.removeEventListener("keydown", this.handleKeyDown);
81
+ window.removeEventListener("keydown", this.handleKeydown);
82
+ window.removeEventListener("focusin", this.handleFocusin);
57
83
  super.disconnectedCallback();
58
84
  }
59
85
  updated(changedProperties) {
@@ -61,39 +87,74 @@ class Dialog extends BaseElement {
61
87
  if (changedProperties.has("open")) {
62
88
  this.updateOpenState(this.open);
63
89
  }
90
+ if (changedProperties.has("modal")) {
91
+ this.updateModalState(this.modal);
92
+ }
64
93
  }
65
94
  render() {
66
95
  return html`
67
- <div class="overlay" part="overlay"
68
- ?hidden=${!this.open}
69
- @click=${this.handleOverlayClick}>
70
- <div class="panel" part="panel">
71
- <slot></slot>
72
- </div>
96
+ <div class="dialog scrollable" part="base" tabindex="-1">
97
+
98
+ ${this.heading ? html`
99
+ <div class="header" part="header">
100
+ <span class="title" part="title">
101
+ ${this.heading}
102
+ </span>
103
+ <u-icon-button class="close-btn" part="close-btn"
104
+ lib="internal"
105
+ name="x-lg"
106
+ borderless
107
+ @click=${() => this.hide()}
108
+ ></u-icon-button>
109
+ </div>` : nothing}
110
+
111
+ <slot></slot>
112
+
73
113
  </div>
74
114
  `;
75
115
  }
116
+ /** 패널을 흔드는 애니메이션을 재생합니다 */
117
+ shake() {
118
+ this.dialogEl.classList.add("shake");
119
+ setTimeout(() => {
120
+ this.dialogEl.classList.remove("shake");
121
+ }, 500);
122
+ }
76
123
  updateOpenState(open) {
77
124
  if (open) {
78
- document.body.style.overflow = "hidden";
79
125
  this.emit("u-show");
126
+ document.body.style.overflow = this.modal ? "hidden" : "";
80
127
  } else {
81
- document.body.style.overflow = "";
82
128
  this.emit("u-hide");
129
+ document.body.style.overflow = "";
130
+ }
131
+ }
132
+ updateModalState(modal) {
133
+ if (modal) {
134
+ window.addEventListener("keydown", this.handleKeydown);
135
+ window.addEventListener("focusin", this.handleFocusin);
136
+ document.body.style.overflow = this.open ? "hidden" : "";
137
+ } else {
138
+ window.removeEventListener("keydown", this.handleKeydown);
139
+ window.removeEventListener("focusin", this.handleFocusin);
140
+ document.body.style.overflow = "";
83
141
  }
84
142
  }
85
143
  }
86
144
  __decorateClass([
87
- query(".overlay")
88
- ], Dialog.prototype, "overlayEl");
145
+ query(".dialog")
146
+ ], Dialog.prototype, "dialogEl");
147
+ __decorateClass([
148
+ property({ type: Boolean, reflect: true })
149
+ ], Dialog.prototype, "modal");
89
150
  __decorateClass([
90
151
  property({ type: Boolean, reflect: true })
91
152
  ], Dialog.prototype, "open");
92
153
  __decorateClass([
93
154
  property({ type: Boolean })
94
- ], Dialog.prototype, "closeOnOverlayClick");
155
+ ], Dialog.prototype, "closable");
95
156
  __decorateClass([
96
- property({ type: Boolean })
97
- ], Dialog.prototype, "closeOnEscape");
157
+ property({ type: String })
158
+ ], Dialog.prototype, "heading");
98
159
 
99
160
  export { Dialog };
@@ -2,30 +2,79 @@ import { css } from 'lit';
2
2
 
3
3
  const styles = css`
4
4
  :host {
5
- display: inline-block;
6
- }
7
-
8
- .overlay {
9
5
  position: fixed;
10
6
  z-index: 9999;
11
7
  top: 0;
8
+ bottom: 0;
12
9
  left: 0;
13
- width: 100vw;
14
- height: 100vh;
10
+ right: 0;
15
11
  display: flex;
16
12
  align-items: center;
17
13
  justify-content: center;
14
+ background: transparent;
15
+ visibility: hidden;
16
+ pointer-events: none;
17
+ }
18
+ :host([open]) {
19
+ visibility: visible;
20
+ pointer-events: auto;
21
+ }
22
+ :host([modal]) {
18
23
  background: var(--u-overlay-bg-color);
19
24
  }
20
25
 
21
- .panel {
26
+ .dialog {
27
+ position: relative;
22
28
  display: block;
23
- background: var(--u-panel-bg-color);
24
- border: 1px solid var(--u-border-color);
25
- border-radius: 6px;
26
29
  max-width: 90vw;
27
30
  max-height: 90vh;
28
- overflow: hidden;
31
+ padding: 20px;
32
+ border: 1px solid var(--u-border-color);
33
+ border-radius: 6px;
34
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
35
+ background: var(--u-panel-bg-color);
36
+ overflow: auto;
37
+ }
38
+ .dialog.shake {
39
+ animation: shake 0.5s cubic-bezier(0.36, 0.07, 0.19, 0.97);
40
+ }
41
+
42
+ .header {
43
+ display: flex;
44
+ flex-direction: row;
45
+ align-items: center;
46
+ justify-content: space-between;
47
+ font-size: 20px;
48
+ margin-bottom: 20px;
49
+ }
50
+ .header .title {
51
+ line-height: 1.2;
52
+ font-weight: 600;
53
+ }
54
+
55
+ /* 페이드 인 및 스케일 업 애니메이션 */
56
+ @keyframes fadeout {
57
+ 0% {
58
+ opacity: 0;
59
+ transform: scale(0.9);
60
+ }
61
+ 100% {
62
+ opacity: 1;
63
+ transform: scale(1);
64
+ }
65
+ }
66
+
67
+ /* 진동 애니메이션 */
68
+ @keyframes shake {
69
+ 0%, 100% {
70
+ transform: translateX(0);
71
+ }
72
+ 10%, 30%, 50%, 70%, 90% {
73
+ transform: translateX(-8px);
74
+ }
75
+ 20%, 40%, 60%, 80% {
76
+ transform: translateX(8px);
77
+ }
29
78
  }
30
79
  `;
31
80
 
@@ -0,0 +1,5 @@
1
+ import { Dialog } from './Dialog.js';
2
+
3
+ Dialog.define("u-dialog");
4
+
5
+ export { Dialog };
@@ -1,25 +1,25 @@
1
1
  import { nothing } from 'lit';
2
2
  import { BaseElement } from '../BaseElement.js';
3
3
  /**
4
- * Divider 컴포넌트는 엘리먼트 사이에 드래그 가능한 구분선을 표시합니다.
4
+ * Divider 컴포넌트는 엘리먼트 사이에 움직임이 가능한 구분선을 제공합니다.
5
5
  */
6
6
  export declare class Divider extends BaseElement {
7
7
  static styles: import('lit').CSSResultGroup[];
8
8
  static dependencies: Record<string, typeof BaseElement>;
9
- /** 마지막 마우스 위치를 저장합니다. */
10
- private position;
11
- /** 드래그 중인지 여부를 나타냅니다. */
12
- dragging: boolean;
13
- /** 드래그 가능 여부를 설정합니다. */
14
- draggable: boolean;
9
+ /** 마지막 마우스 포인터 위치를 저장합니다. */
10
+ private prevPointerPosition;
11
+ /** 분할선이 움직이는지 여부를 나타냅니다. */
12
+ moving: boolean;
15
13
  /** 분할 방향을 설정합니다. */
16
14
  orientation: 'horizontal' | 'vertical';
15
+ /** 분할선을 움직일 수 있는지 여부를 설정합니다. */
16
+ movable: boolean;
17
17
  disconnectedCallback(): void;
18
18
  render(): typeof nothing | import('lit-html').TemplateResult<1>;
19
19
  /** 마우스 다운 이벤트 핸들러 */
20
- private handleMouseDown;
20
+ private handleMousedown;
21
21
  /** 마우스 무브 이벤트 핸들러 */
22
- private handleMouseMove;
22
+ private handleMousemove;
23
23
  /** 마우스 업 이벤트 핸들러 */
24
- private handleMouseUp;
24
+ private handleMouseup;
25
25
  }
@@ -15,38 +15,38 @@ var __decorateClass = (decorators, target, key, kind) => {
15
15
  class Divider extends BaseElement {
16
16
  constructor() {
17
17
  super(...arguments);
18
- /** 마지막 마우스 위치를 저장합니다. */
19
- this.position = 0;
20
- this.dragging = false;
21
- this.draggable = false;
18
+ /** 마지막 마우스 포인터 위치를 저장합니다. */
19
+ this.prevPointerPosition = 0;
20
+ this.moving = false;
22
21
  this.orientation = "horizontal";
22
+ this.movable = false;
23
23
  /** 마우스 다운 이벤트 핸들러 */
24
- this.handleMouseDown = (e) => {
24
+ this.handleMousedown = (e) => {
25
25
  e.preventDefault();
26
- this.dragging = true;
27
- this.position = this.orientation === "horizontal" ? e.clientX : e.clientY;
28
- this.emit("u-dragstart");
29
- document.addEventListener("mousemove", this.handleMouseMove);
30
- document.addEventListener("mouseup", this.handleMouseUp);
26
+ this.moving = true;
27
+ this.prevPointerPosition = this.orientation === "horizontal" ? e.clientX : e.clientY;
28
+ this.emit("u-movestart");
29
+ document.addEventListener("mousemove", this.handleMousemove);
30
+ document.addEventListener("mouseup", this.handleMouseup);
31
31
  document.body.style.userSelect = "none";
32
32
  document.body.style.cursor = this.orientation === "horizontal" ? "col-resize" : "row-resize";
33
33
  };
34
34
  /** 마우스 무브 이벤트 핸들러 */
35
- this.handleMouseMove = (e) => {
36
- if (!this.dragging) return;
35
+ this.handleMousemove = (e) => {
36
+ if (!this.moving) return;
37
37
  e.preventDefault();
38
- const position = this.orientation === "horizontal" ? e.clientX : e.clientY;
39
- const delta = position - this.position;
40
- this.emit("u-drag", { delta });
41
- this.position = position;
38
+ const currentPointerPosition = this.orientation === "horizontal" ? e.clientX : e.clientY;
39
+ const delta = currentPointerPosition - this.prevPointerPosition;
40
+ this.emit("u-move", { delta });
41
+ this.prevPointerPosition = currentPointerPosition;
42
42
  };
43
43
  /** 마우스 업 이벤트 핸들러 */
44
- this.handleMouseUp = (_) => {
45
- if (!this.dragging) return;
46
- this.dragging = false;
47
- this.emit("u-dragend");
48
- document.removeEventListener("mousemove", this.handleMouseMove);
49
- document.removeEventListener("mouseup", this.handleMouseUp);
44
+ this.handleMouseup = (_) => {
45
+ if (!this.moving) return;
46
+ this.moving = false;
47
+ this.emit("u-moveend");
48
+ document.removeEventListener("mousemove", this.handleMousemove);
49
+ document.removeEventListener("mouseup", this.handleMouseup);
50
50
  document.body.style.userSelect = "";
51
51
  document.body.style.cursor = "";
52
52
  };
@@ -59,16 +59,16 @@ class Divider extends BaseElement {
59
59
  }
60
60
  disconnectedCallback() {
61
61
  super.disconnectedCallback();
62
- document.removeEventListener("mousemove", this.handleMouseMove);
63
- document.removeEventListener("mouseup", this.handleMouseUp);
62
+ document.removeEventListener("mousemove", this.handleMousemove);
63
+ document.removeEventListener("mouseup", this.handleMouseup);
64
64
  }
65
65
  render() {
66
- if (this.draggable) {
66
+ if (this.movable) {
67
67
  return html`
68
- <div class="handler"
69
- ?dragging=${this.dragging}
68
+ <div class="handler" part="handler"
69
+ ?moving=${this.moving}
70
70
  orientation=${this.orientation}
71
- @mousedown=${this.handleMouseDown}
71
+ @mousedown=${this.handleMousedown}
72
72
  ></div>
73
73
  `;
74
74
  } else {
@@ -78,12 +78,12 @@ class Divider extends BaseElement {
78
78
  }
79
79
  __decorateClass([
80
80
  state()
81
- ], Divider.prototype, "dragging");
82
- __decorateClass([
83
- property({ type: Boolean, reflect: true })
84
- ], Divider.prototype, "draggable");
81
+ ], Divider.prototype, "moving");
85
82
  __decorateClass([
86
83
  property({ type: String, reflect: true })
87
84
  ], Divider.prototype, "orientation");
85
+ __decorateClass([
86
+ property({ type: Boolean, reflect: true })
87
+ ], Divider.prototype, "movable");
88
88
 
89
89
  export { Divider };
@@ -2,24 +2,22 @@ import { css } from 'lit';
2
2
 
3
3
  const styles = css`
4
4
  :host {
5
- position: relative;
6
- display: block;
7
- flex-shrink: 0;
8
- background-color: var(--u-neutral-200, #e5e7eb);
9
-
10
5
  --divider-size: 2px;
11
6
  --handler-size: 4px;
12
7
  --handler-color: var(--u-blue-500, #3b82f6);
13
8
  }
9
+
10
+ :host {
11
+ position: relative;
12
+ background-color: var(--u-neutral-200, #e5e7eb);
13
+ }
14
14
  :host([orientation="horizontal"]) {
15
15
  width: var(--divider-size, 2px);
16
- height: 100%;
17
- cursor: col-resize;
16
+ min-height: 0px;
18
17
  }
19
18
  :host([orientation="vertical"]) {
20
- width: 100%;
19
+ min-width: 0px;
21
20
  height: var(--divider-size, 2px);
22
- cursor: row-resize;
23
21
  }
24
22
 
25
23
  .handler {
@@ -37,6 +35,7 @@ const styles = css`
37
35
  transform: translateX(-50%);
38
36
  width: var(--handler-size, 4px);
39
37
  height: 100%;
38
+ cursor: col-resize;
40
39
  }
41
40
  .handler[orientation="vertical"] {
42
41
  left: 0;
@@ -45,8 +44,9 @@ const styles = css`
45
44
  transform: translateY(-50%);
46
45
  width: 100%;
47
46
  height: var(--handler-size, 4px);
47
+ cursor: row-resize;
48
48
  }
49
- .handler[dragging],
49
+ .handler[moving],
50
50
  .handler:hover {
51
51
  opacity: 1;
52
52
  }
@@ -0,0 +1,5 @@
1
+ import { Divider } from './Divider.js';
2
+
3
+ Divider.define("u-divider");
4
+
5
+ export { Divider };
@@ -0,0 +1,27 @@
1
+ import { PropertyValues } from 'lit';
2
+ import { BaseElement } from '../BaseElement.js';
3
+ import { FloatingElement } from '../FloatingElement.js';
4
+ export declare class DropdownMenu extends FloatingElement {
5
+ static styles: import('lit').CSSResultGroup[];
6
+ static dependencies: Record<string, typeof BaseElement>;
7
+ closeOnSelect: boolean;
8
+ closeOnCheck: boolean;
9
+ private onDocPointerDown;
10
+ private onWindowBlur;
11
+ private get menu();
12
+ connectedCallback(): void;
13
+ disconnectedCallback(): void;
14
+ protected updated(changed: PropertyValues): void;
15
+ render(): import('lit-html').TemplateResult<1>;
16
+ show: () => Promise<void>;
17
+ hide: () => Promise<void>;
18
+ private attachAnchor;
19
+ private detachAnchor;
20
+ private onTriggerPointerDown;
21
+ private onTriggerKeydown;
22
+ private onSelect;
23
+ private onCheck;
24
+ private onRequestClose;
25
+ private attachDismiss;
26
+ private detachDismiss;
27
+ }
@@ -0,0 +1,135 @@
1
+ import { html } from 'lit';
2
+ import { property } from 'lit/decorators.js';
3
+ import { FloatingElement } from '../FloatingElement.js';
4
+ import { Menu } from '../menu/Menu.js';
5
+ import { MenuItem } from '../menu-item/MenuItem.js';
6
+ import { styles } from './DropdownMenu.styles.js';
7
+
8
+ var __defProp = Object.defineProperty;
9
+ var __decorateClass = (decorators, target, key, kind) => {
10
+ var result = void 0 ;
11
+ for (var i = decorators.length - 1, decorator; i >= 0; i--)
12
+ if (decorator = decorators[i])
13
+ result = (decorator(target, key, result) ) || result;
14
+ if (result) __defProp(target, key, result);
15
+ return result;
16
+ };
17
+ class DropdownMenu extends FloatingElement {
18
+ constructor() {
19
+ super(...arguments);
20
+ this.closeOnSelect = true;
21
+ this.closeOnCheck = false;
22
+ this.onDocPointerDown = (e) => {
23
+ if (!this.visible) return;
24
+ const path = e.composedPath();
25
+ if (path.includes(this)) return;
26
+ if (this.anchor && path.includes(this.anchor)) return;
27
+ this.hide();
28
+ };
29
+ this.onWindowBlur = () => {
30
+ if (this.visible) this.hide();
31
+ };
32
+ this.show = async () => {
33
+ this.menu && (this.menu.open = true);
34
+ await super.show();
35
+ await this.menu?.focusFirstItem?.();
36
+ };
37
+ this.hide = async () => {
38
+ await super.hide();
39
+ this.menu && (this.menu.open = false);
40
+ this.querySelectorAll("u-menu-item").forEach((i) => i.closeSubmenu?.());
41
+ };
42
+ this.onTriggerPointerDown = async (e) => {
43
+ if (e.button !== 0) return;
44
+ if (this.visible) await this.hide();
45
+ else await this.show();
46
+ };
47
+ this.onTriggerKeydown = async (e) => {
48
+ if (e.key === "ArrowDown" || e.key === "Enter" || e.key === " ") {
49
+ e.preventDefault();
50
+ if (!this.visible) await this.show();
51
+ }
52
+ };
53
+ this.onSelect = async () => {
54
+ if (this.closeOnSelect) await this.hide();
55
+ };
56
+ this.onCheck = async () => {
57
+ if (this.closeOnCheck) await this.hide();
58
+ };
59
+ this.onRequestClose = async () => {
60
+ await this.hide();
61
+ };
62
+ }
63
+ static {
64
+ this.styles = [super.styles, styles];
65
+ }
66
+ static {
67
+ this.dependencies = {
68
+ "u-menu": Menu,
69
+ "u-menu-item": MenuItem
70
+ };
71
+ }
72
+ get menu() {
73
+ return this.querySelector("u-menu");
74
+ }
75
+ connectedCallback() {
76
+ super.connectedCallback();
77
+ this.placement ||= "bottom-start";
78
+ this.distance ||= 6;
79
+ this.addEventListener("u-select", this.onSelect);
80
+ this.addEventListener("u-check", this.onCheck);
81
+ this.addEventListener("u-request-close", this.onRequestClose);
82
+ }
83
+ disconnectedCallback() {
84
+ this.detachAnchor(this.anchor);
85
+ this.detachDismiss();
86
+ this.removeEventListener("u-select", this.onSelect);
87
+ this.removeEventListener("u-check", this.onCheck);
88
+ this.removeEventListener("u-request-close", this.onRequestClose);
89
+ super.disconnectedCallback();
90
+ }
91
+ updated(changed) {
92
+ super.updated(changed);
93
+ if (changed.has("anchor")) {
94
+ this.detachAnchor(changed.get("anchor"));
95
+ this.attachAnchor(this.anchor);
96
+ }
97
+ if (changed.has("visible")) {
98
+ if (this.visible) this.attachDismiss();
99
+ else this.detachDismiss();
100
+ if (this.anchor) {
101
+ this.anchor.setAttribute("aria-expanded", this.visible ? "true" : "false");
102
+ }
103
+ }
104
+ }
105
+ render() {
106
+ return html`<slot></slot>`;
107
+ }
108
+ attachAnchor(target) {
109
+ if (!target) return;
110
+ target.setAttribute("aria-haspopup", "menu");
111
+ target.addEventListener("pointerdown", this.onTriggerPointerDown);
112
+ target.addEventListener("keydown", this.onTriggerKeydown);
113
+ }
114
+ detachAnchor(target) {
115
+ if (!target) return;
116
+ target.removeEventListener("pointerdown", this.onTriggerPointerDown);
117
+ target.removeEventListener("keydown", this.onTriggerKeydown);
118
+ }
119
+ attachDismiss() {
120
+ document.addEventListener("pointerdown", this.onDocPointerDown, true);
121
+ window.addEventListener("blur", this.onWindowBlur);
122
+ }
123
+ detachDismiss() {
124
+ document.removeEventListener("pointerdown", this.onDocPointerDown, true);
125
+ window.removeEventListener("blur", this.onWindowBlur);
126
+ }
127
+ }
128
+ __decorateClass([
129
+ property({ type: Boolean })
130
+ ], DropdownMenu.prototype, "closeOnSelect");
131
+ __decorateClass([
132
+ property({ type: Boolean })
133
+ ], DropdownMenu.prototype, "closeOnCheck");
134
+
135
+ export { DropdownMenu };
@@ -0,0 +1 @@
1
+ export declare const styles: import('lit').CSSResult;
@@ -0,0 +1,15 @@
1
+ import { css } from 'lit';
2
+
3
+ const styles = css`
4
+ :host {
5
+ opacity: 0;
6
+ transform: scale(0.98);
7
+ transition: opacity 0.12s ease, transform 0.12s ease;
8
+ }
9
+ :host([visible]) {
10
+ opacity: 1; /* FloatingElement의 0.8을 덮어씀 */
11
+ transform: scale(1);
12
+ }
13
+ `;
14
+
15
+ export { styles };
@@ -0,0 +1,7 @@
1
+ import { DropdownMenu } from './DropdownMenu.js';
2
+ declare global {
3
+ interface HTMLElementTagNameMap {
4
+ "u-dropdown-menu": DropdownMenu;
5
+ }
6
+ }
7
+ export { DropdownMenu };
@@ -0,0 +1,5 @@
1
+ import { DropdownMenu } from './DropdownMenu.js';
2
+
3
+ DropdownMenu.define("u-dropdown-menu");
4
+
5
+ export { DropdownMenu };
@@ -15,7 +15,9 @@ export declare class Form extends BaseElement {
15
15
  connectedCallback(): void;
16
16
  disconnectedCallback(): void;
17
17
  render(): import('lit-html').TemplateResult<1>;
18
- /** 폼 내의 모든 입력 요소를 검증합니다. */
18
+ /**
19
+ * 폼 내의 모든 입력 요소를 검증합니다.
20
+ */
19
21
  validate(): boolean;
20
22
  /** 입력 요소의 변경 이벤트를 처리합니다. */
21
23
  private handleChange;