@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
@@ -3,142 +3,140 @@ import { css } from 'lit';
3
3
  const styles = css`
4
4
  :host {
5
5
  display: inline-block;
6
+ color: var(--u-txt-color);
6
7
  font-size: inherit;
8
+ font-family: var(--u-font-base);
7
9
  }
8
10
  :host([disabled]) {
9
- opacity: 0.5;
11
+ opacity: 0.6;
12
+ cursor: not-allowed;
10
13
  }
11
14
 
12
15
  /* 헤더 영역 */
13
16
  .header {
14
17
  display: flex;
18
+ flex-direction: row;
15
19
  align-items: center;
16
- gap: 0.375em;
17
20
  margin-bottom: 0.5em;
21
+ user-select: none;
18
22
  }
19
23
  .header .label {
20
24
  font-size: 0.8em;
21
25
  font-weight: 500;
22
- line-height: 1;
23
- color: var(--u-text-color);
24
- user-select: none;
26
+ line-height: 1.2;
25
27
  cursor: pointer;
26
28
  }
27
29
  .header .required-mark {
28
30
  color: var(--u-red-600);
29
- margin-left: 0.25em;
31
+ margin-right: 0.25em;
30
32
  }
31
33
  .header .help-icon {
32
34
  font-size: 0.8em;
35
+ margin-left: 0.5em;
33
36
  cursor: help;
34
37
  }
38
+ .header .help-tooltip {
39
+ font-size: 0.6em;
40
+ }
35
41
 
36
42
  /* 입력 래퍼 */
37
43
  .container {
38
44
  display: flex;
45
+ flex-direction: row;
39
46
  align-items: center;
40
- gap: 0.5em;
41
- padding: 0.5em 0.75em;
42
- background-color: var(--u-bg-color);
47
+ padding: 0.3em 0.6em;
43
48
  border: 1px solid var(--u-input-border-color);
44
- border-radius: 0.375em;
49
+ border-radius: 0.25em;
50
+ background-color: var(--u-input-bg-color);
45
51
  transition: border-color 0.2s ease, box-shadow 0.2s ease;
46
52
  }
47
- .container[invalid] {
48
- border-color: var(--u-red-600);
49
- }
50
- .container[invalid]:focus-within {
51
- box-shadow: 0 0 0 0.125em rgba(244, 67, 54, 0.1);
52
- }
53
+ .container[readonly],
53
54
  .container[disabled] {
54
- background-color: var(--u-bg-color-disabled);
55
55
  border-color: var(--u-border-color-weak);
56
- cursor: not-allowed;
56
+ background-color: var(--u-bg-color-disabled);
57
57
  }
58
- .container[readonly] {
59
- background-color: var(--u-neutral-50);
60
- border-color: var(--u-border-color-weak);
58
+ .container:hover:not([readonly]):not([disabled]) {
59
+ box-shadow:
60
+ 0 0 0 1px var(--u-input-border-color-hover),
61
+ 0 0 0 3px rgba(59, 130, 246, 0.12);
61
62
  }
62
- .container:hover:not(([disabled])):not(([readonly])) {
63
- border-color: var(--u-input-border-hover);
63
+ .container:focus-within:not([readonly]):not([disabled]) {
64
+ box-shadow:
65
+ 0 0 0 1px var(--u-input-border-color-focus),
66
+ 0 0 0 3px rgba(59, 130, 246, 0.22);
64
67
  }
65
- .container:focus-within:not(([disabled])):not(([readonly])) {
66
- border-color: var(--u-input-border-focus);
67
- box-shadow: 0 0 0 0.125em rgba(33, 150, 243, 0.1);
68
- outline: none;
68
+ .container[invalid]:not([readonly]):not([disabled]) {
69
+ box-shadow:
70
+ 0 0 0 1px var(--u-input-border-color-invalid),
71
+ 0 0 0 3px rgba(220, 38, 38, 0.12);
69
72
  }
70
73
 
71
74
  /* 입력 필드 */
72
75
  input {
73
- flex: 1;
76
+ flex: 1 1 auto;
74
77
  min-width: 0;
75
- border: none;
76
- background: transparent;
77
- outline: none;
78
- font-family: inherit;
78
+ all: unset;
79
79
  font-size: 1em;
80
80
  line-height: 1.5;
81
- color: var(--u-text-color);
82
- padding: 0;
83
81
  }
84
82
  input::placeholder {
85
- color: var(--u-text-color-disabled);
83
+ color: var(--u-txt-color-weak);
86
84
  }
87
85
  input:disabled {
88
86
  cursor: not-allowed;
89
- color: var(--u-text-color-disabled);
90
87
  }
91
88
  input:read-only {
92
89
  cursor: default;
93
90
  }
94
91
 
95
- /* Prefix & Suffix 슬롯 */
96
- ::slotted([slot="prefix"]),
92
+ /* 슬롯에 내용이 있을 gap 적용 */
93
+ ::slotted([slot="prefix"]) {
94
+ margin-right: 0.5em;
95
+ }
97
96
  ::slotted([slot="suffix"]) {
98
- display: contents;
97
+ margin-left: 0.5em;
99
98
  }
100
99
 
101
- /* Tools 영역 (clear, password toggle 등) */
102
- .tools {
100
+ /* 영역 (clear, password toggle 등) */
101
+ .suffix-items {
103
102
  display: flex;
104
103
  flex-direction: row;
105
104
  align-items: center;
106
- gap: 0.375em;
107
105
  }
108
- .tool {
109
- font-size: 1.125em;
106
+ .suffix-items u-icon {
110
107
  color: var(--u-icon-color);
108
+ font-size: 1em;
109
+ margin-left: 0.5em;
111
110
  transition: color 0.2s ease;
112
111
  cursor: pointer;
113
112
  }
114
- .tool:hover {
113
+ .suffix-items u-icon:hover {
115
114
  color: var(--u-icon-color-hover);
116
115
  }
117
- .tool:active {
116
+ .suffix-items u-icon:active {
118
117
  color: var(--u-icon-color-active);
119
118
  }
120
119
 
121
120
  /* 유효성 검사 에러 메시지 */
122
- .validation-error {
123
- margin-top: 0.375em;
124
- font-size: 0.8125em;
121
+ .validation-message {
122
+ margin-top: 0.5em;
125
123
  color: var(--u-red-600);
126
- line-height: 1.4;
124
+ font-size: 0.75em;
125
+ line-height: 1.2;
127
126
  }
128
127
 
129
128
  /* 설명 텍스트 */
130
129
  .description {
131
- margin-top: 0.375em;
132
- font-size: 0.8125em;
133
- color: var(--u-soft-text-color);
134
- line-height: 1.4;
130
+ margin-top: 0.5em;
131
+ color: var(--u-txt-color-weak);
132
+ font-size: 0.75em;
133
+ line-height: 1.2;
135
134
  }
136
135
 
137
- /* Number input 기본 스타일 제거 (브라우저 간 일관성 위해) */
136
+ /* input 기본 제공 스타일 초기화 */
138
137
  input[type="number"] {
139
138
  -moz-appearance: textfield;
140
139
  }
141
- /* Number input 스피너 제거 옵션 (선택적) */
142
140
  input[type="number"]::-webkit-inner-spin-button,
143
141
  input[type="number"]::-webkit-outer-spin-button {
144
142
  -webkit-appearance: none;
@@ -0,0 +1,5 @@
1
+ import { Input } from './Input.js';
2
+
3
+ Input.define("u-input");
4
+
5
+ export { Input };
@@ -1,36 +1,25 @@
1
1
  import { PropertyValues } from 'lit';
2
2
  import { BaseElement } from '../BaseElement.js';
3
- /**
4
- * Menu 컴포넌트는 일반적인 메뉴 컨테이너입니다.
5
- * MenuItem 컴포넌트를 자식으로 포함하여 메뉴를 구성합니다.
6
- */
7
3
  export declare class Menu extends BaseElement {
8
4
  static styles: import('lit').CSSResultGroup[];
9
5
  static dependencies: Record<string, typeof BaseElement>;
10
- /** 슬롯에 할당된 메뉴 항목들을 가져옵니다. */
11
6
  private items;
12
- /** 메뉴가 열려있는지 여부입니다. */
13
7
  open: boolean;
14
- /** 메뉴 항목 중 하나만 선택할 수 있는지 여부입니다. */
15
8
  selectable: boolean;
16
- /** 현재 선택된 메뉴 항목의 값입니다. */
17
9
  value: string;
18
10
  connectedCallback(): void;
19
11
  disconnectedCallback(): void;
20
12
  protected updated(changedProperties: PropertyValues): void;
21
13
  render(): import('lit-html').TemplateResult<1>;
22
- /** 메뉴를 표시합니다. */
23
14
  show: () => Promise<void>;
24
- /** 메뉴를 숨깁니다. */
25
15
  hide: () => Promise<void>;
26
- /** open 상태가 변경될 호출됩니다. */
16
+ /** (추가) 번째 활성 아이템 포커스 */
17
+ focusFirstItem: () => Promise<void>;
27
18
  private updateOpenState;
28
- /** 선택 상태를 업데이트합니다. */
29
19
  private updateSelection;
30
- /** 슬롯 변경 이벤트를 처리합니다. */
31
20
  private handleSlotChange;
32
- /** 메뉴 항목 선택 이벤트를 처리합니다. */
33
21
  private handleSelect;
34
- /** 키보드 네비게이션을 처리합니다. */
22
+ /** 같은 레벨 다른 submenu 닫기 */
23
+ private handleSubmenuOpen;
35
24
  private handleKeydown;
36
25
  }
@@ -19,27 +19,23 @@ class Menu extends BaseElement {
19
19
  this.open = false;
20
20
  this.selectable = false;
21
21
  this.value = "";
22
- /** 메뉴를 표시합니다. */
23
22
  this.show = async () => {
24
23
  await this.updateComplete;
25
- requestAnimationFrame(() => {
26
- this.open = true;
27
- });
24
+ requestAnimationFrame(() => this.open = true);
28
25
  };
29
- /** 메뉴를 숨깁니다. */
30
26
  this.hide = async () => {
31
27
  await this.updateComplete;
32
- requestAnimationFrame(() => {
33
- this.open = false;
34
- });
28
+ requestAnimationFrame(() => this.open = false);
29
+ };
30
+ /** (추가) 첫 번째 활성 아이템 포커스 */
31
+ this.focusFirstItem = async () => {
32
+ await this.updateComplete;
33
+ const enabled = (this.items || []).filter((i) => !i.disabled);
34
+ if (enabled.length) enabled[0].focus();
35
35
  };
36
- /** 슬롯 변경 이벤트를 처리합니다. */
37
36
  this.handleSlotChange = () => {
38
- if (this.selectable && this.value) {
39
- this.updateSelection();
40
- }
37
+ if (this.selectable && this.value) this.updateSelection();
41
38
  };
42
- /** 메뉴 항목 선택 이벤트를 처리합니다. */
43
39
  this.handleSelect = (e) => {
44
40
  const event = e;
45
41
  const menuItem = e.target;
@@ -48,9 +44,16 @@ class Menu extends BaseElement {
48
44
  this.updateSelection();
49
45
  }
50
46
  };
51
- /** 키보드 네비게이션을 처리합니다. */
52
- this.handleKeydown = (e) => {
53
- const items = this.items.filter((item) => !item.disabled);
47
+ /** 같은 레벨 다른 submenu 닫기 */
48
+ this.handleSubmenuOpen = (e) => {
49
+ const openedItem = e.detail?.item;
50
+ if (!openedItem) return;
51
+ (this.items || []).forEach((item) => {
52
+ if (item !== openedItem) item.closeSubmenu?.();
53
+ });
54
+ };
55
+ this.handleKeydown = async (e) => {
56
+ const items = (this.items || []).filter((item) => !item.disabled);
54
57
  if (items.length === 0) return;
55
58
  const currentIndex = items.findIndex((item) => item === e.target);
56
59
  let nextIndex = currentIndex;
@@ -76,14 +79,29 @@ class Menu extends BaseElement {
76
79
  case "Enter":
77
80
  case " ":
78
81
  e.preventDefault();
79
- if (currentIndex >= 0) {
80
- items[currentIndex].click();
82
+ if (currentIndex >= 0) items[currentIndex].click();
83
+ break;
84
+ case "ArrowLeft": {
85
+ const parentItem = this.parentElement;
86
+ if (parentItem?.tagName?.toLowerCase() === "u-menu-item") {
87
+ e.preventDefault();
88
+ parentItem.closeSubmenu?.();
89
+ parentItem.focus?.();
81
90
  }
82
91
  break;
83
- case "Escape":
92
+ }
93
+ case "Escape": {
84
94
  e.preventDefault();
85
- this.hide();
95
+ const parentItem = this.parentElement;
96
+ if (parentItem?.tagName?.toLowerCase() === "u-menu-item") {
97
+ parentItem.closeSubmenu?.();
98
+ parentItem.focus?.();
99
+ } else {
100
+ this.emit("u-request-close");
101
+ await this.hide();
102
+ }
86
103
  break;
104
+ }
87
105
  }
88
106
  };
89
107
  }
@@ -100,10 +118,12 @@ class Menu extends BaseElement {
100
118
  this.setAttribute("role", "menu");
101
119
  this.addEventListener("u-select", this.handleSelect);
102
120
  this.addEventListener("keydown", this.handleKeydown);
121
+ this.addEventListener("u-submenu-open", this.handleSubmenuOpen);
103
122
  }
104
123
  disconnectedCallback() {
105
124
  this.removeEventListener("u-select", this.handleSelect);
106
125
  this.removeEventListener("keydown", this.handleKeydown);
126
+ this.removeEventListener("u-submenu-open", this.handleSubmenuOpen);
107
127
  super.disconnectedCallback();
108
128
  }
109
129
  updated(changedProperties) {
@@ -122,17 +142,12 @@ class Menu extends BaseElement {
122
142
  </div>
123
143
  `;
