@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.
- package/CHANGELOG.md +18 -18
- package/LICENSE +20 -20
- package/README.md +33 -33
- package/dist/assets/icons/arrow-clockwise.svg.js +1 -1
- package/dist/assets/icons/arrow-down.svg.js +1 -1
- package/dist/assets/icons/arrow-up.svg.js +1 -1
- package/dist/assets/icons/ban.svg.js +1 -1
- package/dist/assets/icons/bell-fill.svg.js +1 -1
- package/dist/assets/icons/check-circle-fill.svg.js +1 -1
- package/dist/assets/icons/check-lg.svg.js +1 -1
- package/dist/assets/icons/chevron-down.svg.js +1 -1
- package/dist/assets/icons/chevron-left.svg.js +1 -1
- package/dist/assets/icons/chevron-right.svg.js +1 -1
- package/dist/assets/icons/chevron-up.svg.js +1 -1
- package/dist/assets/icons/copy.svg.js +1 -1
- package/dist/assets/icons/dash-lg.svg.js +1 -1
- package/dist/assets/icons/exclamation-circle-fill.svg.js +1 -1
- package/dist/assets/icons/exclamation-triangle-fill.svg.js +1 -1
- package/dist/assets/icons/eye-slash.svg.js +1 -1
- package/dist/assets/icons/eye.svg.js +1 -1
- package/dist/assets/icons/info-circle-fill.svg.js +1 -1
- package/dist/assets/icons/layout-sidebar.svg.js +1 -1
- package/dist/assets/icons/lightbulb-fill.svg.js +1 -1
- package/dist/assets/icons/lightbulb-off.svg.js +1 -1
- package/dist/assets/icons/lightbulb.svg.js +1 -1
- package/dist/assets/icons/mic-fill.svg.js +1 -1
- package/dist/assets/icons/mic-mute-fill.svg.js +1 -1
- package/dist/assets/icons/paperclip.svg.js +1 -1
- package/dist/assets/icons/pencil-square.svg.js +1 -1
- package/dist/assets/icons/plus-lg.svg.js +1 -1
- package/dist/assets/icons/search.svg.js +1 -1
- package/dist/assets/icons/speedometer.svg.js +1 -1
- package/dist/assets/icons/x-lg.svg.js +1 -1
- package/dist/assets/styles/dark.css +129 -129
- package/dist/assets/styles/dark.css.js +1 -1
- package/dist/assets/styles/light.css +129 -129
- package/dist/assets/styles/light.css.js +1 -1
- package/dist/components/FloatingElement.d.ts +84 -0
- package/dist/components/FloatingElement.js +166 -0
- package/dist/components/FloatingElement.styles.d.ts +1 -0
- package/dist/components/FloatingElement.styles.js +26 -0
- package/dist/components/context-menu/ContextMenu.d.ts +20 -39
- package/dist/components/context-menu/ContextMenu.js +92 -137
- package/dist/components/context-menu/ContextMenu.styles.js +3 -28
- package/dist/components/context-menu/index.d.ts +1 -1
- package/dist/components/dialog/Dialog.d.ts +14 -7
- package/dist/components/dialog/Dialog.js +88 -27
- package/dist/components/dialog/Dialog.styles.js +60 -11
- package/dist/components/divider/Divider.d.ts +5 -5
- package/dist/components/divider/Divider.js +17 -17
- package/dist/components/divider/Divider.styles.js +4 -6
- package/dist/components/dropdown-menu/DropdownMenu.d.ts +27 -0
- package/dist/components/dropdown-menu/DropdownMenu.js +135 -0
- package/dist/components/dropdown-menu/DropdownMenu.styles.d.ts +1 -0
- package/dist/components/dropdown-menu/DropdownMenu.styles.js +15 -0
- package/dist/components/dropdown-menu/index.d.ts +7 -0
- package/dist/components/dropdown-menu/index.js +5 -0
- package/dist/components/icon/Icon.js +1 -0
- package/dist/components/index.d.ts +2 -0
- package/dist/components/input/Input.js +1 -1
- package/dist/components/input/Input.styles.js +5 -5
- package/dist/components/menu/Menu.d.ts +4 -15
- package/dist/components/menu/Menu.js +43 -28
- package/dist/components/menu/Menu.styles.js +7 -19
- package/dist/components/menu-item/MenuItem.d.ts +21 -12
- package/dist/components/menu-item/MenuItem.js +184 -15
- package/dist/components/menu-item/MenuItem.styles.js +6 -0
- package/dist/components/menu-item/index.js +5 -0
- package/dist/components/split-panel/SplitPanel.d.ts +10 -2
- package/dist/components/split-panel/SplitPanel.js +41 -22
- package/dist/components/split-panel/SplitPanel.styles.js +1 -16
- package/dist/components/tooltip/Tooltip.d.ts +9 -29
- package/dist/components/tooltip/Tooltip.js +27 -149
- package/dist/components/tooltip/Tooltip.styles.js +8 -22
- package/dist/index.js +4 -0
- package/dist/integrations/react/UDropdownMenu.d.ts +8 -0
- package/dist/integrations/react/UDropdownMenu.js +10 -0
- package/dist/integrations/react/index.d.ts +1 -0
- package/dist/integrations/react/index.js +1 -0
- package/dist/internals/node-helpers.d.ts +6 -1
- package/dist/internals/node-helpers.js +5 -6
- 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.
|
|
26
|
-
this.
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
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.
|
|
37
|
-
const totalRatio = this.
|
|
38
|
-
this.panelSizes = this.
|
|
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.
|
|
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: "
|
|
118
|
-
], SplitPanel.prototype, "
|
|
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:
|
|
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
|
|
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
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
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 {
|
|
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
|
-
|
|
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
|
-
|
|
21
|
-
this.
|
|
22
|
-
this.
|
|
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.
|
|
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("
|
|
97
|
-
|
|
98
|
-
this.
|
|
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
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
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
|
-
|
|
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-
|
|
15
|
-
font-size:
|
|
16
|
-
line-height: 1.
|
|
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
|
-
|
|
22
|
-
|
|
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([
|
|
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
|
|
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
|
|
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
|
-
|
|
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 {
|
|
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
|
-
"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.
|
|
44
|
-
"reflect-metadata": "^0.2.2"
|
|
45
|
-
},
|
|
46
|
-
"devDependencies": {
|
|
47
|
-
"@lit/react": "^1.0.8",
|
|
48
|
-
"@eslint/js": "^9.39.1",
|
|
49
|
-
"@types/node": "^
|
|
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
|
+
}
|