capacitor-extended-dialog 0.0.2 → 0.0.4

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
@@ -1,6 +1,6 @@
1
1
  # capacitor-extended-dialog
2
2
 
3
- Show native dialogs in Capacitor with Material 3 and Liquid Glass UI
3
+ A Capacitor 6+ plugin for native dialogs — alerts, confirms, prompts, single/multi-select, and structured sheets — with Material 3 styling on Android, Liquid Glass on iOS, and a web fallback. Supports basic and fullscreen presentation modes with customizable colors, fonts, and layout.
4
4
 
5
5
  ## Install
6
6
 
@@ -18,7 +18,9 @@ npx cap sync
18
18
  * [`prompt(...)`](#prompt)
19
19
  * [`singleSelect(...)`](#singleselect)
20
20
  * [`multiSelect(...)`](#multiselect)
21
+ * [`sheet(...)`](#sheet)
21
22
  * [Interfaces](#interfaces)
23
+ * [Type Aliases](#type-aliases)
22
24
 
23
25
  </docgen-index>
24
26
 
@@ -31,9 +33,11 @@ npx cap sync
31
33
  alert(options: AlertOptions) => any
32
34
  ```
33
35
 
34
- | Param | Type |
35
- | ------------- | ----------------------------------------------------- |
36
- | **`options`** | <code><a href="#alertoptions">AlertOptions</a></code> |
36
+ Show an alert dialog with a single dismiss button.
37
+
38
+ | Param | Type | Description |
39
+ | ------------- | ----------------------------------------------------- | ------------------------------ |
40
+ | **`options`** | <code><a href="#alertoptions">AlertOptions</a></code> | - Alert configuration options. |
37
41
 
38
42
  **Returns:** <code>any</code>
39
43
 
@@ -46,9 +50,11 @@ alert(options: AlertOptions) => any
46
50
  confirm(options: ConfirmOptions) => any
47
51
  ```
48
52
 
49
- | Param | Type |
50
- | ------------- | --------------------------------------------------------- |
51
- | **`options`** | <code><a href="#confirmoptions">ConfirmOptions</a></code> |
53
+ Show a confirmation dialog with OK and Cancel buttons.
54
+
55
+ | Param | Type | Description |
56
+ | ------------- | --------------------------------------------------------- | -------------------------------- |
57
+ | **`options`** | <code><a href="#confirmoptions">ConfirmOptions</a></code> | - Confirm configuration options. |
52
58
 
53
59
  **Returns:** <code>any</code>
54
60
 
@@ -61,9 +67,11 @@ confirm(options: ConfirmOptions) => any
61
67
  prompt(options: PromptOptions) => any
62
68
  ```
63
69
 
64
- | Param | Type |
65
- | ------------- | ------------------------------------------------------- |
66
- | **`options`** | <code><a href="#promptoptions">PromptOptions</a></code> |
70
+ Show a prompt dialog with a text input field.
71
+
72
+ | Param | Type | Description |
73
+ | ------------- | ------------------------------------------------------- | ------------------------------- |
74
+ | **`options`** | <code><a href="#promptoptions">PromptOptions</a></code> | - Prompt configuration options. |
67
75
 
68
76
  **Returns:** <code>any</code>
69
77
 
@@ -76,9 +84,11 @@ prompt(options: PromptOptions) => any
76
84
  singleSelect(options: SingleSelectOptions) => any
77
85
  ```
78
86
 
79
- | Param | Type |
80
- | ------------- | ------------------------------------------------------------------- |
81
- | **`options`** | <code><a href="#singleselectoptions">SingleSelectOptions</a></code> |
87
+ Show a single-select dialog where the user picks one option.
88
+
89
+ | Param | Type | Description |
90
+ | ------------- | ------------------------------------------------------------------- | -------------------------------------- |
91
+ | **`options`** | <code><a href="#singleselectoptions">SingleSelectOptions</a></code> | - Single select configuration options. |
82
92
 
83
93
  **Returns:** <code>any</code>
84
94
 
@@ -91,9 +101,28 @@ singleSelect(options: SingleSelectOptions) => any
91
101
  multiSelect(options: MultiSelectOptions) => any
92
102
  ```
93
103
 
94
- | Param | Type |
95
- | ------------- | ----------------------------------------------------------------- |
96
- | **`options`** | <code><a href="#multiselectoptions">MultiSelectOptions</a></code> |
104
+ Show a multi-select dialog where the user picks one or more options.
105
+
106
+ | Param | Type | Description |
107
+ | ------------- | ----------------------------------------------------------------- | ------------------------------------- |
108
+ | **`options`** | <code><a href="#multiselectoptions">MultiSelectOptions</a></code> | - Multi select configuration options. |
109
+
110
+ **Returns:** <code>any</code>
111
+
112
+ --------------------
113
+
114
+
115
+ ### sheet(...)
116
+
117
+ ```typescript
118
+ sheet(options: SheetOptions) => any
119
+ ```
120
+
121
+ Show a sheet dialog with a header, title, and structured data rows.
122
+
123
+ | Param | Type | Description |
124
+ | ------------- | ----------------------------------------------------- | ------------------------------ |
125
+ | **`options`** | <code><a href="#sheetoptions">SheetOptions</a></code> | - Sheet configuration options. |
97
126
 
98
127
  **Returns:** <code>any</code>
99
128
 
@@ -105,86 +134,127 @@ multiSelect(options: MultiSelectOptions) => any
105
134
 
106
135
  #### AlertOptions
107
136
 
108
- | Prop | Type |
109
- | ----------------- | ------------------- |
110
- | **`buttonTitle`** | <code>string</code> |
137
+ | Prop | Type | Description | Default |
138
+ | ----------------- | ------------------- | ----------------------------- | ----------------- |
139
+ | **`buttonTitle`** | <code>string</code> | Title for the dismiss button. | <code>"OK"</code> |
111
140
 
112
141
 
113
142
  #### ConfirmOptions
114
143
 
115
- | Prop | Type |
116
- | ----------------------- | ------------------- |
117
- | **`okButtonTitle`** | <code>string</code> |
118
- | **`cancelButtonTitle`** | <code>string</code> |
144
+ | Prop | Type | Description | Default |
145
+ | ----------------------- | ------------------- | ---------------------------------- | --------------------- |
146
+ | **`okButtonTitle`** | <code>string</code> | Title for the confirmation button. | <code>"OK"</code> |
147
+ | **`cancelButtonTitle`** | <code>string</code> | Title for the cancel button. | <code>"Cancel"</code> |
119
148
 
120
149
 
121
150
  #### ConfirmResult
122
151
 
123
- | Prop | Type |
124
- | ----------- | -------------------- |
125
- | **`value`** | <code>boolean</code> |
152
+ | Prop | Type | Description |
153
+ | ----------- | -------------------- | ----------------------------------------------------------- |
154
+ | **`value`** | <code>boolean</code> | Whether the user confirmed (`true`) or cancelled (`false`). |
126
155
 
127
156
 
128
157
  #### PromptOptions
129
158
 
130
- | Prop | Type | Description | Default |
131
- | ----------------------- | -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ |
132
- | **`okButtonTitle`** | <code>string</code> | | |
133
- | **`cancelButtonTitle`** | <code>string</code> | | |
134
- | **`inputPlaceholder`** | <code>string</code> | | |
135
- | **`inputText`** | <code>string</code> | | |
136
- | **`focusInput`** | <code>boolean</code> | Whether to automatically focus the input field and open the keyboard when the dialog appears. Note: On iOS, basic (non-fullscreen) dialogs always auto-focus the input field due to UIAlertController's built-in behavior. This option only takes effect on iOS when using fullscreen mode (`mode: 'fullscreen'`). On Android and web, this works for all modes. | <code>false</code> |
159
+ | Prop | Type | Description | Default |
160
+ | ----------------------- | -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------- |
161
+ | **`okButtonTitle`** | <code>string</code> | Title for the confirmation button. | <code>"OK"</code> |
162
+ | **`cancelButtonTitle`** | <code>string</code> | Title for the cancel button. | <code>"Cancel"</code> |
163
+ | **`inputPlaceholder`** | <code>string</code> | Placeholder text shown in the input field when empty. | |
164
+ | **`inputText`** | <code>string</code> | Pre-filled value for the input field. | |
165
+ | **`focusInput`** | <code>boolean</code> | Whether to automatically focus the input field and open the keyboard when the dialog appears. Note: On iOS, basic (non-fullscreen) dialogs always auto-focus the input field due to UIAlertController's built-in behavior. This option only takes effect on iOS when using fullscreen mode (`mode: 'fullscreen'`). On Android and web, this works for all modes. | <code>false</code> |
137
166
 
138
167
 
139
168
  #### PromptResult
140
169
 
141
- | Prop | Type |
142
- | --------------- | -------------------- |
143
- | **`value`** | <code>string</code> |
144
- | **`cancelled`** | <code>boolean</code> |
170
+ | Prop | Type | Description |
171
+ | --------------- | -------------------- | -------------------------------------------------------- |
172
+ | **`value`** | <code>string</code> | The text entered by the user. Empty string if cancelled. |
173
+ | **`cancelled`** | <code>boolean</code> | Whether the user cancelled the dialog. |
145
174
 
146
175
 
147
176
  #### SingleSelectOptions
148
177
 
149
- | Prop | Type |
150
- | ----------------------- | ------------------- |
151
- | **`options`** | <code>{}</code> |
152
- | **`selectedValue`** | <code>string</code> |
153
- | **`okButtonTitle`** | <code>string</code> |
154
- | **`cancelButtonTitle`** | <code>string</code> |
178
+ | Prop | Type | Description | Default |
179
+ | ----------------------- | ------------------- | ----------------------------------------- | --------------------- |
180
+ | **`options`** | <code>{}</code> | List of options to display for selection. | |
181
+ | **`selectedValue`** | <code>string</code> | Value of the initially selected option. | |
182
+ | **`okButtonTitle`** | <code>string</code> | Title for the confirmation button. | <code>"OK"</code> |
183
+ | **`cancelButtonTitle`** | <code>string</code> | Title for the cancel button. | <code>"Cancel"</code> |
155
184
 
156
185
 
157
186
  #### SelectOption
158
187
 
159
- | Prop | Type |
160
- | ----------- | ------------------- |
161
- | **`label`** | <code>string</code> |
162
- | **`value`** | <code>string</code> |
188
+ | Prop | Type | Description |
189
+ | ----------- | ------------------- | ------------------------------------------- |
190
+ | **`label`** | <code>string</code> | Display text for the option. |
191
+ | **`value`** | <code>string</code> | Value returned when the option is selected. |
163
192
 
164
193
 
165
194
  #### SingleSelectResult
166
195
 
167
- | Prop | Type |
168
- | --------------- | --------------------------- |
169
- | **`value`** | <code>string \| null</code> |
170
- | **`cancelled`** | <code>boolean</code> |
196
+ | Prop | Type | Description |
197
+ | --------------- | --------------------------- | --------------------------------------------------------- |
198
+ | **`value`** | <code>string \| null</code> | The value of the selected option, or `null` if cancelled. |
199
+ | **`cancelled`** | <code>boolean</code> | Whether the user cancelled the dialog. |
171
200
 
172
201
 
173
202
  #### MultiSelectOptions
174
203
 
175
- | Prop | Type |
176
- | ----------------------- | ------------------- |
177
- | **`options`** | <code>{}</code> |
178
- | **`selectedValues`** | <code>{}</code> |
179
- | **`okButtonTitle`** | <code>string</code> |
180
- | **`cancelButtonTitle`** | <code>string</code> |
204
+ | Prop | Type | Description | Default |
205
+ | ----------------------- | ------------------- | ----------------------------------------- | --------------------- |
206
+ | **`options`** | <code>{}</code> | List of options to display for selection. | |
207
+ | **`selectedValues`** | <code>{}</code> | Values of the initially selected options. | |
208
+ | **`okButtonTitle`** | <code>string</code> | Title for the confirmation button. | <code>"OK"</code> |
209
+ | **`cancelButtonTitle`** | <code>string</code> | Title for the cancel button. | <code>"Cancel"</code> |
181
210
 
182
211
 
183
212
  #### MultiSelectResult
184
213
 
185
- | Prop | Type |
186
- | --------------- | -------------------- |
187
- | **`values`** | <code>{}</code> |
188
- | **`cancelled`** | <code>boolean</code> |
214
+ | Prop | Type | Description |
215
+ | --------------- | -------------------- | ------------------------------------------------------------- |
216
+ | **`values`** | <code>{}</code> | The values of the selected options. Empty array if cancelled. |
217
+ | **`cancelled`** | <code>boolean</code> | Whether the user cancelled the dialog. |
218
+
219
+
220
+ #### SheetOptions
221
+
222
+ | Prop | Type | Description |
223
+ | ------------------------ | ------------------------------------------------- | -------------------------------------------------------- |
224
+ | **`headerLogo`** | <code>string</code> | Header logo - supports base64 data URL or HTTP/HTTPS URL |
225
+ | **`title`** | <code>string</code> | Sheet title |
226
+ | **`rows`** | <code>{}</code> | Description rows |
227
+ | **`confirmButtonTitle`** | <code>string</code> | Confirm button title |
228
+ | **`cancelButtonTitle`** | <code>string</code> | Cancel button title |
229
+ | **`mode`** | <code><a href="#dialogmode">DialogMode</a></code> | Dialog mode |
230
+
231
+
232
+ #### SheetRow
233
+
234
+ | Prop | Type | Description |
235
+ | ----------- | ------------------- | --------------------------------------------------------------- |
236
+ | **`title`** | <code>string</code> | Row title (required) |
237
+ | **`logo`** | <code>string</code> | Optional logo/icon - supports base64 data URL or HTTP/HTTPS URL |
238
+ | **`value`** | <code>string</code> | Optional value displayed on the right |
239
+
240
+
241
+ #### SheetResult
242
+
243
+ | Prop | Type | Description |
244
+ | --------------- | -------------------- | ------------------------------------- |
245
+ | **`confirmed`** | <code>boolean</code> | True if confirmed, false if cancelled |
246
+
247
+
248
+ ### Type Aliases
249
+
250
+
251
+ #### DialogMode
252
+
253
+ Dialog presentation mode.
254
+
255
+ - `'basic'` — Standard modal dialog (default)
256
+ - `'fullscreen'` — Full-screen dialog presentation
257
+
258
+ <code>'basic' | 'fullscreen'</code>
189
259
 
190
260
  </docgen-api>
@@ -7,7 +7,6 @@ import android.content.res.ColorStateList;
7
7
  import android.text.InputType;
8
8
  import android.util.TypedValue;
9
9
  import android.view.ContextThemeWrapper;
10
- import android.view.View;
11
10
  import android.view.WindowManager;
12
11
  import android.widget.Button;
13
12
  import android.widget.LinearLayout;
@@ -169,6 +168,10 @@ public class ExtendedDialog {
169
168
  void onResult(String[] values, boolean cancelled);
170
169
  }
171
170
 
171
+ public interface SheetCallback {
172
+ void onResult(boolean confirmed);
173
+ }
174
+
172
175
  public void showAlert(
173
176
  Activity activity,
174
177
  String title,
@@ -728,4 +731,37 @@ public class ExtendedDialog {
728
731
  fragment.show(activity.getSupportFragmentManager(), "fullscreen_multi_select");
729
732
  });
730
733
  }
734
+
735
+ // MARK: - Sheet
736
+
737
+ public void showSheet(
738
+ Activity activity,
739
+ String title,
740
+ String headerLogo,
741
+ JSONArray rows,
742
+ String confirmButtonTitle,
743
+ String cancelButtonTitle,
744
+ boolean fullscreen,
745
+ DialogStyleOptions styleOptions,
746
+ SheetCallback callback
747
+ ) {
748
+ if (!(activity instanceof FragmentActivity)) {
749
+ callback.onResult(false);
750
+ return;
751
+ }
752
+ FragmentActivity fragmentActivity = (FragmentActivity) activity;
753
+ fragmentActivity.runOnUiThread(() -> {
754
+ SheetBottomDialogFragment fragment = SheetBottomDialogFragment.newInstance(
755
+ title,
756
+ headerLogo,
757
+ rows.toString(),
758
+ confirmButtonTitle != null ? confirmButtonTitle : "Confirm",
759
+ cancelButtonTitle != null ? cancelButtonTitle : "Cancel",
760
+ fullscreen,
761
+ styleOptions
762
+ );
763
+ fragment.setSheetCallback(callback);
764
+ fragment.show(fragmentActivity.getSupportFragmentManager(), "bottom_sheet");
765
+ });
766
+ }
731
767
  }
@@ -8,6 +8,7 @@ import com.getcapacitor.PluginMethod;
8
8
  import com.getcapacitor.annotation.CapacitorPlugin;
9
9
  import org.json.JSONArray;
10
10
  import org.json.JSONException;
11
+ import org.json.JSONObject;
11
12
 
12
13
  @CapacitorPlugin(name = "ExtendedDialog")
13
14
  public class ExtendedDialogPlugin extends Plugin {
@@ -204,4 +205,48 @@ public class ExtendedDialogPlugin extends Plugin {
204
205
  call.reject("Invalid options format");
205
206
  }
206
207
  }
208
+
209
+ @PluginMethod
210
+ public void sheet(PluginCall call) {
211
+ String title = call.getString("title");
212
+ String headerLogo = call.getString("headerLogo");
213
+ JSArray rowsArray = call.getArray("rows");
214
+ String confirmButtonTitle = call.getString("confirmButtonTitle");
215
+ String cancelButtonTitle = call.getString("cancelButtonTitle");
216
+ String mode = call.getString("mode", "basic");
217
+ boolean fullscreen = "fullscreen".equals(mode);
218
+ DialogStyleOptions styleOptions = extractStyleOptions(call);
219
+
220
+ if (title == null) {
221
+ call.reject("title is required");
222
+ return;
223
+ }
224
+
225
+ if (rowsArray == null) {
226
+ call.reject("rows is required");
227
+ return;
228
+ }
229
+
230
+ try {
231
+ JSONArray rows = new JSONArray(rowsArray.toString());
232
+
233
+ implementation.showSheet(
234
+ getActivity(),
235
+ title,
236
+ headerLogo,
237
+ rows,
238
+ confirmButtonTitle,
239
+ cancelButtonTitle,
240
+ fullscreen,
241
+ styleOptions,
242
+ (confirmed) -> {
243
+ JSObject result = new JSObject();
244
+ result.put("confirmed", confirmed);
245
+ call.resolve(result);
246
+ }
247
+ );
248
+ } catch (JSONException e) {
249
+ call.reject("Invalid rows format");
250
+ }
251
+ }
207
252
  }
@@ -9,6 +9,7 @@ import android.os.Bundle;
9
9
  import android.text.InputType;
10
10
  import android.util.TypedValue;
11
11
  import android.view.ContextThemeWrapper;
12
+ import android.view.Gravity;
12
13
  import android.view.LayoutInflater;
13
14
  import android.view.View;
14
15
  import android.view.ViewGroup;
@@ -229,13 +230,14 @@ public class FullScreenDialogFragment extends DialogFragment {
229
230
 
230
231
  root.addView(toolbar);
231
232
 
233
+ float density = getResources().getDisplayMetrics().density;
234
+
232
235
  // Create scroll view for content
233
236
  ScrollView scrollView = new ScrollView(ctx);
234
237
  scrollView.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 0, 1f));
235
238
 
236
239
  LinearLayout contentLayout = new LinearLayout(ctx);
237
240
  contentLayout.setOrientation(LinearLayout.VERTICAL);
238
- float density = getResources().getDisplayMetrics().density;
239
241
  int horizontalPadding = (int) (32 * density);
240
242
  int verticalPadding = (int) (24 * density);
241
243
  contentLayout.setPadding(horizontalPadding, verticalPadding, horizontalPadding, verticalPadding);
@@ -284,18 +286,17 @@ public class FullScreenDialogFragment extends DialogFragment {
284
286
  scrollView.addView(contentLayout);
285
287
  root.addView(scrollView);
286
288
 
287
- // Create button container
289
+ // Button container at the bottom
290
+ int primaryColorValue = MaterialColors.getColor(ctx, android.R.attr.colorPrimary, 0xFF6750A4);
291
+
288
292
  LinearLayout buttonContainer = new LinearLayout(ctx);
289
293
  buttonContainer.setOrientation(LinearLayout.HORIZONTAL);
290
- buttonContainer.setPadding(horizontalPadding, verticalPadding / 2, horizontalPadding, verticalPadding);
291
- buttonContainer.setGravity(android.view.Gravity.END);
292
-
293
- // Get M3 primary color for text buttons
294
- // Use android.R.attr.colorPrimary with M3 baseline fallback
295
- int primaryColorValue = MaterialColors.getColor(ctx, android.R.attr.colorPrimary, 0xFF6750A4);
294
+ buttonContainer.setGravity(Gravity.END);
295
+ int buttonPadding = (int) (16 * density);
296
+ buttonContainer.setPadding(buttonPadding, buttonPadding, buttonPadding, buttonPadding);
296
297
 
298
+ // Cancel button (not shown for ALERT type)
297
299
  if (type != DialogType.ALERT) {
298
- // Cancel button - M3 text button style (never disabled per M3 guidelines)
299
300
  MaterialButton cancelBtn = new MaterialButton(ctx, null,
300
301
  com.google.android.material.R.attr.borderlessButtonStyle);
301
302
  cancelBtn.setText(cancelButton);
@@ -303,8 +304,6 @@ public class FullScreenDialogFragment extends DialogFragment {
303
304
  handleCancel();
304
305
  dismiss();
305
306
  });
306
-
307
- // Apply cancel button color - use custom or M3 primary
308
307
  if (styleOptions.getCancelButtonColor() != null) {
309
308
  cancelBtn.setTextColor(ColorStateList.valueOf(styleOptions.getCancelButtonColor()));
310
309
  } else {
@@ -313,17 +312,10 @@ public class FullScreenDialogFragment extends DialogFragment {
313
312
  if (styleOptions.getButtonFontSize() != null) {
314
313
  cancelBtn.setTextSize(TypedValue.COMPLEX_UNIT_SP, styleOptions.getButtonFontSize());
315
314
  }
316
-
317
- LinearLayout.LayoutParams cancelParams = new LinearLayout.LayoutParams(
318
- ViewGroup.LayoutParams.WRAP_CONTENT,
319
- ViewGroup.LayoutParams.WRAP_CONTENT
320
- );
321
- cancelParams.rightMargin = (int) (8 * getResources().getDisplayMetrics().density);
322
- cancelBtn.setLayoutParams(cancelParams);
323
315
  buttonContainer.addView(cancelBtn);
324
316
  }
325
317
 
326
- // OK button - M3 text button style (same as Cancel per M3 guidelines)
318
+ // OK button
327
319
  okBtn = new MaterialButton(ctx, null,
328
320
  com.google.android.material.R.attr.borderlessButtonStyle);
329
321
  okBtn.setText(okButton);
@@ -331,8 +323,6 @@ public class FullScreenDialogFragment extends DialogFragment {
331
323
  handleConfirm(type);
332
324
  dismiss();
333
325
  });
334
-
335
- // Apply OK button color - use custom or M3 primary
336
326
  if (styleOptions.getButtonColor() != null) {
337
327
  okBtn.setTextColor(ColorStateList.valueOf(styleOptions.getButtonColor()));
338
328
  } else {
@@ -342,7 +332,7 @@ public class FullScreenDialogFragment extends DialogFragment {
342
332
  okBtn.setTextSize(TypedValue.COMPLEX_UNIT_SP, styleOptions.getButtonFontSize());
343
333
  }
344
334
 
345
- // M3 guideline: Disable confirming action until a choice is made for selection dialogs
335
+ // Disable confirming action until a choice is made for selection dialogs
346
336
  if (type == DialogType.SINGLE_SELECT && selectedValue == null) {
347
337
  okBtn.setEnabled(false);
348
338
  } else if (type == DialogType.MULTI_SELECT && selectedValues.isEmpty()) {
@@ -350,7 +340,6 @@ public class FullScreenDialogFragment extends DialogFragment {
350
340
  }
351
341
 
352
342
  buttonContainer.addView(okBtn);
353
-
354
343
  root.addView(buttonContainer);
355
344
 
356
345
  return root;