@iyulab/components 0.1.5 → 0.1.7

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 (82) 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 -129
  35. package/dist/assets/styles/dark.css.js +1 -1
  36. package/dist/assets/styles/light.css +129 -129
  37. package/dist/assets/styles/light.css.js +1 -1
  38. package/dist/components/FloatingElement.d.ts +84 -0
  39. package/dist/components/FloatingElement.js +166 -0
  40. package/dist/components/FloatingElement.styles.d.ts +1 -0
  41. package/dist/components/FloatingElement.styles.js +26 -0
  42. package/dist/components/context-menu/ContextMenu.d.ts +20 -39
  43. package/dist/components/context-menu/ContextMenu.js +92 -137
  44. package/dist/components/context-menu/ContextMenu.styles.js +3 -28
  45. package/dist/components/context-menu/index.d.ts +1 -1
  46. package/dist/components/dialog/Dialog.d.ts +14 -7
  47. package/dist/components/dialog/Dialog.js +88 -27
  48. package/dist/components/dialog/Dialog.styles.js +60 -11
  49. package/dist/components/divider/Divider.d.ts +5 -5
  50. package/dist/components/divider/Divider.js +17 -17
  51. package/dist/components/divider/Divider.styles.js +4 -6
  52. package/dist/components/dropdown-menu/DropdownMenu.d.ts +27 -0
  53. package/dist/components/dropdown-menu/DropdownMenu.js +135 -0
  54. package/dist/components/dropdown-menu/DropdownMenu.styles.d.ts +1 -0
  55. package/dist/components/dropdown-menu/DropdownMenu.styles.js +15 -0
  56. package/dist/components/dropdown-menu/index.d.ts +7 -0
  57. package/dist/components/dropdown-menu/index.js +5 -0
  58. package/dist/components/icon/Icon.js +1 -0
  59. package/dist/components/index.d.ts +2 -0
  60. package/dist/components/input/Input.js +1 -1
  61. package/dist/components/input/Input.styles.js +5 -5
  62. package/dist/components/menu/Menu.d.ts +4 -15
  63. package/dist/components/menu/Menu.js +43 -28
  64. package/dist/components/menu/Menu.styles.js +7 -19
  65. package/dist/components/menu-item/MenuItem.d.ts +21 -12
  66. package/dist/components/menu-item/MenuItem.js +184 -15
  67. package/dist/components/menu-item/MenuItem.styles.js +6 -0
  68. package/dist/components/menu-item/index.js +5 -0
  69. package/dist/components/split-panel/SplitPanel.d.ts +10 -2
  70. package/dist/components/split-panel/SplitPanel.js +41 -22
  71. package/dist/components/split-panel/SplitPanel.styles.js +1 -16
  72. package/dist/components/tooltip/Tooltip.d.ts +9 -29
  73. package/dist/components/tooltip/Tooltip.js +27 -149
  74. package/dist/components/tooltip/Tooltip.styles.js +8 -22
  75. package/dist/index.js +4 -0
  76. package/dist/integrations/react/UDropdownMenu.d.ts +8 -0
  77. package/dist/integrations/react/UDropdownMenu.js +10 -0
  78. package/dist/integrations/react/index.d.ts +1 -0
  79. package/dist/integrations/react/index.js +1 -0
  80. package/dist/internals/node-helpers.d.ts +6 -1
  81. package/dist/internals/node-helpers.js +5 -6
  82. package/package.json +59 -59
@@ -1,5 +1,5 @@
1
1
  import { html } from 'lit';
2
- import { property } from 'lit/decorators.js';
2
+ import { queryAssignedElements, property } from 'lit/decorators.js';
3
3
  import { arrayAttributeConverter } from '../../internals/attribute-converters.js';
4
4
  import { BaseElement } from '../BaseElement.js';
5
5
  import { Divider } from '../divider/Divider.js';