124
144
  }
125
- /** open 상태가 변경될 때 호출됩니다. */
126
145
  updateOpenState(open) {
127
- if (open) {
128
- this.emit("u-show");
129
- } else {
130
- this.emit("u-hide");
131
- }
146
+ if (open) this.emit("u-show");
147
+ else this.emit("u-hide");
132
148
  }
133
- /** 선택 상태를 업데이트합니다. */
134
149
  updateSelection() {
135
- this.items.forEach((item) => {
150
+ (this.items || []).forEach((item) => {
136
151
  item.selected = item.value === this.value;
137
152
  });
138
153
  }
@@ -2,31 +2,19 @@ import { css } from 'lit';
2
2
 
3
3
  const styles = css`
4
4
  :host {
5
- display: block;
6
- width: max-content;
5
+ display: none;
7
6
  min-width: 180px;
8
-
9
- opacity: 0;
10
- transform: scale(0.95);
11
- transform-origin: top left;
12
- transition: opacity 0.2s ease, transform 0.2s ease;
13
- pointer-events: none;
7
+ padding: 6px;
8
+ border-radius: 8px;
9
+ background: var(--u-menu-bg, #fff);
10
+ box-shadow: 0 10px 24px rgba(0,0,0,0.18);
14
11
  }
15
12
  :host([open]) {
16
- opacity: 1;
17
- transform: scale(1);
18
- pointer-events: auto;
13
+ display: block;
19
14
  }
20
15
 
21
16
  .container {
22
- display: flex;
23
- flex-direction: column;
24
- gap: 2px;
25
- padding: 4px;
26
- border: 1px solid var(--u-border-color, #ddd);
27
- border-radius: 8px;
28
- background-color: var(--u-bg-color, #fff);
29
- overflow: auto;
17
+ display: block;
30
18
  }
31
19
  `;
32
20
 
@@ -0,0 +1,5 @@
1
+ import { Menu } from './Menu.js';
2
+
3
+ Menu.define("u-menu");
4
+
5
+ export { Menu };
@@ -1,27 +1,36 @@
1
1
  import { PropertyValues } from 'lit';
2
2
  import { BaseElement } from '../BaseElement.js';
3
- /**
4
- * MenuItem 컴포넌트는 메뉴의 개별 항목을 나타냅니다.
5
- * u-menu 및 u-context-menu와 함께 사용됩니다.
6
- */
7
3
  export declare class MenuItem extends BaseElement {
8
4
  static styles: import('lit').CSSResultGroup[];
9
5
  static dependencies: Record<string, typeof BaseElement>;
10
- /** 메뉴 항목이 비활성화 상태인지 여부입니다. */
11
6
  disabled: boolean;
12
- /** 메뉴 항목이 선택된 상태인지 여부입니다. */
13
7
  selected: boolean;
14
- /** 체크 가능한 경우, 체크 상태인지 여부입니다. */
15
8
  checked: boolean;
16
- /** 메뉴 항목에 체크 표시를 할 수 있는지 여부입니다. */
17
9
  checkable: boolean;
18
- /** 메뉴 항목의 값입니다. */
19
10
  value: string;
11
+ private submenuOpen;
12
+ private containerEl;
13
+ private submenuList;
14
+ private submenuCleanup;
15
+ private closeTimer;
16
+ private get submenu();
20
17
  connectedCallback(): void;
21
- protected updated(changedProperties: PropertyValues): void;
18
+ disconnectedCallback(): void;
19
+ protected updated(changed: PropertyValues): void;
20
+ private updateRole;
22
21
  render(): import('lit-html').TemplateResult<1>;
23
- /** 메뉴 항목의 앞부분을 렌더링합니다. */
24
22
  private renderPrefixItem;
25
- /** 클릭 이벤트를 처리합니다. */
23
+ /** 외부에서 호출 가능하게(부모 menu가 형제 submenu 닫을 때 사용) */
24
+ closeSubmenu: () => Promise<void>;
25
+ private openSubmenu;
26
+ private onSubmenuSelect;
27
+ private scheduleCloseSubmenu;
28
+ private stopSubmenuAutoUpdate;
29
+ private positionSubmenu;
30
+ private onPointerEnter;
31
+ private onPointerLeave;
32
+ private onFocusIn;
33
+ private onFocusOut;
34
+ private handleKeydown;
26
35
  private handleClick;
27
36
  }