mendraw
Mendix widget .mpk file bindings for Gleam, compatible with redraw.
.mpk 파일을 파싱하여 Gleam/redraw 프로젝트에서 바로 사용할 수 있는 위젯 바인딩을 자동 생성한다.
Pluggable(React) 위젯과 Classic(Dojo) 위젯 모두 지원한다.
설치
gleam add mendraw@1
사용법
1. .mpk 파일 배치
방법 A: gleam.toml로 자동 다운로드 (추천)
[tools.mendraw.widgets.Charts]
version = "3.0.0"
# s3_id = "com/..." ← 있으면 인증 없이 직접 다운로드
방법 B: .mpk를 widgets/에 수동 배치
widgets/
Charts.mpk
Switch.mpk
CameraWidget.mpk
2. 바인딩 생성
gleam run -m mendraw/install
TOML 위젯 다운로드 + src/widgets/에 위젯별 .gleam 파일 생성 + 빌드 경로에 widget_ffi.mjs(컴포넌트 레지스트리) 생성.
src/widgets/
area_chart.gleam
bar_chart.gleam
switch.gleam
...
3. 위젯 사용
Pluggable 위젯
생성된 바인딩 파일을 import하여 render(props)를 호출하거나,
mendraw/widget + mendraw/interop로 직접 조립할 수 있다.
import mendraw/widget
import mendraw/interop
import mendraw/mendix.{type JsProps}
import redraw.{type Element}
pub fn my_component(props: JsProps) -> Element {
let value = mendix.get_prop_required(props, "textAttr")
let comp = widget.component("Switch")
interop.component_el(comp, [
widget.prop("caption", "제목"),
widget.editable_prop("textAttr", value, "표시값", set_value),
widget.action_prop("onClick", handler),
], [])
}
Classic (Dojo) 위젯
import mendraw/classic
classic.render("CameraWidget.widget.CameraWidget", [
#("mfToExecute", classic.to_dynamic(mf_value)),
#("preferRearCamera", classic.to_dynamic(True)),
])
4. Mendix 타입 활용
생성된 바인딩에서 받는 Mendix 값들을 mendraw/mendix/* 모듈로 다룬다.
import mendraw/mendix
import mendraw/mendix/editable_value.{type EditableValue}
import mendraw/mendix/action
// EditableValue 읽기/쓰기
let display = editable_value.display_value(text_attr)
let is_editable = editable_value.is_editable(text_attr)
editable_value.set_text_value(text_attr, "새 값")
// Option(ActionValue) 실행
action.execute_action(on_click)
// CSS 클래스 조건부 조합
let class = mendix.cx([
#("active", is_selected),
#("disabled", !is_editable),
])
데이터 소스와 필터:
import mendraw/mendix/list_value
import mendraw/mendix/list_attribute
import mendraw/mendix/filter
// ListValue 페이지네이션
list_value.set_offset(data_source, 20)
list_value.set_limit(data_source, 10)
// 필터 조건 구성
let cond = filter.and_([
filter.contains(filter.attribute("Name"), filter.literal("검색어")),
filter.greater_than(filter.attribute("Age"), filter.literal(18)),
])
list_value.set_filter(data_source, option.Some(cond))
5. Marketplace에서 위젯 다운로드
Mendix Marketplace에서 위젯을 검색하고 다운로드할 수 있는 TUI를 제공한다.
gleam run -m mendraw/marketplace
.env 파일에 Mendix Personal Access Token이 필요하다.
MENDIX_PAT=your_personal_access_token
PAT는 Mendix Portal → Settings → Personal Access Tokens에서 발급한다 (scope: mx:marketplace-content:read).
다운로드한 위젯은 build/widgets/에 캐시되고 gleam.toml에 자동 추가된다. 완료 후 자동으로 바인딩이 생성된다.
모듈 구조
코어
| 모듈 | 설명 |
|---|---|
mendraw/install | 진입점 — gleam run -m mendraw/install |
mendraw/cmd | generate_widget_bindings, resolve_toml_widgets, download_to_cache, write_widget_toml, file_exists API |
mendraw/mendix | JsProps, ValueStatus, ObjectItem, prop 접근자, Option 변환, cx CSS 유틸리티 |
mendraw/interop | JsComponent → redraw Element 브릿지 (component_el, component_el_, void_component_el) |
mendraw/widget | 위젯 컴포넌트 조회 + prop 래핑 (prop, editable_prop, action_prop) |
mendraw/classic | Classic(Dojo) 위젯 React 래퍼 (render, render_with_class) |
Mendix 타입 (mendraw/mendix/*)
Mendix Pluggable Widget API의 타입을 Gleam opaque type으로 래핑한다.
| 모듈 | 타입 | 설명 |
|---|---|---|
mendraw/mendix/action | ActionValue | 실행 가능한 액션 (마이크로플로우, 나노플로우) |
mendraw/mendix/dynamic_value | DynamicValue | 읽기 전용 동적 값 (expression 속성) |
mendraw/mendix/editable_value | EditableValue | 편집 가능한 값 (텍스트, 숫자, 날짜 등) |
mendraw/mendix/list_value | ListValue | 데이터 소스 객체 목록 (페이지네이션, 정렬, 필터) |
mendraw/mendix/list_attribute | ListAttributeValue, ListActionValue, ListExpressionValue, ListWidgetValue | ListValue 아이템별 접근자 |
mendraw/mendix/filter | FilterCondition, ValueExpression | 필터 조건 빌더 (and/or/not, 비교, 문자열 검색, 날짜 비교) |
mendraw/mendix/reference | ReferenceValue | 단일 연관 관계 |
mendraw/mendix/reference_set | ReferenceSetValue | 다중 연관 관계 |
mendraw/mendix/selection | SelectionSingleValue, SelectionMultiValue | 단일/다중 선택 |
mendraw/mendix/formatter | ValueFormatter | 값 포맷팅/파싱 |
mendraw/mendix/decimal | Decimal | Big.js 래퍼 (경계 변환 전용) |
mendraw/mendix/date | JsDate | JS Date 래퍼 (생성, 변환, 접근자) |
mendraw/mendix/icon | WebIcon | 아이콘 (Glyph, Image, IconFont) |
mendraw/mendix/file | FileValue, WebImage | 파일 및 이미지 속성 |
Marketplace
| 모듈 | 설명 |
|---|---|
mendraw/marketplace | Mendix Marketplace 위젯 검색·다운로드 TUI (TTY + 프롬프트 폴백) |
mendraw/marketplace/ui | Marketplace TUI 스타일링 출력 함수 |
의존성
- gleam_stdlib — 표준 라이브러리
- gleam_javascript — JS 타겟 유틸리티
- redraw — React 바인딩 (위젯 렌더링)
- redraw_dom — DOM 속성/이벤트
- etch — 터미널 TUI (Marketplace CLI)
라이선스
이 프로젝트는 Blue Oak Model License 1.0.0 하에 배포된다.
glendix 연동
glendix 프로젝트에서 mendraw를 의존성으로 추가하면 MPK 처리를 위임할 수 있다.
// glendix/install.gleam
import mendraw/cmd as mendraw_cmd
pub fn main() {
cmd.exec(cmd.detect_install_command())
cmd.generate_bindings()
mendraw_cmd.generate_widget_bindings()
}