@@ -22,35 +22,32 @@ class SplitPanel extends BaseElement {
22
22
  this.panelSizes = [];
23
23
  this.panelAdjustSizes = [];
24
24
  this.orientation = "horizontal";
25
- this.initialRatio = [];
26
- this.handleSlotChange = async (e) => {
27
- const slot = e.target;
28
- const children = slot.assignedElements({ flatten: true });
29
- const panels = children.filter((el) => el instanceof HTMLElement);
30
- if (this.panels.length === panels.length && this.panels.every((p, i) => p === panels[i])) {
31
- return;
32
- }
33
- this.panels = panels;
25
+ this.initRatio = [];
26
+ this.minSizes = [];
27
+ this.maxSizes = [];
28
+ // 초기화 메서드
29
+ this.initialize = async () => {
30
+ this.panels = this.childElements.filter((el) => el instanceof Divider === false);
34
31
  this.dividers.forEach((divider) => divider.remove());
35
32
  this.dividers = [];
36
- if (this.initialRatio.length === panels.length) {
37
- const totalRatio = this.initialRatio.reduce((sum, r) => sum + r, 0);
38
- this.panelSizes = this.initialRatio.map((r) => r / totalRatio * 100);
33
+ if (this.initRatio.length === this.panels.length) {
34
+ const totalRatio = this.initRatio.reduce((sum, r) => sum + r, 0);
35
+ this.panelSizes = this.initRatio.map((r) => r / totalRatio * 100);
39
36
  } else {
40
- const equalRatio = 100 / panels.length;
41
- this.panelSizes = panels.map(() => equalRatio);
37
+ const equalRatio = 100 / this.panels.length;
38
+ this.panelSizes = this.panels.map(() => equalRatio);
42
39
  }
43
- this.panelAdjustSizes = panels.map(() => 0);
40
+ this.panelAdjustSizes = this.panels.map(() => 0);
44
41
  const property2 = this.orientation === "horizontal" ? "width" : "height";
45
42
  const dividerSize = this.getDividerSize();
46
- panels.forEach((panel, index) => {
43
+ this.panels.forEach((panel, index) => {
47
44
  const ratio = this.panelSizes[index];
48
45
  panel.style.flex = "none";
49
- panel.style[property2] = index === 0 || index === panels.length - 1 ? `calc(${ratio}% - ${dividerSize / 2}px)` : `calc(${ratio}% - ${dividerSize}px)`;
50
- if (index === panels.length - 1) return;
46
+ panel.style[property2] = index === 0 || index === this.panels.length - 1 ? `calc(${ratio}% - ${dividerSize / 2}px)` : `calc(${ratio}% - ${dividerSize}px)`;
47
+ if (index === this.panels.length - 1) return;
51
48
  const divider = new Divider();
52
49
  divider.orientation = this.orientation;
53
- divider.draggable = true;
50
+ divider.movable = true;
54
51
  divider.addEventListener("u-move", this.handleDividerMove);
55
52
  this.dividers.push(divider);
56
53
  panel.after(divider);
@@ -58,6 +55,13 @@ class SplitPanel extends BaseElement {
58
55
  this.requestUpdate();
59
56
  await this.updateComplete;
60
57
  };
58
+ this.handleSlotChange = async () => {
59
+ const panels = this.childElements.filter((el) => el instanceof Divider === false);
60
+ if (panels.every((p, i) => p === this.panels[i])) {
61
+ return;
62
+ }
63
+ await this.initialize();
64
+ };
61
65
  /** 디바이더 드래그 이벤트 핸들러 */
62
66
  this.handleDividerMove = (event) => {
63
67
  const divider = event.target;
@@ -99,6 +103,12 @@ class SplitPanel extends BaseElement {
99
103
  this.dividers.forEach((divider) => divider.remove());
100
104
  super.disconnectedCallback();
101
105
  }
106
+ willUpdate(changedProperties) {
107
+ super.willUpdate(changedProperties);
108
+ if (changedProperties.has("orientation")) {
109
+ this.initialize();
110
+ }
111
+ }
102
112
  render() {
103
113
  return html`
104
114
  <slot @slotchange=${this.handleSlotChange}></slot>
@@ -110,11 +120,20 @@ class SplitPanel extends BaseElement {
110
120
  return parseFloat(sizeStr) || 2;
111
121
  }
112
122
  }
123
+ __decorateClass([
124
+ queryAssignedElements({ flatten: true })
125
+ ], SplitPanel.prototype, "childElements");
113
126
  __decorateClass([
114
127
  property({ type: String, reflect: true })
115
128
  ], SplitPanel.prototype, "orientation");
116
129
  __decorateClass([
117
- property({ type: Array, attribute: "initial-ratio", converter: arrayAttributeConverter(parseFloat) })
118
- ], SplitPanel.prototype, "initialRatio");
130
+ property({ type: Array, attribute: "init-ratio", converter: arrayAttributeConverter(parseFloat) })
131
+ ], SplitPanel.prototype, "initRatio");
132
+ __decorateClass([
133
+ property({ type: Array, attribute: "min-sizes", converter: arrayAttributeConverter(parseFloat) })
134
+ ], SplitPanel.prototype, "minSizes");
135
+ __decorateClass([
136
+ property({ type: Array, attribute: "max-sizes", converter: arrayAttributeConverter(parseFloat) })
137
+ ], SplitPanel.prototype, "maxSizes");
119
138
 
120
139
  export { SplitPanel };
@@ -3,32 +3,17 @@ import { css } from 'lit';
3
3
  const styles = css`
4
4
  :host {
5
5
  position: relative;
6
- display: block;
6
+ display: flex;
7
7
  width: 100%;
8
8
  height: 100%;
9
9
  overflow: hidden;
10
-
11
- --divider-size: 2px;
12
- --divider-color: var(--u-neutral-200, #d1d5db);
13
- --divider-handle-size: 4px;
14
- --divider-handle-color: var(--u-blue-500, #3b82f6);
15
10
  }
16
11
  :host([orientation="horizontal"]) {
17
- display: flex;
18
12
  flex-direction: row;
19
13
  }
20
14
  :host([orientation="vertical"]) {
21
- display: flex;
22
15
  flex-direction: column;
23
16
  }
24
-
25
- ::slotted(u-divider) {
26
- background-color: var(--divider-color, var(--u-neutral-200, #d1d5db));
27
-
28
- --divider-size: var(--divider-size, 2px);
29
- --handler-size: var(--divider-handle-size, 4px);
30
- --handler-color: var(--divider-handle-color, var(--u-blue-500, #3b82f6));
31
- }
32
17
  `;
33
18
 
34
19
  export { styles };
@@ -1,40 +1,20 @@
1
1
  import { PropertyValues } from 'lit';
2
- import { Placement } from '@floating-ui/dom';
3
2
  import { BaseElement } from '../BaseElement.js';
3
+ import { FloatingElement } from '../FloatingElement.js';
4
4
  /**
5
5
  * Tooltip 컴포넌트는 대상 엘리먼트에 툴팁을 표시하는 기능을 제공합니다.
6
6
  */
7
- export declare class Tooltip extends BaseElement {
7
+ export declare class Tooltip extends FloatingElement {
8
8
  static styles: import('lit').CSSResultGroup[];
9
9
  static dependencies: Record<string, typeof BaseElement>;
10
- /** 툴팁이 연결될 대상 엘리먼트입니다. 지정하지 않으면 부모 엘리먼트가 대상이 됩니다. */
11
- triggers: HTMLElement[];
12
- /** 트리거 셀렉터 문자열입니다. 이 속성을 사용하여 트리거 엘리먼트를 지정할 수 있습니다. */
13
- triggerSelectors?: string;
14
- /** 'fixed' 위치에서 포지션을 계산할지 여부를 설정합니다. 기본값은 false입니다. */
15
- hoist: boolean;
16
- /** 툴팁이 나타날 위치를 설정합니다. */
17
- placement?: Placement;
18
- /** 툴팁의 위치에서 대상 엘리먼트까지의 거리를 픽셀단위로 설정합니다. 기본값은 8입니다. */
19
- distance: number;
20
- /** 툴팁의 표시 딜레이 시간을 밀리초 단위로 설정합니다. 기본값은 0입니다. */
21
- delay: number;
22
- constructor();
23
- connectedCallback(): void;
24
10
  disconnectedCallback(): void;
25
- protected willUpdate(changedProperties: PropertyValues): void;
26
11
  protected updated(changedProperties: PropertyValues): void;
27
12
  render(): import('lit-html').TemplateResult<1>;
28
- /** 툴팁을 표시합니다. */
29
- show: (event: Event) => Promise<void>;
30
- /** 툴팁을 숨깁니다. */
31
- hide: (event: Event) => Promise<void>;
32
- /** 대상 엘리먼트에 툴팁 이벤트를 바인딩 합니다. */
33
- private attachTriggers;
34
- /** 대상 엘리먼트에 바인딩된 툴팁 이벤트를 제거합니다. */
35
- private detachTriggers;
36
- /**
37
- * 툴팁이 나타날 위치에 따라 transform-origin 값을 반환합니다.
38
- */
39
- private getTransformOrigin;
13
+ /** 바인딩 이벤트 핸들러 */
14
+ private _show;
15
+ private _hide;
16
+ /** 대상 엘리먼트에 트리거 이벤트를 바인딩합니다. */
17
+ private attachAnchor;
18
+ /** 바인딩된 트리거 이벤트를 제거합니다. */
19
+ private detachAnchor;
40
20
  }
@@ -1,70 +1,13 @@
1
1
  import { html } from 'lit';
2
- import { property } from 'lit/decorators.js';
3
- import { offset, shift, flip, autoPlacement, computePosition } from '@floating-ui/dom';
4
- import { getParentElement, findElementsBy } from '../../internals/node-helpers.js';
5
- import { BaseElement } from '../BaseElement.js';
2
+ import { FloatingElement } from '../FloatingElement.js';
6
3
  import { styles } from './Tooltip.styles.js';
7
4
 
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 Tooltip extends BaseElement {
5
+ class Tooltip extends FloatingElement {
18
6
  constructor() {
19
- super();
20
- this.triggers = [];
21
- this.hoist = false;
22
- this.distance = 8;
23
- this.delay = 0;
24
- /** 툴팁을 표시합니다. */
25
- this.show = async (event) => {
26
- await this.updateComplete;
27
- const trigger = event?.currentTarget;
28
- if (trigger instanceof HTMLElement === false) {
29
- return;
30
- }
31
- const middleware = [
32
- offset({ mainAxis: this.distance }),
33
- shift(),
34
- flip()
35
- ];
36
- if (!this.placement) {
37
- middleware.push(autoPlacement());
38
- }
39
- const position = await computePosition(trigger, this, {
40
- strategy: this.hoist ? "fixed" : "absolute",
41
- placement: this.placement,
42
- middleware
43
- });
44
- Object.assign(this.style, {
45
- left: `${position.x}px`,
46
- top: `${position.y}px`,
47
- transformOrigin: this.getTransformOrigin(position.placement)
48
- });
49
- if (this.delay > 0) {
50
- await new Promise((resolve) => setTimeout(resolve, this.delay));
51
- }
52
- requestAnimationFrame(() => {
53
- this.setAttribute("open", "");
54
- });
55
- };
56
- /** 툴팁을 숨깁니다. */
57
- this.hide = async (event) => {
58
- await this.updateComplete;
59
- if ("relatedTarget" in event) {
60
- const relatedTarget = event["relatedTarget"];
61
- if (this.contains(relatedTarget)) {
62
- return;
63
- }
64
- }
65
- this.removeAttribute("open");
66
- };
67
- this.setAttribute("tabindex", "0");
7
+ super(...arguments);
8
+ /** 바인딩 이벤트 핸들러 */
9
+ this._show = () => this.show();
10
+ this._hide = () => this.hide();
68
11
  }
69
12
  static {
70
13
  this.styles = [super.styles, styles];
@@ -72,101 +15,36 @@ class Tooltip extends BaseElement {
72
15
  static {
73
16
  this.dependencies = {};
74
17
  }
75
- connectedCallback() {
76
- super.connectedCallback();
77
- if (this.triggers.length === 0) {
78
- const parent = getParentElement(this);
79
- if (parent) this.triggers = [parent];
80
- }
81
- this.addEventListener("mouseleave", this.hide);
82
- this.addEventListener("focusout", this.hide);
83
- }
84
18
  disconnectedCallback() {
85
- this.detachTriggers(this.triggers);
19
+ this.detachAnchor(this.anchor);
86
20
  super.disconnectedCallback();
87
21
  }
88
- willUpdate(changedProperties) {
89
- super.willUpdate(changedProperties);
90
- if (changedProperties.has("triggerSelectors") && this.triggerSelectors) {
91
- this.triggers = findElementsBy(this, this.triggerSelectors);
92
- }
93
- }
94
22
  updated(changedProperties) {
95
23
  super.updated(changedProperties);
96
- if (changedProperties.has("triggers")) {
97
- const oldTriggers = changedProperties.get("triggers");
98
- this.detachTriggers(oldTriggers);
99
- this.attachTriggers(this.triggers);
24
+ if (changedProperties.has("anchor")) {
25
+ this.detachAnchor(changedProperties.get("anchor"));
26
+ this.attachAnchor(this.anchor);
100
27
  }
101
28
  }
102
29
  render() {
103
- return html`
104
- <slot></slot>
105
- `;
106
- }
107
- /** 대상 엘리먼트에 툴팁 이벤트를 바인딩 합니다. */
108
- attachTriggers(triggers) {
109
- if (!triggers) return;
110
- for (const trigger of triggers) {
111
- trigger.addEventListener("mouseenter", this.show);
112
- trigger.addEventListener("mouseleave", this.hide);
113
- trigger.addEventListener("focusin", this.show);
114
- trigger.addEventListener("focusout", this.hide);
115
- }
116
- }
117
- /** 대상 엘리먼트에 바인딩된 툴팁 이벤트를 제거합니다. */
118
- detachTriggers(triggers) {
119
- if (!triggers) return;
120
- for (const trigger of triggers) {
121
- trigger.removeEventListener("mouseenter", this.show);
122
- trigger.removeEventListener("mouseleave", this.hide);
123
- trigger.removeEventListener("focusin", this.show);
124
- trigger.removeEventListener("focusout", this.hide);
125
- }
126
- }
127
- /**
128
- * 툴팁이 나타날 위치에 따라 transform-origin 값을 반환합니다.
129
- */
130
- getTransformOrigin(placement) {
131
- switch (placement) {
132
- case "top":
133
- case "top-start":
134
- case "top-end":
135
- return "center bottom";
136
- case "bottom":
137
- case "bottom-start":
138
- case "bottom-end":
139
- return "center top";
140
- case "left":
141
- case "left-start":
142
- case "left-end":
143
- return "right center";
144
- case "right":
145
- case "right-start":
146
- case "right-end":
147
- return "left center";
148
- default:
149
- return "center";
150
- }
30
+ return html`<slot></slot>`;
31
+ }
32
+ /** 대상 엘리먼트에 트리거 이벤트를 바인딩합니다. */
33
+ attachAnchor(target) {
34
+ if (!target) return;
35
+ target.addEventListener("pointerenter", this._show);
36
+ target.addEventListener("pointerleave", this._hide);
37
+ target.addEventListener("focusin", this._show);
38
+ target.addEventListener("focusout", this._hide);
39
+ }
40
+ /** 바인딩된 트리거 이벤트를 제거합니다. */
41
+ detachAnchor(target) {
42
+ if (!target) return;
43
+ target.removeEventListener("pointerenter", this._show);
44
+ target.removeEventListener("pointerleave", this._hide);
45
+ target.removeEventListener("focusin", this._show);
46
+ target.removeEventListener("focusout", this._hide);
151
47
  }
152
48
  }
153
- __decorateClass([
154
- property({ attribute: false })
155
- ], Tooltip.prototype, "triggers");
156
- __decorateClass([
157
- property({ type: String, attribute: "trigger-selectors" })
158
- ], Tooltip.prototype, "triggerSelectors");
159
- __decorateClass([
160
- property({ type: Boolean, reflect: true })
161
- ], Tooltip.prototype, "hoist");
162
- __decorateClass([
163
- property({ type: String })
164
- ], Tooltip.prototype, "placement");
165
- __decorateClass([
166
- property({ type: Number })
167
- ], Tooltip.prototype, "distance");
168
- __decorateClass([
169
- property({ type: Number })
170
- ], Tooltip.prototype, "delay");
171
49
 
172
50
  export { Tooltip };
@@ -2,34 +2,20 @@ 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
-
10
- display: block;
11
- width: max-content;
12
- padding: 8px;
5
+ padding: 6px 8px;
13
6
  color: var(--u-tooltip-txt-color);
14
- font-family: var(--u-font-modern, inherit);
15
- font-size: 14px;
16
- line-height: 1.5;
7
+ font-family: var(--u-font-display, inherit);
8
+ font-size: 12px;
9
+ line-height: 1.25;
17
10
  border: none;
18
11
  border-radius: 4px;
19
12
  background-color: var(--u-tooltip-bg-color);
20
-
21
- opacity: 0;
22
- pointer-events: none;
23
- transform: scale(0);
24
- transition: opacity 0.15s ease, transform 0.15s ease;
25
- }
26
- :host([hoist]) {
27
- position: fixed;
13
+ box-shadow: 0 6px 18px rgba(0, 0, 0, 0.2);
14
+ transform: scale(0.8);
15
+ transition: opacity 0.2s ease, transform 0.2s ease;
28
16
  }
29
- :host([open]) {
30
- opacity: 0.8;
17
+ :host([visible]) {
31
18
  transform: scale(1);
32
- pointer-events: auto;
33
19
  }
34
20
  `;
35
21
 
package/dist/index.js CHANGED
@@ -4,11 +4,13 @@ import './components/context-menu/index.js';
4
4
  import './components/copy-button/index.js';
5
5
  import './components/dialog/index.js';
6
6
  import './components/divider/index.js';
7
+ import './components/dropdown-menu/index.js';
7
8
  import './components/form/index.js';
8
9
  import './components/icon/index.js';
9
10
  import './components/icon-button/index.js';
10
11
  import './components/input/index.js';
11
12
  import './components/menu/index.js';
13
+ import './components/menu-item/index.js';
12
14
  import './components/progress-bar/index.js';
13
15
  import './components/progress-ring/index.js';
14
16
  import './components/spinner/index.js';
@@ -27,11 +29,13 @@ export { ContextMenu } from './components/context-menu/ContextMenu.js';
27
29
  export { CopyButton } from './components/copy-button/CopyButton.js';
28
30
  export { Dialog } from './components/dialog/Dialog.js';
29
31
  export { Divider } from './components/divider/Divider.js';
32
+ export { DropdownMenu } from './components/dropdown-menu/DropdownMenu.js';
30
33
  export { Form } from './components/form/Form.js';
31
34
  export { Icon } from './components/icon/Icon.js';
32
35
  export { IconButton } from './components/icon-button/IconButton.js';
33
36
  export { Input } from './components/input/Input.js';
34
37
  export { Menu } from './components/menu/Menu.js';
38
+ export { MenuItem } from './components/menu-item/MenuItem.js';
35
39
  export { ProgressBar } from './components/progress-bar/ProgressBar.js';
36
40
  export { ProgressRing } from './components/progress-ring/ProgressRing.js';
37
41
  export { Spinner } from './components/spinner/Spinner.js';
@@ -0,0 +1,8 @@
1
+ import React from 'react';
2
+ import { DropdownMenu } from '../../components/dropdown-menu/index';
3
+
4
+ export declare const UDropdownMenu: React.ForwardRefExoticComponent<
5
+ Partial<DropdownMenu> & React.HTMLAttributes<DropdownMenu>
6
+ >;
7
+
8
+ export type UDropdownMenuProps = React.ComponentProps<typeof UDropdownMenu>;
@@ -0,0 +1,10 @@
1
+ import React from 'react';
2
+ import { createComponent } from '@lit/react';
3
+ import { DropdownMenu } from '../../components/dropdown-menu/index';
4
+
5
+ export const UDropdownMenu = createComponent({
6
+ react: React,
7
+ tagName: 'u-dropdown-menu',
8
+ elementClass: DropdownMenu,
9
+ events: {}
10
+ });
@@ -11,6 +11,7 @@ export { UContextMenu, UContextMenuProps } from './UContextMenu';
11
11
  export { UCopyButton, UCopyButtonProps } from './UCopyButton';
12
12
  export { UDialog, UDialogProps } from './UDialog';
13
13
  export { UDivider, UDividerProps } from './UDivider';
14
+ export { UDropdownMenu, UDropdownMenuProps } from './UDropdownMenu';
14
15
  export { UForm, UFormProps } from './UForm';
15
16
  export { UIcon, UIconProps } from './UIcon';
16
17
  export { UIconButton, UIconButtonProps } from './UIconButton';
@@ -4,6 +4,7 @@ export { UContextMenu } from './UContextMenu.js';
4
4
  export { UCopyButton } from './UCopyButton.js';
5
5
  export { UDialog } from './UDialog.js';
6
6
  export { UDivider } from './UDivider.js';
7
+ export { UDropdownMenu } from './UDropdownMenu.js';
7
8
  export { UForm } from './UForm.js';
8
9
  export { UIcon } from './UIcon.js';
9
10
  export { UIconButton } from './UIconButton.js';
@@ -5,8 +5,13 @@
5
5
  * 찾을 수 없는 경우 undefined을 반환합니다.
6
6
  */
7
7
  export declare function getParentElement(element: Element): HTMLElement | undefined;
8
+ /**
9
+ * element 기준으로 selector와 매치되는 첫번째 HTMLElement를 반환합니다.
10
+ * - 탐색은 element가 존재하는 shadow DOM 또는 document 루트 안에서 이루어집니다.
11
+ */
12
+ export declare function querySelectorFrom(element: Element, selectors: string): HTMLElement | null;
8
13
  /**
9
14
  * element 기준으로 selector와 매치되는 모든 HTMLElement를 반환합니다.
10
15
  * - 탐색은 element가 존재하는 shadow DOM 또는 document 루트 안에서 이루어집니다.
11
16
  */
12
- export declare function findElementsBy(element: Element, selectors: string): HTMLElement[];
17
+ export declare function querySelectorAllFrom(element: Element, selectors: string): HTMLElement[];
@@ -6,15 +6,14 @@ function getParentElement(element) {
6
6
  return root instanceof Document ? root.documentElement : root instanceof ShadowRoot ? root.host : root instanceof HTMLElement ? root : void 0;
7
7
  }
8
8
  }
9
- function findElementsBy(element, selectors) {
10
- if (!selectors) return [];
9
+ function querySelectorFrom(element, selectors) {
10
+ if (!selectors) return null;
11
11
  const rootNode = element.getRootNode({ composed: false });
12
12
  if (rootNode instanceof ShadowRoot || rootNode instanceof Document) {
13
- const nodeList = rootNode.querySelectorAll(selectors);
14
- return Array.from(nodeList);
13
+ return rootNode.querySelector(selectors);
15
14
  } else {
16
- return [];
15
+ return null;
17
16
  }
18
17
  }
19
18
 
20
- export { findElementsBy, getParentElement };
19
+ export { getParentElement, querySelectorFrom };
package/package.json CHANGED
@@ -1,59 +1,59 @@
1
- {
2
- "name": "@iyulab/components",
3
- "description": "web-components library based on lit-element made by iyulab",
4
- "version": "0.1.5",
5
- "keywords": [
6
- "iyulab",
7
- "components",
8
- "web-components",
9
- "lit-element"
10
- ],
11
- "license": "MIT",
12
- "author": "iyulab",
13
- "repository": {
14
- "type": "git",
15
- "url": "https://github.com/iyulab/node-components.git"
16
- },
17
- "files": [
18
- "dist",
19
- "LICENSE",
20
- "README.md",
21
- "CHANGELOG.md",
22
- "package.json"
23
- ],
24
- "type": "module",
25
- "types": "./dist/index.d.ts",
26
- "exports": {
27
- ".": {
28
- "types": "./dist/index.d.ts",
29
- "import": "./dist/index.js"
30
- },
31
- "./dist/*": {
32
- "types": "./dist/*.d.ts",
33
- "import": "./dist/*"
34
- }
35
- },
36
- "scripts": {
37
- "start": "vite --force",
38
- "build": "eslint && vite build"
39
- },
40
- "dependencies": {
41
- "@floating-ui/dom": "^1.7.4",
42
- "lit": "^3.3.1",
43
- "react": "^19.2.1",
44
- "reflect-metadata": "^0.2.2"
45
- },
46
- "devDependencies": {
47
- "@lit/react": "^1.0.8",
48
- "@eslint/js": "^9.39.1",
49
- "@types/node": "^24.10.2",
50
- "eslint": "^9.39.1",
51
- "eslint-plugin-lit": "^2.1.1",
52
- "globals": "^16.5.0",
53
- "typescript": "^5.9.3",
54
- "typescript-eslint": "^8.49.0",
55
- "vite": "^7.2.7",
56
- "vite-plugin-dts": "^4.5.4",
57
- "vite-plugin-static-copy": "^3.1.4"
58
- }
59
- }
1
+ {
2
+ "name": "@iyulab/components",
3
+ "description": "web-components library based on lit-element made by iyulab",
4
+ "version": "0.1.7",
5
+ "keywords": [
6
+ "iyulab",
7
+ "components",
8
+ "web-components",
9
+ "lit-element"
10
+ ],
11
+ "license": "MIT",
12
+ "author": "iyulab",
13
+ "repository": {
14
+ "type": "git",
15
+ "url": "https://github.com/iyulab/node-components.git"
16
+ },
17
+ "files": [
18
+ "dist",
19
+ "LICENSE",
20
+ "README.md",
21
+ "CHANGELOG.md",
22
+ "package.json"
23
+ ],
24
+ "type": "module",
25
+ "types": "./dist/index.d.ts",
26
+ "exports": {
27
+ ".": {
28
+ "types": "./dist/index.d.ts",
29
+ "import": "./dist/index.js"
30
+ },
31
+ "./dist/*": {
32
+ "types": "./dist/*.d.ts",
33
+ "import": "./dist/*"
34
+ }
35
+ },
36
+ "scripts": {
37
+ "start": "vite --force",
38
+ "build": "eslint && vite build"
39
+ },
40
+ "dependencies": {
41
+ "@floating-ui/dom": "^1.7.4",
42
+ "lit": "^3.3.1",
43
+ "react": "^19.2.3",
44
+ "reflect-metadata": "^0.2.2"
45
+ },
46
+ "devDependencies": {
47
+ "@lit/react": "^1.0.8",
48
+ "@eslint/js": "^9.39.1",
49
+ "@types/node": "^25.0.1",
50
+ "eslint": "^9.39.1",
51
+ "eslint-plugin-lit": "^2.1.1",
52
+ "globals": "^16.5.0",
53
+ "typescript": "^5.9.3",
54
+ "typescript-eslint": "^8.49.0",
55
+ "vite": "^7.2.7",
56
+ "vite-plugin-dts": "^4.5.4",
57
+ "vite-plugin-static-copy": "^3.1.4"
58
+ }
59
+ }