create-mendix-widget-gleam 1.1.3 → 2.0.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/README.md CHANGED
@@ -27,7 +27,10 @@ my-widget/
27
27
  editor_preview.gleam # Studio Pro 디자인 뷰 미리보기
28
28
  components/
29
29
  hello_world.gleam # Hello World 공유 컴포넌트
30
- gleam.toml # Gleam 프로젝트 설정 (glendix >= 1.2.0 의존성 포함)
30
+ widgets/ # .mpk 위젯 파일 (glendix/widget로 바인딩)
31
+ bindings.json # 외부 React 컴포넌트 바인딩 설정
32
+ package.json # npm 의존성 (React, 외부 라이브러리 등)
33
+ gleam.toml # Gleam 프로젝트 설정 (glendix >= 2.0.0 의존성 포함)
31
34
  CLAUDE.md # AI 어시스턴트용 프로젝트 컨텍스트
32
35
  ```
33
36
 
@@ -46,8 +49,8 @@ gleam run -m glendix/build # 프로덕션 빌드 (.mpk 생성)
46
49
 
47
50
  생성된 프로젝트는 [glendix](https://hexdocs.pm/glendix/) Hex 패키지를 의존성으로 사용한다. glendix가 React 원시 함수와 Mendix Pluggable Widget API 전체에 대한 타입 안전한 Gleam 바인딩을 제공한다:
48
51
 
49
- - **React** — `react`, `react/prop`, `react/hook`, `react/event`, `react/html`
50
- - **Mendix** — `mendix`, `mendix/editable_value`, `mendix/action`, `mendix/list_value`, `mendix/selection`, `mendix/reference`, `mendix/date`, `mendix/big`, `mendix/filter` 등
52
+ - **React** — `react`, `react/attribute`, `react/hook`, `react/event`, `react/html`, `react/svg`, `react/svg_attribute`, `binding`, `widget`
53
+ - **Mendix** — `mendix`, `mendix/editable_value`, `mendix/action`, `mendix/list_value`, `mendix/selection`, `mendix/reference`, `mendix/reference_set`, `mendix/date`, `mendix/big`, `mendix/filter` 등
51
54
 
52
55
  ## 라이선스
53
56
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-mendix-widget-gleam",
3
- "version": "1.1.3",
3
+ "version": "2.0.0",
4
4
  "description": "Scaffold a Mendix Pluggable Widget powered by Gleam",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
package/src/index.mjs CHANGED
@@ -117,10 +117,10 @@ export async function main(args) {
117
117
  console.error(` ${CYAN}gleam build --target javascript${RESET}\n`);
118
118
  }
119
119
 
120
- // 의존성 설치
121
- console.log(`\n${BOLD}의존성 설치 중...${RESET}\n`);
120
+ // 의존성 설치 (사용자가 선택한 패키지 매니저 사용)
121
+ console.log(`\n${BOLD}의존성 설치 중... (${pm})${RESET}\n`);
122
122
  try {
123
- execSync("gleam run -m glendix/install", {
123
+ execSync(pmConfig.install, {
124
124
  cwd: targetDir,
125
125
  stdio: "inherit",
126
126
  });
@@ -129,7 +129,7 @@ export async function main(args) {
129
129
  console.error(
130
130
  `\n${YELLOW}⚠ 의존성 설치 실패. 프로젝트 디렉토리에서 직접 실행하세요:${RESET}`,
131
131
  );
132
- console.error(` ${CYAN}gleam run -m glendix/install${RESET}\n`);
132
+ console.error(` ${CYAN}${pmConfig.install}${RESET}\n`);
133
133
  }
134
134
 
135
135
  // 프로덕션 빌드
@@ -192,6 +192,9 @@ src/
192
192
  package.xml # Mendix 패키지 매니페스트
193
193
  ui/
194
194
  ${names.pascalCase}.css # 위젯 스타일시트
195
+ widgets/ # .mpk 위젯 파일 (glendix/widget로 바인딩)
196
+ bindings.json # 외부 React 컴포넌트 바인딩 설정
197
+ package.json # npm 의존성 (React, 외부 라이브러리 등)
195
198
  gleam.toml # Gleam 프로젝트 설정 (glendix 의존성 포함)
196
199
  docs/
197
200
  gleam_language_tour.md # Gleam 언어 레퍼런스
@@ -231,8 +234,8 @@ gleam format # Gleam 코드 포맷팅
231
234
 
232
235
  \`docs/glendix_guide.md\` 파일에 glendix 패키지의 사용법이 수록되어 있다. 주요 내용:
233
236
  - 프로젝트 설정 및 첫 번째 위젯 만들기
234
- - 핵심 개념: opaque 타입, undefined ↔ Option 변환, 파이프라인 API
235
- - React 바인딩: 엘리먼트 생성, Props 빌더, HTML 태그 함수, Hooks, 이벤트 처리, 조건부/리스트 렌더링, 스타일
237
+ - 핵심 개념: opaque 타입, undefined ↔ Option 변환, Attribute 리스트 API
238
+ - React 바인딩: 엘리먼트 생성, Attribute 리스트, HTML 태그 함수, Hooks, 이벤트 처리, 조건부/리스트 렌더링, 스타일, 외부 React 컴포넌트 바인딩, .mpk 위젯 바인딩
236
239
  - Mendix 바인딩: Props 접근, ValueStatus, EditableValue, ActionValue, DynamicValue, ListValue, ListAttribute, Selection, Reference, Filter, JsDate, Big 등
237
240
  - 실전 패턴: 폼 입력 위젯, 데이터 테이블, 검색 가능 리스트, 컴포넌트 합성
238
241
  - 트러블슈팅
@@ -240,12 +243,15 @@ gleam format # Gleam 코드 포맷팅
240
243
  ## glendix Modules
241
244
 
242
245
  React:
243
- - \`glendix/react\` — 핵심 타입 + createElement + fragment/text/none + 조건부 렌더링
244
- - \`glendix/react/prop\` — Props 파이프라인 빌더
245
- - \`glendix/react/hook\` — React Hooks (useState, useEffect 등)
246
- - \`glendix/react/event\` — 이벤트 타입 + 추출
247
- - \`glendix/react/html\` — HTML 태그 편의 함수
246
+ - \`glendix/react\` — 핵심 타입 + element/element_/void_element/component_el + fragment/text/none + 조건부 렌더링 + define_component/memo/Context
247
+ - \`glendix/react/attribute\` — Attribute 리스트 API (90+ HTML 속성 함수)
248
+ - \`glendix/react/hook\` — React Hooks (useState, useEffect, useMemo, useCallback, useRef 등)
249
+ - \`glendix/react/event\` — 15개 이벤트 타입 + 148+ 핸들러 Attribute + 67+ 접근자
250
+ - \`glendix/react/html\` — 75+ HTML 태그 편의 함수
251
+ - \`glendix/react/svg\` — 57 SVG 요소 편의 함수
252
+ - \`glendix/react/svg_attribute\` — 97+ SVG 전용 속성 함수
248
253
  - \`glendix/binding\` — 외부 React 컴포넌트 바인딩
254
+ - \`glendix/widget\` — .mpk 위젯 컴포넌트 바인딩
249
255
 
250
256
  Mendix:
251
257
  - \`glendix/mendix\` — \`ValueStatus\`, \`ObjectItem\`, Props 접근자
@@ -255,7 +261,8 @@ Mendix:
255
261
  - \`glendix/mendix/list_value\` — 리스트 데이터 + 정렬/필터
256
262
  - \`glendix/mendix/list_attribute\` — 리스트 아이템별 접근
257
263
  - \`glendix/mendix/selection\` — 단일/다중 선택
258
- - \`glendix/mendix/reference\` — 참조 관계
264
+ - \`glendix/mendix/reference\` — 단일 연관 참조
265
+ - \`glendix/mendix/reference_set\` — 다중 연관 참조
259
266
  - \`glendix/mendix/date\` — JS Date 래퍼
260
267
  - \`glendix/mendix/big\` — Big.js 고정밀 십진수 래퍼
261
268
  - \`glendix/mendix/file\` — 파일/이미지
@@ -288,6 +295,44 @@ async function generateReadme(targetDir, names, pm, pmConfig) {
288
295
 
289
296
  Gleam 언어로 작성된 Mendix Pluggable Widget.
290
297
 
298
+ ## 핵심 원리
299
+
300
+ Gleam 함수 \`fn(JsProps) -> ReactElement\`는 React 함수형 컴포넌트와 동일한 시그니처다. glendix가 React 원시 함수와 Mendix 런타임 타입 접근자를 타입 안전하게 제공하므로, 위젯 프로젝트에서는 비즈니스 로직에만 집중하면 된다.
301
+
302
+ \`\`\`gleam
303
+ // src/${names.snakeCase}.gleam
304
+ import glendix/mendix
305
+ import glendix/react.{type JsProps, type ReactElement}
306
+ import glendix/react/attribute
307
+ import glendix/react/html
308
+
309
+ pub fn widget(props: JsProps) -> ReactElement {
310
+ let sample_text = mendix.get_string_prop(props, "sampleText")
311
+ html.div([attribute.class("widget-hello-world")], [
312
+ react.text("Hello " <> sample_text),
313
+ ])
314
+ }
315
+ \`\`\`
316
+
317
+ Mendix 복합 타입도 Gleam에서 타입 안전하게 사용할 수 있다:
318
+
319
+ \`\`\`gleam
320
+ import glendix/mendix
321
+ import glendix/mendix/editable_value
322
+ import glendix/mendix/action
323
+
324
+ pub fn widget(props: JsProps) -> ReactElement {
325
+ // EditableValue 접근
326
+ let name_attr: EditableValue = mendix.get_prop_required(props, "name")
327
+ let display = editable_value.display_value(name_attr)
328
+
329
+ // ActionValue 실행
330
+ let on_save: Option(ActionValue) = mendix.get_prop(props, "onSave")
331
+ action.execute_action(on_save)
332
+ // ...
333
+ }
334
+ \`\`\`
335
+
291
336
  ## 시작하기
292
337
 
293
338
  ### 사전 요구사항
@@ -338,10 +383,109 @@ src/
338
383
  components/
339
384
  hello_world.gleam # Hello World 공유 컴포넌트
340
385
  ${names.pascalCase}.xml # 위젯 속성 정의
386
+ widgets/ # .mpk 위젯 파일 (glendix/widget로 바인딩)
387
+ bindings.json # 외부 React 컴포넌트 바인딩 설정
388
+ package.json # npm 의존성 (React, 외부 라이브러리 등)
341
389
  \`\`\`
342
390
 
343
391
  React/Mendix FFI 바인딩은 [glendix](https://hexdocs.pm/glendix/) Hex 패키지로 제공됩니다.
344
392
 
393
+ ## 외부 React 컴포넌트 사용
394
+
395
+ npm 패키지로 제공되는 React 컴포넌트 라이브러리를 \`.mjs\` FFI 파일 작성 없이 순수 Gleam에서 사용할 수 있다.
396
+
397
+ ### 1단계: npm 패키지 설치
398
+
399
+ \`\`\`bash
400
+ ${pm === "npm" ? "npm install" : pm === "yarn" ? "yarn add" : pm === "pnpm" ? "pnpm add" : "bun add"} recharts
401
+ \`\`\`
402
+
403
+ ### 2단계: \`bindings.json\` 작성
404
+
405
+ 프로젝트 루트에 \`bindings.json\`을 생성하고, 사용할 컴포넌트를 등록한다:
406
+
407
+ \`\`\`json
408
+ {
409
+ "recharts": {
410
+ "components": ["PieChart", "Pie", "Cell", "Tooltip", "ResponsiveContainer"]
411
+ }
412
+ }
413
+ \`\`\`
414
+
415
+ ### 3단계: 바인딩 생성
416
+
417
+ \`\`\`bash
418
+ gleam run -m glendix/install
419
+ \`\`\`
420
+
421
+ \`binding_ffi.mjs\`가 자동 생성된다. 이후 \`gleam run -m glendix/build\` 등 빌드 시에도 자동 갱신된다.
422
+
423
+ ### 4단계: Gleam에서 사용
424
+
425
+ \`\`\`gleam
426
+ import glendix/binding
427
+ import glendix/react.{type ReactElement}
428
+ import glendix/react/attribute.{type Attribute}
429
+
430
+ fn m() { binding.module("recharts") }
431
+
432
+ pub fn pie_chart(attrs: List(Attribute), children: List(ReactElement)) -> ReactElement {
433
+ react.component_el(binding.resolve(m(), "PieChart"), attrs, children)
434
+ }
435
+
436
+ pub fn tooltip(attrs: List(Attribute)) -> ReactElement {
437
+ react.void_component_el(binding.resolve(m(), "Tooltip"), attrs)
438
+ }
439
+ \`\`\`
440
+
441
+ \`html.div\`와 동일한 호출 패턴으로 외부 React 컴포넌트를 사용할 수 있다.
442
+
443
+ ## .mpk 위젯 컴포넌트 사용
444
+
445
+ \`widgets/\` 디렉토리에 \`.mpk\` 파일(Mendix 위젯 빌드 결과물)을 배치하면, 다른 위젯 안에서 기존 Mendix 위젯을 React 컴포넌트로 렌더링할 수 있다.
446
+
447
+ ### 1단계: \`.mpk\` 파일 배치
448
+
449
+ \`\`\`
450
+ 프로젝트 루트/
451
+ ├── widgets/
452
+ │ ├── Switch.mpk
453
+ │ └── Badge.mpk
454
+ ├── src/
455
+ └── gleam.toml
456
+ \`\`\`
457
+
458
+ ### 2단계: 바인딩 생성
459
+
460
+ \`\`\`bash
461
+ gleam run -m glendix/install
462
+ \`\`\`
463
+
464
+ 실행 시 다음이 자동 처리된다:
465
+ - \`.mpk\`에서 \`.mjs\`/\`.css\`를 추출하고 \`widget_ffi.mjs\`가 생성된다
466
+ - \`.mpk\` XML의 \`<property>\` 정의가 부모 위젯 XML에 자동 주입된다
467
+
468
+ ### 3단계: Gleam에서 사용
469
+
470
+ \`\`\`gleam
471
+ import glendix/mendix
472
+ import glendix/widget
473
+ import glendix/react
474
+ import glendix/react/attribute
475
+
476
+ // props에서 자동 주입된 속성을 읽어 위젯에 전달
477
+ let boolean_attr = mendix.get_prop_required(props, "booleanAttribute")
478
+ let action = mendix.get_prop_required(props, "action")
479
+
480
+ let switch_comp = widget.component("Switch")
481
+ react.component_el(switch_comp, [
482
+ attribute.attribute("booleanAttribute", boolean_attr),
483
+ attribute.attribute("action", action),
484
+ ], [])
485
+ \`\`\`
486
+
487
+ 위젯 이름은 \`.mpk\` 내부 XML의 \`<name>\` 값(PascalCase)을, property key는 \`.mpk\` XML의 원본 key를 그대로 사용한다.
488
+
345
489
  ## 기술 스택
346
490
 
347
491
  - **Gleam** → JavaScript 컴파일