capacitor-extended-dialog 0.0.9 → 0.0.11

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
@@ -19,6 +19,7 @@ npx cap sync
19
19
  * [`singleSelect(...)`](#singleselect)
20
20
  * [`multiSelect(...)`](#multiselect)
21
21
  * [`sheet(...)`](#sheet)
22
+ * [`messageSheet(...)`](#messagesheet)
22
23
  * [Interfaces](#interfaces)
23
24
  * [Type Aliases](#type-aliases)
24
25
 
@@ -129,6 +130,23 @@ Show a sheet dialog with a header, title, and structured data rows.
129
130
  --------------------
130
131
 
131
132
 
133
+ ### messageSheet(...)
134
+
135
+ ```typescript
136
+ messageSheet(options: MessageSheetOptions) => any
137
+ ```
138
+
139
+ Show a message sheet dialog with an optional header logo, title, and message.
140
+
141
+ | Param | Type | Description |
142
+ | ------------- | ------------------------------------------------------------------- | -------------------------------------- |
143
+ | **`options`** | <code><a href="#messagesheetoptions">MessageSheetOptions</a></code> | - Message sheet configuration options. |
144
+
145
+ **Returns:** <code>any</code>
146
+
147
+ --------------------
148
+
149
+
132
150
  ### Interfaces
133
151
 
134
152
 
@@ -245,6 +263,25 @@ Show a sheet dialog with a header, title, and structured data rows.
245
263
  | **`confirmed`** | <code>boolean</code> | True if confirmed, false if cancelled |
246
264
 
247
265
 
266
+ #### MessageSheetOptions
267
+
268
+ | Prop | Type | Description |
269
+ | ------------------------ | ------------------------------------------------- | -------------------------------------------------------- |
270
+ | **`headerLogo`** | <code>string</code> | Header logo - supports base64 data URL or HTTP/HTTPS URL |
271
+ | **`title`** | <code>string</code> | Sheet title |
272
+ | **`message`** | <code>string</code> | Message body displayed in the sheet |
273
+ | **`confirmButtonTitle`** | <code>string</code> | Confirm button title |
274
+ | **`cancelButtonTitle`** | <code>string</code> | Cancel button title |
275
+ | **`mode`** | <code><a href="#dialogmode">DialogMode</a></code> | Dialog mode |
276
+
277
+
278
+ #### MessageSheetResult
279
+
280
+ | Prop | Type | Description |
281
+ | --------------- | -------------------- | ------------------------------------- |
282
+ | **`confirmed`** | <code>boolean</code> | True if confirmed, false if cancelled |
283
+
284
+
248
285
  ### Type Aliases
249
286
 
250
287
 
@@ -16,6 +16,8 @@ public class DialogStyleOptions {
16
16
  private static final String KEY_TITLE_FONT_SIZE = "titleFontSize";
17
17
  private static final String KEY_MESSAGE_FONT_SIZE = "messageFontSize";
18
18
  private static final String KEY_BUTTON_FONT_SIZE = "buttonFontSize";
19
+ private static final String KEY_CONTENT_BUTTON_SPACING = "contentButtonSpacing";
20
+ private static final String KEY_HEADER_LOGO_CORNER_RADIUS = "headerLogoCornerRadius";
19
21
 
20
22
  private Integer buttonColor;
21
23
  private Integer cancelButtonColor;
@@ -25,6 +27,8 @@ public class DialogStyleOptions {
25
27
  private Float titleFontSize;
26
28
  private Float messageFontSize;
27
29
  private Float buttonFontSize;
30
+ private Float contentButtonSpacing;
31
+ private Float headerLogoCornerRadius;
28
32
 
29
33
  public DialogStyleOptions() {}
30
34
 
@@ -43,34 +47,104 @@ public class DialogStyleOptions {
43
47
  return (size != null && size > 0) ? size.floatValue() : null;
44
48
  }
45
49
 
46
- public Integer getButtonColor() { return buttonColor; }
47
- public void setButtonColor(String hexColor) { this.buttonColor = parseColor(hexColor); }
50
+ private static Float parseSpacing(Double size) {
51
+ return (size != null && size >= 0) ? size.floatValue() : null;
52
+ }
53
+
54
+ public Integer getButtonColor() {
55
+ return buttonColor;
56
+ }
57
+
58
+ public void setButtonColor(String hexColor) {
59
+ this.buttonColor = parseColor(hexColor);
60
+ }
61
+
62
+ public Integer getCancelButtonColor() {
63
+ return cancelButtonColor;
64
+ }
65
+
66
+ public void setCancelButtonColor(String hexColor) {
67
+ this.cancelButtonColor = parseColor(hexColor);
68
+ }
69
+
70
+ public Integer getTitleColor() {
71
+ return titleColor;
72
+ }
73
+
74
+ public void setTitleColor(String hexColor) {
75
+ this.titleColor = parseColor(hexColor);
76
+ }
77
+
78
+ public Integer getMessageColor() {
79
+ return messageColor;
80
+ }
81
+
82
+ public void setMessageColor(String hexColor) {
83
+ this.messageColor = parseColor(hexColor);
84
+ }
48
85
 
49
- public Integer getCancelButtonColor() { return cancelButtonColor; }
50
- public void setCancelButtonColor(String hexColor) { this.cancelButtonColor = parseColor(hexColor); }
86
+ public Integer getBackgroundColor() {
87
+ return backgroundColor;
88
+ }
51
89
 
52
- public Integer getTitleColor() { return titleColor; }
53
- public void setTitleColor(String hexColor) { this.titleColor = parseColor(hexColor); }
90
+ public void setBackgroundColor(String hexColor) {
91
+ this.backgroundColor = parseColor(hexColor);
92
+ }
54
93
 
55
- public Integer getMessageColor() { return messageColor; }
56
- public void setMessageColor(String hexColor) { this.messageColor = parseColor(hexColor); }
94
+ public Float getTitleFontSize() {
95
+ return titleFontSize;
96
+ }
57
97
 
58
- public Integer getBackgroundColor() { return backgroundColor; }
59
- public void setBackgroundColor(String hexColor) { this.backgroundColor = parseColor(hexColor); }
98
+ public void setTitleFontSize(Double size) {
99
+ this.titleFontSize = parseSize(size);
100
+ }
60
101
 
61
- public Float getTitleFontSize() { return titleFontSize; }
62
- public void setTitleFontSize(Double size) { this.titleFontSize = parseSize(size); }
102
+ public Float getMessageFontSize() {
103
+ return messageFontSize;
104
+ }
63
105
 
64
- public Float getMessageFontSize() { return messageFontSize; }
65
- public void setMessageFontSize(Double size) { this.messageFontSize = parseSize(size); }
106
+ public void setMessageFontSize(Double size) {
107
+ this.messageFontSize = parseSize(size);
108
+ }
109
+
110
+ public Float getButtonFontSize() {
111
+ return buttonFontSize;
112
+ }
66
113
 
67
- public Float getButtonFontSize() { return buttonFontSize; }
68
- public void setButtonFontSize(Double size) { this.buttonFontSize = parseSize(size); }
114
+ public void setButtonFontSize(Double size) {
115
+ this.buttonFontSize = parseSize(size);
116
+ }
117
+
118
+ public Float getContentButtonSpacing() {
119
+ return contentButtonSpacing;
120
+ }
121
+
122
+ public void setContentButtonSpacing(Double size) {
123
+ this.contentButtonSpacing = parseSpacing(size);
124
+ }
125
+
126
+ public Float getHeaderLogoCornerRadius() {
127
+ return headerLogoCornerRadius;
128
+ }
129
+
130
+ public void setHeaderLogoCornerRadius(Double radius) {
131
+ // Allow any value: positive for custom radius, 0 for square, -1 for circle
132
+ this.headerLogoCornerRadius = radius != null ? radius.floatValue() : null;
133
+ }
69
134
 
70
135
  public boolean hasStyles() {
71
- return buttonColor != null || cancelButtonColor != null || titleColor != null ||
72
- messageColor != null || backgroundColor != null || titleFontSize != null ||
73
- messageFontSize != null || buttonFontSize != null;
136
+ return (
137
+ buttonColor != null ||
138
+ cancelButtonColor != null ||
139
+ titleColor != null ||
140
+ messageColor != null ||
141
+ backgroundColor != null ||
142
+ titleFontSize != null ||
143
+ messageFontSize != null ||
144
+ buttonFontSize != null ||
145
+ contentButtonSpacing != null ||
146
+ headerLogoCornerRadius != null
147
+ );
74
148
  }
75
149
 
76
150
  public void writeToBundle(Bundle bundle) {
@@ -82,6 +156,8 @@ public class DialogStyleOptions {
82
156
  if (titleFontSize != null) bundle.putFloat(KEY_TITLE_FONT_SIZE, titleFontSize);
83
157
  if (messageFontSize != null) bundle.putFloat(KEY_MESSAGE_FONT_SIZE, messageFontSize);
84
158
  if (buttonFontSize != null) bundle.putFloat(KEY_BUTTON_FONT_SIZE, buttonFontSize);
159
+ if (contentButtonSpacing != null) bundle.putFloat(KEY_CONTENT_BUTTON_SPACING, contentButtonSpacing);
160
+ if (headerLogoCornerRadius != null) bundle.putFloat(KEY_HEADER_LOGO_CORNER_RADIUS, headerLogoCornerRadius);
85
161
  }
86
162
 
87
163
  public static DialogStyleOptions readFromBundle(Bundle bundle) {
@@ -94,6 +170,8 @@ public class DialogStyleOptions {
94
170
  options.titleFontSize = bundle.containsKey(KEY_TITLE_FONT_SIZE) ? bundle.getFloat(KEY_TITLE_FONT_SIZE) : null;
95
171
  options.messageFontSize = bundle.containsKey(KEY_MESSAGE_FONT_SIZE) ? bundle.getFloat(KEY_MESSAGE_FONT_SIZE) : null;
96
172
  options.buttonFontSize = bundle.containsKey(KEY_BUTTON_FONT_SIZE) ? bundle.getFloat(KEY_BUTTON_FONT_SIZE) : null;
173
+ options.contentButtonSpacing = bundle.containsKey(KEY_CONTENT_BUTTON_SPACING) ? bundle.getFloat(KEY_CONTENT_BUTTON_SPACING) : null;
174
+ options.headerLogoCornerRadius = bundle.containsKey(KEY_HEADER_LOGO_CORNER_RADIUS) ? bundle.getFloat(KEY_HEADER_LOGO_CORNER_RADIUS) : null;
97
175
  return options;
98
176
  }
99
177
  }
@@ -111,8 +111,7 @@ public class ExtendedDialog {
111
111
  // MaterialAlertDialogBuilder uses appcompat's alertTitle, not android's
112
112
  TextView titleView = dialog.findViewById(androidx.appcompat.R.id.alertTitle);
113
113
  if (titleView != null) {
114
- TextViewCompat.setTextAppearance(titleView,
115
- com.google.android.material.R.style.TextAppearance_Material3_HeadlineSmall);
114
+ TextViewCompat.setTextAppearance(titleView, com.google.android.material.R.style.TextAppearance_Material3_HeadlineSmall);
116
115
  // M3 dialog headline color: onSurface (#1D1B20)
117
116
  // Use MaterialColors for proper theme attribute resolution across different R class configurations
118
117
  int onSurfaceColor = MaterialColors.getColor(ctx, android.R.attr.textColorPrimary, 0xFF1D1B20);
@@ -122,8 +121,7 @@ public class ExtendedDialog {
122
121
  // Apply M3 BodyMedium to message with onSurfaceVariant color
123
122
  TextView messageView = dialog.findViewById(android.R.id.message);
124
123
  if (messageView != null) {
125
- TextViewCompat.setTextAppearance(messageView,
126
- com.google.android.material.R.style.TextAppearance_Material3_BodyMedium);
124
+ TextViewCompat.setTextAppearance(messageView, com.google.android.material.R.style.TextAppearance_Material3_BodyMedium);
127
125
  // M3 dialog supporting text color: onSurfaceVariant (#49454F)
128
126
  // Use MaterialColors for proper theme attribute resolution
129
127
  int onSurfaceVariantColor = MaterialColors.getColor(ctx, android.R.attr.textColorSecondary, 0xFF49454F);
@@ -198,8 +196,10 @@ public class ExtendedDialog {
198
196
  ) {
199
197
  activity.runOnUiThread(() -> {
200
198
  Context themedContext = getThemedContext(activity);
201
- MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(themedContext,
202
- R.style.ThemeOverlay_ExtendedDialog_MaterialAlertDialog);
199
+ MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(
200
+ themedContext,
201
+ R.style.ThemeOverlay_ExtendedDialog_MaterialAlertDialog
202
+ );
203
203
 
204
204
  if (title != null && !title.isEmpty()) {
205
205
  builder.setTitle(title);
@@ -268,8 +268,10 @@ public class ExtendedDialog {
268
268
  ) {
269
269
  activity.runOnUiThread(() -> {
270
270
  Context themedContext = getThemedContext(activity);
271
- MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(themedContext,
272
- R.style.ThemeOverlay_ExtendedDialog_MaterialAlertDialog);
271
+ MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(
272
+ themedContext,
273
+ R.style.ThemeOverlay_ExtendedDialog_MaterialAlertDialog
274
+ );
273
275
 
274
276
  if (title != null && !title.isEmpty()) {
275
277
  builder.setTitle(title);
@@ -370,8 +372,10 @@ public class ExtendedDialog {
370
372
  ) {
371
373
  activity.runOnUiThread(() -> {
372
374
  Context themedContext = getThemedContext(activity);
373
- MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(themedContext,
374
- R.style.ThemeOverlay_ExtendedDialog_MaterialAlertDialog);
375
+ MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(
376
+ themedContext,
377
+ R.style.ThemeOverlay_ExtendedDialog_MaterialAlertDialog
378
+ );
375
379
 
376
380
  if (title != null && !title.isEmpty()) {
377
381
  builder.setTitle(title);
@@ -519,8 +523,10 @@ public class ExtendedDialog {
519
523
 
520
524
  final int[] selectedIndex = { checkedItem };
521
525
 
522
- MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(getThemedContext(activity),
523
- R.style.ThemeOverlay_ExtendedDialog_MaterialAlertDialog);
526
+ MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(
527
+ getThemedContext(activity),
528
+ R.style.ThemeOverlay_ExtendedDialog_MaterialAlertDialog
529
+ );
524
530
 
525
531
  if (title != null && !title.isEmpty()) {
526
532
  builder.setTitle(title);
@@ -662,8 +668,10 @@ public class ExtendedDialog {
662
668
 
663
669
  final Set<String> resultSet = new HashSet<>(selectedSet);
664
670
 
665
- MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(getThemedContext(activity),
666
- R.style.ThemeOverlay_ExtendedDialog_MaterialAlertDialog);
671
+ MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(
672
+ getThemedContext(activity),
673
+ R.style.ThemeOverlay_ExtendedDialog_MaterialAlertDialog
674
+ );
667
675
 
668
676
  if (title != null && !title.isEmpty()) {
669
677
  builder.setTitle(title);
@@ -763,4 +771,35 @@ public class ExtendedDialog {
763
771
  fragment.show(fragmentActivity.getSupportFragmentManager(), "bottom_sheet");
764
772
  });
765
773
  }
774
+
775
+ public void showMessageSheet(
776
+ Activity activity,
777
+ String title,
778
+ String message,
779
+ String headerLogo,
780
+ String confirmButtonTitle,
781
+ String cancelButtonTitle,
782
+ boolean fullscreen,
783
+ DialogStyleOptions styleOptions,
784
+ SheetCallback callback
785
+ ) {
786
+ if (!(activity instanceof FragmentActivity)) {
787
+ callback.onResult(false);
788
+ return;
789
+ }
790
+ FragmentActivity fragmentActivity = (FragmentActivity) activity;
791
+ fragmentActivity.runOnUiThread(() -> {
792
+ SheetBottomDialogFragment fragment = SheetBottomDialogFragment.newMessageInstance(
793
+ title,
794
+ headerLogo,
795
+ message,
796
+ confirmButtonTitle != null ? confirmButtonTitle : "Confirm",
797
+ cancelButtonTitle != null ? cancelButtonTitle : "Cancel",
798
+ fullscreen,
799
+ styleOptions
800
+ );
801
+ fragment.setSheetCallback(callback);
802
+ fragment.show(fragmentActivity.getSupportFragmentManager(), "message_sheet");
803
+ });
804
+ }
766
805
  }
@@ -25,6 +25,8 @@ public class ExtendedDialogPlugin extends Plugin {
25
25
  styleOptions.setTitleFontSize(call.getDouble("titleFontSize"));
26
26
  styleOptions.setMessageFontSize(call.getDouble("messageFontSize"));
27
27
  styleOptions.setButtonFontSize(call.getDouble("buttonFontSize"));
28
+ styleOptions.setContentButtonSpacing(call.getDouble("contentButtonSpacing"));
29
+ styleOptions.setHeaderLogoCornerRadius(call.getDouble("headerLogoCornerRadius"));
28
30
  return styleOptions;
29
31
  }
30
32
 
@@ -249,4 +251,42 @@ public class ExtendedDialogPlugin extends Plugin {
249
251
  call.reject("Invalid rows format");
250
252
  }
251
253
  }
254
+
255
+ @PluginMethod
256
+ public void messageSheet(PluginCall call) {
257
+ String title = call.getString("title");
258
+ String message = call.getString("message");
259
+ String headerLogo = call.getString("headerLogo");
260
+ String confirmButtonTitle = call.getString("confirmButtonTitle");
261
+ String cancelButtonTitle = call.getString("cancelButtonTitle");
262
+ String mode = call.getString("mode", "basic");
263
+ boolean fullscreen = "fullscreen".equals(mode);
264
+ DialogStyleOptions styleOptions = extractStyleOptions(call);
265
+
266
+ if (title == null) {
267
+ call.reject("title is required");
268
+ return;
269
+ }
270
+
271
+ if (message == null) {
272
+ call.reject("message is required");
273
+ return;
274
+ }
275
+
276
+ implementation.showMessageSheet(
277
+ getActivity(),
278
+ title,
279
+ message,
280
+ headerLogo,
281
+ confirmButtonTitle,
282
+ cancelButtonTitle,
283
+ fullscreen,
284
+ styleOptions,
285
+ (confirmed) -> {
286
+ JSObject result = new JSObject();
287
+ result.put("confirmed", confirmed);
288
+ call.resolve(result);
289
+ }
290
+ );
291
+ }
252
292
  }
@@ -250,8 +250,7 @@ public class FullScreenDialogFragment extends DialogFragment {
250
250
  messageView.setTextSize(TypedValue.COMPLEX_UNIT_SP, styleOptions.getMessageFontSize());
251
251
  } else {
252
252
  // M3 dialog supporting text: 14sp, weight 400, tracking 0.25sp
253
- TextViewCompat.setTextAppearance(messageView,
254
- com.google.android.material.R.style.TextAppearance_Material3_BodyMedium);
253
+ TextViewCompat.setTextAppearance(messageView, com.google.android.material.R.style.TextAppearance_Material3_BodyMedium);
255
254
  }
256
255
  if (styleOptions.getMessageColor() != null) {
257
256
  messageView.setTextColor(styleOptions.getMessageColor());
@@ -293,7 +292,9 @@ public class FullScreenDialogFragment extends DialogFragment {
293
292
  buttonContainer.setOrientation(LinearLayout.HORIZONTAL);
294
293
  buttonContainer.setGravity(Gravity.END);
295
294
  int buttonPadding = (int) (16 * density);
296
- buttonContainer.setPadding(buttonPadding, buttonPadding, buttonPadding, buttonPadding);
295
+ float topSpacing = styleOptions.getContentButtonSpacing() != null ? styleOptions.getContentButtonSpacing() : 16f;
296
+ int buttonTopPadding = (int) (topSpacing * density);
297
+ buttonContainer.setPadding(buttonPadding, buttonTopPadding, buttonPadding, buttonPadding);
297
298
 
298
299
  // Cancel button (not shown for ALERT type)
299
300
  if (type != DialogType.ALERT) {
@@ -353,8 +354,9 @@ public class FullScreenDialogFragment extends DialogFragment {
353
354
  // Use Material 3 TextInputLayout with outlined style
354
355
  TextInputLayout textInputLayout = new TextInputLayout(ctx);
355
356
  textInputLayout.setBoxBackgroundMode(TextInputLayout.BOX_BACKGROUND_OUTLINE);
356
- textInputLayout.setLayoutParams(new LinearLayout.LayoutParams(
357
- ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
357
+ textInputLayout.setLayoutParams(
358
+ new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
359
+ );
358
360
 
359
361
  inputField = new TextInputEditText(textInputLayout.getContext());
360
362
  inputField.setInputType(InputType.TYPE_CLASS_TEXT);
@@ -371,15 +373,18 @@ public class FullScreenDialogFragment extends DialogFragment {
371
373
  if (focusInput) {
372
374
  inputField.requestFocus();
373
375
  // Show keyboard when dialog is shown
374
- inputField.postDelayed(() -> {
375
- if (getContext() != null) {
376
- android.view.inputmethod.InputMethodManager imm =
377
- (android.view.inputmethod.InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
378
- if (imm != null) {
379
- imm.showSoftInput(inputField, android.view.inputmethod.InputMethodManager.SHOW_IMPLICIT);
376
+ inputField.postDelayed(
377
+ () -> {
378
+ if (getContext() != null) {
379
+ android.view.inputmethod.InputMethodManager imm =
380
+ (android.view.inputmethod.InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
381
+ if (imm != null) {
382
+ imm.showSoftInput(inputField, android.view.inputmethod.InputMethodManager.SHOW_IMPLICIT);
383
+ }
380
384
  }
381
- }
382
- }, 200);
385
+ },
386
+ 200
387
+ );
383
388
  }
384
389
  }
385
390
 
@@ -403,8 +408,7 @@ public class FullScreenDialogFragment extends DialogFragment {
403
408
 
404
409
  RadioButton radioButton = new RadioButton(ctx);
405
410
  radioButton.setText(label);
406
- TextViewCompat.setTextAppearance(radioButton,
407
- com.google.android.material.R.style.TextAppearance_Material3_BodyLarge);
411
+ TextViewCompat.setTextAppearance(radioButton, com.google.android.material.R.style.TextAppearance_Material3_BodyLarge);
408
412
  // M3 list item text color: onSurface (#1D1B20)
409
413
  // Use android.R.attr.textColorPrimary which maps to onSurface in M3 themes
410
414
  int onSurfaceColor = MaterialColors.getColor(ctx, android.R.attr.textColorPrimary, 0xFF1D1B20);
@@ -465,8 +469,7 @@ public class FullScreenDialogFragment extends DialogFragment {
465
469
 
466
470
  CheckBox checkBox = new CheckBox(ctx);
467
471
  checkBox.setText(label);
468
- TextViewCompat.setTextAppearance(checkBox,
469
- com.google.android.material.R.style.TextAppearance_Material3_BodyLarge);
472
+ TextViewCompat.setTextAppearance(checkBox, com.google.android.material.R.style.TextAppearance_Material3_BodyLarge);
470
473
  // M3 list item text color: onSurface (#1D1B20)
471
474
  // Use android.R.attr.textColorPrimary which maps to onSurface in M3 themes
472
475
  int onSurfaceColor = MaterialColors.getColor(ctx, android.R.attr.textColorPrimary, 0xFF1D1B20);