@lumir-company/editor 0.4.14 → 0.4.15

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/style.css CHANGED
@@ -1,6 +1,18 @@
1
- @import "@blocknote/core/fonts/inter.css";
2
- @import "@blocknote/mantine/style.css";
3
- @import "@blocknote/react/style.css";
1
+ @import '@blocknote/core/fonts/inter.css';
2
+ @import '@blocknote/mantine/style.css';
3
+ @import '@blocknote/react/style.css';
4
+
5
+ /* Pretendard 한글 글꼴 (가변 폰트, swap).
6
+ @import url()은 번들 시 @import 순서 규칙을 위반해 사용 불가 → @font-face로 로드.
7
+ 호스트 앱이 Pretendard를 자체 로드한다면 이 블록은 제거해도 된다. */
8
+ @font-face {
9
+ font-family: 'Pretendard';
10
+ font-weight: 100 900;
11
+ font-style: normal;
12
+ font-display: swap;
13
+ src: url('https://cdn.jsdelivr.net/npm/pretendard@1.3.9/dist/web/variable/woff2/PretendardVariable.woff2')
14
+ format('woff2-variations');
15
+ }
4
16
 
5
17
  .lumirEditor {
6
18
  width: 100%;
@@ -8,6 +20,15 @@
8
20
  min-width: 200px;
9
21
  overflow: visible; /* 슬래시 메뉴가 컨테이너를 넘어서 표시되도록 변경 */
10
22
  background-color: #ffffff;
23
+ /* 에디터 전체(본문·툴바·인-DOM 드롭다운) 한글 글꼴 Pretendard */
24
+ font-family:
25
+ 'Pretendard',
26
+ 'Noto Sans KR',
27
+ -apple-system,
28
+ BlinkMacSystemFont,
29
+ 'Segoe UI',
30
+ 'Roboto',
31
+ sans-serif;
11
32
  }
12
33
 
13
34
  /* 에디터 내부 콘텐츠 영역만 스크롤 가능하게 설정 */
@@ -23,6 +44,23 @@
23
44
  .mantine-Popover-dropdown {
24
45
  z-index: 9999 !important;
25
46
  }
47
+
48
+ /* 포털(body)로 빠지는 메뉴/드롭다운에도 Pretendard 적용 */
49
+ .bn-suggestion-menu,
50
+ .bn-slash-menu,
51
+ .mantine-Menu-dropdown,
52
+ .mantine-Popover-dropdown,
53
+ .bn-table-handle-menu,
54
+ .bn-menu-dropdown {
55
+ font-family:
56
+ 'Pretendard',
57
+ 'Noto Sans KR',
58
+ -apple-system,
59
+ BlinkMacSystemFont,
60
+ 'Segoe UI',
61
+ 'Roboto',
62
+ sans-serif;
63
+ }
26
64
  /* 포커스 상태 스타일 - 테두리 없음 */
