@iyulab/components 1.38.0 → 1.40.0
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 +194 -0
- package/README.md +24 -0
- package/dist/_virtual/{_@oxc-project_runtime@0.148.0 → _@oxc-project_runtime@0.149.0}/helpers/esm/decorate.js +1 -1
- package/dist/_virtual/{_@oxc-project_runtime@0.148.0 → _@oxc-project_runtime@0.149.0}/helpers/esm/decorateMetadata.js +1 -1
- package/dist/_virtual/_glob-assets_raw/dark.css.e8ac080d.js +1 -1
- package/dist/_virtual/_glob-assets_raw/light.css.637cb2f8.js +1 -1
- package/dist/assets/locales/ar.json.js +6 -2
- package/dist/assets/locales/de.json.js +6 -2
- package/dist/assets/locales/en.json.js +6 -2
- package/dist/assets/locales/es.json.js +6 -2
- package/dist/assets/locales/fr.json.js +6 -2
- package/dist/assets/locales/id.json.js +6 -2
- package/dist/assets/locales/ja.json.js +6 -2
- package/dist/assets/locales/ko.json.js +6 -2
- package/dist/assets/locales/pt-BR.json.js +6 -2
- package/dist/assets/locales/ru.json.js +6 -2
- package/dist/assets/locales/th.json.js +6 -2
- package/dist/assets/locales/vi.json.js +6 -2
- package/dist/assets/locales/zh-CN.json.js +6 -2
- package/dist/assets/locales/zh-TW.json.js +6 -2
- package/dist/components/UFloatingElement.js +2 -2
- package/dist/components/UFormControlElement.js +2 -2
- package/dist/components/UOverlayElement.js +2 -2
- package/dist/components/alert/UAlert.js +2 -2
- package/dist/components/avatar/UAvatar.js +2 -2
- package/dist/components/badge/UBadge.js +2 -2
- package/dist/components/breadcrumb/UBreadcrumb.js +1 -1
- package/dist/components/breadcrumb/UBreadcrumb.styles.js +1 -1
- package/dist/components/breadcrumb-item/UBreadcrumbItem.js +2 -2
- package/dist/components/breadcrumb-item/UBreadcrumbItem.styles.js +1 -1
- package/dist/components/button/UButton.js +2 -2
- package/dist/components/button-group/UButtonGroup.js +2 -2
- package/dist/components/card/UCard.js +2 -2
- package/dist/components/carousel/UCarousel.js +2 -2
- package/dist/components/checkbox/UCheckbox.js +2 -2
- package/dist/components/checkbox/UCheckbox.styles.js +7 -1
- package/dist/components/chip/UChip.js +2 -2
- package/dist/components/chip/UChip.styles.js +7 -0
- package/dist/components/copy-button/UCopyButton.js +2 -2
- package/dist/components/date-picker/UDatePicker.js +2 -2
- package/dist/components/date-picker/UDatePicker.styles.js +2 -2
- package/dist/components/dialog/UDialog.js +2 -2
- package/dist/components/divider/UDivider.js +2 -2
- package/dist/components/divider/UDivider.styles.js +1 -1
- package/dist/components/drawer/UDrawer.js +2 -2
- package/dist/components/expander/UExpander.js +2 -2
- package/dist/components/expander/UExpander.styles.js +1 -1
- package/dist/components/field/UField.js +2 -2
- package/dist/components/field/UField.styles.js +1 -1
- package/dist/components/file-input/UFileInput.js +2 -2
- package/dist/components/file-input/UFileInput.styles.js +2 -2
- package/dist/components/form/UForm.js +2 -2
- package/dist/components/icon/UIcon.js +3 -3
- package/dist/components/icon-button/UIconButton.js +2 -2
- package/dist/components/input/UInput.d.ts +15 -1
- package/dist/components/input/UInput.js +62 -12
- package/dist/components/input/UInput.styles.js +25 -6
- package/dist/components/menu/UMenu.js +2 -2
- package/dist/components/menu-item/UMenuItem.js +2 -2
- package/dist/components/option/UOption.js +2 -2
- package/dist/components/panel/UPanel.js +2 -2
- package/dist/components/popover/UPopover.js +23 -7
- package/dist/components/progress-bar/UProgressBar.js +2 -2
- package/dist/components/progress-ring/UProgressRing.js +2 -2
- package/dist/components/radio/URadio.js +2 -2
- package/dist/components/rating/URating.js +2 -2
- package/dist/components/rating/URating.styles.js +6 -0
- package/dist/components/select/USelect.d.ts +7 -1
- package/dist/components/select/USelect.js +19 -8
- package/dist/components/select/USelect.styles.js +18 -5
- package/dist/components/skeleton/USkeleton.js +2 -2
- package/dist/components/slider/USlider.d.ts +3 -1
- package/dist/components/slider/USlider.js +2 -2
- package/dist/components/slider/USlider.styles.js +19 -2
- package/dist/components/spinner/USpinner.js +2 -2
- package/dist/components/split-panel/USplitPanel.d.ts +37 -2
- package/dist/components/split-panel/USplitPanel.js +120 -11
- package/dist/components/split-panel/USplitPanel.styles.js +37 -6
- package/dist/components/switch/USwitch.js +2 -2
- package/dist/components/switch/USwitch.styles.js +8 -3
- package/dist/components/tab/UTab.js +2 -2
- package/dist/components/tab/UTab.styles.js +1 -1
- package/dist/components/tab-panel/UTabPanel.js +3 -3
- package/dist/components/tag/UTag.js +2 -2
- package/dist/components/text/UText.js +2 -2
- package/dist/components/text/UText.styles.js +1 -1
- package/dist/components/textarea/UTextarea.d.ts +5 -0
- package/dist/components/textarea/UTextarea.js +2 -2
- package/dist/components/textarea/UTextarea.styles.js +6 -3
- package/dist/components/tooltip/UTooltip.js +2 -2
- package/dist/components/tree/UTree.js +2 -2
- package/dist/components/tree-item/UTreeItem.js +2 -2
- package/dist/components/tree-item/UTreeItem.styles.js +50 -13
- package/dist/styles/dark.css +4 -1
- package/dist/styles/light.css +7 -4
- package/dist/utilities/Locale.d.ts +1 -1
- package/dist/utilities/OverlayManager.d.ts +36 -4
- package/dist/utilities/OverlayManager.js +39 -4
- package/dist/utilities/Toast.d.ts +55 -4
- package/dist/utilities/Toast.js +84 -19
- package/package.json +4 -4
- package/skills/iyulab-components/references/components/dialog.md +19 -0
- package/skills/iyulab-components/references/components/input.md +17 -0
- package/skills/iyulab-components/references/components/panel.md +12 -0
- package/skills/iyulab-components/references/components/select.md +9 -0
- package/skills/iyulab-components/references/components/slider.md +1 -1
- package/skills/iyulab-components/references/components/split-panel.md +41 -3
- package/skills/iyulab-components/references/components/tab-panel.md +18 -0
- package/skills/iyulab-components/references/utilities/overlay-manager.md +16 -2
|
@@ -6,14 +6,22 @@ import { UElement } from '../UElement.js';
|
|
|
6
6
|
* @slot - 분할된 패널 요소들
|
|
7
7
|
* @slot splitter - 핸들(스플리터) UI
|
|
8
8
|
*
|
|
9
|
-
* @cssprop --splitter-size -
|
|
9
|
+
* @cssprop --splitter-size - 보이는 구분선 두께 (default: 4px)
|
|
10
|
+
* @cssprop --splitter-hit-size - 포인터를 받는 핸들 영역의 두께 — 레이아웃 공간을 차지하므로 패널을
|
|
11
|
+
* 가리지 않는다. 실제 핸들 두께는 이 값과 `--splitter-size` 중 큰 쪽 (default: 24px — WCAG 2.5.8)
|
|
10
12
|
* @cssprop --splitter-color - 스플리터 색상
|
|
11
13
|
* @cssprop --splitter-color-hover - 스플리터 호버 색상
|
|
12
14
|
* @cssprop --splitter-color-active - 스플리터 활성 색상
|
|
13
15
|
*
|
|
14
16
|
* @event shift-start - 구분선 이동 시작 시 발생
|
|
15
17
|
* @event shift - 구분선 이동 중 발생
|
|
16
|
-
* @event shift-end - 구분선 이동 완료 시 발생
|
|
18
|
+
* @event shift-end - 구분선 이동 완료 시 발생 (포인터·키보드 공통)
|
|
19
|
+
*
|
|
20
|
+
* 키보드(WAI-ARIA APG «Window Splitter»): 분할 핸들은 `role="separator"` 로 포커스를 받는다.
|
|
21
|
+
* 방향키(가로 배치는 ←/→, 세로 배치는 ↑/↓)로 앞 패널을 줄이거나 늘리고, Home/End 는 앞 패널을
|
|
22
|
+
* 최소/최대로, Enter 는 앞 패널을 접거나 접기 전 크기로 되돌린다. 키 입력 한 번은 하나의 완결된
|
|
23
|
+
* 이동이라 `shift-start`·`shift`·`shift-end` 를 연달아 낸다 — 비율을 저장하는 소비자는 포인터든
|
|
24
|
+
* 키보드든 `shift-end` 하나만 들으면 된다.
|
|
17
25
|
*/
|
|
18
26
|
export declare class USplitPanel extends UElement {
|
|
19
27
|
static styles: import('lit').CSSResultGroup[];
|
|
@@ -30,8 +38,15 @@ export declare class USplitPanel extends UElement {
|
|
|
30
38
|
private ghost?;
|
|
31
39
|
private panels;
|
|
32
40
|
private splitter?;
|
|
41
|
+
/** Enter 로 접은 핸들별 «접기 전 앞 패널 비율» — 다시 Enter 를 누르면 여기로 돌아간다. */
|
|
42
|
+
private collapsedFrom;
|
|
33
43
|
private dragState;
|
|
34
44
|
private get percentages();
|
|
45
|
+
/**
|
|
46
|
+
* 핸들 하나가 레이아웃에서 차지하는 두께(px). 렌더된 핸들을 재는 것이 정본이다 — CSS 가
|
|
47
|
+
* `max(--splitter-size, --splitter-hit-size)` 로 정하고 `rem` 등 어떤 단위든 올 수 있다.
|
|
48
|
+
* 아직 렌더되지 않았거나 숨겨져 0 이면 두 변수를 읽어 같은 규칙을 흉내 낸다.
|
|
49
|
+
*/
|
|
35
50
|
private get splitterSize();
|
|
36
51
|
private get splitterCount();
|
|
37
52
|
protected willUpdate(changedProperties: PropertyValues): void;
|
|
@@ -40,11 +55,31 @@ export declare class USplitPanel extends UElement {
|
|
|
40
55
|
private handleSplitterSlotChange;
|
|
41
56
|
private appendSplitters;
|
|
42
57
|
private createSplitter;
|
|
58
|
+
/**
|
|
59
|
+
* 분할 핸들의 접근성 상태 — APG «Window Splitter». 핸들은 명령형으로 만들어 Lit 템플릿 밖에
|
|
60
|
+
* 있으므로, 비율·방향·비활성이 바뀔 때마다 여기서 다시 쓴다.
|
|
61
|
+
*
|
|
62
|
+
* 값은 **앞 패널(primary pane)의 몫**이다. 패널이 셋 이상이면 한 핸들은 이웃한 두 패널 사이만
|
|
63
|
+
* 옮기므로 최대값은 100 이 아니라 그 두 패널의 몫의 합이다.
|
|
64
|
+
*/
|
|
65
|
+
private syncSplitterAria;
|
|
66
|
+
/** 방향키 한 번이 옮기는 앞 패널의 몫(나머지 공간 기준 %). */
|
|
67
|
+
private static readonly KEY_STEP;
|
|
68
|
+
private handleKeyDown;
|
|
43
69
|
private updatePanelLayout;
|
|
44
70
|
private handleDblClick;
|
|
45
71
|
private handlePointerDown;
|
|
46
72
|
private handlePointerMove;
|
|
47
73
|
private handlePointerUp;
|
|
74
|
+
/**
|
|
75
|
+
* 패널 하나의 크기 — 비율은 «핸들을 뺀 나머지 공간»에 대한 몫이다.
|
|
76
|
+
*
|
|
77
|
+
* 🔴각 패널은 핸들 전체 두께 중 **자기 비율만큼**을 뺀다. 종전에는 핸들 몫을 패널 수로 똑같이
|
|
78
|
+
* 나눠 뺐는데(`p% - 핸들합/n`), 그 식은 비율이 균등할 때만 «나머지 공간의 p%» 와 같다. 드래그는
|
|
79
|
+
* 이동량을 나머지 공간 기준 비율로 바꾸므로(`availableSize`), 비율이 균등에서 멀어질수록 패널이
|
|
80
|
+
* 포인터보다 더 움직였다 — 핸들이 굵을수록 크게(24px 핸들이면 이동량의 약 9%).
|
|
81
|
+
*/
|
|
82
|
+
private panelSize;
|
|
48
83
|
private clampPair;
|
|
49
84
|
}
|
|
50
85
|
declare global {
|
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
import { UElement } from "../UElement.js";
|
|
2
|
-
import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.
|
|
3
|
-
import __decorate from "../../_virtual/_@oxc-project_runtime@0.
|
|
2
|
+
import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.149.0/helpers/esm/decorateMetadata.js";
|
|
3
|
+
import __decorate from "../../_virtual/_@oxc-project_runtime@0.149.0/helpers/esm/decorate.js";
|
|
4
4
|
import { arrayAttrConverter } from "../../utilities/converters.js";
|
|
5
|
+
import { Locale } from "../../utilities/Locale.js";
|
|
5
6
|
import { styles } from "./USplitPanel.styles.js";
|
|
6
7
|
import { html } from "lit";
|
|
7
8
|
import { customElement, property, query } from "lit/decorators.js";
|
|
8
9
|
//#region src/components/split-panel/USplitPanel.ts
|
|
10
|
+
var _USplitPanel;
|
|
9
11
|
var USplitPanel = class USplitPanel extends UElement {
|
|
12
|
+
static {
|
|
13
|
+
_USplitPanel = this;
|
|
14
|
+
}
|
|
10
15
|
constructor(..._args) {
|
|
11
16
|
super(..._args);
|
|
12
17
|
this.disabled = false;
|
|
@@ -15,6 +20,7 @@ var USplitPanel = class USplitPanel extends UElement {
|
|
|
15
20
|
this.defaultRatio = [];
|
|
16
21
|
this.ratio = [];
|
|
17
22
|
this.panels = [];
|
|
23
|
+
this.collapsedFrom = /* @__PURE__ */ new Map();
|
|
18
24
|
this.dragState = {
|
|
19
25
|
index: -1,
|
|
20
26
|
startPoint: 0,
|
|
@@ -33,6 +39,52 @@ var USplitPanel = class USplitPanel extends UElement {
|
|
|
33
39
|
this.splitter = slot.assignedNodes({ flatten: true }).at(0);
|
|
34
40
|
this.appendSplitters();
|
|
35
41
|
};
|
|
42
|
+
this.handleKeyDown = (e) => {
|
|
43
|
+
if (this.disabled) return;
|
|
44
|
+
const i = Number(e.currentTarget.dataset.index);
|
|
45
|
+
const p = this.percentages;
|
|
46
|
+
if (p[i] === void 0 || p[i + 1] === void 0) return;
|
|
47
|
+
const pair = p[i] + p[i + 1];
|
|
48
|
+
const horizontal = this.orientation === "horizontal";
|
|
49
|
+
const rtl = horizontal && getComputedStyle(this).direction === "rtl";
|
|
50
|
+
const shrink = horizontal ? rtl ? "ArrowRight" : "ArrowLeft" : "ArrowUp";
|
|
51
|
+
const grow = horizontal ? rtl ? "ArrowLeft" : "ArrowRight" : "ArrowDown";
|
|
52
|
+
let a;
|
|
53
|
+
if (e.key === shrink) a = p[i] - _USplitPanel.KEY_STEP;
|
|
54
|
+
else if (e.key === grow) a = p[i] + _USplitPanel.KEY_STEP;
|
|
55
|
+
else if (e.key === "Home") a = 0;
|
|
56
|
+
else if (e.key === "End") a = pair;
|
|
57
|
+
else if (e.key === "Enter") {
|
|
58
|
+
const restore = this.collapsedFrom.get(i);
|
|
59
|
+
if (p[i] > 0) {
|
|
60
|
+
this.collapsedFrom.set(i, p[i]);
|
|
61
|
+
a = 0;
|
|
62
|
+
} else {
|
|
63
|
+
a = restore ?? pair / 2;
|
|
64
|
+
this.collapsedFrom.delete(i);
|
|
65
|
+
}
|
|
66
|
+
} else return;
|
|
67
|
+
e.preventDefault();
|
|
68
|
+
a = Math.round(Math.min(pair, Math.max(0, a)) * 1e6) / 1e6;
|
|
69
|
+
if (Math.abs(a - p[i]) < 1e-6) return;
|
|
70
|
+
if (e.key !== "Enter") this.collapsedFrom.delete(i);
|
|
71
|
+
const next = [...p];
|
|
72
|
+
next[i] = a;
|
|
73
|
+
next[i + 1] = pair - a;
|
|
74
|
+
const init = (ratio) => ({
|
|
75
|
+
bubbles: false,
|
|
76
|
+
composed: false,
|
|
77
|
+
detail: {
|
|
78
|
+
index: i,
|
|
79
|
+
ratio: [...ratio]
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
this.fire("shift-start", init(p));
|
|
83
|
+
this.ratio = next;
|
|
84
|
+
this.updatePanelLayout();
|
|
85
|
+
this.fire("shift", init(next));
|
|
86
|
+
this.fire("shift-end", init(next));
|
|
87
|
+
};
|
|
36
88
|
this.handleDblClick = () => {
|
|
37
89
|
if (this.disabled) return;
|
|
38
90
|
this.ratio = this.defaultRatio.length === this.panels.length ? [...this.defaultRatio] : [];
|
|
@@ -91,9 +143,8 @@ var USplitPanel = class USplitPanel extends UElement {
|
|
|
91
143
|
} else {
|
|
92
144
|
const [aPercent, bPercent] = this.clampPair(this.dragState.percentages[aIdx] + deltaPercent, this.dragState.percentages[bIdx] - deltaPercent);
|
|
93
145
|
const dim = this.orientation === "horizontal" ? "width" : "height";
|
|
94
|
-
|
|
95
|
-
this.panels[
|
|
96
|
-
this.panels[bIdx].style[dim] = `calc(${bPercent}% - ${offset}px)`;
|
|
146
|
+
this.panels[aIdx].style[dim] = this.panelSize(aPercent);
|
|
147
|
+
this.panels[bIdx].style[dim] = this.panelSize(bPercent);
|
|
97
148
|
const newRatio = [...this.dragState.percentages];
|
|
98
149
|
newRatio[aIdx] = aPercent;
|
|
99
150
|
newRatio[bIdx] = bPercent;
|
|
@@ -143,7 +194,8 @@ var USplitPanel = class USplitPanel extends UElement {
|
|
|
143
194
|
this.styles = [super.styles, styles];
|
|
144
195
|
}
|
|
145
196
|
get percentages() {
|
|
146
|
-
const
|
|
197
|
+
const usable = (r) => r.length === this.panels.length && r.every((v) => Number.isFinite(v) && v >= 0) && r.some((v) => v > 0);
|
|
198
|
+
const source = usable(this.ratio) ? this.ratio : usable(this.defaultRatio) ? this.defaultRatio : [];
|
|
147
199
|
if (source.length === this.panels.length) {
|
|
148
200
|
const total = source.reduce((sum, s) => sum + s, 0);
|
|
149
201
|
return source.map((s) => s / total * 100);
|
|
@@ -151,9 +203,21 @@ var USplitPanel = class USplitPanel extends UElement {
|
|
|
151
203
|
const equals = 100 / this.panels.length;
|
|
152
204
|
return this.panels.map(() => equals);
|
|
153
205
|
}
|
|
206
|
+
/**
|
|
207
|
+
* 핸들 하나가 레이아웃에서 차지하는 두께(px). 렌더된 핸들을 재는 것이 정본이다 — CSS 가
|
|
208
|
+
* `max(--splitter-size, --splitter-hit-size)` 로 정하고 `rem` 등 어떤 단위든 올 수 있다.
|
|
209
|
+
* 아직 렌더되지 않았거나 숨겨져 0 이면 두 변수를 읽어 같은 규칙을 흉내 낸다.
|
|
210
|
+
*/
|
|
154
211
|
get splitterSize() {
|
|
155
|
-
const
|
|
156
|
-
|
|
212
|
+
const el = this.renderRoot?.querySelector(".splitter");
|
|
213
|
+
if (el) {
|
|
214
|
+
const r = el.getBoundingClientRect();
|
|
215
|
+
const measured = this.orientation === "horizontal" ? r.width : r.height;
|
|
216
|
+
if (measured > 0) return measured;
|
|
217
|
+
}
|
|
218
|
+
const style = getComputedStyle(this);
|
|
219
|
+
const read = (name, fallback) => parseFloat(style.getPropertyValue(name).trim()) || fallback;
|
|
220
|
+
return Math.max(read("--splitter-size", 4), read("--splitter-hit-size", 24));
|
|
157
221
|
}
|
|
158
222
|
get splitterCount() {
|
|
159
223
|
return Math.max(0, this.panels.length - 1);
|
|
@@ -165,6 +229,7 @@ var USplitPanel = class USplitPanel extends UElement {
|
|
|
165
229
|
"defaultRatio",
|
|
166
230
|
"ratio"
|
|
167
231
|
].some((k) => changedProperties.has(k))) this.updatePanelLayout();
|
|
232
|
+
else if (changedProperties.has("disabled")) this.syncSplitterAria();
|
|
168
233
|
}
|
|
169
234
|
render() {
|
|
170
235
|
return html`
|
|
@@ -185,6 +250,7 @@ var USplitPanel = class USplitPanel extends UElement {
|
|
|
185
250
|
const splitter = this.createSplitter(i);
|
|
186
251
|
root.insertBefore(splitter, ref);
|
|
187
252
|
}
|
|
253
|
+
this.syncSplitterAria();
|
|
188
254
|
}
|
|
189
255
|
createSplitter(index) {
|
|
190
256
|
const el = document.createElement("div");
|
|
@@ -193,24 +259,67 @@ var USplitPanel = class USplitPanel extends UElement {
|
|
|
193
259
|
el.style.order = String(index * 2 + 1);
|
|
194
260
|
el.dataset.index = String(index);
|
|
195
261
|
if (this.splitter) el.appendChild(this.splitter.cloneNode(true));
|
|
262
|
+
el.setAttribute("role", "separator");
|
|
196
263
|
el.addEventListener("pointerdown", this.handlePointerDown);
|
|
197
264
|
el.addEventListener("dblclick", this.handleDblClick);
|
|
265
|
+
el.addEventListener("keydown", this.handleKeyDown);
|
|
198
266
|
return el;
|
|
199
267
|
}
|
|
268
|
+
/**
|
|
269
|
+
* 분할 핸들의 접근성 상태 — APG «Window Splitter». 핸들은 명령형으로 만들어 Lit 템플릿 밖에
|
|
270
|
+
* 있으므로, 비율·방향·비활성이 바뀔 때마다 여기서 다시 쓴다.
|
|
271
|
+
*
|
|
272
|
+
* 값은 **앞 패널(primary pane)의 몫**이다. 패널이 셋 이상이면 한 핸들은 이웃한 두 패널 사이만
|
|
273
|
+
* 옮기므로 최대값은 100 이 아니라 그 두 패널의 몫의 합이다.
|
|
274
|
+
*/
|
|
275
|
+
syncSplitterAria() {
|
|
276
|
+
const root = this.renderRoot;
|
|
277
|
+
if (!root) return;
|
|
278
|
+
const p = this.percentages;
|
|
279
|
+
const round = (v) => String(Math.round(v * 10) / 10);
|
|
280
|
+
const label = Locale.getValue("resizePanels");
|
|
281
|
+
root.querySelectorAll(".splitter").forEach((el) => {
|
|
282
|
+
const i = Number(el.dataset.index);
|
|
283
|
+
el.setAttribute("aria-valuenow", round(p[i] ?? 0));
|
|
284
|
+
el.setAttribute("aria-valuemin", "0");
|
|
285
|
+
el.setAttribute("aria-valuemax", round((p[i] ?? 0) + (p[i + 1] ?? 0)));
|
|
286
|
+
el.setAttribute("aria-orientation", this.orientation === "horizontal" ? "vertical" : "horizontal");
|
|
287
|
+
el.setAttribute("aria-label", label);
|
|
288
|
+
el.tabIndex = this.disabled ? -1 : 0;
|
|
289
|
+
if (this.disabled) el.setAttribute("aria-disabled", "true");
|
|
290
|
+
else el.removeAttribute("aria-disabled");
|
|
291
|
+
const reflect = el;
|
|
292
|
+
if ("ariaControlsElements" in reflect && this.panels[i]) reflect.ariaControlsElements = [this.panels[i]];
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
static {
|
|
296
|
+
this.KEY_STEP = 5;
|
|
297
|
+
}
|
|
200
298
|
updatePanelLayout() {
|
|
201
299
|
if (this.panels.length === 0) return;
|
|
202
300
|
const dim = this.orientation === "horizontal" ? "width" : "height";
|
|
203
301
|
const otherDim = this.orientation === "horizontal" ? "height" : "width";
|
|
204
302
|
const percentages = this.percentages;
|
|
205
|
-
const splitterOffset = this.splitterSize * (this.splitterCount / this.panels.length);
|
|
206
303
|
this.panels.forEach((panel, index) => {
|
|
207
|
-
panel.style[dim] =
|
|
304
|
+
panel.style[dim] = this.panelSize(percentages[index]);
|
|
208
305
|
panel.style[otherDim] = "";
|
|
209
306
|
panel.style.order = String(index * 2);
|
|
210
307
|
panel.style.boxSizing = "border-box";
|
|
211
308
|
panel.style.flexShrink = "0";
|
|
212
309
|
panel.style.overflow = "auto";
|
|
213
310
|
});
|
|
311
|
+
this.syncSplitterAria();
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* 패널 하나의 크기 — 비율은 «핸들을 뺀 나머지 공간»에 대한 몫이다.
|
|
315
|
+
*
|
|
316
|
+
* 🔴각 패널은 핸들 전체 두께 중 **자기 비율만큼**을 뺀다. 종전에는 핸들 몫을 패널 수로 똑같이
|
|
317
|
+
* 나눠 뺐는데(`p% - 핸들합/n`), 그 식은 비율이 균등할 때만 «나머지 공간의 p%» 와 같다. 드래그는
|
|
318
|
+
* 이동량을 나머지 공간 기준 비율로 바꾸므로(`availableSize`), 비율이 균등에서 멀어질수록 패널이
|
|
319
|
+
* 포인터보다 더 움직였다 — 핸들이 굵을수록 크게(24px 핸들이면 이동량의 약 9%).
|
|
320
|
+
*/
|
|
321
|
+
panelSize(percent) {
|
|
322
|
+
return `calc(${percent}% - ${this.splitterSize * this.splitterCount * percent / 100}px)`;
|
|
214
323
|
}
|
|
215
324
|
clampPair(aRaw, bRaw) {
|
|
216
325
|
const sum = aRaw + bRaw;
|
|
@@ -249,6 +358,6 @@ __decorate([property({
|
|
|
249
358
|
converter: arrayAttrConverter(parseFloat)
|
|
250
359
|
}), __decorateMetadata("design:type", Array)], USplitPanel.prototype, "ratio", void 0);
|
|
251
360
|
__decorate([query(".splitter-ghost"), __decorateMetadata("design:type", typeof HTMLElement === "undefined" ? Object : HTMLElement)], USplitPanel.prototype, "ghost", void 0);
|
|
252
|
-
USplitPanel = __decorate([customElement("u-split-panel")], USplitPanel);
|
|
361
|
+
USplitPanel = _USplitPanel = __decorate([customElement("u-split-panel")], USplitPanel);
|
|
253
362
|
//#endregion
|
|
254
363
|
export { USplitPanel };
|
|
@@ -3,9 +3,15 @@ import { css } from "lit";
|
|
|
3
3
|
var styles = css`
|
|
4
4
|
:host {
|
|
5
5
|
--splitter-size: 4px;
|
|
6
|
+
--splitter-hit-size: 24px;
|
|
6
7
|
--splitter-color: var(--u-neutral-200, #EEEEEE);
|
|
7
8
|
--splitter-color-hover: var(--u-primary-color-weaker, #64B5F6);
|
|
8
9
|
--splitter-color-active: var(--u-primary-color-strong, #1565C0);
|
|
10
|
+
|
|
11
|
+
/* The handle's box: the larger of the visible line and the pointer area. It takes real
|
|
12
|
+
layout space, so it never overlaps a panel — each panel is a scroll container and its
|
|
13
|
+
scrollbar sits right against the handle. */
|
|
14
|
+
--_splitter-box: max(var(--splitter-size), var(--splitter-hit-size));
|
|
9
15
|
}
|
|
10
16
|
|
|
11
17
|
:host {
|
|
@@ -27,7 +33,7 @@ var styles = css`
|
|
|
27
33
|
opacity: 0.4;
|
|
28
34
|
}
|
|
29
35
|
|
|
30
|
-
/* Splitter */
|
|
36
|
+
/* Splitter — the box receives the pointer; the line inside it is what you see */
|
|
31
37
|
.splitter {
|
|
32
38
|
position: relative;
|
|
33
39
|
z-index: 1;
|
|
@@ -35,24 +41,46 @@ var styles = css`
|
|
|
35
41
|
display: flex;
|
|
36
42
|
align-items: center;
|
|
37
43
|
justify-content: center;
|
|
44
|
+
touch-action: none;
|
|
45
|
+
}
|
|
46
|
+
.splitter::before {
|
|
47
|
+
content: "";
|
|
48
|
+
position: absolute;
|
|
49
|
+
z-index: -1;
|
|
38
50
|
background-color: var(--splitter-color);
|
|
39
51
|
transition: background-color var(--u-duration-fast, 140ms) var(--u-ease-standard, cubic-bezier(0.2, 0, 0, 1));
|
|
40
|
-
|
|
52
|
+
pointer-events: none;
|
|
41
53
|
}
|
|
42
|
-
.splitter:hover {
|
|
54
|
+
.splitter:hover::before {
|
|
43
55
|
background-color: var(--splitter-color-hover);
|
|
44
56
|
}
|
|
45
|
-
.splitter:active
|
|
57
|
+
.splitter:active::before,
|
|
58
|
+
.splitter:focus-visible::before {
|
|
46
59
|
background-color: var(--splitter-color-active);
|
|
47
60
|
}
|
|
61
|
+
/* The handle spans the host's full cross axis and the host clips overflow, so the base
|
|
62
|
+
focus ring (drawn 2px outside) would lose two of its sides. Draw it inside the box. */
|
|
63
|
+
.splitter:focus-visible {
|
|
64
|
+
outline-offset: -2px;
|
|
65
|
+
}
|
|
48
66
|
:host([orientation="horizontal"]) .splitter {
|
|
49
|
-
width: var(--
|
|
67
|
+
width: var(--_splitter-box);
|
|
50
68
|
cursor: col-resize;
|
|
51
69
|
}
|
|
70
|
+
:host([orientation="horizontal"]) .splitter::before {
|
|
71
|
+
inset-block: 0;
|
|
72
|
+
left: calc(50% - var(--splitter-size) / 2);
|
|
73
|
+
width: var(--splitter-size);
|
|
74
|
+
}
|
|
52
75
|
:host([orientation="vertical"]) .splitter {
|
|
53
|
-
height: var(--
|
|
76
|
+
height: var(--_splitter-box);
|
|
54
77
|
cursor: row-resize;
|
|
55
78
|
}
|
|
79
|
+
:host([orientation="vertical"]) .splitter::before {
|
|
80
|
+
inset-inline: 0;
|
|
81
|
+
top: calc(50% - var(--splitter-size) / 2);
|
|
82
|
+
height: var(--splitter-size);
|
|
83
|
+
}
|
|
56
84
|
|
|
57
85
|
/* Ghost Splitter (lazy) */
|
|
58
86
|
.splitter-ghost {
|
|
@@ -66,15 +94,18 @@ var styles = css`
|
|
|
66
94
|
.splitter-ghost[active] {
|
|
67
95
|
display: block;
|
|
68
96
|
}
|
|
97
|
+
/* The ghost is placed at the box's leading edge; the margin centres it on the line. */
|
|
69
98
|
:host([orientation="horizontal"]) .splitter-ghost {
|
|
70
99
|
top: 0;
|
|
71
100
|
width: var(--splitter-size);
|
|
72
101
|
height: 100%;
|
|
102
|
+
margin-left: calc((var(--_splitter-box) - var(--splitter-size)) / 2);
|
|
73
103
|
}
|
|
74
104
|
:host([orientation="vertical"]) .splitter-ghost {
|
|
75
105
|
left: 0;
|
|
76
106
|
width: 100%;
|
|
77
107
|
height: var(--splitter-size);
|
|
108
|
+
margin-top: calc((var(--_splitter-box) - var(--splitter-size)) / 2);
|
|
78
109
|
}
|
|
79
110
|
`;
|
|
80
111
|
//#endregion
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.
|
|
2
|
-
import __decorate from "../../_virtual/_@oxc-project_runtime@0.
|
|
1
|
+
import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.149.0/helpers/esm/decorateMetadata.js";
|
|
2
|
+
import __decorate from "../../_virtual/_@oxc-project_runtime@0.149.0/helpers/esm/decorate.js";
|
|
3
3
|
import { UFormControlElement } from "../UFormControlElement.js";
|
|
4
4
|
import { Locale } from "../../utilities/Locale.js";
|
|
5
5
|
import { styles } from "./USwitch.styles.js";
|
|
@@ -21,6 +21,11 @@ var styles = css`
|
|
|
21
21
|
:host {
|
|
22
22
|
display: inline-flex;
|
|
23
23
|
flex-direction: column;
|
|
24
|
+
/* WCAG 2.2 SC 2.5.8 — 트랙(--switch-track-height)의 시각 치수는 그대로 두고
|
|
25
|
+
포인터 타깃만 24px 하한을 갖는다. UCheckbox 와 같은 처방이다.
|
|
26
|
+
⚠이 주석에 백틱을 쓰면 css 템플릿이 그 자리에서 끝난다(sweep 의 「css 백틱」). */
|
|
27
|
+
min-block-size: 24px;
|
|
28
|
+
justify-content: center;
|
|
24
29
|
color: var(--u-txt-color, #212121);
|
|
25
30
|
font-size: inherit;
|
|
26
31
|
font-family: var(--u-font-base);
|
|
@@ -108,7 +113,7 @@ var styles = css`
|
|
|
108
113
|
.track-unchecked {
|
|
109
114
|
opacity: 1;
|
|
110
115
|
right: var(--switch-thumb-offset);
|
|
111
|
-
color: var(--u-txt-color-weak, #
|
|
116
|
+
color: var(--u-txt-color-weak, #616161);
|
|
112
117
|
}
|
|
113
118
|
:host([checked]) .track-unchecked {
|
|
114
119
|
opacity: 0;
|
|
@@ -166,7 +171,7 @@ var styles = css`
|
|
|
166
171
|
.thumb-unchecked {
|
|
167
172
|
opacity: 1;
|
|
168
173
|
transform: scale(1) rotate(0deg);
|
|
169
|
-
color: var(--u-txt-color-weak, #
|
|
174
|
+
color: var(--u-txt-color-weak, #616161);
|
|
170
175
|
}
|
|
171
176
|
:host([checked]) .thumb-unchecked {
|
|
172
177
|
opacity: 0;
|
|
@@ -185,7 +190,7 @@ var styles = css`
|
|
|
185
190
|
|
|
186
191
|
.description {
|
|
187
192
|
margin-top: 0.5em;
|
|
188
|
-
color: var(--u-txt-color-weak, #
|
|
193
|
+
color: var(--u-txt-color-weak, #616161);
|
|
189
194
|
font-size: 0.75em;
|
|
190
195
|
line-height: 1.3;
|
|
191
196
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { UElement } from "../UElement.js";
|
|
2
|
-
import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.
|
|
3
|
-
import __decorate from "../../_virtual/_@oxc-project_runtime@0.
|
|
2
|
+
import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.149.0/helpers/esm/decorateMetadata.js";
|
|
3
|
+
import __decorate from "../../_virtual/_@oxc-project_runtime@0.149.0/helpers/esm/decorate.js";
|
|
4
4
|
import "../button/UButton.js";
|
|
5
5
|
import "../icon/UIcon.js";
|
|
6
6
|
import { styles } from "./UTab.styles.js";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { UElement } from "../UElement.js";
|
|
2
|
-
import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.
|
|
3
|
-
import __decorate from "../../_virtual/_@oxc-project_runtime@0.
|
|
2
|
+
import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.149.0/helpers/esm/decorateMetadata.js";
|
|
3
|
+
import __decorate from "../../_virtual/_@oxc-project_runtime@0.149.0/helpers/esm/decorate.js";
|
|
4
4
|
import { UPanel } from "../panel/UPanel.js";
|
|
5
5
|
import { UTab } from "../tab/UTab.js";
|
|
6
6
|
import { styles } from "./UTabPanel.styles.js";
|
|
@@ -45,7 +45,7 @@ var UTabPanel = class UTabPanel extends UElement {
|
|
|
45
45
|
const enabledTabs = this.tabs.filter((t) => !t.disabled);
|
|
46
46
|
const currentIndex = enabledTabs.indexOf(e.currentTarget);
|
|
47
47
|
if (currentIndex === -1) return;
|
|
48
|
-
let targetIndex
|
|
48
|
+
let targetIndex;
|
|
49
49
|
switch (e.key) {
|
|
50
50
|
case this.isVertical ? "ArrowDown" : "ArrowRight":
|
|
51
51
|
targetIndex = (currentIndex + 1) % enabledTabs.length;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { UElement } from "../UElement.js";
|
|
2
|
-
import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.
|
|
3
|
-
import __decorate from "../../_virtual/_@oxc-project_runtime@0.
|
|
2
|
+
import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.149.0/helpers/esm/decorateMetadata.js";
|
|
3
|
+
import __decorate from "../../_virtual/_@oxc-project_runtime@0.149.0/helpers/esm/decorate.js";
|
|
4
4
|
import "../icon/UIcon.js";
|
|
5
5
|
import { statusIcon } from "../../utilities/statusIcon.js";
|
|
6
6
|
import { styles } from "./UTag.styles.js";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { UElement } from "../UElement.js";
|
|
2
|
-
import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.
|
|
3
|
-
import __decorate from "../../_virtual/_@oxc-project_runtime@0.
|
|
2
|
+
import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.149.0/helpers/esm/decorateMetadata.js";
|
|
3
|
+
import __decorate from "../../_virtual/_@oxc-project_runtime@0.149.0/helpers/esm/decorate.js";
|
|
4
4
|
import { styles } from "./UText.styles.js";
|
|
5
5
|
import { customElement, property } from "lit/decorators.js";
|
|
6
6
|
import { html, literal } from "lit/static-html.js";
|
|
@@ -11,6 +11,11 @@ type TextareaResize = 'none' | 'vertical' | 'horizontal' | 'both' | 'auto';
|
|
|
11
11
|
* @csspart textarea - 실제 텍스트에어리어 요소
|
|
12
12
|
* @csspart counter - 글자 수 표시 영역
|
|
13
13
|
*
|
|
14
|
+
* @cssprop --u-textarea-display - 호스트의 display (기본값: inline-block). 폼/그리드 셀에서
|
|
15
|
+
* 컨테이너 폭을 채우려면 `block`으로 지정한다.
|
|
16
|
+
* @cssprop --u-textarea-width - 호스트의 width (기본값: auto). flex 컨테이너처럼 block만으로는
|
|
17
|
+
* 늘어나지 않는 맥락에서 `100%`로 지정한다.
|
|
18
|
+
*
|
|
14
19
|
* @event input - 입력값이 변경될 때 발생
|
|
15
20
|
* @event change - 값이 확정됐을 때 발생
|
|
16
21
|
*/
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.
|
|
2
|
-
import __decorate from "../../_virtual/_@oxc-project_runtime@0.
|
|
1
|
+
import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.149.0/helpers/esm/decorateMetadata.js";
|
|
2
|
+
import __decorate from "../../_virtual/_@oxc-project_runtime@0.149.0/helpers/esm/decorate.js";
|
|
3
3
|
import { UFormControlElement } from "../UFormControlElement.js";
|
|
4
4
|
import { Locale } from "../../utilities/Locale.js";
|
|
5
5
|
import "../field/UField.js";
|
|
@@ -2,7 +2,10 @@ import { css } from "lit";
|
|
|
2
2
|
//#region src/components/textarea/UTextarea.styles.ts
|
|
3
3
|
var styles = css`
|
|
4
4
|
:host {
|
|
5
|
-
display:
|
|
5
|
+
/* 폼/그리드 셀에서 컨테이너 폭을 채우려면 소비자가 --u-textarea-display: block 을 준다.
|
|
6
|
+
flex 컨테이너처럼 block 만으로 늘어나지 않는 맥락을 위해 width 경로도 함께 연다. */
|
|
7
|
+
display: var(--u-textarea-display, inline-block);
|
|
8
|
+
width: var(--u-textarea-width, auto);
|
|
6
9
|
color: var(--u-txt-color, #212121);
|
|
7
10
|
font-size: inherit;
|
|
8
11
|
font-family: var(--u-font-base);
|
|
@@ -117,7 +120,7 @@ var styles = css`
|
|
|
117
120
|
word-wrap: break-word;
|
|
118
121
|
}
|
|
119
122
|
textarea::placeholder {
|
|
120
|
-
color: var(--u-txt-color-weak, #
|
|
123
|
+
color: var(--u-txt-color-weak, #616161);
|
|
121
124
|
}
|
|
122
125
|
textarea:disabled {
|
|
123
126
|
cursor: not-allowed;
|
|
@@ -155,7 +158,7 @@ var styles = css`
|
|
|
155
158
|
.counter {
|
|
156
159
|
margin-top: 0.25em;
|
|
157
160
|
text-align: right;
|
|
158
|
-
color: var(--u-txt-color-weak, #
|
|
161
|
+
color: var(--u-txt-color-weak, #616161);
|
|
159
162
|
font-size: 0.75em;
|
|
160
163
|
line-height: 1.2;
|
|
161
164
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.
|
|
2
|
-
import __decorate from "../../_virtual/_@oxc-project_runtime@0.
|
|
1
|
+
import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.149.0/helpers/esm/decorateMetadata.js";
|
|
2
|
+
import __decorate from "../../_virtual/_@oxc-project_runtime@0.149.0/helpers/esm/decorate.js";
|
|
3
3
|
import { UFloatingElement } from "../UFloatingElement.js";
|
|
4
4
|
import { styles } from "./UTooltip.styles.js";
|
|
5
5
|
import { html } from "lit";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { UElement } from "../UElement.js";
|
|
2
|
-
import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.
|
|
3
|
-
import __decorate from "../../_virtual/_@oxc-project_runtime@0.
|
|
2
|
+
import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.149.0/helpers/esm/decorateMetadata.js";
|
|
3
|
+
import __decorate from "../../_virtual/_@oxc-project_runtime@0.149.0/helpers/esm/decorate.js";
|
|
4
4
|
import { UTreeItem } from "../tree-item/UTreeItem.js";
|
|
5
5
|
import { styles } from "./UTree.styles.js";
|
|
6
6
|
import { html } from "lit";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { UElement } from "../UElement.js";
|
|
2
|
-
import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.
|
|
3
|
-
import __decorate from "../../_virtual/_@oxc-project_runtime@0.
|
|
2
|
+
import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.149.0/helpers/esm/decorateMetadata.js";
|
|
3
|
+
import __decorate from "../../_virtual/_@oxc-project_runtime@0.149.0/helpers/esm/decorate.js";
|
|
4
4
|
import "../spinner/USpinner.js";
|
|
5
5
|
import "../icon/UIcon.js";
|
|
6
6
|
import { styles } from "./UTreeItem.styles.js";
|