@iyulab/enterprise 0.6.0 → 0.7.1
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/dist/FormSection.d.ts +9 -0
- package/dist/index.js +18 -9
- package/dist/styles/preset.css +142 -0
- package/package.json +11 -4
package/dist/FormSection.d.ts
CHANGED
|
@@ -2,6 +2,15 @@ import { CSSProperties, ReactNode } from 'react';
|
|
|
2
2
|
/**
|
|
3
3
|
* L2 폼 블록 — 제목이 붙은 필드 묶음.
|
|
4
4
|
*
|
|
5
|
+
* 🔴**제목에 `text-transform: uppercase` 와 `letter-spacing` 을 걸지 않는다**(0.7.0 에서 제거).
|
|
6
|
+
* ⑴ 한글에는 대문자가 없어 `uppercase` 가 **아무 효과가 없고**, 제목에 영문이 섞이면
|
|
7
|
+
* 그것만 커져 오히려 어수선해진다.
|
|
8
|
+
* ⑵ 양수 `letter-spacing` 은 **한글 가독성을 떨어뜨린다** — 라틴 소문자 조판 관례를
|
|
9
|
+
* 그대로 옮기면 안 되는 자리다.
|
|
10
|
+
* ⇒ 위계는 **크기·굵기·색** 세 신호로만 만든다(타입 스케일의 `label` 단).
|
|
11
|
+
* 영문 전용 UI 에서 눈썹 텍스트 느낌이 필요하면 `titleStyle` 로 `--u-text-overline-*`
|
|
12
|
+
* 단을 직접 지정한다 — 그 단은 영문·숫자 라벨을 전제하고 양수 자간을 갖는다.
|
|
13
|
+
*
|
|
5
14
|
* 오버라이드 계약(docs/lob-layers.md §2): 구조는 두고 **children 치환 + prop** 으로 바꾼다.
|
|
6
15
|
* ⚠기본 스타일은 병합 가능한 형태로만 둔다 — 호출자의 `style` 이 뒤에 오므로 필요한
|
|
7
16
|
* 항목만 골라 덮을 수 있다. 인라인으로 굳혀 두면 소비자 CSS 가 이길 수 없어(`!important`
|
package/dist/index.js
CHANGED
|
@@ -5,6 +5,15 @@ import buildQuery from "odata-query";
|
|
|
5
5
|
/**
|
|
6
6
|
* L2 폼 블록 — 제목이 붙은 필드 묶음.
|
|
7
7
|
*
|
|
8
|
+
* 🔴**제목에 `text-transform: uppercase` 와 `letter-spacing` 을 걸지 않는다**(0.7.0 에서 제거).
|
|
9
|
+
* ⑴ 한글에는 대문자가 없어 `uppercase` 가 **아무 효과가 없고**, 제목에 영문이 섞이면
|
|
10
|
+
* 그것만 커져 오히려 어수선해진다.
|
|
11
|
+
* ⑵ 양수 `letter-spacing` 은 **한글 가독성을 떨어뜨린다** — 라틴 소문자 조판 관례를
|
|
12
|
+
* 그대로 옮기면 안 되는 자리다.
|
|
13
|
+
* ⇒ 위계는 **크기·굵기·색** 세 신호로만 만든다(타입 스케일의 `label` 단).
|
|
14
|
+
* 영문 전용 UI 에서 눈썹 텍스트 느낌이 필요하면 `titleStyle` 로 `--u-text-overline-*`
|
|
15
|
+
* 단을 직접 지정한다 — 그 단은 영문·숫자 라벨을 전제하고 양수 자간을 갖는다.
|
|
16
|
+
*
|
|
8
17
|
* 오버라이드 계약(docs/lob-layers.md §2): 구조는 두고 **children 치환 + prop** 으로 바꾼다.
|
|
9
18
|
* ⚠기본 스타일은 병합 가능한 형태로만 둔다 — 호출자의 `style` 이 뒤에 오므로 필요한
|
|
10
19
|
* 항목만 골라 덮을 수 있다. 인라인으로 굳혀 두면 소비자 CSS 가 이길 수 없어(`!important`
|
|
@@ -14,19 +23,19 @@ function FormSection({ title, children, className, style, titleStyle }) {
|
|
|
14
23
|
return /* @__PURE__ */ jsxs("div", {
|
|
15
24
|
className,
|
|
16
25
|
style: {
|
|
17
|
-
marginBottom: "20px",
|
|
26
|
+
marginBottom: "var(--u-space-xl, 20px)",
|
|
18
27
|
...style
|
|
19
28
|
},
|
|
20
29
|
children: [/* @__PURE__ */ jsx("div", {
|
|
21
30
|
style: {
|
|
22
|
-
fontSize: "
|
|
23
|
-
fontWeight:
|
|
24
|
-
|
|
25
|
-
letterSpacing: "0
|
|
31
|
+
fontSize: "var(--u-text-label-size, 13px)",
|
|
32
|
+
fontWeight: "var(--u-text-label-weight, 600)",
|
|
33
|
+
lineHeight: "var(--u-text-label-leading, 1.5)",
|
|
34
|
+
letterSpacing: "var(--u-text-label-tracking, 0)",
|
|
26
35
|
color: "color-mix(in srgb, var(--u-primary-color, #1E88E5) 85%, black)",
|
|
27
|
-
paddingBottom: "6px",
|
|
36
|
+
paddingBottom: "var(--u-space-xs, 6px)",
|
|
28
37
|
borderBottom: "1px solid var(--u-border-color-weak, #EEEEEE)",
|
|
29
|
-
marginBottom: "
|
|
38
|
+
marginBottom: "var(--u-space-sm, 8px)",
|
|
30
39
|
...titleStyle
|
|
31
40
|
},
|
|
32
41
|
children: title
|
|
@@ -34,7 +43,7 @@ function FormSection({ title, children, className, style, titleStyle }) {
|
|
|
34
43
|
style: {
|
|
35
44
|
display: "flex",
|
|
36
45
|
flexDirection: "column",
|
|
37
|
-
gap: "8px"
|
|
46
|
+
gap: "var(--u-space-sm, 8px)"
|
|
38
47
|
},
|
|
39
48
|
children
|
|
40
49
|
})]
|
|
@@ -63,7 +72,7 @@ function FormRow({ children, full, columns = 2, className, style }) {
|
|
|
63
72
|
style: {
|
|
64
73
|
display: "grid",
|
|
65
74
|
gridTemplateColumns: `repeat(${columns}, 1fr)`,
|
|
66
|
-
gap: "8px",
|
|
75
|
+
gap: "var(--u-space-sm, 8px)",
|
|
67
76
|
...style
|
|
68
77
|
},
|
|
69
78
|
children
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* @iyulab/enterprise — **하우스 스타일 프리셋** (이유랩 LOB 앱 기본값)
|
|
3
|
+
* ==========================================================================
|
|
4
|
+
*
|
|
5
|
+
* import '@iyulab/enterprise/styles/preset.css';
|
|
6
|
+
*
|
|
7
|
+
* ⚠**`@iyulab/components` 1.21.0 이상이 필요하다.** 이 파일은 값만 정하고, 그 값을 **읽는
|
|
8
|
+
* 쪽은 컴포넌트**다. 1.20.0 이하에는 타입 스케일·반경 상단 축이 아예 없어서 여기 적은
|
|
9
|
+
* `--u-text-*` 는 **아무도 읽지 않는다** — 에러 없이 절반만 적용된 것처럼 보인다.
|
|
10
|
+
* `peerDependencies` 에 선언해 두었으나 **optional** 이다(프리셋을 쓰지 않는 소비자는
|
|
11
|
+
* `components` 자체가 필요 없다). 즉 버전 불일치는 **경고 없이 조용하다** — 프리셋을
|
|
12
|
+
* 로드했는데 글자 크기가 안 바뀌면 먼저 이 버전을 본다.
|
|
13
|
+
*
|
|
14
|
+
* `@iyulab/components` 가 여는 **토큰 축**에 이유랩의 값을 채운 한 장이다.
|
|
15
|
+
* 축(이름·단 수)은 `components` 소유이고, 이 파일은 **값만** 정한다.
|
|
16
|
+
*
|
|
17
|
+
* ──────────────────────────────────────────────────────────────────────────
|
|
18
|
+
* ★★계약 — 이 세 줄이 이 파일의 전부다.
|
|
19
|
+
* ──────────────────────────────────────────────────────────────────────────
|
|
20
|
+
* ⑴ **선택적 로드다.** 로드하지 않은 소비자는 `components` 의 중립 기본값을 그대로 받는다.
|
|
21
|
+
* `@iyulab/enterprise` 는 공개 패키지이므로 외부 소비자도 이 값을 받게 되지만,
|
|
22
|
+
* **로드하지 않을 자유가 소비자에게 있다.**
|
|
23
|
+
* ⑵ **`--u-*` 값만 덮는다.** 새 클래스·새 선택자를 만들지 않는다. 만들기 시작하면
|
|
24
|
+
* 소비자가 그 선택자와 특이도 싸움을 하게 되고, 그때부터 이 파일은 프리셋이 아니라
|
|
25
|
+
* 또 하나의 프레임워크가 된다. (`tests/preset-contract.test.ts` 가 지킨다.)
|
|
26
|
+
* ⑶ 🔴**층은 «로드 순서»로 선다.** 세 층이 전부 `:root`(0,1,0)이므로 나중에 로드된
|
|
27
|
+
* 것이 이긴다 — 소비자가 이미 통제하는 축이다.
|
|
28
|
+
*
|
|
29
|
+
* 기본값(components/styles/light.css) → 하우스(이 파일) → 소비자 브랜드
|
|
30
|
+
*
|
|
31
|
+
* ⚠**종전 판(0.7.0)은 이 자리를 `:where()` 로 감싸 특이도 0 으로 만들었고,
|
|
32
|
+
* 그래서 «한 줄도 적용되지 않았다».** 의도는 옳았다 — *"프리셋이 소비자 브랜드를
|
|
33
|
+
* 덮으면 안 된다"*. 그러나 특이도 0 은 **이겨야 할 상대(기본값)와 지지 말아야 할
|
|
34
|
+
* 상대(브랜드)를 구분하지 못한다.** 기본 시트가 같은 토큰을 `:root` 로 선언하므로
|
|
35
|
+
* 구조적으로 졌다. 실측: 이 파일의 40선언 중 **기본 시트에 없는 것이 0개** —
|
|
36
|
+
* `:where()` 가 이길 수 있는 자리가 하나도 없었다.
|
|
37
|
+
* ★그리고 **그 실패는 조용했다.** 오류도 경고도 없고, 소비자에게는
|
|
38
|
+
* *"프리셋 값이 우리 값과 우연히 같았나 보다"* 로 보인다.
|
|
39
|
+
*
|
|
40
|
+
* ──────────────────────────────────────────────────────────────────────────
|
|
41
|
+
* 이 프리셋이 정하는 것 / 정하지 않는 것
|
|
42
|
+
* ──────────────────────────────────────────────────────────────────────────
|
|
43
|
+
* 정한다 타이포 스케일 값 · 형태(반경) · 엘리베이션 · 여백 리듬
|
|
44
|
+
* 안 정한다 **중립 램프의 색조(웜/쿨)** — 역할 토큰 다수가 중립에서 파생되므로 램프를
|
|
45
|
+
* 옮기면 대비가 함께 움직인다. 전수 대비 검증을 붙이기 전에는 손대지 않는다.
|
|
46
|
+
* (LOB 화면에서 "낡아 보임"의 지분은 타이포·여백·형태가 훨씬 크다.)
|
|
47
|
+
* 안 정한다 **브랜드 색** — 그것은 소비앱의 몫이다. 프리셋은 브랜드를 갖지 않는다.
|
|
48
|
+
* ========================================================================== */
|
|
49
|
+
|
|
50
|
+
:root {
|
|
51
|
+
/* ==========================================================================
|
|
52
|
+
타이포 — LOB 밀도
|
|
53
|
+
★업무 화면은 한 화면에 담기는 정보량이 곧 생산성이다. 중립 기본값보다 한 단씩
|
|
54
|
+
조밀하게 잡되, **행간은 줄이지 않는다**(한글에서 행간을 줄이면 바로 읽기 어려워진다).
|
|
55
|
+
자간은 큰 제목만 음수이고 나머지는 0 — 한글에 양수 자간을 주지 않는다.
|
|
56
|
+
========================================================================== */
|
|
57
|
+
--u-text-display-size: 24px;
|
|
58
|
+
--u-text-display-weight: 700;
|
|
59
|
+
--u-text-display-leading: 1.4;
|
|
60
|
+
--u-text-display-tracking: -0.02em;
|
|
61
|
+
|
|
62
|
+
--u-text-title-size: 18px;
|
|
63
|
+
--u-text-title-weight: 700;
|
|
64
|
+
--u-text-title-leading: 1.45;
|
|
65
|
+
--u-text-title-tracking: -0.01em;
|
|
66
|
+
|
|
67
|
+
--u-text-subtitle-size: 15px;
|
|
68
|
+
--u-text-subtitle-weight: 600;
|
|
69
|
+
--u-text-subtitle-leading: 1.5;
|
|
70
|
+
--u-text-subtitle-tracking: 0;
|
|
71
|
+
|
|
72
|
+
--u-text-body-size: 14px;
|
|
73
|
+
--u-text-body-weight: 400;
|
|
74
|
+
--u-text-body-leading: 1.6;
|
|
75
|
+
--u-text-body-tracking: 0;
|
|
76
|
+
|
|
77
|
+
/* ★라벨 단이 이 프리셋에서 가장 많이 쓰인다 — 폼 라벨·표 머리행·섹션 제목이 전부
|
|
78
|
+
이 단이다. 한글에 대문자가 없으므로 위계는 **크기·굵기·색** 세 신호로만 만든다. */
|
|
79
|
+
--u-text-label-size: 13px;
|
|
80
|
+
--u-text-label-weight: 600;
|
|
81
|
+
--u-text-label-leading: 1.5;
|
|
82
|
+
--u-text-label-tracking: 0;
|
|
83
|
+
|
|
84
|
+
--u-text-caption-size: 12px;
|
|
85
|
+
--u-text-caption-weight: 400;
|
|
86
|
+
--u-text-caption-leading: 1.5;
|
|
87
|
+
--u-text-caption-tracking: 0;
|
|
88
|
+
|
|
89
|
+
/* ⚠양수 자간은 이 단 하나뿐이고, 이 단은 **영문·숫자 라벨**을 전제한다.
|
|
90
|
+
한글을 넣을 소비자는 `--u-text-overline-tracking: 0` 으로 덮는다. */
|
|
91
|
+
--u-text-overline-size: 11px;
|
|
92
|
+
--u-text-overline-weight: 700;
|
|
93
|
+
--u-text-overline-leading: 1.45;
|
|
94
|
+
--u-text-overline-tracking: 0.06em;
|
|
95
|
+
|
|
96
|
+
/* ==========================================================================
|
|
97
|
+
형태 — 반경
|
|
98
|
+
★컨트롤 단(sm~xl)을 한 단씩 올린다. 중립 기본값(3/4/6/8)은 어떤 값을 골라도
|
|
99
|
+
각진 인상이 되는데, 각짐은 "낡아 보임"에 대한 기여가 큰 축이다.
|
|
100
|
+
면(surface) 단(2xl·3xl)은 중립 기본값과 같다 — 이미 적절하다.
|
|
101
|
+
========================================================================== */
|
|
102
|
+
--u-radius-sm: 4px;
|
|
103
|
+
--u-radius-md: 6px;
|
|
104
|
+
--u-radius-lg: 8px;
|
|
105
|
+
--u-radius-xl: 10px;
|
|
106
|
+
|
|
107
|
+
/* ==========================================================================
|
|
108
|
+
엘리베이션 — 청흑 틴트
|
|
109
|
+
★순수 검정 그림자는 경계에 회색이 낀 것처럼 보인다. 배경의 색조를 살짝 섞은
|
|
110
|
+
어두운 값(`20,20,25`)을 쓰면 같은 세기라도 깨끗하게 떨어진다.
|
|
111
|
+
2겹 구조(지배 + 접촉)는 `components` 가 이미 정했고, 여기서는 **색만** 바꾼다.
|
|
112
|
+
⚠첫 레이어가 지배 레이어라는 배치 규약을 유지한다(`components` 의 elevation 계약).
|
|
113
|
+
========================================================================== */
|
|
114
|
+
--u-shadow-color-weaker: rgba(20, 20, 25, 0.04);
|
|
115
|
+
--u-shadow-color-weak: rgba(20, 20, 25, 0.08);
|
|
116
|
+
--u-shadow-color-normal: rgba(20, 20, 25, 0.10);
|
|
117
|
+
--u-shadow-color-strong: rgba(20, 20, 25, 0.14);
|
|
118
|
+
--u-shadow-color-stronger: rgba(20, 20, 25, 0.20);
|
|
119
|
+
|
|
120
|
+
--u-shadow-sm: 0 1px 3px rgba(20, 20, 25, 0.08), 0 1px 1px rgba(20, 20, 25, 0.04);
|
|
121
|
+
--u-shadow-md: 0 2px 8px rgba(20, 20, 25, 0.10), 0 1px 2px rgba(20, 20, 25, 0.04);
|
|
122
|
+
--u-shadow-lg: 0 6px 16px rgba(20, 20, 25, 0.14), 0 2px 4px rgba(20, 20, 25, 0.05);
|
|
123
|
+
--u-shadow-xl: 0 12px 28px rgba(20, 20, 25, 0.20), 0 2px 6px rgba(20, 20, 25, 0.06);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/*
|
|
127
|
+
* 다크 — 그림자는 **밝기 차**가 주역이다.
|
|
128
|
+
* ★어두운 배경 위의 검은 그림자는 보이지 않는다. 알파를 라이트보다 크게 잡되,
|
|
129
|
+
* 깊이의 대부분은 표면 밝기 차(`--u-bg-color-raised` 등, `components` 소유)가 낸다.
|
|
130
|
+
*/
|
|
131
|
+
:root[theme='dark'] {
|
|
132
|
+
--u-shadow-color-weaker: rgba(0, 0, 0, 0.20);
|
|
133
|
+
--u-shadow-color-weak: rgba(0, 0, 0, 0.28);
|
|
134
|
+
--u-shadow-color-normal: rgba(0, 0, 0, 0.36);
|
|
135
|
+
--u-shadow-color-strong: rgba(0, 0, 0, 0.46);
|
|
136
|
+
--u-shadow-color-stronger: rgba(0, 0, 0, 0.60);
|
|
137
|
+
|
|
138
|
+
--u-shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.28), 0 1px 1px rgba(0, 0, 0, 0.16);
|
|
139
|
+
--u-shadow-md: 0 2px 8px rgba(0, 0, 0, 0.36), 0 1px 2px rgba(0, 0, 0, 0.18);
|
|
140
|
+
--u-shadow-lg: 0 6px 16px rgba(0, 0, 0, 0.46), 0 2px 4px rgba(0, 0, 0, 0.22);
|
|
141
|
+
--u-shadow-xl: 0 12px 28px rgba(0, 0, 0, 0.60), 0 2px 6px rgba(0, 0, 0, 0.30);
|
|
142
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@iyulab/enterprise",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.1",
|
|
4
4
|
"description": "Enterprise utilities and components for iyulab framework",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"enterprise",
|
|
@@ -25,10 +25,11 @@
|
|
|
25
25
|
".": {
|
|
26
26
|
"types": "./dist/index.d.ts",
|
|
27
27
|
"import": "./dist/index.js"
|
|
28
|
-
}
|
|
28
|
+
},
|
|
29
|
+
"./styles/preset.css": "./dist/styles/preset.css"
|
|
29
30
|
},
|
|
30
31
|
"scripts": {
|
|
31
|
-
"build": "vite build",
|
|
32
|
+
"build": "vite build && node scripts/copy-styles.mjs",
|
|
32
33
|
"test": "vitest run"
|
|
33
34
|
},
|
|
34
35
|
"dependencies": {
|
|
@@ -43,6 +44,12 @@
|
|
|
43
44
|
"vitest": "^4.1.10"
|
|
44
45
|
},
|
|
45
46
|
"peerDependencies": {
|
|
46
|
-
"react": ">=18"
|
|
47
|
+
"react": ">=18",
|
|
48
|
+
"@iyulab/components": ">=1.21.0"
|
|
49
|
+
},
|
|
50
|
+
"peerDependenciesMeta": {
|
|
51
|
+
"@iyulab/components": {
|
|
52
|
+
"optional": true
|
|
53
|
+
}
|
|
47
54
|
}
|
|
48
55
|
}
|