27
65
  .lumirEditor:focus-within {
28
66
  outline: none;
@@ -36,15 +74,15 @@
36
74
  .lumirEditor .bn-editor,
37
75
  .lumirEditor .bn-inline-content {
38
76
  font-family:
39
- "Pretendard",
40
- "Noto Sans KR",
77
+ 'Pretendard',
78
+ 'Noto Sans KR',
41
79
  -apple-system,
42
80
  BlinkMacSystemFont,
43
- "Segoe UI",
44
- "Roboto",
45
- "Oxygen",
46
- "Ubuntu",
47
- "Cantarell",
81
+ 'Segoe UI',
82
+ 'Roboto',
83
+ 'Oxygen',
84
+ 'Ubuntu',
85
+ 'Cantarell',
48
86
  sans-serif;
49
87
  }
50
88
 
@@ -76,24 +114,24 @@
76
114
  * `p.bn-inline-content`에 명시적으로 14px (`.bn-block-content`에 data-type이 붙음)
77
115
  */
78
116
  .lumirEditor
79
- .bn-block-content[data-content-type="paragraph"]
117
+ .bn-block-content[data-content-type='paragraph']
80
118
  p.bn-inline-content,
81
119
  .lumirEditor
82
- .bn-block-content[data-content-type="numberedListItem"]
120
+ .bn-block-content[data-content-type='numberedListItem']
83
121
  p.bn-inline-content,
84
122
  .lumirEditor
85
- .bn-block-content[data-content-type="bulletListItem"]
123
+ .bn-block-content[data-content-type='bulletListItem']
86
124
  p.bn-inline-content,
87
125
  .lumirEditor
88
- .bn-block-content[data-content-type="checkListItem"]
126
+ .bn-block-content[data-content-type='checkListItem']
89
127
  p.bn-inline-content {
90
128
  font-size: 14px;
91
129
  }
92
130
 
93
131
  /* 마커(번호·불릿)·체크 행 */
94
- .lumirEditor .bn-block-content[data-content-type="numberedListItem"],
95
- .lumirEditor .bn-block-content[data-content-type="bulletListItem"],
96
- .lumirEditor .bn-block-content[data-content-type="checkListItem"] {
132
+ .lumirEditor .bn-block-content[data-content-type='numberedListItem'],
133
+ .lumirEditor .bn-block-content[data-content-type='bulletListItem'],
134
+ .lumirEditor .bn-block-content[data-content-type='checkListItem'] {
97
135
  font-size: 14px;
98
136
  }
99
137
 
@@ -102,7 +140,7 @@
102
140
  }
103
141
 
104
142
  /* File Panel: Embed 탭 미노출 (URL 입력 방식 비활성화) */
105
- .lumirEditor [data-test="embed-tab"] {
143
+ .lumirEditor [data-test='embed-tab'] {
106
144
  display: none !important;
107
145
  }
108
146
 
@@ -114,7 +152,7 @@
114
152
  }
115
153
 
116
154
  /* 우측 정렬 시 빈 블록 placeholder 위치 수정 */
117
- .lumirEditor [data-text-alignment="right"] .bn-inline-content::before {
155
+ .lumirEditor [data-text-alignment='right'] .bn-inline-content::before {
118
156
  position: relative;
119
157
  max-width: 100%;
120
158
  }
@@ -203,12 +241,12 @@
203
241
  padding: 0;
204
242
  }
205
243
 
206
- .lumir-floating-toolbar-wrapper[data-position="sticky"] {
244
+ .lumir-floating-toolbar-wrapper[data-position='sticky'] {
207
245
  position: sticky;
208
246
  top: 0;
209
247
  }
210
248
 
211
- .lumir-floating-toolbar-wrapper[data-position="fixed"] {
249
+ .lumir-floating-toolbar-wrapper[data-position='fixed'] {
212
250
  position: fixed;
213
251
  top: 64px;
214
252
  left: 0;
@@ -743,7 +781,7 @@
743
781
  }
744
782
 
745
783
  .lumir-color-swatch.is-active::after {
746
- content: "";
784
+ content: '';
747
785
  position: absolute;
748
786
  top: 50%;
749
787
  left: 50%;
@@ -989,53 +1027,215 @@
989
1027
  }
990
1028
 
991
1029
  /* 다크 테마 대응 */
992
- [data-color-scheme="dark"] .lumir-link-preview-card,
993
- .bn-container[data-color-scheme="dark"] .lumir-link-preview-card {
1030
+ [data-color-scheme='dark'] .lumir-link-preview-card,
1031
+ .bn-container[data-color-scheme='dark'] .lumir-link-preview-card {
994
1032
  background-color: #292524 !important;
995
1033
  border-color: #44403c !important;
996
1034
  }
997
1035
 
998
- [data-color-scheme="dark"] .lumir-link-preview-card:hover,
999
- .bn-container[data-color-scheme="dark"] .lumir-link-preview-card:hover {
1036
+ [data-color-scheme='dark'] .lumir-link-preview-card:hover,
1037
+ .bn-container[data-color-scheme='dark'] .lumir-link-preview-card:hover {
1000
1038
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3) !important;
1001
1039
  }
1002
1040
 
1003
- [data-color-scheme="dark"] .lumir-link-preview-skeleton,
1004
- .bn-container[data-color-scheme="dark"] .lumir-link-preview-skeleton {
1041
+ [data-color-scheme='dark'] .lumir-link-preview-skeleton,
1042
+ .bn-container[data-color-scheme='dark'] .lumir-link-preview-skeleton {
1005
1043
  background-color: #292524 !important;
1006
1044
  border-color: #44403c !important;
1007
1045
  }
1008
1046
 
1009
- [data-color-scheme="dark"] .lumir-link-preview-error,
1010
- .bn-container[data-color-scheme="dark"] .lumir-link-preview-error {
1047
+ [data-color-scheme='dark'] .lumir-link-preview-error,
1048
+ .bn-container[data-color-scheme='dark'] .lumir-link-preview-error {
1011
1049
  background-color: #292524 !important;
1012
1050
  border-color: #44403c !important;
1013
1051
  }
1014
1052
 
1015
1053
  /* 인용·코드·테이블 본문 14px */
1016
- .lumirEditor .bn-block-content[data-content-type="quote"] p.bn-inline-content,
1017
- .lumirEditor [data-content-type="quote"] blockquote {
1054
+ .lumirEditor .bn-block-content[data-content-type='quote'] p.bn-inline-content,
1055
+ .lumirEditor [data-content-type='quote'] blockquote {
1018
1056
  font-size: 14px;
1019
1057
  }
1020
1058
 
1021
- .lumirEditor .bn-block-content[data-content-type="codeBlock"] pre,
1022
- .lumirEditor .bn-block-content[data-content-type="codeBlock"] pre code {
1059
+ .lumirEditor .bn-block-content[data-content-type='codeBlock'] pre,
1060
+ .lumirEditor .bn-block-content[data-content-type='codeBlock'] pre code {
1023
1061
  font-size: 14px;
1024
1062
  }
1025
1063
 
1026
- .lumirEditor .bn-editor [data-content-type="table"] th,
1027
- .lumirEditor .bn-editor [data-content-type="table"] td,
1028
- .lumirEditor .bn-editor [data-content-type="table"] p.bn-inline-content {
1064
+ .lumirEditor .bn-editor [data-content-type='table'] th,
1065
+ .lumirEditor .bn-editor [data-content-type='table'] td,
1066
+ .lumirEditor .bn-editor [data-content-type='table'] p.bn-inline-content {
1029
1067
  font-size: 14px;
1030
1068
  }
1031
1069
 
1032
1070
  /* 테이블 셀 세로 정렬 (VerticalAlignmentExtension) */
1033
- .lumirEditor .bn-editor [data-content-type="table"] td[data-vertical-alignment="middle"],
1034
- .lumirEditor .bn-editor [data-content-type="table"] th[data-vertical-alignment="middle"] {
1071
+ .lumirEditor
1072
+ .bn-editor
1073
+ [data-content-type='table']
1074
+ td[data-vertical-alignment='middle'],
1075
+ .lumirEditor
1076
+ .bn-editor
1077
+ [data-content-type='table']
1078
+ th[data-vertical-alignment='middle'] {
1035
1079
  vertical-align: middle;
1036
1080
  }
1037
1081
 
1038
- .lumirEditor .bn-editor [data-content-type="table"] td[data-vertical-alignment="bottom"],
1039
- .lumirEditor .bn-editor [data-content-type="table"] th[data-vertical-alignment="bottom"] {
1082
+ .lumirEditor
1083
+ .bn-editor
1084
+ [data-content-type='table']
1085
+ td[data-vertical-alignment='bottom'],
1086
+ .lumirEditor
1087
+ .bn-editor
1088
+ [data-content-type='table']
1089
+ th[data-vertical-alignment='bottom'] {
1040
1090
  vertical-align: bottom;
1041
1091
  }
1092
+
1093
+ /* ==========================================================================
1094
+ Notion 스타일 FOCUS 기반 테이블 gutter/grip (LumirTableHandlesController)
1095
+ - 셀 focus 시: 셀 테두리 하이라이트(파란 보더, 셀을 살짝 감쌈)
1096
+ - 상단(열)·좌측(행): 짧고 두꺼운 회색 gutter 바 / 우측(셀): 작은 파란 앵커
1097
+ - gutter hover 시: 발판 grip 노출 → 클릭 시 드롭다운
1098
+ - active(메뉴 열림/드래그): 발판이 파란 배경 + 흰 점
1099
+ 기본 BlockNote hover 핸들은 tableHandles={false}로 비활성.
1100
+ ========================================================================== */
1101
+
1102
+ /* focus된 셀 테두리 하이라이트 (셀을 ~2px 바깥에서 감싸는 비클릭 오버레이) */
1103
+ .lumirEditor .lumir-tbl-cell-focus {
1104
+ position: absolute;
1105
+ top: 0;
1106
+ left: 0;
1107
+ box-sizing: border-box;
1108
+ border: 2px solid #2383e2;
1109
+ border-radius: 2px;
1110
+ pointer-events: none;
1111
+ z-index: 1;
1112
+ }
1113
+
1114
+ /* gutter wrapper = hover 히트 영역. 보더에 걸쳐 중앙 배치(positioner offset -7). */
1115
+ .lumirEditor .lumir-tbl-gutter-wrap {
1116
+ position: absolute;
1117
+ z-index: 2;
1118
+ cursor: pointer;
1119
+ }
1120
+
1121
+ .lumirEditor .lumir-tbl-gutter-wrap--col {
1122
+ width: 34px;
1123
+ height: 14px;
1124
+ }
1125
+
1126
+ .lumirEditor .lumir-tbl-gutter-wrap--row,
1127
+ .lumirEditor .lumir-tbl-gutter-wrap--cell {
1128
+ width: 14px;
1129
+ height: 34px;
1130
+ }
1131
+
1132
+ /* 기본 노출: 짧고 두꺼운 gutter 바. wrapper가 셀 보더에 중앙 정렬되어 있으므로,
1133
+ gutter를 wrapper 중앙에 두면 "거터 중앙이 셀 보더선 위"에 오도록 걸쳐진다
1134
+ (절반은 셀 안쪽, 절반은 바깥쪽). */
1135
+ .lumirEditor .lumir-tbl-gutter {
1136
+ position: absolute;
1137
+ inset: 0;
1138
+ margin: auto;
1139
+ box-sizing: border-box;
1140
+ background-color: #c0c0c2;
1141
+ transition: opacity 0.1s ease;
1142
+ }
1143
+
1144
+ /* 상(top): 가로 pill — 상단 보더 중앙 */
1145
+ .lumirEditor .lumir-tbl-gutter-wrap--col .lumir-tbl-gutter {
1146
+ width: 14px;
1147
+ height: 4px;
1148
+ border-left: 1px solid #fff;
1149
+ border-right: 1px solid #fff;
1150
+ }
1151
+
1152
+ /* 좌(left): 세로 pill — 좌측 보더 중앙 (Notion도 좌측에 표시) */
1153
+ .lumirEditor .lumir-tbl-gutter-wrap--row .lumir-tbl-gutter {
1154
+ width: 4px;
1155
+ height: 14px;
1156
+ border-top: 1px solid #fff;
1157
+ border-bottom: 1px solid #fff;
1158
+ }
1159
+
1160
+ /* 우(right): Notion의 파란 선택 앵커 — 우측 보더 중앙 */
1161
+ /* 우(right): 셀 우측 보더의 파란 세로 앵커 */
1162
+ .lumirEditor .lumir-tbl-gutter-wrap--cell .lumir-tbl-gutter {
1163
+ width: 4px;
1164
+ height: 14px;
1165
+ background-color: #2383e2;
1166
+ border-top: 1px solid #fff;
1167
+ border-bottom: 1px solid #fff;
1168
+ }
1169
+
1170
+ .lumirEditor .lumir-tbl-gutter-wrap:hover .lumir-tbl-gutter {
1171
+ opacity: 0;
1172
+ }
1173
+
1174
+ /* 발판 grip: 기본 숨김, gutter hover 시 노출 */
1175
+ .lumirEditor .lumir-tbl-grip {
1176
+ position: absolute;
1177
+ inset: 0;
1178
+ display: flex;
1179
+ align-items: center;
1180
+ justify-content: center;
1181
+ opacity: 0;
1182
+ pointer-events: none;
1183
+ cursor: pointer;
1184
+ transition: opacity 0.1s ease;
1185
+ }
1186
+
1187
+ .lumirEditor .lumir-tbl-gutter-wrap:hover .lumir-tbl-grip {
1188
+ opacity: 1;
1189
+ pointer-events: auto;
1190
+ }
1191
+
1192
+ /* 메뉴 열림(active) 동안 발판 유지(마우스가 떠나도) + rest 바 숨김 */
1193
+ .lumirEditor .lumir-tbl-gutter-wrap--active .lumir-tbl-grip {
1194
+ opacity: 1;
1195
+ pointer-events: auto;
1196
+ }
1197
+
1198
+ .lumirEditor .lumir-tbl-gutter-wrap--active .lumir-tbl-gutter {
1199
+ opacity: 0;
1200
+ }
1201
+
1202
+ /* 드롭다운 오픈(active)·드래그 시 발판: 배경·보더 파랑(#2383e2) + 흰 아이콘 */
1203
+ .lumirEditor .lumir-tbl-gutter-wrap--active .bn-table-handle,
1204
+ .lumirEditor .lumir-tbl-gutter-wrap--active .bn-table-cell-handle,
1205
+ .lumirEditor .lumir-tbl-grip .bn-table-handle-dragging {
1206
+ background-color: #2383e2 !important;
1207
+ border-color: #2383e2 !important;
1208
+ color: #fff !important;
1209
+ }
1210
+
1211
+ /* 발판 크기: 너비(11)↓·높이(14) 유지. 상단 발판은 90° 회전이라 너비↓ = 시각적 높이↓.
1212
+ 배경 흰색 + 보더 진하게(#999). */
1213
+ .lumirEditor .lumir-tbl-grip .bn-table-handle,
1214
+ .lumirEditor .lumir-tbl-grip .bn-table-cell-handle {
1215
+ width: 12px;
1216
+ min-width: 12px;
1217
+ height: 16px;
1218
+ padding: 0;
1219
+ border-radius: 3px;
1220
+ cursor: pointer; /* mantine 기본 grab → pointer */
1221
+ background-color: #fff;
1222
+ border: 1px solid #cfcfcf;
1223
+ box-shadow: none; /* mantine 기본 그림자(--bn-shadow-light, 블러처럼 보임) 제거 */
1224
+ }
1225
+
1226
+ /* hover 시에도 흰 배경 유지 (mantine hover 회색 오버라이드) */
1227
+ .lumirEditor .lumir-tbl-grip .bn-table-handle:hover,
1228
+ .lumirEditor .lumir-tbl-grip .bn-table-cell-handle:hover {
1229
+ background-color: #fff;
1230
+ }
1231
+
1232
+ .lumirEditor .lumir-tbl-grip .bn-table-handle svg {
1233
+ width: 12px;
1234
+ height: 12px;
1235
+ margin-inline: 0;
1236
+ }
1237
+
1238
+ .lumirEditor .lumir-tbl-grip .bn-table-cell-handle svg {
1239
+ width: 12px;
1240
+ height: 12px;
1241
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lumir-company/editor",
3
- "version": "0.4.14",
3
+ "version": "0.4.15",
4
4
  "private": false,
5
5
  "description": "Image-only BlockNote rich text editor with S3 upload, customizable filename transforms, UUID support, and loading spinner",
6
6
  "keywords": [
@@ -16,6 +16,7 @@
16
16
  "filename-transform",
17
17
  "uuid",
18
18
  "file-upload",
19
+ "table",
19
20
  "lumir"
20
21
  ],
21
22
  "main": "dist/index.js",
@@ -70,7 +71,8 @@
70
71
  "dependencies": {
71
72
  "@blocknote/core": "^0.35.0",
72
73
  "@blocknote/react": "^0.35.0",
73
- "@blocknote/mantine": "^0.35.0"
74
+ "@blocknote/mantine": "^0.35.0",
75
+ "@floating-ui/react": "^0.26.28"
74
76
  },
75
77
  "devDependencies": {
76
78
  "typescript": "^5.4.0",