capacitor-extended-dialog 0.0.9 → 0.0.10
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/android/src/main/java/com/albermonte/extendeddialog/DialogStyleOptions.java +83 -19
- package/android/src/main/java/com/albermonte/extendeddialog/ExtendedDialog.java +22 -14
- package/android/src/main/java/com/albermonte/extendeddialog/ExtendedDialogPlugin.java +1 -0
- package/android/src/main/java/com/albermonte/extendeddialog/FullScreenDialogFragment.java +20 -17
- package/android/src/main/java/com/albermonte/extendeddialog/SheetBottomDialogFragment.java +56 -19
- package/dist/esm/definitions.d.ts +22 -0
- package/dist/esm/definitions.js.map +1 -1
- package/dist/esm/web.js +20 -7
- package/dist/esm/web.js.map +1 -1
- package/dist/plugin.cjs.js +20 -7
- package/dist/plugin.cjs.js.map +1 -1
- package/dist/plugin.js +20 -7
- package/dist/plugin.js.map +1 -1
- package/ios/Sources/ExtendedDialogPlugin/ExtendedDialog.swift +6 -2
- package/ios/Sources/ExtendedDialogPlugin/ExtendedDialogPlugin.swift +2 -1
- package/ios/Sources/ExtendedDialogPlugin/FullScreenDialogViewController.swift +24 -3
- package/package.json +1 -1
|
@@ -16,6 +16,7 @@ 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";
|
|
19
20
|
|
|
20
21
|
private Integer buttonColor;
|
|
21
22
|
private Integer cancelButtonColor;
|
|
@@ -25,6 +26,7 @@ public class DialogStyleOptions {
|
|
|
25
26
|
private Float titleFontSize;
|
|
26
27
|
private Float messageFontSize;
|
|
27
28
|
private Float buttonFontSize;
|
|
29
|
+
private Float contentButtonSpacing;
|
|
28
30
|
|
|
29
31
|
public DialogStyleOptions() {}
|
|
30
32
|
|
|
@@ -43,34 +45,94 @@ public class DialogStyleOptions {
|
|
|
43
45
|
return (size != null && size > 0) ? size.floatValue() : null;
|
|
44
46
|
}
|
|
45
47
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
+
private static Float parseSpacing(Double size) {
|
|
49
|
+
return (size != null && size >= 0) ? size.floatValue() : null;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
public Integer getButtonColor() {
|
|
53
|
+
return buttonColor;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
public void setButtonColor(String hexColor) {
|
|
57
|
+
this.buttonColor = parseColor(hexColor);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
public Integer getCancelButtonColor() {
|
|
61
|
+
return cancelButtonColor;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
public void setCancelButtonColor(String hexColor) {
|
|
65
|
+
this.cancelButtonColor = parseColor(hexColor);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
public Integer getTitleColor() {
|
|
69
|
+
return titleColor;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
public void setTitleColor(String hexColor) {
|
|
73
|
+
this.titleColor = parseColor(hexColor);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
public Integer getMessageColor() {
|
|
77
|
+
return messageColor;
|
|
78
|
+
}
|
|
48
79
|
|
|
49
|
-
public
|
|
50
|
-
|
|
80
|
+
public void setMessageColor(String hexColor) {
|
|
81
|
+
this.messageColor = parseColor(hexColor);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
public Integer getBackgroundColor() {
|
|
85
|
+
return backgroundColor;
|
|
86
|
+
}
|
|
51
87
|
|
|
52
|
-
public
|
|
53
|
-
|
|
88
|
+
public void setBackgroundColor(String hexColor) {
|
|
89
|
+
this.backgroundColor = parseColor(hexColor);
|
|
90
|
+
}
|
|
54
91
|
|
|
55
|
-
public
|
|
56
|
-
|
|
92
|
+
public Float getTitleFontSize() {
|
|
93
|
+
return titleFontSize;
|
|
94
|
+
}
|
|
57
95
|
|
|
58
|
-
public
|
|
59
|
-
|
|
96
|
+
public void setTitleFontSize(Double size) {
|
|
97
|
+
this.titleFontSize = parseSize(size);
|
|
98
|
+
}
|
|
60
99
|
|
|
61
|
-
public Float
|
|
62
|
-
|
|
100
|
+
public Float getMessageFontSize() {
|
|
101
|
+
return messageFontSize;
|
|
102
|
+
}
|
|
63
103
|
|
|
64
|
-
public
|
|
65
|
-
|
|
104
|
+
public void setMessageFontSize(Double size) {
|
|
105
|
+
this.messageFontSize = parseSize(size);
|
|
106
|
+
}
|
|
66
107
|
|
|
67
|
-
public Float getButtonFontSize() {
|
|
68
|
-
|
|
108
|
+
public Float getButtonFontSize() {
|
|
109
|
+
return buttonFontSize;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
public void setButtonFontSize(Double size) {
|
|
113
|
+
this.buttonFontSize = parseSize(size);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
public Float getContentButtonSpacing() {
|
|
117
|
+
return contentButtonSpacing;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
public void setContentButtonSpacing(Double size) {
|
|
121
|
+
this.contentButtonSpacing = parseSpacing(size);
|
|
122
|
+
}
|
|
69
123
|
|
|
70
124
|
public boolean hasStyles() {
|
|
71
|
-
return
|
|
72
|
-
|
|
73
|
-
|
|
125
|
+
return (
|
|
126
|
+
buttonColor != null ||
|
|
127
|
+
cancelButtonColor != null ||
|
|
128
|
+
titleColor != null ||
|
|
129
|
+
messageColor != null ||
|
|
130
|
+
backgroundColor != null ||
|
|
131
|
+
titleFontSize != null ||
|
|
132
|
+
messageFontSize != null ||
|
|
133
|
+
buttonFontSize != null ||
|
|
134
|
+
contentButtonSpacing != null
|
|
135
|
+
);
|
|
74
136
|
}
|
|
75
137
|
|
|
76
138
|
public void writeToBundle(Bundle bundle) {
|
|
@@ -82,6 +144,7 @@ public class DialogStyleOptions {
|
|
|
82
144
|
if (titleFontSize != null) bundle.putFloat(KEY_TITLE_FONT_SIZE, titleFontSize);
|
|
83
145
|
if (messageFontSize != null) bundle.putFloat(KEY_MESSAGE_FONT_SIZE, messageFontSize);
|
|
84
146
|
if (buttonFontSize != null) bundle.putFloat(KEY_BUTTON_FONT_SIZE, buttonFontSize);
|
|
147
|
+
if (contentButtonSpacing != null) bundle.putFloat(KEY_CONTENT_BUTTON_SPACING, contentButtonSpacing);
|
|
85
148
|
}
|
|
86
149
|
|
|
87
150
|
public static DialogStyleOptions readFromBundle(Bundle bundle) {
|
|
@@ -94,6 +157,7 @@ public class DialogStyleOptions {
|
|
|
94
157
|
options.titleFontSize = bundle.containsKey(KEY_TITLE_FONT_SIZE) ? bundle.getFloat(KEY_TITLE_FONT_SIZE) : null;
|
|
95
158
|
options.messageFontSize = bundle.containsKey(KEY_MESSAGE_FONT_SIZE) ? bundle.getFloat(KEY_MESSAGE_FONT_SIZE) : null;
|
|
96
159
|
options.buttonFontSize = bundle.containsKey(KEY_BUTTON_FONT_SIZE) ? bundle.getFloat(KEY_BUTTON_FONT_SIZE) : null;
|
|
160
|
+
options.contentButtonSpacing = bundle.containsKey(KEY_CONTENT_BUTTON_SPACING) ? bundle.getFloat(KEY_CONTENT_BUTTON_SPACING) : null;
|
|
97
161
|
return options;
|
|
98
162
|
}
|
|
99
163
|
}
|
|
@@ -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(
|
|
202
|
-
|
|
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(
|
|
272
|
-
|
|
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(
|
|
374
|
-
|
|
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(
|
|
523
|
-
|
|
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(
|
|
666
|
-
|
|
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);
|
|
@@ -25,6 +25,7 @@ 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"));
|
|
28
29
|
return styleOptions;
|
|
29
30
|
}
|
|
30
31
|
|
|
@@ -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
|
-
|
|
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(
|
|
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
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
imm
|
|
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
|
-
|
|
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);
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
package com.albermonte.extendeddialog;
|
|
2
2
|
|
|
3
|
-
import android.
|
|
3
|
+
import android.app.Dialog;
|
|
4
4
|
import android.content.Context;
|
|
5
|
+
import android.content.DialogInterface;
|
|
5
6
|
import android.content.res.ColorStateList;
|
|
6
7
|
import android.graphics.Bitmap;
|
|
7
8
|
import android.graphics.BitmapFactory;
|
|
@@ -18,7 +19,6 @@ import android.widget.ImageView;
|
|
|
18
19
|
import android.widget.LinearLayout;
|
|
19
20
|
import android.widget.ScrollView;
|
|
20
21
|
import android.widget.TextView;
|
|
21
|
-
import android.app.Dialog;
|
|
22
22
|
import androidx.annotation.NonNull;
|
|
23
23
|
import androidx.annotation.Nullable;
|
|
24
24
|
import androidx.core.widget.TextViewCompat;
|
|
@@ -151,8 +151,7 @@ public class SheetBottomDialogFragment extends BottomSheetDialogFragment {
|
|
|
151
151
|
|
|
152
152
|
// ScrollView for content
|
|
153
153
|
ScrollView scrollView = new ScrollView(ctx);
|
|
154
|
-
scrollView.setLayoutParams(new LinearLayout.LayoutParams(
|
|
155
|
-
ViewGroup.LayoutParams.MATCH_PARENT, 0, 1f));
|
|
154
|
+
scrollView.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 0, 1f));
|
|
156
155
|
|
|
157
156
|
LinearLayout contentLayout = new LinearLayout(ctx);
|
|
158
157
|
contentLayout.setOrientation(LinearLayout.VERTICAL);
|
|
@@ -176,8 +175,7 @@ public class SheetBottomDialogFragment extends BottomSheetDialogFragment {
|
|
|
176
175
|
if (title != null && !title.isEmpty()) {
|
|
177
176
|
TextView titleView = new TextView(ctx);
|
|
178
177
|
titleView.setText(title);
|
|
179
|
-
TextViewCompat.setTextAppearance(titleView,
|
|
180
|
-
com.google.android.material.R.style.TextAppearance_Material3_HeadlineSmall);
|
|
178
|
+
TextViewCompat.setTextAppearance(titleView, com.google.android.material.R.style.TextAppearance_Material3_HeadlineSmall);
|
|
181
179
|
if (styleOptions.getTitleColor() != null) {
|
|
182
180
|
titleView.setTextColor(styleOptions.getTitleColor());
|
|
183
181
|
} else {
|
|
@@ -214,10 +212,37 @@ public class SheetBottomDialogFragment extends BottomSheetDialogFragment {
|
|
|
214
212
|
scrollView.addView(contentLayout);
|
|
215
213
|
root.addView(scrollView);
|
|
216
214
|
|
|
215
|
+
// Count rows for minimum height calculation
|
|
216
|
+
int rowCount = 0;
|
|
217
|
+
if (rowsJson != null) {
|
|
218
|
+
try {
|
|
219
|
+
JSONArray countRows = new JSONArray(rowsJson);
|
|
220
|
+
rowCount = countRows.length();
|
|
221
|
+
} catch (JSONException e) {
|
|
222
|
+
// ignore
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
217
226
|
// Button container pinned at bottom
|
|
218
227
|
LinearLayout buttonContainer = new LinearLayout(ctx);
|
|
219
228
|
buttonContainer.setOrientation(LinearLayout.VERTICAL);
|
|
220
|
-
|
|
229
|
+
float topSpacing = styleOptions.getContentButtonSpacing() != null ? styleOptions.getContentButtonSpacing() : 12f;
|
|
230
|
+
|
|
231
|
+
// For sheets with ≤4 rows and no explicit spacing, add extra spacing to reach ~50% screen height
|
|
232
|
+
if (rowCount <= 4 && styleOptions.getContentButtonSpacing() == null) {
|
|
233
|
+
int screenHeight = getResources().getDisplayMetrics().heightPixels;
|
|
234
|
+
float targetHeight = screenHeight * 0.5f;
|
|
235
|
+
// Estimate current content height: header + title + rows + buttons
|
|
236
|
+
float estimatedContent = (16 + 8 + 48 + 12 + 20) * density; // drag handle + logo area + title + margins
|
|
237
|
+
estimatedContent += rowCount * 56 * density; // ~56dp per row
|
|
238
|
+
estimatedContent += (48 + 12 + 48 + 4) * density; // buttons + padding
|
|
239
|
+
estimatedContent += topSpacing * density;
|
|
240
|
+
if (targetHeight > estimatedContent) {
|
|
241
|
+
topSpacing += (targetHeight - estimatedContent) / density;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
buttonContainer.setPadding(horizontalPadding, (int) (topSpacing * density), horizontalPadding, (int) (4 * density));
|
|
221
246
|
|
|
222
247
|
int primaryColor = MaterialColors.getColor(ctx, android.R.attr.colorPrimary, 0xFF6750A4);
|
|
223
248
|
|
|
@@ -228,7 +253,7 @@ public class SheetBottomDialogFragment extends BottomSheetDialogFragment {
|
|
|
228
253
|
// Confirm button (filled style with purple background, white text)
|
|
229
254
|
MaterialButton confirmBtn = new MaterialButton(ctx);
|
|
230
255
|
confirmBtn.setText(confirmButton);
|
|
231
|
-
confirmBtn.setOnClickListener(v -> {
|
|
256
|
+
confirmBtn.setOnClickListener((v) -> {
|
|
232
257
|
handleConfirm();
|
|
233
258
|
dismiss();
|
|
234
259
|
});
|
|
@@ -246,14 +271,16 @@ public class SheetBottomDialogFragment extends BottomSheetDialogFragment {
|
|
|
246
271
|
confirmBtn.setTextSize(TypedValue.COMPLEX_UNIT_SP, styleOptions.getButtonFontSize());
|
|
247
272
|
}
|
|
248
273
|
LinearLayout.LayoutParams confirmParams = new LinearLayout.LayoutParams(
|
|
249
|
-
ViewGroup.LayoutParams.MATCH_PARENT,
|
|
274
|
+
ViewGroup.LayoutParams.MATCH_PARENT,
|
|
275
|
+
ViewGroup.LayoutParams.WRAP_CONTENT
|
|
276
|
+
);
|
|
250
277
|
confirmBtn.setLayoutParams(confirmParams);
|
|
251
278
|
buttonContainer.addView(confirmBtn);
|
|
252
279
|
|
|
253
280
|
// Cancel button (text-only style, no background fill)
|
|
254
281
|
MaterialButton cancelBtn = new MaterialButton(ctx, null, android.R.attr.borderlessButtonStyle);
|
|
255
282
|
cancelBtn.setText(cancelButton);
|
|
256
|
-
cancelBtn.setOnClickListener(v -> {
|
|
283
|
+
cancelBtn.setOnClickListener((v) -> {
|
|
257
284
|
handleCancel();
|
|
258
285
|
dismiss();
|
|
259
286
|
});
|
|
@@ -270,7 +297,9 @@ public class SheetBottomDialogFragment extends BottomSheetDialogFragment {
|
|
|
270
297
|
cancelBtn.setTextSize(TypedValue.COMPLEX_UNIT_SP, styleOptions.getButtonFontSize());
|
|
271
298
|
}
|
|
272
299
|
LinearLayout.LayoutParams cancelParams = new LinearLayout.LayoutParams(
|
|
273
|
-
ViewGroup.LayoutParams.MATCH_PARENT,
|
|
300
|
+
ViewGroup.LayoutParams.MATCH_PARENT,
|
|
301
|
+
ViewGroup.LayoutParams.WRAP_CONTENT
|
|
302
|
+
);
|
|
274
303
|
cancelBtn.setLayoutParams(cancelParams);
|
|
275
304
|
buttonContainer.addView(cancelBtn);
|
|
276
305
|
|
|
@@ -290,7 +319,7 @@ public class SheetBottomDialogFragment extends BottomSheetDialogFragment {
|
|
|
290
319
|
BottomSheetDialog dialog = (BottomSheetDialog) getDialog();
|
|
291
320
|
if (dialog == null) return;
|
|
292
321
|
|
|
293
|
-
dialog.setOnShowListener(dialogInterface -> {
|
|
322
|
+
dialog.setOnShowListener((dialogInterface) -> {
|
|
294
323
|
BottomSheetDialog d = (BottomSheetDialog) dialogInterface;
|
|
295
324
|
FrameLayout bottomSheet = d.findViewById(com.google.android.material.R.id.design_bottom_sheet);
|
|
296
325
|
if (bottomSheet == null) return;
|
|
@@ -315,12 +344,20 @@ public class SheetBottomDialogFragment extends BottomSheetDialogFragment {
|
|
|
315
344
|
});
|
|
316
345
|
}
|
|
317
346
|
|
|
318
|
-
private LinearLayout createSheetRow(
|
|
347
|
+
private LinearLayout createSheetRow(
|
|
348
|
+
Context context,
|
|
349
|
+
JSONObject row,
|
|
350
|
+
DialogStyleOptions styleOptions,
|
|
351
|
+
float density,
|
|
352
|
+
boolean showDivider
|
|
353
|
+
) throws JSONException {
|
|
319
354
|
LinearLayout rowLayout = new LinearLayout(context);
|
|
320
355
|
rowLayout.setOrientation(LinearLayout.HORIZONTAL);
|
|
321
356
|
rowLayout.setGravity(Gravity.CENTER_VERTICAL);
|
|
322
357
|
LinearLayout.LayoutParams rowParams = new LinearLayout.LayoutParams(
|
|
323
|
-
LinearLayout.LayoutParams.MATCH_PARENT,
|
|
358
|
+
LinearLayout.LayoutParams.MATCH_PARENT,
|
|
359
|
+
LinearLayout.LayoutParams.WRAP_CONTENT
|
|
360
|
+
);
|
|
324
361
|
rowLayout.setLayoutParams(rowParams);
|
|
325
362
|
rowLayout.setPadding(0, (int) (8 * density), 0, (int) (8 * density));
|
|
326
363
|
|
|
@@ -338,8 +375,7 @@ public class SheetBottomDialogFragment extends BottomSheetDialogFragment {
|
|
|
338
375
|
// Row title
|
|
339
376
|
TextView rowTitle = new TextView(context);
|
|
340
377
|
rowTitle.setText(row.getString("title"));
|
|
341
|
-
TextViewCompat.setTextAppearance(rowTitle,
|
|
342
|
-
com.google.android.material.R.style.TextAppearance_Material3_TitleMedium);
|
|
378
|
+
TextViewCompat.setTextAppearance(rowTitle, com.google.android.material.R.style.TextAppearance_Material3_TitleMedium);
|
|
343
379
|
if (styleOptions.getMessageColor() != null) {
|
|
344
380
|
rowTitle.setTextColor(styleOptions.getMessageColor());
|
|
345
381
|
} else {
|
|
@@ -357,8 +393,7 @@ public class SheetBottomDialogFragment extends BottomSheetDialogFragment {
|
|
|
357
393
|
if (row.has("value") && !row.getString("value").isEmpty()) {
|
|
358
394
|
TextView rowValue = new TextView(context);
|
|
359
395
|
rowValue.setText(row.getString("value"));
|
|
360
|
-
TextViewCompat.setTextAppearance(rowValue,
|
|
361
|
-
com.google.android.material.R.style.TextAppearance_Material3_BodyLarge);
|
|
396
|
+
TextViewCompat.setTextAppearance(rowValue, com.google.android.material.R.style.TextAppearance_Material3_BodyLarge);
|
|
362
397
|
int onSurfaceVariantColor = MaterialColors.getColor(context, android.R.attr.textColorSecondary, 0xFF49454F);
|
|
363
398
|
rowValue.setTextColor(onSurfaceVariantColor);
|
|
364
399
|
rowValue.setGravity(Gravity.END);
|
|
@@ -381,7 +416,9 @@ public class SheetBottomDialogFragment extends BottomSheetDialogFragment {
|
|
|
381
416
|
View divider = new View(context);
|
|
382
417
|
divider.setBackgroundColor(MaterialColors.getColor(context, android.R.attr.listDivider, 0xFFE0E0E0));
|
|
383
418
|
LinearLayout.LayoutParams dividerParams = new LinearLayout.LayoutParams(
|
|
384
|
-
LinearLayout.LayoutParams.MATCH_PARENT,
|
|
419
|
+
LinearLayout.LayoutParams.MATCH_PARENT,
|
|
420
|
+
(int) (1 * density)
|
|
421
|
+
);
|
|
385
422
|
divider.setLayoutParams(dividerParams);
|
|
386
423
|
container.addView(divider);
|
|
387
424
|
}
|
|
@@ -38,6 +38,28 @@ export interface DialogStyleOptions {
|
|
|
38
38
|
* Font size for the button text in sp/pt (e.g., 14)
|
|
39
39
|
*/
|
|
40
40
|
buttonFontSize?: number;
|
|
41
|
+
/**
|
|
42
|
+
* Vertical spacing between dialog content and the confirm/cancel buttons in dp/pt/px (e.g., 16).
|
|
43
|
+
* Only applies to fullscreen and sheet modes.
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* // Fullscreen confirm with extra spacing between content and buttons
|
|
47
|
+
* await ExtendedDialog.confirm({
|
|
48
|
+
* title: 'Delete Account',
|
|
49
|
+
* message: 'This action cannot be undone.',
|
|
50
|
+
* mode: 'fullscreen',
|
|
51
|
+
* contentButtonSpacing: 32,
|
|
52
|
+
* });
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* // Sheet with tight spacing
|
|
56
|
+
* await ExtendedDialog.sheet({
|
|
57
|
+
* title: 'Order Summary',
|
|
58
|
+
* rows: [{ title: 'Total', value: '$9.99' }],
|
|
59
|
+
* contentButtonSpacing: 8,
|
|
60
|
+
* });
|
|
61
|
+
*/
|
|
62
|
+
contentButtonSpacing?: number;
|
|
41
63
|
}
|
|
42
64
|
export interface BaseDialogOptions extends DialogStyleOptions {
|
|
43
65
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * Dialog presentation mode.\n *\n * - `'basic'` — Standard modal dialog (default)\n * - `'fullscreen'` — Full-screen dialog presentation\n */\nexport type DialogMode = 'basic' | 'fullscreen';\n\nexport interface DialogStyleOptions {\n /**\n * Color for the OK/primary button (hex format, e.g., \"#FF5722\")\n */\n buttonColor?: string;\n /**\n * Color for the cancel button (hex format, e.g., \"#757575\")\n */\n cancelButtonColor?: string;\n /**\n * Color for the title text (hex format, e.g., \"#000000\")\n */\n titleColor?: string;\n /**\n * Color for the message text (hex format, e.g., \"#666666\")\n */\n messageColor?: string;\n /**\n * Background color of the dialog (hex format, e.g., \"#FFFFFF\")\n */\n backgroundColor?: string;\n /**\n * Font size for the title text in sp/pt (e.g., 20)\n */\n titleFontSize?: number;\n /**\n * Font size for the message text in sp/pt (e.g., 16)\n */\n messageFontSize?: number;\n /**\n * Font size for the button text in sp/pt (e.g., 14)\n */\n buttonFontSize?: number;\n}\n\nexport interface BaseDialogOptions extends DialogStyleOptions {\n /**\n * Title displayed at the top of the dialog.\n */\n title?: string;\n /**\n * Message body displayed in the dialog.\n */\n message: string;\n /**\n * Presentation mode for the dialog.\n *\n * @default 'basic'\n */\n mode?: DialogMode;\n}\n\nexport interface AlertOptions extends BaseDialogOptions {\n /**\n * Title for the dismiss button.\n *\n * @default \"OK\"\n */\n buttonTitle?: string;\n}\n\nexport interface ConfirmOptions extends BaseDialogOptions {\n /**\n * Title for the confirmation button.\n *\n * @default \"OK\"\n */\n okButtonTitle?: string;\n /**\n * Title for the cancel button.\n *\n * @default \"Cancel\"\n */\n cancelButtonTitle?: string;\n}\n\nexport interface PromptOptions extends BaseDialogOptions {\n /**\n * Title for the confirmation button.\n *\n * @default \"OK\"\n */\n okButtonTitle?: string;\n /**\n * Title for the cancel button.\n *\n * @default \"Cancel\"\n */\n cancelButtonTitle?: string;\n /**\n * Placeholder text shown in the input field when empty.\n */\n inputPlaceholder?: string;\n /**\n * Pre-filled value for the input field.\n */\n inputText?: string;\n /**\n * Whether to automatically focus the input field and open the keyboard when the dialog appears.\n *\n * Note: On iOS, basic (non-fullscreen) dialogs always auto-focus the input field due to\n * UIAlertController's built-in behavior. This option only takes effect on iOS when using\n * fullscreen mode (`mode: 'fullscreen'`). On Android and web, this works for all modes.\n *\n * @default false\n */\n focusInput?: boolean;\n}\n\nexport interface SelectOption {\n /**\n * Display text for the option.\n */\n label: string;\n /**\n * Value returned when the option is selected.\n */\n value: string;\n}\n\nexport interface SingleSelectOptions extends BaseDialogOptions {\n /**\n * List of options to display for selection.\n */\n options: SelectOption[];\n /**\n * Value of the initially selected option.\n */\n selectedValue?: string;\n /**\n * Title for the confirmation button.\n *\n * @default \"OK\"\n */\n okButtonTitle?: string;\n /**\n * Title for the cancel button.\n *\n * @default \"Cancel\"\n */\n cancelButtonTitle?: string;\n}\n\nexport interface MultiSelectOptions extends BaseDialogOptions {\n /**\n * List of options to display for selection.\n */\n options: SelectOption[];\n /**\n * Values of the initially selected options.\n */\n selectedValues?: string[];\n /**\n * Title for the confirmation button.\n *\n * @default \"OK\"\n */\n okButtonTitle?: string;\n /**\n * Title for the cancel button.\n *\n * @default \"Cancel\"\n */\n cancelButtonTitle?: string;\n}\n\nexport interface ConfirmResult {\n /**\n * Whether the user confirmed (`true`) or cancelled (`false`).\n */\n value: boolean;\n}\n\nexport interface PromptResult {\n /**\n * The text entered by the user. Empty string if cancelled.\n */\n value: string;\n /**\n * Whether the user cancelled the dialog.\n */\n cancelled: boolean;\n}\n\nexport interface SingleSelectResult {\n /**\n * The value of the selected option, or `null` if cancelled.\n */\n value: string | null;\n /**\n * Whether the user cancelled the dialog.\n */\n cancelled: boolean;\n}\n\nexport interface MultiSelectResult {\n /**\n * The values of the selected options. Empty array if cancelled.\n */\n values: string[];\n /**\n * Whether the user cancelled the dialog.\n */\n cancelled: boolean;\n}\n\nexport interface SheetRow {\n /** Row title (required) */\n title: string;\n /** Optional logo/icon - supports base64 data URL or HTTP/HTTPS URL */\n logo?: string;\n /** Optional value displayed on the right */\n value?: string;\n}\n\nexport interface SheetOptions extends DialogStyleOptions {\n /** Header logo - supports base64 data URL or HTTP/HTTPS URL */\n headerLogo?: string;\n /** Sheet title */\n title: string;\n /** Description rows */\n rows: SheetRow[];\n /** Confirm button title */\n confirmButtonTitle?: string; // default: \"Confirm\"\n /** Cancel button title */\n cancelButtonTitle?: string; // default: \"Cancel\"\n /** Dialog mode */\n mode?: DialogMode;\n}\n\nexport interface SheetResult {\n /** True if confirmed, false if cancelled */\n confirmed: boolean;\n}\n\nexport interface ExtendedDialogPlugin {\n /**\n * Show an alert dialog with a single dismiss button.\n *\n * @param options - Alert configuration options.\n */\n alert(options: AlertOptions): Promise<void>;\n /**\n * Show a confirmation dialog with OK and Cancel buttons.\n *\n * @param options - Confirm configuration options.\n * @returns The user's confirmation choice.\n */\n confirm(options: ConfirmOptions): Promise<ConfirmResult>;\n /**\n * Show a prompt dialog with a text input field.\n *\n * @param options - Prompt configuration options.\n * @returns The entered text and whether the dialog was cancelled.\n */\n prompt(options: PromptOptions): Promise<PromptResult>;\n /**\n * Show a single-select dialog where the user picks one option.\n *\n * @param options - Single select configuration options.\n * @returns The selected value and whether the dialog was cancelled.\n */\n singleSelect(options: SingleSelectOptions): Promise<SingleSelectResult>;\n /**\n * Show a multi-select dialog where the user picks one or more options.\n *\n * @param options - Multi select configuration options.\n * @returns The selected values and whether the dialog was cancelled.\n */\n multiSelect(options: MultiSelectOptions): Promise<MultiSelectResult>;\n /**\n * Show a sheet dialog with a header, title, and structured data rows.\n *\n * @param options - Sheet configuration options.\n * @returns Whether the user confirmed or cancelled the sheet.\n */\n sheet(options: SheetOptions): Promise<SheetResult>;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * Dialog presentation mode.\n *\n * - `'basic'` — Standard modal dialog (default)\n * - `'fullscreen'` — Full-screen dialog presentation\n */\nexport type DialogMode = 'basic' | 'fullscreen';\n\nexport interface DialogStyleOptions {\n /**\n * Color for the OK/primary button (hex format, e.g., \"#FF5722\")\n */\n buttonColor?: string;\n /**\n * Color for the cancel button (hex format, e.g., \"#757575\")\n */\n cancelButtonColor?: string;\n /**\n * Color for the title text (hex format, e.g., \"#000000\")\n */\n titleColor?: string;\n /**\n * Color for the message text (hex format, e.g., \"#666666\")\n */\n messageColor?: string;\n /**\n * Background color of the dialog (hex format, e.g., \"#FFFFFF\")\n */\n backgroundColor?: string;\n /**\n * Font size for the title text in sp/pt (e.g., 20)\n */\n titleFontSize?: number;\n /**\n * Font size for the message text in sp/pt (e.g., 16)\n */\n messageFontSize?: number;\n /**\n * Font size for the button text in sp/pt (e.g., 14)\n */\n buttonFontSize?: number;\n /**\n * Vertical spacing between dialog content and the confirm/cancel buttons in dp/pt/px (e.g., 16).\n * Only applies to fullscreen and sheet modes.\n *\n * @example\n * // Fullscreen confirm with extra spacing between content and buttons\n * await ExtendedDialog.confirm({\n * title: 'Delete Account',\n * message: 'This action cannot be undone.',\n * mode: 'fullscreen',\n * contentButtonSpacing: 32,\n * });\n *\n * @example\n * // Sheet with tight spacing\n * await ExtendedDialog.sheet({\n * title: 'Order Summary',\n * rows: [{ title: 'Total', value: '$9.99' }],\n * contentButtonSpacing: 8,\n * });\n */\n contentButtonSpacing?: number;\n}\n\nexport interface BaseDialogOptions extends DialogStyleOptions {\n /**\n * Title displayed at the top of the dialog.\n */\n title?: string;\n /**\n * Message body displayed in the dialog.\n */\n message: string;\n /**\n * Presentation mode for the dialog.\n *\n * @default 'basic'\n */\n mode?: DialogMode;\n}\n\nexport interface AlertOptions extends BaseDialogOptions {\n /**\n * Title for the dismiss button.\n *\n * @default \"OK\"\n */\n buttonTitle?: string;\n}\n\nexport interface ConfirmOptions extends BaseDialogOptions {\n /**\n * Title for the confirmation button.\n *\n * @default \"OK\"\n */\n okButtonTitle?: string;\n /**\n * Title for the cancel button.\n *\n * @default \"Cancel\"\n */\n cancelButtonTitle?: string;\n}\n\nexport interface PromptOptions extends BaseDialogOptions {\n /**\n * Title for the confirmation button.\n *\n * @default \"OK\"\n */\n okButtonTitle?: string;\n /**\n * Title for the cancel button.\n *\n * @default \"Cancel\"\n */\n cancelButtonTitle?: string;\n /**\n * Placeholder text shown in the input field when empty.\n */\n inputPlaceholder?: string;\n /**\n * Pre-filled value for the input field.\n */\n inputText?: string;\n /**\n * Whether to automatically focus the input field and open the keyboard when the dialog appears.\n *\n * Note: On iOS, basic (non-fullscreen) dialogs always auto-focus the input field due to\n * UIAlertController's built-in behavior. This option only takes effect on iOS when using\n * fullscreen mode (`mode: 'fullscreen'`). On Android and web, this works for all modes.\n *\n * @default false\n */\n focusInput?: boolean;\n}\n\nexport interface SelectOption {\n /**\n * Display text for the option.\n */\n label: string;\n /**\n * Value returned when the option is selected.\n */\n value: string;\n}\n\nexport interface SingleSelectOptions extends BaseDialogOptions {\n /**\n * List of options to display for selection.\n */\n options: SelectOption[];\n /**\n * Value of the initially selected option.\n */\n selectedValue?: string;\n /**\n * Title for the confirmation button.\n *\n * @default \"OK\"\n */\n okButtonTitle?: string;\n /**\n * Title for the cancel button.\n *\n * @default \"Cancel\"\n */\n cancelButtonTitle?: string;\n}\n\nexport interface MultiSelectOptions extends BaseDialogOptions {\n /**\n * List of options to display for selection.\n */\n options: SelectOption[];\n /**\n * Values of the initially selected options.\n */\n selectedValues?: string[];\n /**\n * Title for the confirmation button.\n *\n * @default \"OK\"\n */\n okButtonTitle?: string;\n /**\n * Title for the cancel button.\n *\n * @default \"Cancel\"\n */\n cancelButtonTitle?: string;\n}\n\nexport interface ConfirmResult {\n /**\n * Whether the user confirmed (`true`) or cancelled (`false`).\n */\n value: boolean;\n}\n\nexport interface PromptResult {\n /**\n * The text entered by the user. Empty string if cancelled.\n */\n value: string;\n /**\n * Whether the user cancelled the dialog.\n */\n cancelled: boolean;\n}\n\nexport interface SingleSelectResult {\n /**\n * The value of the selected option, or `null` if cancelled.\n */\n value: string | null;\n /**\n * Whether the user cancelled the dialog.\n */\n cancelled: boolean;\n}\n\nexport interface MultiSelectResult {\n /**\n * The values of the selected options. Empty array if cancelled.\n */\n values: string[];\n /**\n * Whether the user cancelled the dialog.\n */\n cancelled: boolean;\n}\n\nexport interface SheetRow {\n /** Row title (required) */\n title: string;\n /** Optional logo/icon - supports base64 data URL or HTTP/HTTPS URL */\n logo?: string;\n /** Optional value displayed on the right */\n value?: string;\n}\n\nexport interface SheetOptions extends DialogStyleOptions {\n /** Header logo - supports base64 data URL or HTTP/HTTPS URL */\n headerLogo?: string;\n /** Sheet title */\n title: string;\n /** Description rows */\n rows: SheetRow[];\n /** Confirm button title */\n confirmButtonTitle?: string; // default: \"Confirm\"\n /** Cancel button title */\n cancelButtonTitle?: string; // default: \"Cancel\"\n /** Dialog mode */\n mode?: DialogMode;\n}\n\nexport interface SheetResult {\n /** True if confirmed, false if cancelled */\n confirmed: boolean;\n}\n\nexport interface ExtendedDialogPlugin {\n /**\n * Show an alert dialog with a single dismiss button.\n *\n * @param options - Alert configuration options.\n */\n alert(options: AlertOptions): Promise<void>;\n /**\n * Show a confirmation dialog with OK and Cancel buttons.\n *\n * @param options - Confirm configuration options.\n * @returns The user's confirmation choice.\n */\n confirm(options: ConfirmOptions): Promise<ConfirmResult>;\n /**\n * Show a prompt dialog with a text input field.\n *\n * @param options - Prompt configuration options.\n * @returns The entered text and whether the dialog was cancelled.\n */\n prompt(options: PromptOptions): Promise<PromptResult>;\n /**\n * Show a single-select dialog where the user picks one option.\n *\n * @param options - Single select configuration options.\n * @returns The selected value and whether the dialog was cancelled.\n */\n singleSelect(options: SingleSelectOptions): Promise<SingleSelectResult>;\n /**\n * Show a multi-select dialog where the user picks one or more options.\n *\n * @param options - Multi select configuration options.\n * @returns The selected values and whether the dialog was cancelled.\n */\n multiSelect(options: MultiSelectOptions): Promise<MultiSelectResult>;\n /**\n * Show a sheet dialog with a header, title, and structured data rows.\n *\n * @param options - Sheet configuration options.\n * @returns Whether the user confirmed or cancelled the sheet.\n */\n sheet(options: SheetOptions): Promise<SheetResult>;\n}\n"]}
|
package/dist/esm/web.js
CHANGED
|
@@ -49,7 +49,7 @@ export class ExtendedDialogWeb extends WebPlugin {
|
|
|
49
49
|
optionsContainer.appendChild(label);
|
|
50
50
|
});
|
|
51
51
|
dialog.appendChild(optionsContainer);
|
|
52
|
-
const buttonContainer = this.createButtonContainer();
|
|
52
|
+
const buttonContainer = this.createButtonContainer(options.contentButtonSpacing);
|
|
53
53
|
const cancelButton = this.createButton((_b = options.cancelButtonTitle) !== null && _b !== void 0 ? _b : 'Cancel', false, () => {
|
|
54
54
|
this.removeOverlay(overlay);
|
|
55
55
|
resolve({ value: null, cancelled: true });
|
|
@@ -98,7 +98,7 @@ export class ExtendedDialogWeb extends WebPlugin {
|
|
|
98
98
|
optionsContainer.appendChild(label);
|
|
99
99
|
});
|
|
100
100
|
dialog.appendChild(optionsContainer);
|
|
101
|
-
const buttonContainer = this.createButtonContainer();
|
|
101
|
+
const buttonContainer = this.createButtonContainer(options.contentButtonSpacing);
|
|
102
102
|
const cancelButton = this.createButton((_b = options.cancelButtonTitle) !== null && _b !== void 0 ? _b : 'Cancel', false, () => {
|
|
103
103
|
this.removeOverlay(overlay);
|
|
104
104
|
resolve({ values: [], cancelled: true });
|
|
@@ -162,9 +162,10 @@ export class ExtendedDialogWeb extends WebPlugin {
|
|
|
162
162
|
}
|
|
163
163
|
return dialog;
|
|
164
164
|
}
|
|
165
|
-
createButtonContainer() {
|
|
165
|
+
createButtonContainer(contentButtonSpacing) {
|
|
166
166
|
const container = document.createElement('div');
|
|
167
|
-
|
|
167
|
+
const spacing = contentButtonSpacing !== null && contentButtonSpacing !== void 0 ? contentButtonSpacing : 24;
|
|
168
|
+
container.style.cssText = `display: flex; justify-content: flex-end; gap: 8px; margin-top: ${spacing}px;`;
|
|
168
169
|
return container;
|
|
169
170
|
}
|
|
170
171
|
createButton(text, primary, onClick, styleOptions) {
|
|
@@ -200,7 +201,8 @@ export class ExtendedDialogWeb extends WebPlugin {
|
|
|
200
201
|
if (options.headerLogo) {
|
|
201
202
|
const headerLogo = document.createElement('img');
|
|
202
203
|
headerLogo.src = options.headerLogo;
|
|
203
|
-
headerLogo.style.cssText =
|
|
204
|
+
headerLogo.style.cssText =
|
|
205
|
+
'width: 48px; height: 48px; object-fit: contain; margin-bottom: 12px; border-radius: 8px;';
|
|
204
206
|
headerLogo.onerror = () => {
|
|
205
207
|
headerLogo.style.display = 'none';
|
|
206
208
|
};
|
|
@@ -228,7 +230,8 @@ export class ExtendedDialogWeb extends WebPlugin {
|
|
|
228
230
|
if (row.logo) {
|
|
229
231
|
const rowLogo = document.createElement('img');
|
|
230
232
|
rowLogo.src = row.logo;
|
|
231
|
-
rowLogo.style.cssText =
|
|
233
|
+
rowLogo.style.cssText =
|
|
234
|
+
'width: 24px; height: 24px; object-fit: contain; margin-right: 12px; border-radius: 4px; flex-shrink: 0;';
|
|
232
235
|
rowLogo.onerror = () => {
|
|
233
236
|
rowLogo.style.display = 'none';
|
|
234
237
|
};
|
|
@@ -249,8 +252,18 @@ export class ExtendedDialogWeb extends WebPlugin {
|
|
|
249
252
|
rowsContainer.appendChild(rowEl);
|
|
250
253
|
});
|
|
251
254
|
dialog.appendChild(rowsContainer);
|
|
255
|
+
// For sheets with ≤4 rows and no explicit spacing, add extra spacing to reach ~50% viewport height
|
|
256
|
+
let sheetSpacing = options.contentButtonSpacing;
|
|
257
|
+
if (sheetSpacing === undefined && options.rows.length <= 4) {
|
|
258
|
+
const targetHeight = window.innerHeight * 0.5;
|
|
259
|
+
// Estimate content: padding(48) + header(~80) + rows(~49 each) + buttons(~44) + default spacing(24)
|
|
260
|
+
const estimatedHeight = 48 + 80 + options.rows.length * 49 + 44 + 24;
|
|
261
|
+
if (targetHeight > estimatedHeight) {
|
|
262
|
+
sheetSpacing = 24 + (targetHeight - estimatedHeight);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
252
265
|
// Button container
|
|
253
|
-
const buttonContainer = this.createButtonContainer();
|
|
266
|
+
const buttonContainer = this.createButtonContainer(sheetSpacing);
|
|
254
267
|
const cancelButton = this.createButton((_c = options.cancelButtonTitle) !== null && _c !== void 0 ? _c : 'Cancel', false, () => {
|
|
255
268
|
this.removeOverlay(overlay);
|
|
256
269
|
resolve({ confirmed: false });
|