create-mendix-widget-gleam 2.0.12 → 2.0.13

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.
@@ -0,0 +1,272 @@
1
+ /**
2
+ * widgets/README.md template — 3 language versions
3
+ */
4
+
5
+ export function generateWidgetsReadmeContent(lang) {
6
+ switch (lang) {
7
+ case "ko":
8
+ return generateKo();
9
+ case "ja":
10
+ return generateJa();
11
+ default:
12
+ return generateEn();
13
+ }
14
+ }
15
+
16
+ function generateEn() {
17
+ return `# widgets/
18
+
19
+ Mendix widget binding directory. Place \`.mpk\` files (Mendix widget build artifacts) in this directory to render existing Mendix widgets as React components from Gleam code.
20
+
21
+ ## Usage
22
+
23
+ ### 1. Place \`.mpk\` files
24
+
25
+ Copy built Mendix widget \`.mpk\` files into this directory:
26
+
27
+ \`\`\`
28
+ widgets/
29
+ ├── Switch.mpk
30
+ ├── Badge.mpk
31
+ └── README.md
32
+ \`\`\`
33
+
34
+ ### 2. Generate bindings
35
+
36
+ \`\`\`bash
37
+ gleam run -m glendix/install
38
+ \`\`\`
39
+
40
+ This automatically:
41
+
42
+ - Extracts \`.mjs\` and \`.css\` from \`.mpk\` and generates \`widget_ffi.mjs\`
43
+ - Parses \`<property>\` definitions from \`.mpk\` XML and generates binding \`.gleam\` files in \`src/widgets/\` (existing files are skipped)
44
+
45
+ ### 3. Review auto-generated bindings
46
+
47
+ For example, placing \`Switch.mpk\` generates \`src/widgets/switch.gleam\`:
48
+
49
+ \`\`\`gleam
50
+ // src/widgets/switch.gleam (auto-generated)
51
+ import glendix/mendix
52
+ import glendix/react.{type JsProps, type ReactElement}
53
+ import glendix/react/attribute
54
+ import glendix/widget
55
+
56
+ /// Render Switch widget - reads properties from props and passes them to the widget
57
+ pub fn render(props: JsProps) -> ReactElement {
58
+ let boolean_attribute = mendix.get_prop_required(props, "booleanAttribute")
59
+ let action = mendix.get_prop_required(props, "action")
60
+
61
+ let comp = widget.component("Switch")
62
+ react.component_el(
63
+ comp,
64
+ [
65
+ attribute.attribute("booleanAttribute", boolean_attribute),
66
+ attribute.attribute("action", action),
67
+ ],
68
+ [],
69
+ )
70
+ }
71
+ \`\`\`
72
+
73
+ - Required/optional properties are distinguished automatically
74
+ - If optional properties exist, \`optional_attr\` helper and \`gleam/option\` import are added automatically
75
+ - Gleam reserved words (e.g. \`type\`) are automatically suffixed with \`_\`
76
+ - Generated files can be freely modified as needed
77
+
78
+ ### 4. Use from Gleam
79
+
80
+ \`\`\`gleam
81
+ import widgets/switch
82
+
83
+ // Inside a component
84
+ switch.render(props)
85
+ \`\`\`
86
+
87
+ ## How it works
88
+
89
+ - \`glendix/widget\` module's \`widget.component("Name")\` imports \`.mpk\` widgets as React components
90
+ - Props are passed via the generic \`attribute.attribute(key, value)\` function
91
+ - Widget names use the \`<name>\` value from the \`.mpk\`'s internal XML, and property keys use the original keys from the \`.mpk\` XML
92
+ - Unlike the \`binding\` module, 1 mpk = 1 component, so \`widget.component("Name")\` imports it in one call
93
+
94
+ ## Notes
95
+
96
+ - After adding/removing \`.mpk\` files, you must run \`gleam run -m glendix/install\` again
97
+ - \`widget_ffi.mjs\` is auto-generated — do not edit it directly
98
+ - Do not write \`.mjs\` FFI files for \`.mpk\` widgets manually — use the \`widgets/\` directory + \`glendix/widget\`
99
+ `;
100
+ }
101
+
102
+ function generateKo() {
103
+ return `# widgets/
104
+
105
+ Mendix 위젯 바인딩 디렉토리. \`.mpk\` 파일(Mendix 위젯 빌드 결과물)을 이 디렉토리에 배치하면, Gleam 코드에서 기존 Mendix 위젯을 React 컴포넌트로 렌더링할 수 있다.
106
+
107
+ ## 사용법
108
+
109
+ ### 1. \`.mpk\` 파일 배치
110
+
111
+ 빌드된 Mendix 위젯의 \`.mpk\` 파일을 이 디렉토리에 복사한다:
112
+
113
+ \`\`\`
114
+ widgets/
115
+ ├── Switch.mpk
116
+ ├── Badge.mpk
117
+ └── README.md
118
+ \`\`\`
119
+
120
+ ### 2. 바인딩 생성
121
+
122
+ \`\`\`bash
123
+ gleam run -m glendix/install
124
+ \`\`\`
125
+
126
+ 실행 시 다음이 자동 처리된다:
127
+
128
+ - \`.mpk\` 내부의 \`.mjs\`와 \`.css\`가 추출되고, \`widget_ffi.mjs\`가 생성된다
129
+ - \`.mpk\` XML의 \`<property>\` 정의를 파싱하여 \`src/widgets/\`에 바인딩 \`.gleam\` 파일이 자동 생성된다 (이미 존재하면 건너뜀)
130
+
131
+ ### 3. 자동 생성된 바인딩 확인
132
+
133
+ 예를 들어 \`Switch.mpk\`를 배치하면 \`src/widgets/switch.gleam\`이 생성된다:
134
+
135
+ \`\`\`gleam
136
+ // src/widgets/switch.gleam (자동 생성)
137
+ import glendix/mendix
138
+ import glendix/react.{type JsProps, type ReactElement}
139
+ import glendix/react/attribute
140
+ import glendix/widget
141
+
142
+ /// Switch 위젯 렌더링 - props에서 속성을 읽어 위젯에 전달
143
+ pub fn render(props: JsProps) -> ReactElement {
144
+ let boolean_attribute = mendix.get_prop_required(props, "booleanAttribute")
145
+ let action = mendix.get_prop_required(props, "action")
146
+
147
+ let comp = widget.component("Switch")
148
+ react.component_el(
149
+ comp,
150
+ [
151
+ attribute.attribute("booleanAttribute", boolean_attribute),
152
+ attribute.attribute("action", action),
153
+ ],
154
+ [],
155
+ )
156
+ }
157
+ \`\`\`
158
+
159
+ - required/optional 속성이 자동 구분된다
160
+ - optional 속성이 있으면 \`optional_attr\` 헬퍼와 \`gleam/option\` import가 자동 추가된다
161
+ - Gleam 예약어(\`type\` 등)는 접미사 \`_\`로 자동 회피된다
162
+ - 생성된 파일은 필요에 따라 자유롭게 수정 가능하다
163
+
164
+ ### 4. Gleam에서 사용
165
+
166
+ \`\`\`gleam
167
+ import widgets/switch
168
+
169
+ // 컴포넌트 내부에서
170
+ switch.render(props)
171
+ \`\`\`
172
+
173
+ ## 동작 원리
174
+
175
+ - \`glendix/widget\` 모듈의 \`widget.component("Name")\`으로 \`.mpk\` 위젯을 React 컴포넌트로 가져온다
176
+ - Props는 \`attribute.attribute(key, value)\` 범용 함수로 전달한다
177
+ - 위젯 이름은 \`.mpk\` 내부 XML의 \`<name>\` 값을, property key는 XML의 원본 key를 그대로 사용한다
178
+ - \`binding\` 모듈과 달리 1 mpk = 1 컴포넌트이므로 \`widget.component("Name")\` 한 번에 가져온다
179
+
180
+ ## 주의사항
181
+
182
+ - \`.mpk\` 파일을 추가/제거한 후에는 반드시 \`gleam run -m glendix/install\`을 다시 실행해야 한다
183
+ - \`widget_ffi.mjs\`는 자동 생성 파일이므로 직접 수정하지 않는다
184
+ - \`.mpk\` 위젯용 \`.mjs\` FFI 파일을 직접 작성하지 않는다 — \`widgets/\` 디렉토리 + \`glendix/widget\`을 사용한다
185
+ `;
186
+ }
187
+
188
+ function generateJa() {
189
+ return `# widgets/
190
+
191
+ Mendixウィジェットバインディングディレクトリ。\`.mpk\`ファイル(Mendixウィジェットビルド成果物)をこのディレクトリに配置すると、Gleamコードから既存のMendixウィジェットをReactコンポーネントとしてレンダリングできる。
192
+
193
+ ## 使い方
194
+
195
+ ### 1. \`.mpk\`ファイルの配置
196
+
197
+ ビルド済みMendixウィジェットの\`.mpk\`ファイルをこのディレクトリにコピーする:
198
+
199
+ \`\`\`
200
+ widgets/
201
+ ├── Switch.mpk
202
+ ├── Badge.mpk
203
+ └── README.md
204
+ \`\`\`
205
+
206
+ ### 2. バインディングの生成
207
+
208
+ \`\`\`bash
209
+ gleam run -m glendix/install
210
+ \`\`\`
211
+
212
+ 実行時に以下が自動処理される:
213
+
214
+ - \`.mpk\`内部の\`.mjs\`と\`.css\`が抽出され、\`widget_ffi.mjs\`が生成される
215
+ - \`.mpk\` XMLの\`<property>\`定義をパースし、\`src/widgets/\`にバインディング\`.gleam\`ファイルが自動生成される(既存ファイルはスキップ)
216
+
217
+ ### 3. 自動生成されたバインディングの確認
218
+
219
+ 例えば\`Switch.mpk\`を配置すると\`src/widgets/switch.gleam\`が生成される:
220
+
221
+ \`\`\`gleam
222
+ // src/widgets/switch.gleam(自動生成)
223
+ import glendix/mendix
224
+ import glendix/react.{type JsProps, type ReactElement}
225
+ import glendix/react/attribute
226
+ import glendix/widget
227
+
228
+ /// Switchウィジェットのレンダリング - propsからプロパティを読み取りウィジェットに渡す
229
+ pub fn render(props: JsProps) -> ReactElement {
230
+ let boolean_attribute = mendix.get_prop_required(props, "booleanAttribute")
231
+ let action = mendix.get_prop_required(props, "action")
232
+
233
+ let comp = widget.component("Switch")
234
+ react.component_el(
235
+ comp,
236
+ [
237
+ attribute.attribute("booleanAttribute", boolean_attribute),
238
+ attribute.attribute("action", action),
239
+ ],
240
+ [],
241
+ )
242
+ }
243
+ \`\`\`
244
+
245
+ - required/optionalプロパティは自動的に区別される
246
+ - optionalプロパティがある場合、\`optional_attr\`ヘルパーと\`gleam/option\` importが自動追加される
247
+ - Gleam予約語(\`type\`等)はサフィックス\`_\`で自動回避される
248
+ - 生成されたファイルは必要に応じて自由に編集できる
249
+
250
+ ### 4. Gleamから使用
251
+
252
+ \`\`\`gleam
253
+ import widgets/switch
254
+
255
+ // コンポーネント内で
256
+ switch.render(props)
257
+ \`\`\`
258
+
259
+ ## 仕組み
260
+
261
+ - \`glendix/widget\`モジュールの\`widget.component("Name")\`で\`.mpk\`ウィジェットをReactコンポーネントとしてインポートする
262
+ - Propsは\`attribute.attribute(key, value)\`汎用関数で渡す
263
+ - ウィジェット名は\`.mpk\`内部XMLの\`<name>\`値を、プロパティキーはXMLの元のキーをそのまま使用する
264
+ - \`binding\`モジュールと異なり1 mpk = 1コンポーネントなので、\`widget.component("Name")\`で一度にインポートする
265
+
266
+ ## 注意事項
267
+
268
+ - \`.mpk\`ファイルを追加/削除した後は必ず\`gleam run -m glendix/install\`を再実行すること
269
+ - \`widget_ffi.mjs\`は自動生成ファイルなので直接編集しない
270
+ - \`.mpk\`ウィジェット用の\`.mjs\` FFIファイルを直接記述しない — \`widgets/\`ディレクトリ + \`glendix/widget\`を使用する
271
+ `;
272
+ }
@@ -1,58 +1,58 @@
1
- # 의존성
2
- node_modules/
3
- .yarn/
4
- .pnp.*
5
-
6
- # 패키지 매니저 lock 파일
7
- package-lock.json
8
- yarn.lock
9
- pnpm-lock.yaml
10
- bun.lockb
11
- bun.lock
12
-
13
- # 패키지 매니저 캐시/설정
14
- .npmrc
15
- .yarnrc
16
- .yarnrc.yml
17
- .pnpmfile.cjs
18
- .npmignore
19
-
20
- # Gleam 컴파일 출력
21
- build/
22
-
23
- # Mendix 위젯 빌드 출력
24
- dist/
25
-
26
- # 환경 변수
27
- .env
28
-
29
- # 로그
30
- *.log
31
-
32
- # OS
33
- .DS_Store
34
-
35
- # IDE
36
- .idea/
37
- .vscode/
38
- *.launch
39
-
40
- # Mendix 테스트 프로젝트
41
- tests/testProject/
42
-
43
- # 테스트 산출물
44
- coverage/
45
- **/e2e/diffs/
46
- **/screenshot/
47
- **/screenshot-results/
48
- **/artifacts/
49
-
50
- # 자동 생성 브릿지 파일 (glendix가 빌드 시 생성/삭제)
51
- src/*.js
52
-
53
- # AI
54
- .claude/
55
-
56
- # Mendix marketplace 캐시/설정
57
- .marketplace-cache/
58
-
1
+ {{I18N:gitignore_deps}}
2
+ node_modules/
3
+ .yarn/
4
+ .pnp.*
5
+
6
+ {{I18N:gitignore_lockfiles}}
7
+ package-lock.json
8
+ yarn.lock
9
+ pnpm-lock.yaml
10
+ bun.lockb
11
+ bun.lock
12
+
13
+ {{I18N:gitignore_pm_cache}}
14
+ .npmrc
15
+ .yarnrc
16
+ .yarnrc.yml
17
+ .pnpmfile.cjs
18
+ .npmignore
19
+
20
+ {{I18N:gitignore_gleam_build}}
21
+ build/
22
+
23
+ {{I18N:gitignore_mendix_build}}
24
+ dist/
25
+
26
+ {{I18N:gitignore_env}}
27
+ .env
28
+
29
+ {{I18N:gitignore_logs}}
30
+ *.log
31
+
32
+ {{I18N:gitignore_os}}
33
+ .DS_Store
34
+
35
+ {{I18N:gitignore_ide}}
36
+ .idea/
37
+ .vscode/
38
+ *.launch
39
+
40
+ {{I18N:gitignore_test_project}}
41
+ tests/testProject/
42
+
43
+ {{I18N:gitignore_test_artifacts}}
44
+ coverage/
45
+ **/e2e/diffs/
46
+ **/screenshot/
47
+ **/screenshot-results/
48
+ **/artifacts/
49
+
50
+ {{I18N:gitignore_bridge}}
51
+ src/*.js
52
+
53
+ {{I18N:gitignore_ai}}
54
+ .claude/
55
+
56
+ {{I18N:gitignore_marketplace}}
57
+ .marketplace-cache/
58
+
@@ -1,11 +1,11 @@
1
- name = "{{SNAKE_CASE}}"
2
- version = "1.0.0"
3
- target = "javascript"
4
-
5
- [javascript]
6
- typescript_declarations = false
7
- runtime = "node"
8
-
9
- [dependencies]
10
- gleam_stdlib = ">= 0.44.0 and < 2.0.0"
11
- glendix = ">= 2.0.11 and < 3.0.0"
1
+ name = "{{SNAKE_CASE}}"
2
+ version = "1.0.0"
3
+ target = "javascript"
4
+
5
+ [javascript]
6
+ typescript_declarations = false
7
+ runtime = "node"
8
+
9
+ [dependencies]
10
+ gleam_stdlib = ">= 0.44.0 and < 2.0.0"
11
+ glendix = ">= 2.0.13 and < 3.0.0"
@@ -1,12 +1,12 @@
1
- // Mendix Pluggable Widget - "Hello World"
2
- // React 함수형 컴포넌트: fn(JsProps) -> ReactElement
3
-
4
- import components/hello_world
5
- import glendix/mendix
6
- import glendix/react.{type JsProps, type ReactElement}
7
-
8
- /// 위젯 메인 함수 - Mendix 런타임이 React 컴포넌트로 호출
9
- pub fn widget(props: JsProps) -> ReactElement {
10
- let sample_text = mendix.get_string_prop(props, "sampleText")
11
- hello_world.render(sample_text)
12
- }
1
+ {{I18N:widget_main_1}}
2
+ {{I18N:widget_main_2}}
3
+
4
+ import components/hello_world
5
+ import glendix/mendix
6
+ import glendix/react.{type JsProps, type ReactElement}
7
+
8
+ {{I18N:widget_main_doc}}
9
+ pub fn widget(props: JsProps) -> ReactElement {
10
+ let sample_text = mendix.get_string_prop(props, "sampleText")
11
+ hello_world.render(sample_text)
12
+ }
@@ -1,13 +1,13 @@
1
- // Hello World 컴포넌트
2
- // 위젯 런타임과 Studio Pro 미리보기에서 공유
3
-
4
- import glendix/react.{type ReactElement}
5
- import glendix/react/attribute
6
- import glendix/react/html
7
-
8
- /// Hello World UI 렌더링
9
- pub fn render(sample_text: String) -> ReactElement {
10
- html.div([attribute.class("widget-hello-world")], [
11
- react.text("Hello " <> sample_text),
12
- ])
13
- }
1
+ {{I18N:hello_world_1}}
2
+ {{I18N:hello_world_2}}
3
+
4
+ import glendix/react.{type ReactElement}
5
+ import glendix/react/attribute
6
+ import glendix/react/html
7
+
8
+ {{I18N:hello_world_doc}}
9
+ pub fn render(sample_text: String) -> ReactElement {
10
+ html.div([attribute.class("widget-hello-world")], [
11
+ react.text("Hello " <> sample_text),
12
+ ])
13
+ }
@@ -1,18 +1,18 @@
1
- // Mendix Studio Pro 속성 패널 설정
2
- // getProperties, check, getPreview 등을 정의
3
-
4
- // 외부 타입 (Mendix가 전달하는 JS 객체)
5
- pub type Values
6
-
7
- pub type Properties
8
-
9
- pub type Target
10
-
11
- /// 속성 패널 설정 - Studio Pro에서 위젯 속성의 가시성을 제어
12
- pub fn get_properties(
13
- _values: Values,
14
- default_properties: Properties,
15
- _target: Target,
16
- ) -> Properties {
17
- default_properties
18
- }
1
+ {{I18N:editor_config_1}}
2
+ {{I18N:editor_config_2}}
3
+
4
+ {{I18N:editor_config_3}}
5
+ pub type Values
6
+
7
+ pub type Properties
8
+
9
+ pub type Target
10
+
11
+ {{I18N:editor_config_doc}}
12
+ pub fn get_properties(
13
+ _values: Values,
14
+ default_properties: Properties,
15
+ _target: Target,
16
+ ) -> Properties {
17
+ default_properties
18
+ }
@@ -1,12 +1,12 @@
1
- // Mendix Studio Pro 디자인 뷰 미리보기
2
- // Studio Pro에서 위젯의 시각적 미리보기를 렌더링
3
-
4
- import components/hello_world
5
- import glendix/mendix
6
- import glendix/react.{type JsProps, type ReactElement}
7
-
8
- /// Studio Pro 디자인 뷰 미리보기 - 위젯의 시각적 표현을 렌더링
9
- pub fn preview(props: JsProps) -> ReactElement {
10
- let sample_text = mendix.get_string_prop(props, "sampleText")
11
- hello_world.render(sample_text)
12
- }
1
+ {{I18N:editor_preview_1}}
2
+ {{I18N:editor_preview_2}}
3
+
4
+ import components/hello_world
5
+ import glendix/mendix
6
+ import glendix/react.{type JsProps, type ReactElement}
7
+
8
+ {{I18N:editor_preview_doc}}
9
+ pub fn preview(props: JsProps) -> ReactElement {
10
+ let sample_text = mendix.get_string_prop(props, "sampleText")
11
+ hello_world.render(sample_text)
12
+ }
@@ -1,82 +1 @@
1
- # widgets/
2
-
3
- Mendix 위젯 바인딩 디렉토리. `.mpk` 파일(Mendix 위젯 빌드 결과물)을 이 디렉토리에 배치하면, Gleam 코드에서 기존 Mendix 위젯을 React 컴포넌트로 렌더링할 수 있다.
4
-
5
- ## 사용법
6
-
7
- ### 1. `.mpk` 파일 배치
8
-
9
- 빌드된 Mendix 위젯의 `.mpk` 파일을 이 디렉토리에 복사한다:
10
-
11
- ```
12
- widgets/
13
- ├── Switch.mpk
14
- ├── Badge.mpk
15
- └── README.md
16
- ```
17
-
18
- ### 2. 바인딩 생성
19
-
20
- ```bash
21
- gleam run -m glendix/install
22
- ```
23
-
24
- 실행 시 다음이 자동 처리된다:
25
-
26
- - `.mpk` 내부의 `.mjs`와 `.css`가 추출되고, `widget_ffi.mjs`가 생성된다
27
- - `.mpk` XML의 `<property>` 정의를 파싱하여 `src/widgets/`에 바인딩 `.gleam` 파일이 자동 생성된다 (이미 존재하면 건너뜀)
28
-
29
- ### 3. 자동 생성된 바인딩 확인
30
-
31
- 예를 들어 `Switch.mpk`를 배치하면 `src/widgets/switch.gleam`이 생성된다:
32
-
33
- ```gleam
34
- // src/widgets/switch.gleam (자동 생성)
35
- import glendix/mendix
36
- import glendix/react.{type JsProps, type ReactElement}
37
- import glendix/react/attribute
38
- import glendix/widget
39
-
40
- /// Switch 위젯 렌더링 - props에서 속성을 읽어 위젯에 전달
41
- pub fn render(props: JsProps) -> ReactElement {
42
- let boolean_attribute = mendix.get_prop_required(props, "booleanAttribute")
43
- let action = mendix.get_prop_required(props, "action")
44
-
45
- let comp = widget.component("Switch")
46
- react.component_el(
47
- comp,
48
- [
49
- attribute.attribute("booleanAttribute", boolean_attribute),
50
- attribute.attribute("action", action),
51
- ],
52
- [],
53
- )
54
- }
55
- ```
56
-
57
- - required/optional 속성이 자동 구분된다
58
- - optional 속성이 있으면 `optional_attr` 헬퍼와 `gleam/option` import가 자동 추가된다
59
- - Gleam 예약어(`type` 등)는 접미사 `_`로 자동 회피된다
60
- - 생성된 파일은 필요에 따라 자유롭게 수정 가능하다
61
-
62
- ### 4. Gleam에서 사용
63
-
64
- ```gleam
65
- import widgets/switch
66
-
67
- // 위젯 컴포넌트 내부에서
68
- switch.render(props)
69
- ```
70
-
71
- ## 동작 원리
72
-
73
- - `glendix/widget` 모듈의 `widget.component("Name")`으로 `.mpk` 위젯을 React 컴포넌트로 가져온다
74
- - Props는 `attribute.attribute(key, value)` 범용 함수로 전달한다
75
- - 위젯 이름은 `.mpk` 내부 XML의 `<name>` 값을, property key는 XML의 원본 key를 그대로 사용한다
76
- - `binding` 모듈과 달리 1 mpk = 1 컴포넌트이므로 `widget.component("Name")` 한 번에 가져온다
77
-
78
- ## 주의사항
79
-
80
- - `.mpk` 파일을 추가/제거한 후에는 반드시 `gleam run -m glendix/install`을 다시 실행해야 한다
81
- - `widget_ffi.mjs`는 자동 생성 파일이므로 직접 수정하지 않는다
82
- - `.mpk` 위젯용 `.mjs` FFI 파일을 직접 작성하지 않는다 — `widgets/` 디렉토리 + `glendix/widget`을 사용한다
1
+ {{I18N:widgets_readme}}