@12-apps/ui 6.77.0 → 6.77.2
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/dist/_internal/components/data-display/Alert/Alert.content.js +2 -2
- package/dist/_internal/components/data-display/Alert/Alert.js +4 -4
- package/dist/_internal/components/data-display/Alert/Alert.metrics.js +1 -1
- package/dist/_internal/components/data-display/Alert/Alert.styles.js +2 -2
- package/dist/_internal/components/data-display/Banner/Banner.js +3 -3
- package/dist/_internal/components/data-display/Banner/Banner.styles.js +2 -2
- package/dist/_internal/components/data-display/CardKit/CardKebab.js +2 -2
- package/dist/_internal/components/data-display/CardKit/card-actions-context.js +5 -5
- package/dist/_internal/components/data-display/CardKit/use-remove-confirm.js +8 -8
- package/dist/_internal/components/data-display/CardKit/use-row-confirm.js +2 -2
- package/dist/_internal/components/data-display/DataViews/DataViewsGrid.js +17 -17
- package/dist/_internal/components/data-display/DataViews/DataViewsTableBase.js +27 -27
- package/dist/_internal/components/data-display/DataViews/DeleteViewDialog.js +2 -2
- package/dist/_internal/components/data-display/DataViews/ManageViewsDialog.js +3 -3
- package/dist/_internal/components/data-display/DataViews/SaveViewModal.js +2 -2
- package/dist/_internal/components/data-display/DataViews/data-views-card-body.js +3 -3
- package/dist/_internal/components/data-display/DataViews/data-views-columns.js +3 -3
- package/dist/_internal/components/data-display/DataViews/data-views-display-panel.js +3 -3
- package/dist/_internal/components/data-display/DataViews/data-views-empty.js +2 -2
- package/dist/_internal/components/data-display/DataViews/data-views-export.js +2 -2
- package/dist/_internal/components/data-display/DataViews/data-views-grid-bodies.js +5 -5
- package/dist/_internal/components/data-display/DataViews/data-views-grid-helpers.js +2 -2
- package/dist/_internal/components/data-display/DataViews/data-views-grid-parts.js +14 -14
- package/dist/_internal/components/data-display/DataViews/data-views-inline-bar.js +3 -3
- package/dist/_internal/components/data-display/DataViews/data-views-more-filters.js +2 -2
- package/dist/_internal/components/data-display/DataViews/data-views-select-all-strip.js +2 -2
- package/dist/_internal/components/data-display/DataViews/data-views-shell-toolbar.js +7 -7
- package/dist/_internal/components/data-display/DataViews/data-views-table-parts.js +9 -9
- package/dist/_internal/components/data-display/DataViews/data-views-toolbar.js +6 -6
- package/dist/_internal/components/data-display/DataViews/data-views-view-nav.js +2 -2
- package/dist/_internal/components/data-display/DataViews/use-data-views-state.js +4 -4
- package/dist/_internal/components/data-display/index.js +6 -6
- package/dist/_internal/components/feedback/ConfirmAction/ConfirmButton.js +2 -2
- package/dist/_internal/components/feedback/NotificationStatusNotice/NotificationStatusNotice.js +6 -6
- package/dist/_internal/components/feedback/index.js +7 -7
- package/dist/_internal/components/form/Button/Button.js +1 -1
- package/dist/_internal/components/form/index.js +1 -1
- package/dist/_internal/components/form/total-form/SubmitButton.js +2 -2
- package/dist/_internal/components/index.js +17 -17
- package/dist/_internal/components/layout/SettingCard/SettingCard.js +4 -4
- package/dist/_internal/components/layout/SettingCard/SettingCard.parts.js +2 -2
- package/dist/_internal/components/layout/SettingCard/SettingCard.summary.js +3 -3
- package/dist/_internal/components/layout/SettingCard/SettingGrid.js +3 -3
- package/dist/_internal/components/layout/SettingCard/SettingGroup.js +5 -5
- package/dist/_internal/components/layout/SettingCard/SettingSwitch.js +4 -4
- package/dist/_internal/components/layout/SettingCard/SettingToggle.js +5 -5
- package/dist/_internal/components/layout/index.js +8 -8
- package/dist/_internal/components/navigation/AppHeader/AppHeader.details.js +2 -2
- package/dist/_internal/components/navigation/index.js +2 -2
- package/dist/_internal/social-login-button/social-login-button.js +2 -2
- package/dist/_internal/user-avatar/user-avatar.js +2 -2
- package/dist/{chunk-BF3SGOWT.js → chunk-2ONUSNPZ.js} +2 -2
- package/dist/{chunk-ULK4AGG4.js → chunk-3EIRRLCQ.js} +2 -2
- package/dist/{chunk-TVXUOJAL.js → chunk-4NG3LTRX.js} +2 -2
- package/dist/{chunk-XZE5FIRB.js → chunk-5IIHAYFF.js} +2 -2
- package/dist/{chunk-72L5C74V.js → chunk-5M7T36AT.js} +3 -3
- package/dist/{chunk-J32XJALK.js → chunk-5WUXJDFP.js} +2 -2
- package/dist/{chunk-JNVUB2D4.js → chunk-5ZY3IIIG.js} +2 -2
- package/dist/chunk-5ZY3IIIG.js.map +1 -0
- package/dist/{chunk-3MQZBBUW.js → chunk-7FFY4LJY.js} +2 -2
- package/dist/{chunk-IVI574Y5.js → chunk-7HZ36QDH.js} +16 -7
- package/dist/chunk-7HZ36QDH.js.map +1 -0
- package/dist/{chunk-ENXGWNCX.js → chunk-7LMR2H7O.js} +4 -4
- package/dist/{chunk-H7QTDKA6.js → chunk-BGSUSSAV.js} +2 -2
- package/dist/{chunk-FR2RJXHS.js → chunk-C2NNJMVY.js} +3 -3
- package/dist/{chunk-NIZUFPV3.js → chunk-CW5Z67NA.js} +2 -2
- package/dist/{chunk-BEHM2VLH.js → chunk-FVNY5BNV.js} +2 -2
- package/dist/{chunk-X2SJJZFH.js → chunk-GG7IOJAG.js} +4 -4
- package/dist/{chunk-J5QNJERV.js → chunk-HHFVDOA7.js} +3 -3
- package/dist/{chunk-HVGQH54G.js → chunk-HMWSMRLM.js} +2 -2
- package/dist/{chunk-MA6ENJDP.js → chunk-HXCUKZOB.js} +3 -3
- package/dist/{chunk-CCJJTLF7.js → chunk-L5RS6QAT.js} +2 -2
- package/dist/{chunk-ZSCKXOKE.js → chunk-NQCTANF3.js} +4 -4
- package/dist/{chunk-NIENIKZ5.js → chunk-NRADSKGH.js} +2 -2
- package/dist/{chunk-725H45MT.js → chunk-NZXRPWPW.js} +4 -4
- package/dist/{chunk-LBEZ7A3F.js → chunk-OK3OJGJY.js} +3 -3
- package/dist/{chunk-WJEJ65TF.js → chunk-OY437NRJ.js} +2 -2
- package/dist/{chunk-QZX43FIC.js → chunk-QIP37Y2C.js} +2 -2
- package/dist/{chunk-Y2CCXB7R.js → chunk-QITQFCFY.js} +2 -2
- package/dist/{chunk-P4LR2GLN.js → chunk-R2ODLE6G.js} +2 -2
- package/dist/{chunk-UFNXYOHZ.js → chunk-RCTHCXS6.js} +2 -2
- package/dist/{chunk-VQSBZPKO.js → chunk-RVZMKGWQ.js} +2 -2
- package/dist/{chunk-QWSYHENP.js → chunk-SKIAWOUC.js} +4 -4
- package/dist/{chunk-3FDSXSEP.js → chunk-TDWA2XFJ.js} +2 -2
- package/dist/{chunk-VWVA74JY.js → chunk-UXQVJXQ3.js} +2 -2
- package/dist/{chunk-BEYLI32I.js → chunk-WOUJSKQB.js} +3 -3
- package/dist/{chunk-NDQJDA7O.js → chunk-WULEQKU7.js} +2 -2
- package/dist/{chunk-4QGPRORO.js → chunk-X2GWR75Q.js} +2 -2
- package/dist/{chunk-NKBCUR4V.js → chunk-X3DN2BE3.js} +2 -2
- package/dist/{chunk-B34WHRKH.js → chunk-XGKUXYAD.js} +2 -2
- package/dist/{chunk-TRYYYWV3.js → chunk-Y2CHJLWD.js} +6 -6
- package/dist/{chunk-QDG6V7OC.js → chunk-YNZUYZ2O.js} +3 -3
- package/dist/{chunk-364NH2NY.js → chunk-YOXYSAUI.js} +20 -11
- package/dist/chunk-YOXYSAUI.js.map +1 -0
- package/dist/{chunk-T2KONJ45.js → chunk-Z4ZFJ565.js} +3 -3
- package/dist/{chunk-JA3WJPXH.js → chunk-ZAZOBTVS.js} +2 -2
- package/dist/{chunk-SZSS5KKX.js → chunk-ZCXQ4ZB6.js} +2 -2
- package/dist/{chunk-P7VAMJFJ.js → chunk-ZE4HF3KC.js} +3 -3
- package/dist/data-display/Alert.js +4 -4
- package/dist/data-display/Banner.js +3 -3
- package/dist/data-display/CardKit.js +9 -9
- package/dist/data-display/DataViews.js +27 -27
- package/dist/feedback/ConfirmAction.js +2 -2
- package/dist/feedback/NotificationStatusNotice.js +6 -6
- package/dist/form/Button.js +1 -1
- package/dist/form/total-form.js +2 -2
- package/dist/layout/SettingCard.js +8 -8
- package/dist/native/chunks/{chunk-2MFMON74.js → chunk-EZHCNYQO.js} +67 -33
- package/dist/native/chunks/chunk-EZHCNYQO.js.map +1 -0
- package/dist/native/chunks/{chunk-H22XVP5O.js → chunk-TZPNJ4AU.js} +2 -2
- package/dist/native/data-display/Alert.js.map +1 -1
- package/dist/native/data-display/EmptyState.js +2 -2
- package/dist/native/data-display/ErrorState.js +1 -1
- package/dist/native/data-display/FleetMap.js +2 -2
- package/dist/native/form/Button.js +1 -1
- package/dist/navigation/AppHeader.js +2 -2
- package/dist/social-login-button.js +2 -2
- package/dist/types/components/data-display/Alert/Alert.content.d.ts.map +1 -1
- package/dist/types/components/data-display/Alert/Alert.metrics.d.ts +2 -1
- package/dist/types/components/data-display/Alert/Alert.metrics.d.ts.map +1 -1
- package/dist/types/components/form/Button/Button.d.ts.map +1 -1
- package/dist/types/components/form/Button/Button.native.loading.d.ts +36 -0
- package/dist/types/components/form/Button/Button.native.loading.d.ts.map +1 -0
- package/dist/types-native/components/data-display/Alert/Alert.metrics.d.ts +2 -1
- package/dist/types-native/components/data-display/Alert/Alert.metrics.d.ts.map +1 -1
- package/dist/types-native/components/form/Button/Button.native.d.ts.map +1 -1
- package/dist/types-native/components/form/Button/Button.native.loading.d.ts +36 -0
- package/dist/types-native/components/form/Button/Button.native.loading.d.ts.map +1 -0
- package/dist/user-avatar.js +2 -2
- package/package.json +1 -1
- package/src/components/data-display/Alert/Alert.content.tsx +16 -5
- package/src/components/data-display/Alert/Alert.metrics.ts +2 -2
- package/src/components/form/Button/Button.md +4 -3
- package/src/components/form/Button/Button.native.loading.tsx +89 -0
- package/src/components/form/Button/Button.native.tsx +14 -24
- package/src/components/form/Button/Button.tsx +47 -16
- package/dist/chunk-364NH2NY.js.map +0 -1
- package/dist/chunk-IVI574Y5.js.map +0 -1
- package/dist/chunk-JNVUB2D4.js.map +0 -1
- package/dist/native/chunks/chunk-2MFMON74.js.map +0 -1
- /package/dist/{chunk-BF3SGOWT.js.map → chunk-2ONUSNPZ.js.map} +0 -0
- /package/dist/{chunk-ULK4AGG4.js.map → chunk-3EIRRLCQ.js.map} +0 -0
- /package/dist/{chunk-TVXUOJAL.js.map → chunk-4NG3LTRX.js.map} +0 -0
- /package/dist/{chunk-XZE5FIRB.js.map → chunk-5IIHAYFF.js.map} +0 -0
- /package/dist/{chunk-72L5C74V.js.map → chunk-5M7T36AT.js.map} +0 -0
- /package/dist/{chunk-J32XJALK.js.map → chunk-5WUXJDFP.js.map} +0 -0
- /package/dist/{chunk-3MQZBBUW.js.map → chunk-7FFY4LJY.js.map} +0 -0
- /package/dist/{chunk-ENXGWNCX.js.map → chunk-7LMR2H7O.js.map} +0 -0
- /package/dist/{chunk-H7QTDKA6.js.map → chunk-BGSUSSAV.js.map} +0 -0
- /package/dist/{chunk-FR2RJXHS.js.map → chunk-C2NNJMVY.js.map} +0 -0
- /package/dist/{chunk-NIZUFPV3.js.map → chunk-CW5Z67NA.js.map} +0 -0
- /package/dist/{chunk-BEHM2VLH.js.map → chunk-FVNY5BNV.js.map} +0 -0
- /package/dist/{chunk-X2SJJZFH.js.map → chunk-GG7IOJAG.js.map} +0 -0
- /package/dist/{chunk-J5QNJERV.js.map → chunk-HHFVDOA7.js.map} +0 -0
- /package/dist/{chunk-HVGQH54G.js.map → chunk-HMWSMRLM.js.map} +0 -0
- /package/dist/{chunk-MA6ENJDP.js.map → chunk-HXCUKZOB.js.map} +0 -0
- /package/dist/{chunk-CCJJTLF7.js.map → chunk-L5RS6QAT.js.map} +0 -0
- /package/dist/{chunk-ZSCKXOKE.js.map → chunk-NQCTANF3.js.map} +0 -0
- /package/dist/{chunk-NIENIKZ5.js.map → chunk-NRADSKGH.js.map} +0 -0
- /package/dist/{chunk-725H45MT.js.map → chunk-NZXRPWPW.js.map} +0 -0
- /package/dist/{chunk-LBEZ7A3F.js.map → chunk-OK3OJGJY.js.map} +0 -0
- /package/dist/{chunk-WJEJ65TF.js.map → chunk-OY437NRJ.js.map} +0 -0
- /package/dist/{chunk-QZX43FIC.js.map → chunk-QIP37Y2C.js.map} +0 -0
- /package/dist/{chunk-Y2CCXB7R.js.map → chunk-QITQFCFY.js.map} +0 -0
- /package/dist/{chunk-P4LR2GLN.js.map → chunk-R2ODLE6G.js.map} +0 -0
- /package/dist/{chunk-UFNXYOHZ.js.map → chunk-RCTHCXS6.js.map} +0 -0
- /package/dist/{chunk-VQSBZPKO.js.map → chunk-RVZMKGWQ.js.map} +0 -0
- /package/dist/{chunk-QWSYHENP.js.map → chunk-SKIAWOUC.js.map} +0 -0
- /package/dist/{chunk-3FDSXSEP.js.map → chunk-TDWA2XFJ.js.map} +0 -0
- /package/dist/{chunk-VWVA74JY.js.map → chunk-UXQVJXQ3.js.map} +0 -0
- /package/dist/{chunk-BEYLI32I.js.map → chunk-WOUJSKQB.js.map} +0 -0
- /package/dist/{chunk-NDQJDA7O.js.map → chunk-WULEQKU7.js.map} +0 -0
- /package/dist/{chunk-4QGPRORO.js.map → chunk-X2GWR75Q.js.map} +0 -0
- /package/dist/{chunk-NKBCUR4V.js.map → chunk-X3DN2BE3.js.map} +0 -0
- /package/dist/{chunk-B34WHRKH.js.map → chunk-XGKUXYAD.js.map} +0 -0
- /package/dist/{chunk-TRYYYWV3.js.map → chunk-Y2CHJLWD.js.map} +0 -0
- /package/dist/{chunk-QDG6V7OC.js.map → chunk-YNZUYZ2O.js.map} +0 -0
- /package/dist/{chunk-T2KONJ45.js.map → chunk-Z4ZFJ565.js.map} +0 -0
- /package/dist/{chunk-JA3WJPXH.js.map → chunk-ZAZOBTVS.js.map} +0 -0
- /package/dist/{chunk-SZSS5KKX.js.map → chunk-ZCXQ4ZB6.js.map} +0 -0
- /package/dist/{chunk-P7VAMJFJ.js.map → chunk-ZE4HF3KC.js.map} +0 -0
- /package/dist/native/chunks/{chunk-H22XVP5O.js.map → chunk-TZPNJ4AU.js.map} +0 -0
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import "../chunk-JQRKXMSH.js";
|
|
2
2
|
import {
|
|
3
3
|
NotificationStatusNotice
|
|
4
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-YNZUYZ2O.js";
|
|
5
5
|
import "../chunk-55FFONIV.js";
|
|
6
6
|
import {
|
|
7
7
|
detectNotificationBrowser,
|
|
8
8
|
notificationUnblockSteps
|
|
9
9
|
} from "../chunk-L7BRU4UF.js";
|
|
10
|
-
import "../chunk-
|
|
11
|
-
import "../chunk-
|
|
10
|
+
import "../chunk-NQCTANF3.js";
|
|
11
|
+
import "../chunk-L5RS6QAT.js";
|
|
12
12
|
import "../chunk-QXUXO22M.js";
|
|
13
|
-
import "../chunk-
|
|
13
|
+
import "../chunk-7HZ36QDH.js";
|
|
14
14
|
import "../chunk-L7VH6IMR.js";
|
|
15
|
-
import "../chunk-
|
|
16
|
-
import "../chunk-
|
|
15
|
+
import "../chunk-5ZY3IIIG.js";
|
|
16
|
+
import "../chunk-YOXYSAUI.js";
|
|
17
17
|
import "../chunk-PPEHBI5O.js";
|
|
18
18
|
import "../chunk-G2FUZALJ.js";
|
|
19
19
|
import "../chunk-TAMIZE4Q.js";
|
package/dist/form/Button.js
CHANGED
package/dist/form/total-form.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
SubmitButton
|
|
3
|
-
} from "../chunk-
|
|
3
|
+
} from "../chunk-7FFY4LJY.js";
|
|
4
4
|
import {
|
|
5
5
|
FormErrorSnackbar
|
|
6
6
|
} from "../chunk-EERUSI52.js";
|
|
@@ -67,7 +67,7 @@ import "../chunk-LZRVUOMU.js";
|
|
|
67
67
|
import "../chunk-EEB66IVH.js";
|
|
68
68
|
import "../chunk-RTSK5OZT.js";
|
|
69
69
|
import "../chunk-BA4RHQ3B.js";
|
|
70
|
-
import "../chunk-
|
|
70
|
+
import "../chunk-YOXYSAUI.js";
|
|
71
71
|
import "../chunk-PPEHBI5O.js";
|
|
72
72
|
import "../chunk-G2FUZALJ.js";
|
|
73
73
|
import "../chunk-TAMIZE4Q.js";
|
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
import "../chunk-QGUNUXTT.js";
|
|
2
2
|
import {
|
|
3
3
|
SettingToggle
|
|
4
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-HMWSMRLM.js";
|
|
5
5
|
import {
|
|
6
6
|
SettingGroup
|
|
7
|
-
} from "../chunk-
|
|
8
|
-
import "../chunk-
|
|
7
|
+
} from "../chunk-WOUJSKQB.js";
|
|
8
|
+
import "../chunk-C2NNJMVY.js";
|
|
9
9
|
import "../chunk-XJQNSMGA.js";
|
|
10
10
|
import {
|
|
11
11
|
SETTING_GRID_CONTAINER,
|
|
12
12
|
SettingGrid
|
|
13
|
-
} from "../chunk-
|
|
13
|
+
} from "../chunk-CW5Z67NA.js";
|
|
14
14
|
import {
|
|
15
15
|
SettingCard
|
|
16
|
-
} from "../chunk-
|
|
16
|
+
} from "../chunk-SKIAWOUC.js";
|
|
17
17
|
import "../chunk-SALQ65SM.js";
|
|
18
|
-
import "../chunk-
|
|
19
|
-
import "../chunk-
|
|
18
|
+
import "../chunk-X2GWR75Q.js";
|
|
19
|
+
import "../chunk-3EIRRLCQ.js";
|
|
20
20
|
import "../chunk-IQWPVPV5.js";
|
|
21
21
|
import "../chunk-BFRVMCQM.js";
|
|
22
22
|
import "../chunk-RN7UJI7S.js";
|
|
@@ -49,7 +49,7 @@ import "../chunk-Q3HYEAVQ.js";
|
|
|
49
49
|
import "../chunk-IBOFASAZ.js";
|
|
50
50
|
import "../chunk-HDBP55R3.js";
|
|
51
51
|
import "../chunk-BA4RHQ3B.js";
|
|
52
|
-
import "../chunk-
|
|
52
|
+
import "../chunk-YOXYSAUI.js";
|
|
53
53
|
import "../chunk-PPEHBI5O.js";
|
|
54
54
|
import "../chunk-G2FUZALJ.js";
|
|
55
55
|
import "../chunk-TAMIZE4Q.js";
|
|
@@ -25,15 +25,14 @@ import {
|
|
|
25
25
|
} from "./chunk-DNTO2D5M.js";
|
|
26
26
|
|
|
27
27
|
// src/components/form/Button/Button.native.tsx
|
|
28
|
-
import * as
|
|
28
|
+
import * as React2 from "react";
|
|
29
29
|
import {
|
|
30
|
-
ActivityIndicator,
|
|
31
30
|
Animated,
|
|
32
31
|
Easing,
|
|
33
|
-
Platform,
|
|
32
|
+
Platform as Platform2,
|
|
34
33
|
Pressable,
|
|
35
|
-
StyleSheet,
|
|
36
|
-
View
|
|
34
|
+
StyleSheet as StyleSheet2,
|
|
35
|
+
View as View2
|
|
37
36
|
} from "react-native";
|
|
38
37
|
|
|
39
38
|
// src/components/form/Button/Button.helpers.ts
|
|
@@ -102,8 +101,52 @@ function gradientStops(theme, color, palette) {
|
|
|
102
101
|
}
|
|
103
102
|
}
|
|
104
103
|
|
|
104
|
+
// src/components/form/Button/Button.native.loading.tsx
|
|
105
|
+
import * as React from "react";
|
|
106
|
+
import { ActivityIndicator, Platform, StyleSheet, View } from "react-native";
|
|
107
|
+
import { jsx } from "react/jsx-runtime";
|
|
108
|
+
function Spinner({ color, testID }) {
|
|
109
|
+
return /* @__PURE__ */ jsx(View, { style: styles.spinner, children: /* @__PURE__ */ jsx(
|
|
110
|
+
ActivityIndicator,
|
|
111
|
+
{
|
|
112
|
+
size: Platform.OS === "ios" ? "small" : BUTTON_SPINNER_SIZE,
|
|
113
|
+
color,
|
|
114
|
+
testID,
|
|
115
|
+
accessibilityLabel: "loading"
|
|
116
|
+
}
|
|
117
|
+
) });
|
|
118
|
+
}
|
|
119
|
+
var loadingName = (loading, children) => loading ? textOf(children) : void 0;
|
|
120
|
+
function textOf(children) {
|
|
121
|
+
const parts = React.Children.toArray(children);
|
|
122
|
+
const textual = parts.every((part) => typeof part === "string" || typeof part === "number");
|
|
123
|
+
return textual && parts.length > 0 ? parts.join("") : void 0;
|
|
124
|
+
}
|
|
125
|
+
var hiddenWhile = (loading) => loading ? styles.hidden : null;
|
|
126
|
+
function Label({
|
|
127
|
+
loading,
|
|
128
|
+
label,
|
|
129
|
+
testID,
|
|
130
|
+
children
|
|
131
|
+
}) {
|
|
132
|
+
const text = renderTextChildren(children, label, 1);
|
|
133
|
+
return loading ? /* @__PURE__ */ jsx(View, { style: styles.hidden, testID, children: text }) : text;
|
|
134
|
+
}
|
|
135
|
+
var styles = StyleSheet.create({
|
|
136
|
+
// The label and icon under the spinner: laid out, so the width holds, but unseen.
|
|
137
|
+
hidden: {
|
|
138
|
+
opacity: 0
|
|
139
|
+
},
|
|
140
|
+
spinner: {
|
|
141
|
+
...StyleSheet.absoluteFillObject,
|
|
142
|
+
pointerEvents: "none",
|
|
143
|
+
alignItems: "center",
|
|
144
|
+
justifyContent: "center"
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
|
|
105
148
|
// src/components/form/Button/Button.native.tsx
|
|
106
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
149
|
+
import { jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
107
150
|
var MIN_WIDTH = 64;
|
|
108
151
|
function outlineOf(palette, wash) {
|
|
109
152
|
return {
|
|
@@ -190,7 +233,7 @@ function sizeStyle(theme, size, iconOnly, hasIcon) {
|
|
|
190
233
|
};
|
|
191
234
|
}
|
|
192
235
|
function glowStyle(palette) {
|
|
193
|
-
return
|
|
236
|
+
return Platform2.select({
|
|
194
237
|
android: { elevation: 8 },
|
|
195
238
|
default: {
|
|
196
239
|
shadowColor: palette.main,
|
|
@@ -201,26 +244,26 @@ function glowStyle(palette) {
|
|
|
201
244
|
});
|
|
202
245
|
}
|
|
203
246
|
function Pulse({ color, radius, testID }) {
|
|
204
|
-
const progress =
|
|
205
|
-
|
|
247
|
+
const progress = React2.useRef(new Animated.Value(0)).current;
|
|
248
|
+
React2.useEffect(() => {
|
|
206
249
|
const loop = Animated.loop(
|
|
207
250
|
Animated.timing(progress, {
|
|
208
251
|
toValue: 1,
|
|
209
252
|
duration: PULSE_DURATION_MS,
|
|
210
253
|
easing: Easing.out(Easing.ease),
|
|
211
|
-
useNativeDriver:
|
|
254
|
+
useNativeDriver: Platform2.OS !== "web"
|
|
212
255
|
})
|
|
213
256
|
);
|
|
214
257
|
loop.start();
|
|
215
258
|
return () => loop.stop();
|
|
216
259
|
}, [progress]);
|
|
217
|
-
return /* @__PURE__ */
|
|
260
|
+
return /* @__PURE__ */ jsx2(
|
|
218
261
|
Animated.View,
|
|
219
262
|
{
|
|
220
263
|
testID,
|
|
221
264
|
"aria-hidden": true,
|
|
222
265
|
style: [
|
|
223
|
-
|
|
266
|
+
StyleSheet2.absoluteFill,
|
|
224
267
|
{
|
|
225
268
|
pointerEvents: "none",
|
|
226
269
|
borderRadius: radius,
|
|
@@ -237,13 +280,13 @@ function Pulse({ color, radius, testID }) {
|
|
|
237
280
|
function buttonLook(theme, props) {
|
|
238
281
|
const { variant, color, size, loading, icon, children, glow, pulse, active, disabled, style } = props;
|
|
239
282
|
const palette = buttonPalette(theme, color);
|
|
240
|
-
const iconOnly =
|
|
283
|
+
const iconOnly = icon != null && children == null;
|
|
241
284
|
const inactive = Boolean(disabled) || loading;
|
|
242
285
|
const paint = inactive ? disabledPaint(theme, variant) : paintFor(theme, variant, color, palette, active);
|
|
243
286
|
const radius = theme.radius.field;
|
|
244
287
|
const metrics = BUTTON_SIZES[size];
|
|
245
288
|
const overflow = pulse || glow ? "visible" : "hidden";
|
|
246
|
-
const sized = sizeStyle(theme, size, iconOnly, icon != null
|
|
289
|
+
const sized = sizeStyle(theme, size, iconOnly, icon != null);
|
|
247
290
|
const glowing = glow && !inactive ? glowStyle(palette) : null;
|
|
248
291
|
return {
|
|
249
292
|
inactive,
|
|
@@ -258,7 +301,7 @@ function buttonLook(theme, props) {
|
|
|
258
301
|
...paint.label
|
|
259
302
|
},
|
|
260
303
|
container: (state) => [
|
|
261
|
-
|
|
304
|
+
styles2.base,
|
|
262
305
|
{ borderRadius: radius, overflow },
|
|
263
306
|
sized,
|
|
264
307
|
paint.container,
|
|
@@ -268,18 +311,7 @@ function buttonLook(theme, props) {
|
|
|
268
311
|
]
|
|
269
312
|
};
|
|
270
313
|
}
|
|
271
|
-
|
|
272
|
-
return /* @__PURE__ */ jsx(
|
|
273
|
-
ActivityIndicator,
|
|
274
|
-
{
|
|
275
|
-
size: Platform.OS === "ios" ? "small" : BUTTON_SPINNER_SIZE,
|
|
276
|
-
color,
|
|
277
|
-
testID,
|
|
278
|
-
accessibilityLabel: "loading"
|
|
279
|
-
}
|
|
280
|
-
);
|
|
281
|
-
}
|
|
282
|
-
var Button = React.forwardRef((rawProps, ref) => {
|
|
314
|
+
var Button = React2.forwardRef((rawProps, ref) => {
|
|
283
315
|
const resolved = resolveButtonProps(rawProps);
|
|
284
316
|
const { loading, icon, iconPosition, pulse, ripple, children, onClick, onPress, ...others } = resolved;
|
|
285
317
|
const theme = useUiTheme();
|
|
@@ -292,7 +324,7 @@ var Button = React.forwardRef((rawProps, ref) => {
|
|
|
292
324
|
onClick?.(event);
|
|
293
325
|
onPress?.(event);
|
|
294
326
|
};
|
|
295
|
-
const iconNode =
|
|
327
|
+
const iconNode = icon ? /* @__PURE__ */ jsx2(View2, { style: [styles2.icon, hiddenWhile(loading)], testID: idFor("icon"), children: icon }) : null;
|
|
296
328
|
return /* @__PURE__ */ jsxs(
|
|
297
329
|
Pressable,
|
|
298
330
|
{
|
|
@@ -300,6 +332,7 @@ var Button = React.forwardRef((rawProps, ref) => {
|
|
|
300
332
|
role: "button",
|
|
301
333
|
"aria-disabled": look.inactive,
|
|
302
334
|
"aria-busy": loading,
|
|
335
|
+
"aria-label": loadingName(loading, children),
|
|
303
336
|
disabled: look.inactive,
|
|
304
337
|
onPress: handlePress,
|
|
305
338
|
android_ripple: ripple && !look.inactive ? { color: alpha(look.palette.main, 0.2), borderless: false } : void 0,
|
|
@@ -307,16 +340,17 @@ var Button = React.forwardRef((rawProps, ref) => {
|
|
|
307
340
|
testID: testId,
|
|
308
341
|
...pressable,
|
|
309
342
|
children: [
|
|
310
|
-
pulse && !look.inactive ? /* @__PURE__ */
|
|
343
|
+
pulse && !look.inactive ? /* @__PURE__ */ jsx2(Pulse, { color: look.palette.main, radius: look.radius, testID: idFor("pulse") }) : null,
|
|
311
344
|
iconPosition === "left" ? iconNode : null,
|
|
312
|
-
|
|
313
|
-
iconPosition === "right" ? iconNode : null
|
|
345
|
+
/* @__PURE__ */ jsx2(Label, { loading, label: look.label, testID: idFor("busy-label"), children }),
|
|
346
|
+
iconPosition === "right" ? iconNode : null,
|
|
347
|
+
loading ? /* @__PURE__ */ jsx2(Spinner, { color: look.label.color, testID: idFor("loading") }) : null
|
|
314
348
|
]
|
|
315
349
|
}
|
|
316
350
|
);
|
|
317
351
|
});
|
|
318
352
|
Button.displayName = "Button";
|
|
319
|
-
var
|
|
353
|
+
var styles2 = StyleSheet2.create({
|
|
320
354
|
base: {
|
|
321
355
|
flexDirection: "row",
|
|
322
356
|
alignItems: "center",
|
|
@@ -333,4 +367,4 @@ var styles = StyleSheet.create({
|
|
|
333
367
|
export {
|
|
334
368
|
Button
|
|
335
369
|
};
|
|
336
|
-
//# sourceMappingURL=chunk-
|
|
370
|
+
//# sourceMappingURL=chunk-EZHCNYQO.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/components/form/Button/Button.native.tsx","../../../src/components/form/Button/Button.helpers.ts","../../../src/components/form/Button/Button.metrics.ts","../../../src/components/form/Button/Button.native.loading.tsx"],"sourcesContent":["import * as React from 'react';\nimport {\n Animated,\n Easing,\n Platform,\n Pressable,\n StyleSheet,\n View,\n type GestureResponderEvent,\n type PressableStateCallbackType,\n type StyleProp,\n type TextStyle,\n type ViewStyle,\n} from 'react-native';\n\nimport { resolveButtonProps } from './Button.helpers';\nimport {\n BUTTON_FONT_WEIGHT,\n BUTTON_ICON_GAP_UNITS,\n BUTTON_LINE_HEIGHT,\n BUTTON_SIZES,\n BUTTON_WASH_ALPHA,\n GLASS_BACKGROUND_ALPHA,\n GLASS_BACKGROUND_ALPHA_PRESSED,\n GLASS_BORDER_ALPHA,\n GLOW_INNER_ALPHA,\n GLOW_RADIUS,\n PULSE_ALPHA,\n PULSE_DURATION_MS,\n PULSE_SPREAD,\n buttonPalette,\n gradientStops,\n quietInk,\n} from './Button.metrics';\nimport type { ButtonProps, ButtonVariant } from './Button.types.native';\nimport { hiddenWhile, Label, loadingName, Spinner } from './Button.native.loading';\nimport { childTestId, resolveTestId, withoutTestIdProps } from '../../../platform/test-id';\nimport { useUiTheme } from '../../../provider/use-ui-theme.native';\nimport { resolveFieldEdge } from '../../../tokens/field-edge.core';\nimport { FIELD_BORDER_WIDTH, fieldHeightPx } from '../../../tokens/field-height.core';\nimport { alpha } from '../../../tokens/color';\nimport type { ColorValue, SizeValue } from '../../../tokens/vocabulary';\nimport type { UiPaletteColor, UiTheme } from '../../../tokens/theme';\n\n/** MUI's `min-width` for a button that carries a label. */\nconst MIN_WIDTH = 64;\n\ninterface Paint {\n container: ViewStyle;\n pressed: ViewStyle;\n label: TextStyle;\n}\n\n/**\n * What the web's `VARIANT_STYLES` paint, as three React Native styles: at rest,\n * while pressed (the web's `:hover`, which touch has no equivalent of), and the\n * label. Same palette arithmetic, same alphas.\n *\n * `gradient` is the one honest gap: React Native core has no gradient fill, so\n * it paints the gradient's first stop. A host wanting the real thing adds a\n * gradient library; the parity ledger records this.\n */\n/** A coloured outline: its colour for the border and the label, washed when pressed. */\nfunction outlineOf(palette: UiPaletteColor, wash: string): Paint {\n return {\n container: { backgroundColor: 'transparent', borderWidth: FIELD_BORDER_WIDTH, borderColor: palette.main },\n pressed: { backgroundColor: wash, borderColor: palette.dark },\n label: { color: palette.main },\n };\n}\n\n/**\n * A neutral outline, as on the web: it rests on the one field border and\n * writes in the theme's text ink, a role that turns with the mode — grey 700\n * was dark on a dark ground.\n */\nfunction neutralOutline(theme: UiTheme): Paint {\n const ink = theme.palette.text.primary;\n return {\n container: {\n backgroundColor: 'transparent',\n borderWidth: FIELD_BORDER_WIDTH,\n borderColor: resolveFieldEdge(theme.palette.divider, theme.palette.background.paper),\n },\n pressed: { backgroundColor: alpha(ink, BUTTON_WASH_ALPHA), borderColor: theme.palette.text.secondary },\n label: { color: ink },\n };\n}\n\nfunction paintFor(\n theme: UiTheme,\n variant: ButtonVariant,\n color: ColorValue,\n palette: UiPaletteColor,\n active: boolean,\n): Paint {\n const wash = alpha(palette.main, BUTTON_WASH_ALPHA);\n switch (variant) {\n case 'outline':\n return color === 'neutral' ? neutralOutline(theme) : outlineOf(palette, wash);\n case 'ghost':\n return {\n container: { backgroundColor: 'transparent' },\n pressed: { backgroundColor: wash },\n label: { color: quietInk(theme, palette) },\n };\n case 'text':\n return {\n container: { backgroundColor: active ? wash : 'transparent' },\n pressed: { backgroundColor: wash },\n label: { color: quietInk(theme, palette) },\n };\n case 'glass':\n return {\n container: {\n backgroundColor: alpha(theme.palette.background.paper, GLASS_BACKGROUND_ALPHA),\n borderWidth: 1,\n borderColor: alpha(theme.palette.divider, GLASS_BORDER_ALPHA),\n },\n pressed: { backgroundColor: alpha(theme.palette.background.paper, GLASS_BACKGROUND_ALPHA_PRESSED) },\n label: { color: palette.main },\n };\n case 'gradient': {\n const [from, to] = gradientStops(theme, color, palette);\n return {\n container: { backgroundColor: from },\n pressed: { backgroundColor: to },\n label: { color: '#fff' },\n };\n }\n default:\n return {\n container: { backgroundColor: palette.main },\n pressed: { backgroundColor: palette.dark },\n label: { color: palette.contrastText || '#fff' },\n };\n }\n}\n\n/** MUI's disabled treatment per variant family, so a disabled button reads as one on both sides. */\nfunction disabledPaint(theme: UiTheme, variant: ButtonVariant): Paint {\n const filled = variant === 'solid' || variant === 'gradient' || variant === 'glass';\n return {\n container: filled\n ? { backgroundColor: theme.palette.action.disabledBackground, borderWidth: 0 }\n : variant === 'outline'\n ? { backgroundColor: 'transparent', borderWidth: 1, borderColor: theme.palette.action.disabledBackground }\n : { backgroundColor: 'transparent' },\n pressed: {},\n label: { color: theme.palette.action.disabled },\n };\n}\n\nfunction sizeStyle(theme: UiTheme, size: SizeValue, iconOnly: boolean, hasIcon: boolean): ViewStyle {\n const metrics = BUTTON_SIZES[size];\n // The theme's field height for the size, as on the web: a button stands\n // level with the field beside it, and an icon-only one is that square.\n const height = fieldHeightPx(theme.fieldHeight, size);\n if (iconOnly) {\n return { padding: 0, minWidth: height, minHeight: height };\n }\n return {\n minHeight: height,\n paddingVertical: 0,\n paddingHorizontal: metrics.paddingHorizontal,\n minWidth: MIN_WIDTH,\n gap: hasIcon ? theme.spacing(BUTTON_ICON_GAP_UNITS) : undefined,\n };\n}\n\nfunction glowStyle(palette: UiPaletteColor): ViewStyle {\n return Platform.select<ViewStyle>({\n android: { elevation: 8 },\n default: {\n shadowColor: palette.main,\n shadowOpacity: GLOW_INNER_ALPHA,\n shadowRadius: GLOW_RADIUS,\n shadowOffset: { width: 0, height: 0 },\n },\n });\n}\n\n/** The web's `::after` pulse ring: a looped scale-and-fade behind the button. */\nfunction Pulse({ color, radius, testID }: { color: string; radius: number; testID: string }): React.JSX.Element {\n const progress = React.useRef(new Animated.Value(0)).current;\n\n React.useEffect(() => {\n const loop = Animated.loop(\n Animated.timing(progress, {\n toValue: 1,\n duration: PULSE_DURATION_MS,\n easing: Easing.out(Easing.ease),\n useNativeDriver: Platform.OS !== 'web',\n }),\n );\n loop.start();\n return () => loop.stop();\n }, [progress]);\n\n return (\n <Animated.View\n testID={testID}\n aria-hidden\n style={[\n StyleSheet.absoluteFill,\n {\n pointerEvents: 'none',\n borderRadius: radius,\n backgroundColor: color,\n opacity: progress.interpolate({ inputRange: [0, 0.7, 1], outputRange: [PULSE_ALPHA, 0, 0] }),\n transform: [\n { scale: progress.interpolate({ inputRange: [0, 0.7, 1], outputRange: [1, 1 + PULSE_SPREAD / 40, 1] }) },\n ],\n },\n ]}\n />\n );\n}\n\n\ntype ResolvedProps = ReturnType<typeof resolveButtonProps<ButtonProps>>;\n\ninterface ButtonLook {\n inactive: boolean;\n palette: UiPaletteColor;\n radius: number;\n label: TextStyle;\n container: (state: PressableStateCallbackType) => StyleProp<ViewStyle>;\n}\n\n/**\n * Everything the button paints, decided once per render from the resolved\n * props and the theme. Kept out of the component so the component reads as\n * structure — what renders where — and this reads as arithmetic.\n */\nfunction buttonLook(theme: UiTheme, props: ResolvedProps): ButtonLook {\n const { variant, color, size, loading, icon, children, glow, pulse, active, disabled, style } = props;\n const palette = buttonPalette(theme, color);\n // Loading keeps the icon (transparent), so it changes neither the shape nor the gap (FUT-3646).\n const iconOnly = icon != null && children == null;\n const inactive = Boolean(disabled) || loading;\n const paint = inactive ? disabledPaint(theme, variant) : paintFor(theme, variant, color, palette, active);\n // The theme's one field radius, so a button and the input beside it agree.\n const radius = theme.radius.field;\n const metrics = BUTTON_SIZES[size];\n // The web button is `overflow: hidden` (its ripple needs it) unless the pulse\n // ring turns it visible; on native the glow's shadow needs it visible too,\n // because a view's own shadow is clipped by its own overflow there.\n const overflow: ViewStyle['overflow'] = pulse || glow ? 'visible' : 'hidden';\n const sized = sizeStyle(theme, size, iconOnly, icon != null);\n const glowing = glow && !inactive ? glowStyle(palette) : null;\n\n return {\n inactive,\n palette,\n radius,\n label: {\n fontFamily: theme.typography.fontFamily,\n fontSize: metrics.fontSize,\n lineHeight: metrics.fontSize * BUTTON_LINE_HEIGHT,\n fontWeight: String(BUTTON_FONT_WEIGHT) as TextStyle['fontWeight'],\n textAlign: 'center',\n ...paint.label,\n },\n container: (state) => [\n styles.base,\n { borderRadius: radius, overflow },\n sized,\n paint.container,\n state.pressed && !inactive ? paint.pressed : null,\n glowing,\n style,\n ],\n };\n}\n\nexport const Button = React.forwardRef<View, ButtonProps>((rawProps, ref) => {\n const resolved = resolveButtonProps(rawProps);\n const { loading, icon, iconPosition, pulse, ripple, children, onClick, onPress, ...others } = resolved;\n const theme = useUiTheme();\n const look = buttonLook(theme, resolved);\n\n // The shared stories pass `'data-testid'` as a plain prop; honour it here and\n // keep all three spellings off the element (react-native-web would drop them).\n const testId = resolveTestId(others, 'button');\n const idFor = (suffix: string) => childTestId(others, suffix, 'button');\n const rest = withoutTestIdProps(others);\n // `buttonLook` consumed these; they are not Pressable props.\n const { variant: _v, color: _c, size: _s, glow: _g, active: _a, disabled: _d, style: _st, ...pressable } = rest;\n\n const handlePress = (event: GestureResponderEvent): void => {\n onClick?.(event);\n onPress?.(event);\n };\n\n const iconNode = icon ? (\n <View style={[styles.icon, hiddenWhile(loading)]} testID={idFor('icon')}>\n {icon}\n </View>\n ) : null;\n\n return (\n <Pressable\n ref={ref}\n role=\"button\"\n aria-disabled={look.inactive}\n aria-busy={loading}\n aria-label={loadingName(loading, children)}\n disabled={look.inactive}\n onPress={handlePress}\n android_ripple={ripple && !look.inactive ? { color: alpha(look.palette.main, 0.2), borderless: false } : undefined}\n style={look.container}\n testID={testId}\n {...pressable}\n >\n {pulse && !look.inactive ? <Pulse color={look.palette.main} radius={look.radius} testID={idFor('pulse')} /> : null}\n {iconPosition === 'left' ? iconNode : null}\n <Label loading={loading} label={look.label} testID={idFor('busy-label')}>\n {children}\n </Label>\n {iconPosition === 'right' ? iconNode : null}\n {loading ? <Spinner color={look.label.color as string} testID={idFor('loading')} /> : null}\n </Pressable>\n );\n});\n\nButton.displayName = 'Button';\n\nconst styles = StyleSheet.create({\n base: {\n flexDirection: 'row',\n alignItems: 'center',\n justifyContent: 'center',\n alignSelf: 'flex-start',\n position: 'relative',\n },\n icon: {\n alignItems: 'center',\n justifyContent: 'center',\n },\n});\n","import type { ButtonBaseProps } from './Button.base';\n\ntype ButtonDefaultedKeys =\n | 'variant'\n | 'color'\n | 'size'\n | 'loading'\n | 'iconPosition'\n | 'glow'\n | 'pulse'\n | 'ripple'\n | 'active';\n\n/**\n * Generic over the renderer's own props: the web and the native `Button` pass\n * different handler types through, and both come back out untouched.\n */\ntype ResolvedButtonProps<P extends ButtonBaseProps> = P &\n Required<Pick<ButtonBaseProps, ButtonDefaultedKeys>>;\n\nconst BUTTON_DEFAULTS: Required<Pick<ButtonBaseProps, ButtonDefaultedKeys>> = {\n variant: 'solid',\n color: 'primary',\n size: 'md',\n loading: false,\n iconPosition: 'left',\n glow: false,\n pulse: false,\n ripple: true,\n active: false,\n};\n\n// Strips explicitly-undefined props before the merge, so `size={undefined}` still\n// falls back to the default exactly as a destructuring default would.\nconst definedProps = <P extends ButtonBaseProps>(props: P): Partial<P> =>\n Object.fromEntries(\n Object.entries(props).filter(([, value]) => value !== undefined),\n ) as Partial<P>;\n\nexport const resolveButtonProps = <P extends ButtonBaseProps>(props: P): ResolvedButtonProps<P> =>\n ({ ...BUTTON_DEFAULTS, ...definedProps(props) }) as ResolvedButtonProps<P>;\n","import { darken, lighten } from '../../../tokens/color';\nimport { ABSOLUTE_INK, NEUTRAL_RAMP } from '../../../tokens/ink.core';\nimport type { ColorValue, SizeValue } from '../../../tokens/vocabulary';\nimport type { UiPaletteColor, UiTheme } from '../../../tokens/theme';\n\n/**\n * THE NUMBERS BOTH `Button` RENDERERS DRAW WITH.\n *\n * `Button.styles.ts` (web, emotion) and `Button.native.tsx` (React Native)\n * read this one table. The web turns the px into rem and the padding into a\n * shorthand string; native uses the numbers as they are. Neither restates a\n * value, which is what keeps a native `md` button 16px tall of padding and\n * 16px of type exactly like the web one.\n */\nexport interface ButtonSizeMetrics {\n paddingVertical: number;\n paddingHorizontal: number;\n fontSize: number;\n}\n\nexport const BUTTON_SIZES: Record<SizeValue, ButtonSizeMetrics> = {\n xs: { paddingVertical: 2, paddingHorizontal: 8, fontSize: 12 },\n sm: { paddingVertical: 6, paddingHorizontal: 12, fontSize: 14 },\n md: { paddingVertical: 8, paddingHorizontal: 16, fontSize: 16 },\n lg: { paddingVertical: 10, paddingHorizontal: 20, fontSize: 18 },\n xl: { paddingVertical: 12, paddingHorizontal: 24, fontSize: 20 },\n};\n\n/** A button that is only an icon is square: uniform padding, no min-width. */\nexport const ICON_ONLY_PADDING: Record<SizeValue, number> = {\n xs: 2,\n sm: 5,\n md: 7,\n lg: 9,\n xl: 11,\n};\n\n/**\n * The start/end icon slot's font-size, in px — MUI's `medium` value, pinned\n * (12-74).\n *\n * MUI sizes that slot off its OWN `size` prop, writing 18/20/22 onto the first\n * child of `.MuiButton-startIcon`. We never passed a `size`, so every button in\n * every size has always drawn medium's 20px; now that `size` IS forwarded — so\n * the rendered class finally names the size the button actually is — the number\n * would start moving with it.\n *\n * WHAT THAT ACTUALLY REACHES, measured in a browser rather than assumed: this\n * Button renders its own wrapper span around the icon (it carries the child\n * test id), so MUI's rule lands on the WRAPPER and reaches the glyph only when\n * the glyph takes its size by inheritance — `fontSize=\"inherit\"`, an em-sized\n * SVG, a text or emoji glyph. With the pin removed, such a glyph measured 18px\n * at `xs`/`sm` and 22px at `lg`/`xl` against the 20px it has always been. An\n * icon carrying an absolute size of its own does not move at all: a default\n * `SvgIcon` stayed 24×24 across all five.\n *\n * A silent resize of the inherited case is still a design decision arriving as\n * a side effect of a class-name fix, so it is pinned to what shipped before —\n * `Button.tsx` puts it on that same wrapper. Scaling the glyph with the button\n * is a ticket of its own.\n */\nexport const BUTTON_ICON_GLYPH_SIZE = 20;\n\nexport const BUTTON_FONT_WEIGHT = 500;\n/** Between the icon and the label: `theme.spacing(0.5)`. */\nexport const BUTTON_ICON_GAP_UNITS = 0.5;\nexport const BUTTON_SPINNER_SIZE = 16;\n/** MUI's `line-height` for button text. */\nexport const BUTTON_LINE_HEIGHT = 1.75;\n\n/** The wash behind an outline, ghost or text button while it is hovered or pressed. */\nexport const BUTTON_WASH_ALPHA = 0.1;\nexport const GLASS_BACKGROUND_ALPHA = 0.1;\nexport const GLASS_BACKGROUND_ALPHA_PRESSED = 0.2;\nexport const GLASS_BORDER_ALPHA = 0.2;\nexport const GLOW_INNER_ALPHA = 0.6;\nexport const GLOW_OUTER_ALPHA = 0.3;\nexport const GLOW_RADIUS = 20;\nexport const PULSE_ALPHA = 0.3;\nexport const PULSE_DURATION_MS = 2000;\nexport const PULSE_SPREAD = 15;\n\n/**\n * `neutral` has no palette slot of its own in MUI, so `Button.styles.ts` has\n * always drawn it from three greys. Same three greys here.\n */\nexport function buttonPalette(theme: UiTheme, color: ColorValue): UiPaletteColor {\n if (color === 'neutral') {\n return {\n main: NEUTRAL_RAMP[700],\n dark: NEUTRAL_RAMP[800],\n light: NEUTRAL_RAMP[500],\n contrastText: ABSOLUTE_INK.white,\n };\n }\n return theme.palette[color];\n}\n\n/**\n * The label colour for `ghost` and `text`: one step darker than `main` in\n * light mode (lighter in dark), because `main` is chosen to sit UNDER white and\n * is not legible AS text on a tinted surface. See the web `quietInk`.\n */\nexport const quietInk = (theme: UiTheme, palette: UiPaletteColor): string =>\n theme.mode === 'dark' ? lighten(palette.main, 0.35) : darken(palette.main, 0.3);\n\n/** Gradients run between two related hues; the named colours pick a specific pair. */\nexport function gradientStops(\n theme: UiTheme,\n color: ColorValue,\n palette: UiPaletteColor,\n): [string, string] {\n switch (color) {\n case 'primary':\n return [theme.palette.primary.main, theme.palette.secondary.main];\n case 'secondary':\n return [theme.palette.secondary.main, theme.palette.primary.main];\n case 'success':\n case 'warning':\n return [theme.palette[color].light, theme.palette[color].dark];\n case 'danger':\n return [theme.palette.danger.light, theme.palette.danger.dark];\n default:\n return [palette.main, palette.dark];\n }\n}\n","import * as React from 'react';\nimport { ActivityIndicator, Platform, StyleSheet, View } from 'react-native';\nimport type { TextStyle } from 'react-native';\n\nimport { BUTTON_SPINNER_SIZE } from './Button.metrics';\nimport { renderTextChildren } from '../../../platform/text-children';\n\n/**\n * The native Button's loading state (FUT-3646): the label and icon stay laid\n * out under the spinner — so the button keeps its width and shape — and the\n * button keeps its name. Split from `Button.native.tsx` to keep that file\n * under the line ceiling.\n */\n\n/**\n * The spinner over the label while loading, across the whole button; `role`\n * comes from react-native's ActivityIndicator. It used to REPLACE the label, so\n * a loading button had no accessible name (FUT-3646).\n */\nexport function Spinner({ color, testID }: { color: string; testID: string }): React.JSX.Element {\n return (\n <View style={styles.spinner}>\n <ActivityIndicator\n size={Platform.OS === 'ios' ? 'small' : BUTTON_SPINNER_SIZE}\n color={color}\n testID={testID}\n accessibilityLabel=\"loading\"\n />\n </View>\n );\n}\n\n/**\n * The button's name while loading: its text label, said outright. The label\n * stays laid out (transparent) so the width holds, but a screen reader may skip\n * a view at opacity 0 — VoiceOver does — so the name cannot ride on it alone.\n * A caller's own `aria-label` still wins, being spread after this.\n */\nexport const loadingName = (loading: boolean | undefined, children: React.ReactNode): string | undefined =>\n loading ? textOf(children) : undefined;\n\n/**\n * The text of a label made only of strings and numbers — `Salvar`, or\n * `Salvar {n}`, which React hands over as an array. Anything else (an element)\n * has no text to say here, so the name is left to the label itself.\n */\nfunction textOf(children: React.ReactNode): string | undefined {\n const parts = React.Children.toArray(children);\n const textual = parts.every((part) => typeof part === 'string' || typeof part === 'number');\n return textual && parts.length > 0 ? parts.join('') : undefined;\n}\n\n/** Laid out but unseen under the spinner while loading, so the width holds. */\nexport const hiddenWhile = (loading: boolean | undefined) => (loading ? styles.hidden : null);\n\n/** The text label; while loading, kept laid out but unseen under the spinner. */\nexport function Label({\n loading,\n label,\n testID,\n children,\n}: {\n loading: boolean | undefined;\n label: TextStyle;\n testID: string;\n children: React.ReactNode;\n}): React.ReactNode {\n const text = renderTextChildren(children, label, 1);\n return loading ? (\n <View style={styles.hidden} testID={testID}>\n {text}\n </View>\n ) : (\n text\n );\n}\n\nconst styles = StyleSheet.create({\n // The label and icon under the spinner: laid out, so the width holds, but unseen.\n hidden: {\n opacity: 0,\n },\n spinner: {\n ...StyleSheet.absoluteFillObject,\n pointerEvents: 'none',\n alignItems: 'center',\n justifyContent: 'center',\n },\n});\n"],"mappings":"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","names":["React","Platform","StyleSheet","View","jsx","Platform","StyleSheet","styles","View"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Button
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-EZHCNYQO.js";
|
|
4
4
|
import {
|
|
5
5
|
ELEVATION_SHADOWS
|
|
6
6
|
} from "./chunk-ZRQHLTYG.js";
|
|
@@ -292,4 +292,4 @@ var styles = StyleSheet.create({
|
|
|
292
292
|
export {
|
|
293
293
|
EmptyState
|
|
294
294
|
};
|
|
295
|
-
//# sourceMappingURL=chunk-
|
|
295
|
+
//# sourceMappingURL=chunk-TZPNJ4AU.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/data-display/Alert/Alert.native.tsx","../../../src/components/data-display/Alert/Alert.helpers.ts","../../../src/components/data-display/Alert/Alert.metrics.ts","../../../src/components/data-display/Alert/Alert.look.native.ts"],"sourcesContent":["import * as React from 'react';\nimport {\n Animated,\n Easing,\n type LayoutChangeEvent,\n Platform,\n Pressable,\n type Role,\n StyleSheet,\n Text as RNText,\n View,\n type ViewStyle,\n} from 'react-native';\n\nimport { resolveAlertProps, resolveAnnouncement, testIdFor, VARIANT_ICON } from './Alert.helpers';\nimport {\n actionSlotStyle,\n alertLook,\n closeButtonStyle,\n descriptionStyle,\n iconSlotStyle,\n messageSlotStyle,\n messageTextStyle,\n titleStyle,\n} from './Alert.look.native';\nimport { CLOSE_BUTTON, CLOSE_DELAY_MS, COLLAPSE_MS, FADE_IN, ICON_SLOT, ICON_SPIN, PULSE } from './Alert.metrics';\nimport type { AlertProps, AlertVariant } from './Alert.types.native';\nimport { Icon } from '../../../icons/Icon.native';\nimport { webAria } from '../../../platform/aria';\nimport { renderTextChildren } from '../../../platform/text-children';\nimport { resolveTestId, withoutTestIdProps } from '../../../platform/test-id';\nimport { useUiTheme } from '../../../provider/use-ui-theme.native';\n\ntype AnimatedStyle = Animated.WithAnimatedValue<ViewStyle>;\nconst nativeDriver = Platform.OS !== 'web';\n\n/** A 0→1 progress that starts on mount when `animate` is set, else sits at 1. */\nfunction useProgress(animate: boolean, duration: number): Animated.Value {\n const progress = React.useRef(new Animated.Value(animate ? 0 : 1)).current;\n React.useEffect(() => {\n if (!animate) return undefined;\n const timing = Animated.timing(progress, { toValue: 1, duration, easing: Easing.out(Easing.ease), useNativeDriver: nativeDriver });\n timing.start();\n return () => timing.stop();\n }, [animate, duration, progress]);\n return progress;\n}\n\n/** The web's `fadeInScale` keyframes: in from 0 opacity, 0.95 scale and 10px above, over 300ms. */\nfunction useFadeIn(animate: boolean): AnimatedStyle | undefined {\n const progress = useProgress(animate, FADE_IN.ms);\n if (!animate) return undefined;\n return {\n opacity: progress,\n transform: [\n { scale: progress.interpolate({ inputRange: [0, 1], outputRange: [FADE_IN.scale, 1] }) },\n { translateY: progress.interpolate({ inputRange: [0, 1], outputRange: [-FADE_IN.lift, 0] }) },\n ],\n };\n}\n\n/** The web's `iconRotate` keyframes: one full turn, 0.8 → 1.1 → 1, over 600ms. */\nfunction useIconSpin(animate: boolean): AnimatedStyle | undefined {\n const progress = useProgress(animate, ICON_SPIN.ms);\n if (!animate) return undefined;\n return {\n transform: [\n { rotate: progress.interpolate({ inputRange: [0, 1], outputRange: ['0deg', '360deg'] }) },\n { scale: progress.interpolate({ inputRange: [0, 0.5, 1], outputRange: [ICON_SPIN.from, ICON_SPIN.mid, 1] }) },\n ],\n };\n}\n\n/** The web's `::after` pulse: a wash of the hue over the card, fading out every two seconds, behind the words. */\nfunction Pulse({ color, radius, testID }: { color: string; radius: number; testID: string }): React.JSX.Element {\n const progress = React.useRef(new Animated.Value(0)).current;\n React.useEffect(() => {\n const loop = Animated.loop(\n Animated.timing(progress, { toValue: 1, duration: PULSE.ms, easing: Easing.linear, useNativeDriver: nativeDriver }),\n );\n loop.start();\n return () => loop.stop();\n }, [progress]);\n return (\n <Animated.View\n testID={testID}\n aria-hidden\n style={[\n StyleSheet.absoluteFill,\n {\n pointerEvents: 'none',\n borderRadius: radius,\n backgroundColor: color,\n opacity: progress.interpolate({ inputRange: [0, 0.7, 1], outputRange: [PULSE.alpha, 0, 0] }),\n },\n ]}\n />\n );\n}\n\n/**\n * MUI's `Collapse`: open, it is a plain wrapper with its overflow visible (so\n * a glow can escape); closing, it clips and shrinks over 300ms, then says so.\n */\nfunction Collapse({ open, onCollapsed, children }: { open: boolean; onCollapsed: () => void; children: React.ReactNode }): React.JSX.Element {\n const [height, setHeight] = React.useState<number | null>(null);\n const progress = React.useRef(new Animated.Value(1)).current;\n React.useEffect(() => {\n if (open) return undefined;\n const timing = Animated.timing(progress, { toValue: 0, duration: COLLAPSE_MS, easing: Easing.inOut(Easing.ease), useNativeDriver: false });\n timing.start(({ finished }) => {\n if (finished) onCollapsed();\n });\n return () => timing.stop();\n }, [open, onCollapsed, progress]);\n const onLayout = (event: LayoutChangeEvent): void => {\n if (open) setHeight(event.nativeEvent.layout.height);\n };\n const shrink: AnimatedStyle = height == null ? {} : { maxHeight: progress.interpolate({ inputRange: [0, 1], outputRange: [0, height] }) };\n return (\n <Animated.View style={[{ overflow: open ? 'visible' : 'hidden', opacity: progress }, shrink]}>\n <View onLayout={onLayout}>{children}</View>\n </Animated.View>\n );\n}\n\ninterface IconSlotProps {\n variant: AlertVariant;\n icon: React.ReactNode;\n color: string;\n animate: boolean;\n testID: string;\n}\n\n/** The icon slot; `glass` and `gradient` have no glyph of their own, so theirs is empty unless an `icon` is given — as on the web. */\nfunction IconSlot({ variant, icon, color, animate, testID }: IconSlotProps): React.JSX.Element {\n const theme = useUiTheme();\n const spin = useIconSpin(animate);\n const glyph = VARIANT_ICON[variant];\n return (\n <Animated.View testID={testID} style={[iconSlotStyle(theme), spin]}>\n {icon || (glyph ? <Icon name={glyph} size={ICON_SLOT.size} color={color} /> : null)}\n </Animated.View>\n );\n}\n\nfunction CloseButton({ label, ink, onPress, testID }: { label: string | undefined; ink: string; onPress: () => void; testID: string }): React.JSX.Element {\n const theme = useUiTheme();\n return (\n <Pressable role=\"button\" aria-label={label} testID={testID} onPress={onPress} style={({ pressed }) => closeButtonStyle(theme, pressed)}>\n <Icon name=\"Close\" size={CLOSE_BUTTON.iconSize} color={ink} />\n </Pressable>\n );\n}\n\ninterface ContentProps {\n title?: string;\n description?: string;\n children?: React.ReactNode;\n ink: string;\n testId: string;\n}\n\nfunction AlertContent({ title, description, children, ink, testId }: ContentProps): React.JSX.Element {\n const theme = useUiTheme();\n return (\n <View style={messageSlotStyle(theme)}>\n {title ? (\n <RNText testID={testIdFor(testId, 'title')} style={titleStyle(theme, ink, Boolean(description))}>\n {title}\n </RNText>\n ) : null}\n {description ? (\n <RNText testID={testIdFor(testId, 'message')} style={descriptionStyle(theme, ink)}>\n {description}\n </RNText>\n ) : null}\n {renderTextChildren(children, messageTextStyle(theme, ink))}\n </View>\n );\n}\n\n/** The dismiss sequence the web runs: mark closing, fire `onClose` 200ms in, stay until the collapse has run. */\nfunction useDismiss(onClose: (() => void) | undefined): { open: boolean; gone: boolean; close: () => void; onCollapsed: () => void } {\n const [closing, setClosing] = React.useState(false);\n const [gone, setGone] = React.useState(false);\n const timer = React.useRef<ReturnType<typeof setTimeout> | null>(null);\n React.useEffect(() => () => {\n if (timer.current) clearTimeout(timer.current);\n }, []);\n const close = (): void => {\n setClosing(true);\n timer.current = setTimeout(() => onClose?.(), CLOSE_DELAY_MS);\n };\n const onCollapsed = React.useCallback(() => setGone(true), []);\n return { open: !closing, gone, close, onCollapsed };\n}\n\nexport const Alert = React.forwardRef<View, AlertProps>((alertProps, ref) => {\n const {\n variant, color, glow, pulse, icon, showIcon, onClose, title, description, children, animate,\n // `role`, `announce` and `aria-live` all leave here and are resolved\n // TOGETHER below, off `alertProps` — see `resolveAnnouncement`.\n role: _role, announce: _announce,\n 'aria-atomic': ariaAtomic, 'aria-live': _ariaLive, closable, closeLabel, style, ...others\n } = resolveAlertProps(alertProps);\n const theme = useUiTheme();\n const testId = resolveTestId(others, 'alert') as string;\n const rest = withoutTestIdProps(others);\n const look = alertLook(theme, { variant, color, glow, pulse });\n const fadeIn = useFadeIn(animate);\n const dismiss = useDismiss(onClose);\n const announcement = resolveAnnouncement(alertProps, variant);\n\n if (dismiss.gone) return null;\n return (\n <Collapse open={dismiss.open} onCollapsed={dismiss.onCollapsed}>\n <Animated.View\n ref={ref}\n role={announcement.role as Role}\n aria-live={announcement['aria-live']}\n {...webAria({ 'aria-atomic': ariaAtomic })}\n tabIndex={0}\n testID={testId}\n style={[look.root, fadeIn, style]}\n {...rest}\n >\n {pulse ? <Pulse color={look.palette.main} radius={look.root.borderRadius as number} testID={testIdFor(testId, 'pulse')} /> : null}\n {showIcon ? <IconSlot variant={variant} icon={icon} color={look.iconColor} animate={animate} testID={testIdFor(testId, 'icon')} /> : null}\n <AlertContent title={title} description={description} ink={look.ink} testId={testId}>\n {children}\n </AlertContent>\n {closable ? (\n <View style={actionSlotStyle(theme)}>\n <CloseButton label={closeLabel} ink={look.ink} onPress={dismiss.close} testID={testIdFor(testId, 'close')} />\n </View>\n ) : null}\n </Animated.View>\n </Collapse>\n );\n});\n\nAlert.displayName = 'Alert';\n","import type { AlertBaseFields, AlertVariant } from './Alert.base';\nimport type { IconName } from '../../../icons/Icon.types';\n\ntype AlertDefaultedKeys = 'variant' | 'glow' | 'pulse' | 'showIcon' | 'animate' | 'role' | 'aria-atomic';\n\nexport const ALERT_DEFAULTS: Required<Pick<AlertBaseFields, AlertDefaultedKeys>> & { closable: false } = {\n variant: 'info',\n glow: false,\n pulse: false,\n showIcon: true,\n closable: false,\n animate: true,\n role: 'alert',\n 'aria-atomic': 'true',\n};\n\n/**\n * Generic over the renderer's own props: the web and the native `Alert` pass\n * different extras through, and both come back out untouched.\n */\nexport type ResolvedAlertProps<P extends AlertBaseFields> = P &\n Required<Pick<AlertBaseFields, AlertDefaultedKeys>>;\n\n// Strips explicitly-undefined props before the merge so `prop={undefined}` still\n// falls back to the default, the way a destructuring default would.\nconst definedProps = <P extends AlertBaseFields>(props: P): Partial<P> =>\n Object.fromEntries(\n Object.entries(props).filter(([, value]) => value !== undefined),\n ) as Partial<P>;\n\n// Through `unknown`: `closable: false` in the defaults belongs to the dismiss\n// union rather than to `AlertBaseFields`, so TypeScript cannot see the merge as\n// comparable to `P` although every field of `P` survives it untouched.\nexport const resolveAlertProps = <P extends AlertBaseFields>(props: P): ResolvedAlertProps<P> =>\n ({ ...ALERT_DEFAULTS, ...definedProps(props) }) as unknown as ResolvedAlertProps<P>;\n\n/** `danger` announces itself; everything else waits its turn. */\nexport const defaultAriaLive = (variant: AlertVariant): 'polite' | 'assertive' =>\n variant === 'danger' ? 'assertive' : 'polite';\n\n/**\n * The ARIA role each `announce` level is spelled with.\n *\n * Both roles carry an IMPLICIT live setting, and that implicit one is what\n * assistive tech acts on — `alert` is assertive, `status` is polite. Pairing\n * them here is what stops `role` and `aria-live` from contradicting each\n * other, which they do by default: every alert is `role=\"alert\"` regardless of\n * variant, so an `info` alert asks to be polite in one attribute and to\n * interrupt in the other.\n */\nexport const ANNOUNCE_ROLE: Record<NonNullable<AlertBaseFields['announce']>, string> = {\n assertive: 'alert',\n polite: 'status',\n};\n\n/**\n * The two attributes that decide whether an alert interrupts, resolved TOGETHER.\n *\n * Both renderers therefore let `role` and `announce` leave their destructure\n * unused (`_role`, `_announce`) and call this instead — the first because the\n * defaults have already answered it, the second because it must never reach\n * the DOM.\n *\n * Reads the caller's own props rather than the defaulted ones, because the\n * whole question is which of them the caller actually spelled:\n * {@link ALERT_DEFAULTS} supplies `role: 'alert'` for everything, so after the\n * merge there is no longer any difference between an alert that asked to\n * interrupt and one that never mentioned it.\n *\n * Precedence, most specific first — an explicit `role` or `aria-live` beats\n * `announce`, so a call site that already spells either by hand is untouched:\n *\n * 1. `role` / `aria-live` as given;\n * 2. {@link AlertBaseFields.announce}, which supplies both;\n * 3. today's behaviour — `ALERT_DEFAULTS.role` and {@link defaultAriaLive}.\n *\n * With none of the three named, the result is byte-for-byte what it was before\n * `announce` existed.\n */\nexport const resolveAnnouncement = (\n props: Pick<AlertBaseFields, 'announce' | 'role' | 'aria-live'>,\n variant: AlertVariant,\n): { role: string; 'aria-live': 'polite' | 'assertive' | 'off' } => {\n const announce = props.announce;\n return {\n role: props.role ?? (announce === undefined ? ALERT_DEFAULTS.role : ANNOUNCE_ROLE[announce]),\n 'aria-live': props['aria-live'] ?? announce ?? defaultAriaLive(variant),\n };\n};\n\nexport const testIdFor = (base: string | undefined, suffix: string): string =>\n base ? `${base}-${suffix}` : `alert-${suffix}`;\n\n/**\n * The glyph each semantic variant carries, by the shared icon set's name.\n * `glass` and `gradient` carry none of their own: the web renders an empty\n * icon slot for them unless the caller passes an `icon`, and so does native.\n */\nexport const VARIANT_ICON: Partial<Record<AlertVariant, IconName>> = {\n info: 'Info',\n success: 'CheckCircle',\n warning: 'Warning',\n danger: 'Error',\n};\n","import type { AlertVariant } from './Alert.base';\nimport { alpha, darken, lighten } from '../../../tokens/color';\nimport { NEUTRAL_RAMP } from '../../../tokens/ink.core';\nimport { contrastText, type UiGreyStep, type UiTheme } from '../../../tokens/theme';\n\n/**\n * THE NUMBERS BOTH `Alert` RENDERERS DRAW WITH.\n *\n * `Alert.styles.tsx` / `Alert.tsx` (MUI) and `Alert.native.tsx` (React\n * Native) read this one table. Spacing is in SPACING UNITS where the web\n * writes `theme.spacing(n)`; durations are ms (the web turns them into `s`\n * through {@link seconds} so its emitted CSS is byte-for-byte what it was);\n * everything else is px, a ratio or an alpha. The hover, active and focus\n * numbers are here too although only the DOM can honour them — a number the\n * web draws with belongs in the table whether or not native can reach it.\n */\n\n/** The root: 12px corners, 14px 16px of padding, one 300ms curve for everything. */\nexport const ALERT_RADIUS_UNITS = 1.5;\nexport const ALERT_PADDING_UNITS = { vertical: 1.75, horizontal: 2 } as const;\nexport const ALERT_TRANSITION_MS = 300;\nexport const ALERT_EASING = 'cubic-bezier(0.4, 0, 0.2, 1)';\n\n/** Mount: the web's `fadeInScale` keyframes and the icon's `iconRotate`. */\nexport const FADE_IN = { ms: 300, scale: 0.95, lift: 10 } as const;\nexport const ICON_SPIN = { ms: 600, from: 0.8, mid: 1.1 } as const;\n/** Dismiss: MUI `Collapse` runs 300ms; `onClose` fires 200ms in. */\nexport const COLLAPSE_MS = 300;\nexport const CLOSE_DELAY_MS = 200;\n\n/** The message column: 8px between title, description and children; 0.95rem body on 1.5. */\nexport const MESSAGE_GAP_UNITS = 1;\nexport const MESSAGE_FONT_SIZE = 15.2;\nexport const MESSAGE_LINE_HEIGHT = 1.5;\n/** A control inside the message gets an edge: 4px above, a hairline at 0.45 of the hue. */\nexport const MESSAGE_BUTTON = { marginTopUnits: 0.5, borderAlpha: 0.45 } as const;\n\n/** The title: 1.05rem at 600; MUI's `AlertTitle` lifts it 2px; 4px below it when a description follows. */\nexport const TITLE = { fontSize: 16.8, fontWeight: 600, marginTop: -2, marginBottomUnits: 0.5 } as const;\n/** The description: 0.925rem, slightly faded. */\nexport const DESCRIPTION = { fontSize: 14.8, opacity: 0.9 } as const;\n\n/** The icon on the title's line (`iconPlacement: 'title'`): 10px from the title. */\nexport const TITLE_ICON = { gapUnits: 1.25 } as const;\n/** The icon slot: MUI's 22px glyph at 0.9, 14px from the words, 2px down (MUI's 7px stays below). */\nexport const ICON_SLOT = { size: 22, opacity: 0.9, marginRightUnits: 1.75, paddingTopUnits: 0.25, paddingBottom: 7 } as const;\n/** The action slot: MUI's `4px 0 0 16px` with the 16px ours, pushed right, 8px into the padding. */\nexport const ACTION_SLOT = { paddingLeftUnits: 2, paddingTop: 4, marginRight: -8 } as const;\n/** The close button: MUI's small `IconButton` (5px padding, 18px glyph) at 0.7. */\nexport const CLOSE_BUTTON = { padding: 5, iconSize: 18, opacity: 0.7, washAlpha: 0.1 } as const;\n\n/**\n * A semantic Alert's surface and ink: an OPAQUE tint of the hue with a dark\n * ink of the same hue — MUI's own `standard` recipe, at its ratios. See\n * `semanticSurface` in `Alert.styles.tsx` for why not `alpha(main, 0.1)`.\n */\nexport const SEMANTIC_SURFACE = { tint: { light: 0.9, dark: 0.8 }, ink: 0.6, borderAlpha: 0.35 } as const;\n/** `glass`: 85% paper under a 20px blur, a 0.4 divider hairline. */\nexport const GLASS = { backgroundAlpha: 0.85, borderAlpha: 0.4, blur: 20, saturatePercent: 180 } as const;\n/**\n * `gradient`: light→dark at 0.9 along 135°, a 0.2 white shimmer sweeping 1000px every 3s.\n *\n * It carries no hover of its own, and that is load-bearing rather than an\n * omission. `alertVariantStyles` is spread AFTER the root's `'&:hover'` in the\n * same object literal, so a second `'&:hover'` key does not merge with it — it\n * REPLACES it. While this variant had one, `gradient` was the only alert that\n * brightened on hover while every other variant darkened, and the only one to\n * lose the shimmer reveal the root's hover performs.\n */\nexport const GRADIENT = {\n angleDeg: 135,\n stopAlpha: 0.9,\n shimmerAlpha: 0.2,\n shimmerMs: 3000,\n shimmerTravel: 1000,\n} as const;\n\n/** Emphasis: the glow's shadow and brightness, the pulse's wash. */\nexport const GLOW = { blur: 20, spread: 5, alpha: 0.3, brightness: 1.05 } as const;\nexport const PULSE = { alpha: 0.2, ms: 2000, spread: 10 } as const;\n\n/**\n * Pointer states — DOM only, kept so the web derives them.\n *\n * HOVER and ACTIVE carry NO geometry, and that is the point rather than an\n * omission. They used to lift the card 3px, scale it 1.01, grow a 20px shadow\n * and spin the icon 10deg at 1.15 — four things moving at once on a surface\n * that is not a control, which made a page of alerts twitch under the pointer.\n *\n * Both are a TINT now: a flat inset layer over the surface. Two mechanisms\n * came before it and each failed on a case the next had to fix. Dropping the\n * element's `opacity` composites toward the PAGE, so it inverted the hover on\n * a light tint (L* 95.0 idle, 89.1 hovered, 91.1 pressed) and vanished on a\n * dark one. A `filter: brightness()` fixed the direction but is MULTIPLICATIVE,\n * so it moved a near-black `glass` by four counts (ΔE76 1.71, under the JND)\n * and Banner's 10%-alpha wash by ΔE76 0.44. A layer is additive: it reads the\n * same on an opaque tint, a translucent wash and a gradient, and because it\n * paints above the background and below the content the ink keeps its own\n * contrast.\n */\nexport const HOVER = { tintAlpha: 0.06 } as const;\n\n/**\n * The press: a 20% tint LAYER, eased back fast.\n *\n * The layer is the point. The first attempt dropped the whole element's\n * opacity, which composites toward the PAGE and so behaves differently on\n * every surface it is asked about. Measured: over a light page it made a light\n * tint LIGHTER (L* 95.0 idle, 89.1 hovered, 91.1 pressed), so pushing the\n * surface looked like the pointer leaving; over a dark page it landed back on\n * the idle surface (ΔE76 0.82 on `glass`); on `gradient` it washed white body\n * copy to 2.31:1, under AA; and it diluted the ink during a text-selection\n * drag. A `brightness()` step instead of it fixed the direction but not the\n * reach — a multiplier does nothing to a near-black `glass` in dark mode\n * (ΔE76 1.71) and nothing to Banner's 10%-alpha wash (ΔE76 0.44), because it\n * scales only what the element already paints.\n *\n * An inset shadow at 100vmax is a flat tint over the whole surface: ADDITIVE,\n * so it reads the same on an opaque tint, a translucent wash and a gradient;\n * painted above the background and below the content, so the ink keeps its\n * own contrast; and animatable, which `background-image` is not.\n *\n * `ms` is 250 and not the 1000 first asked for, and the reason is that ONE\n * property carries both states. CSS runs a transition from the DESTINATION\n * state's declaration, and entering hover and releasing a press share that\n * destination — so they cannot have different durations without a second\n * animatable property, and both free pseudo-elements are already spent on the\n * `gradient` shimmer and the `pulse` wash. At 1000ms the hover inherited the\n * second: crossing an alert in 300ms peaked at a ≈ 0.024, under the JND, and\n * for ~360ms the alert you had just LEFT was darker than the one under the\n * pointer. A fast press-return is the smaller loss, and it is the call the\n * product owner made when shown both.\n */\nexport const ACTIVE = { tintAlpha: 0.2, ms: 250 } as const;\n\nexport const FOCUS = { ringWidth: 2, ringAlpha: 1, offset: 2 } as const;\n\n/** `neutral` has no palette slot; the web has always drawn it from three greys. */\nexport const NEUTRAL_GREY: Record<'main' | 'light' | 'dark', UiGreyStep> = { main: 500, light: 300, dark: 700 };\n\n/** A duration as the CSS the web has always emitted: `2000` → `2s`, `300` → `0.3s`. */\nexport const seconds = (ms: number): string => `${ms / 1000}s`;\n\n/** The palette shape the web's `getColorFromTheme` returns — a main plus optional shades. */\nexport interface AlertPalette {\n main: string;\n light?: string;\n dark?: string;\n}\n\n/**\n * The renderer-free twin of the web's `getColorFromTheme`: a variant or\n * colour name to its palette, `neutral` from the greys, anything unknown\n * (`glass`, `gradient`) to `info`.\n */\nexport function alertPalette(theme: UiTheme, key: string | undefined): AlertPalette {\n switch (key) {\n case 'info':\n case 'success':\n case 'warning':\n case 'danger':\n case 'primary':\n case 'secondary':\n return theme.palette[key];\n case 'neutral':\n return {\n main: NEUTRAL_RAMP[NEUTRAL_GREY.main],\n light: NEUTRAL_RAMP[NEUTRAL_GREY.light],\n dark: NEUTRAL_RAMP[NEUTRAL_GREY.dark],\n };\n default:\n return theme.palette.info;\n }\n}\n\n/** What a variant paints: its fill, its ink, its hairline if any, and the colour of its glyph. */\nexport interface AlertSurface {\n backgroundColor: string;\n color: string;\n borderColor?: string;\n iconColor: string;\n}\n\nexport const SEMANTIC_VARIANTS: ReadonlySet<AlertVariant> = new Set(['info', 'success', 'warning', 'danger']);\n\n/** The opaque tint and same-hue ink, inverted for dark mode; the hairline keeps its alpha. */\nexport function semanticSurface(theme: UiTheme, palette: AlertPalette): AlertSurface {\n const dark = theme.mode === 'dark';\n return {\n backgroundColor: dark\n ? darken(palette.main, SEMANTIC_SURFACE.tint.dark)\n : lighten(palette.main, SEMANTIC_SURFACE.tint.light),\n color: dark ? lighten(palette.main, SEMANTIC_SURFACE.ink) : darken(palette.main, SEMANTIC_SURFACE.ink),\n borderColor: alpha(palette.main, SEMANTIC_SURFACE.borderAlpha),\n iconColor: palette.main,\n };\n}\n\nexport function glassSurface(theme: UiTheme): AlertSurface {\n return {\n backgroundColor: alpha(theme.palette.background.paper, GLASS.backgroundAlpha),\n color: theme.palette.text.primary,\n borderColor: alpha(theme.palette.divider, GLASS.borderAlpha),\n iconColor: theme.palette.primary.main,\n };\n}\n\n/** The gradient's two stops; a renderer with no gradient fill paints `from`. */\nexport function gradientStops(palette: AlertPalette): { from: string; to: string } {\n return {\n from: alpha(palette.light || palette.main, GRADIENT.stopAlpha),\n to: alpha(palette.dark || palette.main, GRADIENT.stopAlpha),\n };\n}\n\nexport function gradientSurface(palette: AlertPalette): AlertSurface {\n const ink = contrastText(palette.main);\n return { backgroundColor: gradientStops(palette).from, color: ink, iconColor: ink };\n}\n\n/** The surface for a variant, `glass` and `gradient` included. */\nexport function alertSurface(theme: UiTheme, variant: AlertVariant, palette: AlertPalette): AlertSurface {\n if (variant === 'glass') return glassSurface(theme);\n if (variant === 'gradient') return gradientSurface(palette);\n return semanticSurface(theme, palette);\n}\n","import type { TextStyle, ViewStyle } from 'react-native';\n\nimport type { AlertVariant } from './Alert.base';\nimport {\n ACTION_SLOT,\n ALERT_PADDING_UNITS,\n ALERT_RADIUS_UNITS,\n type AlertPalette,\n alertPalette,\n alertSurface,\n CLOSE_BUTTON,\n DESCRIPTION,\n GLOW,\n ICON_SLOT,\n MESSAGE_FONT_SIZE,\n MESSAGE_GAP_UNITS,\n MESSAGE_LINE_HEIGHT,\n TITLE,\n} from './Alert.metrics';\nimport { alpha } from '../../../tokens/color';\nimport { muiTypeStyle } from '../../../tokens/mui-type';\nimport type { UiTheme } from '../../../tokens/theme';\nimport type { ColorValue } from '../../../tokens/vocabulary';\n\n/**\n * THE PAINT, KEPT APART FROM THE STRUCTURE.\n *\n * `Alert.native.tsx` reads as what renders where; this file reads as\n * arithmetic — the same palette slots, alphas and px the web's\n * `Alert.styles.tsx` derives from `Alert.metrics.ts`.\n */\n\nexport interface AlertLookArgs {\n variant: AlertVariant;\n color: ColorValue | undefined;\n glow: boolean;\n pulse: boolean;\n}\n\nexport interface AlertLook {\n palette: AlertPalette;\n /** What the words are set in. */\n ink: string;\n iconColor: string;\n root: ViewStyle;\n}\n\n/**\n * The root's paint. The web keeps `overflow: hidden` (its pulse wash is\n * clipped to the card, as it is here); only the glow opens it, because a\n * view's own shadow is clipped by its own overflow on a device.\n */\nexport function alertLook(theme: UiTheme, a: AlertLookArgs): AlertLook {\n const palette = alertPalette(theme, a.color ?? a.variant);\n const surface = alertSurface(theme, a.variant, palette);\n const root: ViewStyle = {\n flexDirection: 'row',\n paddingVertical: theme.spacing(ALERT_PADDING_UNITS.vertical),\n paddingHorizontal: theme.spacing(ALERT_PADDING_UNITS.horizontal),\n borderRadius: theme.spacing(ALERT_RADIUS_UNITS),\n overflow: a.glow ? 'visible' : 'hidden',\n backgroundColor: surface.backgroundColor,\n ...(surface.borderColor ? { borderWidth: 1, borderColor: surface.borderColor } : {}),\n ...(a.glow\n ? {\n boxShadow: `0 0 ${GLOW.blur}px ${GLOW.spread}px ${alpha(palette.main, GLOW.alpha)}`,\n filter: `brightness(${GLOW.brightness})`,\n }\n : {}),\n };\n return { palette, ink: surface.color, iconColor: surface.iconColor, root };\n}\n\n/** The message column: 8px between its lines, allowed to shrink so long text wraps beside the icon. */\nexport const messageSlotStyle = (theme: UiTheme): ViewStyle => ({\n flexDirection: 'column',\n gap: theme.spacing(MESSAGE_GAP_UNITS),\n flexShrink: 1,\n minWidth: 0,\n});\n\n/** A string child: MUI's `body2` letter-spacing at 0.95rem on the message's 1.5. */\nexport const messageTextStyle = (theme: UiTheme, ink: string): TextStyle => ({\n ...muiTypeStyle(theme, 'body2', MESSAGE_FONT_SIZE),\n lineHeight: MESSAGE_FONT_SIZE * MESSAGE_LINE_HEIGHT,\n color: ink,\n});\n\n/** MUI's `AlertTitle` (a `body1` Typography) at 1.05rem and 600, lifted 2px, 4px above a description. */\nexport const titleStyle = (theme: UiTheme, ink: string, hasDescription: boolean): TextStyle => ({\n ...muiTypeStyle(theme, 'body1', TITLE.fontSize),\n fontWeight: `${TITLE.fontWeight}`,\n color: ink,\n marginTop: TITLE.marginTop,\n marginBottom: hasDescription ? theme.spacing(TITLE.marginBottomUnits) : 0,\n});\n\n/** The description: 0.925rem on the message's 1.5, faded to 0.9. */\nexport const descriptionStyle = (theme: UiTheme, ink: string): TextStyle => ({\n ...muiTypeStyle(theme, 'body2', DESCRIPTION.fontSize),\n lineHeight: DESCRIPTION.fontSize * MESSAGE_LINE_HEIGHT,\n color: ink,\n opacity: DESCRIPTION.opacity,\n});\n\n/** MUI's `.MuiAlert-icon` with the web's overrides: first-line aligned, 14px from the words, 2px down. */\nexport const iconSlotStyle = (theme: UiTheme): ViewStyle => ({\n alignSelf: 'flex-start',\n alignItems: 'center',\n marginRight: theme.spacing(ICON_SLOT.marginRightUnits),\n paddingTop: theme.spacing(ICON_SLOT.paddingTopUnits),\n paddingBottom: ICON_SLOT.paddingBottom,\n opacity: ICON_SLOT.opacity,\n});\n\n/** MUI's `.MuiAlert-action`: top-aligned, pushed to the right edge, 16px off the text. */\nexport const actionSlotStyle = (theme: UiTheme): ViewStyle => ({\n alignItems: 'flex-start',\n paddingTop: ACTION_SLOT.paddingTop,\n paddingLeft: theme.spacing(ACTION_SLOT.paddingLeftUnits),\n marginLeft: 'auto',\n marginRight: ACTION_SLOT.marginRight,\n});\n\n/** MUI's small `IconButton` at 0.7; pressed stands in for the web's hover (full opacity, a faint wash). */\nexport const closeButtonStyle = (theme: UiTheme, pressed: boolean): ViewStyle => ({\n padding: CLOSE_BUTTON.padding,\n borderRadius: theme.radius.full,\n opacity: pressed ? 1 : CLOSE_BUTTON.opacity,\n backgroundColor: pressed ? alpha(theme.palette.action.hover, CLOSE_BUTTON.washAlpha) : 'transparent',\n});\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,YAAY,WAAW;AACvB;AAAA,EACE;AAAA,EACA;AAAA,EAEA;AAAA,EACA;AAAA,EAEA;AAAA,EACA,QAAQ;AAAA,EACR;AAAA,OAEK;;;ACPA,IAAM,iBAA4F;AAAA,EACvG,SAAS;AAAA,EACT,MAAM;AAAA,EACN,OAAO;AAAA,EACP,UAAU;AAAA,EACV,UAAU;AAAA,EACV,SAAS;AAAA,EACT,MAAM;AAAA,EACN,eAAe;AACjB;AAWA,IAAM,eAAe,CAA4B,UAC/C,OAAO;AAAA,EACL,OAAO,QAAQ,KAAK,EAAE,OAAO,CAAC,CAAC,EAAE,KAAK,MAAM,UAAU,MAAS;AACjE;AAKK,IAAM,oBAAoB,CAA4B,WAC1D,EAAE,GAAG,gBAAgB,GAAG,aAAa,KAAK,EAAE;AAGxC,IAAM,kBAAkB,CAAC,YAC9B,YAAY,WAAW,cAAc;AAYhC,IAAM,gBAA0E;AAAA,EACrF,WAAW;AAAA,EACX,QAAQ;AACV;AA0BO,IAAM,sBAAsB,CACjC,OACA,YACkE;AAClE,QAAM,WAAW,MAAM;AACvB,SAAO;AAAA,IACL,MAAM,MAAM,SAAS,aAAa,SAAY,eAAe,OAAO,cAAc,QAAQ;AAAA,IAC1F,aAAa,MAAM,WAAW,KAAK,YAAY,gBAAgB,OAAO;AAAA,EACxE;AACF;AAEO,IAAM,YAAY,CAAC,MAA0B,WAClD,OAAO,GAAG,IAAI,IAAI,MAAM,KAAK,SAAS,MAAM;AAOvC,IAAM,eAAwD;AAAA,EACnE,MAAM;AAAA,EACN,SAAS;AAAA,EACT,SAAS;AAAA,EACT,QAAQ;AACV;;;ACrFO,IAAM,qBAAqB;AAC3B,IAAM,sBAAsB,EAAE,UAAU,MAAM,YAAY,EAAE;AAK5D,IAAM,UAAU,EAAE,IAAI,KAAK,OAAO,MAAM,MAAM,GAAG;AACjD,IAAM,YAAY,EAAE,IAAI,KAAK,MAAM,KAAK,KAAK,IAAI;AAEjD,IAAM,cAAc;AACpB,IAAM,iBAAiB;AAGvB,IAAM,oBAAoB;AAC1B,IAAM,oBAAoB;AAC1B,IAAM,sBAAsB;AAK5B,IAAM,QAAQ,EAAE,UAAU,MAAM,YAAY,KAAK,WAAW,IAAI,mBAAmB,IAAI;AAEvF,IAAM,cAAc,EAAE,UAAU,MAAM,SAAS,IAAI;AAKnD,IAAM,YAAY,EAAE,MAAM,IAAI,SAAS,KAAK,kBAAkB,MAAM,iBAAiB,MAAM,eAAe,EAAE;AAE5G,IAAM,cAAc,EAAE,kBAAkB,GAAG,YAAY,GAAG,aAAa,GAAG;AAE1E,IAAM,eAAe,EAAE,SAAS,GAAG,UAAU,IAAI,SAAS,KAAK,WAAW,IAAI;AAO9E,IAAM,mBAAmB,EAAE,MAAM,EAAE,OAAO,KAAK,MAAM,IAAI,GAAG,KAAK,KAAK,aAAa,KAAK;AAExF,IAAM,QAAQ,EAAE,iBAAiB,MAAM,aAAa,KAAK,MAAM,IAAI,iBAAiB,IAAI;AAWxF,IAAM,WAAW;AAAA,EACtB,UAAU;AAAA,EACV,WAAW;AAAA,EACX,cAAc;AAAA,EACd,WAAW;AAAA,EACX,eAAe;AACjB;AAGO,IAAM,OAAO,EAAE,MAAM,IAAI,QAAQ,GAAG,OAAO,KAAK,YAAY,KAAK;AACjE,IAAM,QAAQ,EAAE,OAAO,KAAK,IAAI,KAAM,QAAQ,GAAG;AA2DjD,IAAM,eAA8D,EAAE,MAAM,KAAK,OAAO,KAAK,MAAM,IAAI;AAiBvG,SAAS,aAAa,OAAgB,KAAuC;AAClF,UAAQ,KAAK;AAAA,IACX,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACH,aAAO,MAAM,QAAQ,GAAG;AAAA,IAC1B,KAAK;AACH,aAAO;AAAA,QACL,MAAM,aAAa,aAAa,IAAI;AAAA,QACpC,OAAO,aAAa,aAAa,KAAK;AAAA,QACtC,MAAM,aAAa,aAAa,IAAI;AAAA,MACtC;AAAA,IACF;AACE,aAAO,MAAM,QAAQ;AAAA,EACzB;AACF;AAaO,SAAS,gBAAgB,OAAgB,SAAqC;AACnF,QAAM,OAAO,MAAM,SAAS;AAC5B,SAAO;AAAA,IACL,iBAAiB,OACb,OAAO,QAAQ,MAAM,iBAAiB,KAAK,IAAI,IAC/C,QAAQ,QAAQ,MAAM,iBAAiB,KAAK,KAAK;AAAA,IACrD,OAAO,OAAO,QAAQ,QAAQ,MAAM,iBAAiB,GAAG,IAAI,OAAO,QAAQ,MAAM,iBAAiB,GAAG;AAAA,IACrG,aAAa,MAAM,QAAQ,MAAM,iBAAiB,WAAW;AAAA,IAC7D,WAAW,QAAQ;AAAA,EACrB;AACF;AAEO,SAAS,aAAa,OAA8B;AACzD,SAAO;AAAA,IACL,iBAAiB,MAAM,MAAM,QAAQ,WAAW,OAAO,MAAM,eAAe;AAAA,IAC5E,OAAO,MAAM,QAAQ,KAAK;AAAA,IAC1B,aAAa,MAAM,MAAM,QAAQ,SAAS,MAAM,WAAW;AAAA,IAC3D,WAAW,MAAM,QAAQ,QAAQ;AAAA,EACnC;AACF;AAGO,SAAS,cAAc,SAAqD;AACjF,SAAO;AAAA,IACL,MAAM,MAAM,QAAQ,SAAS,QAAQ,MAAM,SAAS,SAAS;AAAA,IAC7D,IAAI,MAAM,QAAQ,QAAQ,QAAQ,MAAM,SAAS,SAAS;AAAA,EAC5D;AACF;AAEO,SAAS,gBAAgB,SAAqC;AACnE,QAAM,MAAM,aAAa,QAAQ,IAAI;AACrC,SAAO,EAAE,iBAAiB,cAAc,OAAO,EAAE,MAAM,OAAO,KAAK,WAAW,IAAI;AACpF;AAGO,SAAS,aAAa,OAAgB,SAAuB,SAAqC;AACvG,MAAI,YAAY,QAAS,QAAO,aAAa,KAAK;AAClD,MAAI,YAAY,WAAY,QAAO,gBAAgB,OAAO;AAC1D,SAAO,gBAAgB,OAAO,OAAO;AACvC;;;AC7KO,SAAS,UAAU,OAAgB,GAA6B;AACrE,QAAM,UAAU,aAAa,OAAO,EAAE,SAAS,EAAE,OAAO;AACxD,QAAM,UAAU,aAAa,OAAO,EAAE,SAAS,OAAO;AACtD,QAAM,OAAkB;AAAA,IACtB,eAAe;AAAA,IACf,iBAAiB,MAAM,QAAQ,oBAAoB,QAAQ;AAAA,IAC3D,mBAAmB,MAAM,QAAQ,oBAAoB,UAAU;AAAA,IAC/D,cAAc,MAAM,QAAQ,kBAAkB;AAAA,IAC9C,UAAU,EAAE,OAAO,YAAY;AAAA,IAC/B,iBAAiB,QAAQ;AAAA,IACzB,GAAI,QAAQ,cAAc,EAAE,aAAa,GAAG,aAAa,QAAQ,YAAY,IAAI,CAAC;AAAA,IAClF,GAAI,EAAE,OACF;AAAA,MACE,WAAW,OAAO,KAAK,IAAI,MAAM,KAAK,MAAM,MAAM,MAAM,QAAQ,MAAM,KAAK,KAAK,CAAC;AAAA,MACjF,QAAQ,cAAc,KAAK,UAAU;AAAA,IACvC,IACA,CAAC;AAAA,EACP;AACA,SAAO,EAAE,SAAS,KAAK,QAAQ,OAAO,WAAW,QAAQ,WAAW,KAAK;AAC3E;AAGO,IAAM,mBAAmB,CAAC,WAA+B;AAAA,EAC9D,eAAe;AAAA,EACf,KAAK,MAAM,QAAQ,iBAAiB;AAAA,EACpC,YAAY;AAAA,EACZ,UAAU;AACZ;AAGO,IAAM,mBAAmB,CAAC,OAAgB,SAA4B;AAAA,EAC3E,GAAG,aAAa,OAAO,SAAS,iBAAiB;AAAA,EACjD,YAAY,oBAAoB;AAAA,EAChC,OAAO;AACT;AAGO,IAAM,aAAa,CAAC,OAAgB,KAAa,oBAAwC;AAAA,EAC9F,GAAG,aAAa,OAAO,SAAS,MAAM,QAAQ;AAAA,EAC9C,YAAY,GAAG,MAAM,UAAU;AAAA,EAC/B,OAAO;AAAA,EACP,WAAW,MAAM;AAAA,EACjB,cAAc,iBAAiB,MAAM,QAAQ,MAAM,iBAAiB,IAAI;AAC1E;AAGO,IAAM,mBAAmB,CAAC,OAAgB,SAA4B;AAAA,EAC3E,GAAG,aAAa,OAAO,SAAS,YAAY,QAAQ;AAAA,EACpD,YAAY,YAAY,WAAW;AAAA,EACnC,OAAO;AAAA,EACP,SAAS,YAAY;AACvB;AAGO,IAAM,gBAAgB,CAAC,WAA+B;AAAA,EAC3D,WAAW;AAAA,EACX,YAAY;AAAA,EACZ,aAAa,MAAM,QAAQ,UAAU,gBAAgB;AAAA,EACrD,YAAY,MAAM,QAAQ,UAAU,eAAe;AAAA,EACnD,eAAe,UAAU;AAAA,EACzB,SAAS,UAAU;AACrB;AAGO,IAAM,kBAAkB,CAAC,WAA+B;AAAA,EAC7D,YAAY;AAAA,EACZ,YAAY,YAAY;AAAA,EACxB,aAAa,MAAM,QAAQ,YAAY,gBAAgB;AAAA,EACvD,YAAY;AAAA,EACZ,aAAa,YAAY;AAC3B;AAGO,IAAM,mBAAmB,CAAC,OAAgB,aAAiC;AAAA,EAChF,SAAS,aAAa;AAAA,EACtB,cAAc,MAAM,OAAO;AAAA,EAC3B,SAAS,UAAU,IAAI,aAAa;AAAA,EACpC,iBAAiB,UAAU,MAAM,MAAM,QAAQ,OAAO,OAAO,aAAa,SAAS,IAAI;AACzF;;;AH9CI,cAkFA,YAlFA;AAlDJ,IAAM,eAAe,SAAS,OAAO;AAGrC,SAAS,YAAY,SAAkB,UAAkC;AACvE,QAAM,WAAiB,aAAO,IAAI,SAAS,MAAM,UAAU,IAAI,CAAC,CAAC,EAAE;AACnE,EAAM,gBAAU,MAAM;AACpB,QAAI,CAAC,QAAS,QAAO;AACrB,UAAM,SAAS,SAAS,OAAO,UAAU,EAAE,SAAS,GAAG,UAAU,QAAQ,OAAO,IAAI,OAAO,IAAI,GAAG,iBAAiB,aAAa,CAAC;AACjI,WAAO,MAAM;AACb,WAAO,MAAM,OAAO,KAAK;AAAA,EAC3B,GAAG,CAAC,SAAS,UAAU,QAAQ,CAAC;AAChC,SAAO;AACT;AAGA,SAAS,UAAU,SAA6C;AAC9D,QAAM,WAAW,YAAY,SAAS,QAAQ,EAAE;AAChD,MAAI,CAAC,QAAS,QAAO;AACrB,SAAO;AAAA,IACL,SAAS;AAAA,IACT,WAAW;AAAA,MACT,EAAE,OAAO,SAAS,YAAY,EAAE,YAAY,CAAC,GAAG,CAAC,GAAG,aAAa,CAAC,QAAQ,OAAO,CAAC,EAAE,CAAC,EAAE;AAAA,MACvF,EAAE,YAAY,SAAS,YAAY,EAAE,YAAY,CAAC,GAAG,CAAC,GAAG,aAAa,CAAC,CAAC,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,IAC9F;AAAA,EACF;AACF;AAGA,SAAS,YAAY,SAA6C;AAChE,QAAM,WAAW,YAAY,SAAS,UAAU,EAAE;AAClD,MAAI,CAAC,QAAS,QAAO;AACrB,SAAO;AAAA,IACL,WAAW;AAAA,MACT,EAAE,QAAQ,SAAS,YAAY,EAAE,YAAY,CAAC,GAAG,CAAC,GAAG,aAAa,CAAC,QAAQ,QAAQ,EAAE,CAAC,EAAE;AAAA,MACxF,EAAE,OAAO,SAAS,YAAY,EAAE,YAAY,CAAC,GAAG,KAAK,CAAC,GAAG,aAAa,CAAC,UAAU,MAAM,UAAU,KAAK,CAAC,EAAE,CAAC,EAAE;AAAA,IAC9G;AAAA,EACF;AACF;AAGA,SAAS,MAAM,EAAE,OAAO,QAAQ,OAAO,GAAyE;AAC9G,QAAM,WAAiB,aAAO,IAAI,SAAS,MAAM,CAAC,CAAC,EAAE;AACrD,EAAM,gBAAU,MAAM;AACpB,UAAM,OAAO,SAAS;AAAA,MACpB,SAAS,OAAO,UAAU,EAAE,SAAS,GAAG,UAAU,MAAM,IAAI,QAAQ,OAAO,QAAQ,iBAAiB,aAAa,CAAC;AAAA,IACpH;AACA,SAAK,MAAM;AACX,WAAO,MAAM,KAAK,KAAK;AAAA,EACzB,GAAG,CAAC,QAAQ,CAAC;AACb,SACE;AAAA,IAAC,SAAS;AAAA,IAAT;AAAA,MACC;AAAA,MACA,eAAW;AAAA,MACX,OAAO;AAAA,QACL,WAAW;AAAA,QACX;AAAA,UACE,eAAe;AAAA,UACf,cAAc;AAAA,UACd,iBAAiB;AAAA,UACjB,SAAS,SAAS,YAAY,EAAE,YAAY,CAAC,GAAG,KAAK,CAAC,GAAG,aAAa,CAAC,MAAM,OAAO,GAAG,CAAC,EAAE,CAAC;AAAA,QAC7F;AAAA,MACF;AAAA;AAAA,EACF;AAEJ;AAMA,SAAS,SAAS,EAAE,MAAM,aAAa,SAAS,GAA6F;AAC3I,QAAM,CAAC,QAAQ,SAAS,IAAU,eAAwB,IAAI;AAC9D,QAAM,WAAiB,aAAO,IAAI,SAAS,MAAM,CAAC,CAAC,EAAE;AACrD,EAAM,gBAAU,MAAM;AACpB,QAAI,KAAM,QAAO;AACjB,UAAM,SAAS,SAAS,OAAO,UAAU,EAAE,SAAS,GAAG,UAAU,aAAa,QAAQ,OAAO,MAAM,OAAO,IAAI,GAAG,iBAAiB,MAAM,CAAC;AACzI,WAAO,MAAM,CAAC,EAAE,SAAS,MAAM;AAC7B,UAAI,SAAU,aAAY;AAAA,IAC5B,CAAC;AACD,WAAO,MAAM,OAAO,KAAK;AAAA,EAC3B,GAAG,CAAC,MAAM,aAAa,QAAQ,CAAC;AAChC,QAAM,WAAW,CAAC,UAAmC;AACnD,QAAI,KAAM,WAAU,MAAM,YAAY,OAAO,MAAM;AAAA,EACrD;AACA,QAAM,SAAwB,UAAU,OAAO,CAAC,IAAI,EAAE,WAAW,SAAS,YAAY,EAAE,YAAY,CAAC,GAAG,CAAC,GAAG,aAAa,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE;AACxI,SACE,oBAAC,SAAS,MAAT,EAAc,OAAO,CAAC,EAAE,UAAU,OAAO,YAAY,UAAU,SAAS,SAAS,GAAG,MAAM,GACzF,8BAAC,QAAK,UAAqB,UAAS,GACtC;AAEJ;AAWA,SAAS,SAAS,EAAE,SAAS,MAAM,OAAO,SAAS,OAAO,GAAqC;AAC7F,QAAM,QAAQ,WAAW;AACzB,QAAM,OAAO,YAAY,OAAO;AAChC,QAAM,QAAQ,aAAa,OAAO;AAClC,SACE,oBAAC,SAAS,MAAT,EAAc,QAAgB,OAAO,CAAC,cAAc,KAAK,GAAG,IAAI,GAC9D,mBAAS,QAAQ,oBAAC,QAAK,MAAM,OAAO,MAAM,UAAU,MAAM,OAAc,IAAK,OAChF;AAEJ;AAEA,SAAS,YAAY,EAAE,OAAO,KAAK,SAAS,OAAO,GAAuG;AACxJ,QAAM,QAAQ,WAAW;AACzB,SACE,oBAAC,aAAU,MAAK,UAAS,cAAY,OAAO,QAAgB,SAAkB,OAAO,CAAC,EAAE,QAAQ,MAAM,iBAAiB,OAAO,OAAO,GACnI,8BAAC,QAAK,MAAK,SAAQ,MAAM,aAAa,UAAU,OAAO,KAAK,GAC9D;AAEJ;AAUA,SAAS,aAAa,EAAE,OAAO,aAAa,UAAU,KAAK,OAAO,GAAoC;AACpG,QAAM,QAAQ,WAAW;AACzB,SACE,qBAAC,QAAK,OAAO,iBAAiB,KAAK,GAChC;AAAA,YACC,oBAAC,UAAO,QAAQ,UAAU,QAAQ,OAAO,GAAG,OAAO,WAAW,OAAO,KAAK,QAAQ,WAAW,CAAC,GAC3F,iBACH,IACE;AAAA,IACH,cACC,oBAAC,UAAO,QAAQ,UAAU,QAAQ,SAAS,GAAG,OAAO,iBAAiB,OAAO,GAAG,GAC7E,uBACH,IACE;AAAA,IACH,mBAAmB,UAAU,iBAAiB,OAAO,GAAG,CAAC;AAAA,KAC5D;AAEJ;AAGA,SAAS,WAAW,SAAiH;AACnI,QAAM,CAAC,SAAS,UAAU,IAAU,eAAS,KAAK;AAClD,QAAM,CAAC,MAAM,OAAO,IAAU,eAAS,KAAK;AAC5C,QAAM,QAAc,aAA6C,IAAI;AACrE,EAAM,gBAAU,MAAM,MAAM;AAC1B,QAAI,MAAM,QAAS,cAAa,MAAM,OAAO;AAAA,EAC/C,GAAG,CAAC,CAAC;AACL,QAAM,QAAQ,MAAY;AACxB,eAAW,IAAI;AACf,UAAM,UAAU,WAAW,MAAM,UAAU,GAAG,cAAc;AAAA,EAC9D;AACA,QAAM,cAAoB,kBAAY,MAAM,QAAQ,IAAI,GAAG,CAAC,CAAC;AAC7D,SAAO,EAAE,MAAM,CAAC,SAAS,MAAM,OAAO,YAAY;AACpD;AAEO,IAAM,QAAc,iBAA6B,CAAC,YAAY,QAAQ;AAC3E,QAAM;AAAA,IACJ;AAAA,IAAS;AAAA,IAAO;AAAA,IAAM;AAAA,IAAO;AAAA,IAAM;AAAA,IAAU;AAAA,IAAS;AAAA,IAAO;AAAA,IAAa;AAAA,IAAU;AAAA;AAAA;AAAA,IAGpF,MAAM;AAAA,IAAO,UAAU;AAAA,IACvB,eAAe;AAAA,IAAY,aAAa;AAAA,IAAW;AAAA,IAAU;AAAA,IAAY;AAAA,IAAO,GAAG;AAAA,EACrF,IAAI,kBAAkB,UAAU;AAChC,QAAM,QAAQ,WAAW;AACzB,QAAM,SAAS,cAAc,QAAQ,OAAO;AAC5C,QAAM,OAAO,mBAAmB,MAAM;AACtC,QAAM,OAAO,UAAU,OAAO,EAAE,SAAS,OAAO,MAAM,MAAM,CAAC;AAC7D,QAAM,SAAS,UAAU,OAAO;AAChC,QAAM,UAAU,WAAW,OAAO;AAClC,QAAM,eAAe,oBAAoB,YAAY,OAAO;AAE5D,MAAI,QAAQ,KAAM,QAAO;AACzB,SACE,oBAAC,YAAS,MAAM,QAAQ,MAAM,aAAa,QAAQ,aACjD;AAAA,IAAC,SAAS;AAAA,IAAT;AAAA,MACC;AAAA,MACA,MAAM,aAAa;AAAA,MACnB,aAAW,aAAa,WAAW;AAAA,MAClC,GAAG,QAAQ,EAAE,eAAe,WAAW,CAAC;AAAA,MACzC,UAAU;AAAA,MACV,QAAQ;AAAA,MACR,OAAO,CAAC,KAAK,MAAM,QAAQ,KAAK;AAAA,MAC/B,GAAG;AAAA,MAEH;AAAA,gBAAQ,oBAAC,SAAM,OAAO,KAAK,QAAQ,MAAM,QAAQ,KAAK,KAAK,cAAwB,QAAQ,UAAU,QAAQ,OAAO,GAAG,IAAK;AAAA,QAC5H,WAAW,oBAAC,YAAS,SAAkB,MAAY,OAAO,KAAK,WAAW,SAAkB,QAAQ,UAAU,QAAQ,MAAM,GAAG,IAAK;AAAA,QACrI,oBAAC,gBAAa,OAAc,aAA0B,KAAK,KAAK,KAAK,QAClE,UACH;AAAA,QACC,WACC,oBAAC,QAAK,OAAO,gBAAgB,KAAK,GAChC,8BAAC,eAAY,OAAO,YAAY,KAAK,KAAK,KAAK,SAAS,QAAQ,OAAO,QAAQ,UAAU,QAAQ,OAAO,GAAG,GAC7G,IACE;AAAA;AAAA;AAAA,EACN,GACF;AAEJ,CAAC;AAED,MAAM,cAAc;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../src/components/data-display/Alert/Alert.native.tsx","../../../src/components/data-display/Alert/Alert.helpers.ts","../../../src/components/data-display/Alert/Alert.metrics.ts","../../../src/components/data-display/Alert/Alert.look.native.ts"],"sourcesContent":["import * as React from 'react';\nimport {\n Animated,\n Easing,\n type LayoutChangeEvent,\n Platform,\n Pressable,\n type Role,\n StyleSheet,\n Text as RNText,\n View,\n type ViewStyle,\n} from 'react-native';\n\nimport { resolveAlertProps, resolveAnnouncement, testIdFor, VARIANT_ICON } from './Alert.helpers';\nimport {\n actionSlotStyle,\n alertLook,\n closeButtonStyle,\n descriptionStyle,\n iconSlotStyle,\n messageSlotStyle,\n messageTextStyle,\n titleStyle,\n} from './Alert.look.native';\nimport { CLOSE_BUTTON, CLOSE_DELAY_MS, COLLAPSE_MS, FADE_IN, ICON_SLOT, ICON_SPIN, PULSE } from './Alert.metrics';\nimport type { AlertProps, AlertVariant } from './Alert.types.native';\nimport { Icon } from '../../../icons/Icon.native';\nimport { webAria } from '../../../platform/aria';\nimport { renderTextChildren } from '../../../platform/text-children';\nimport { resolveTestId, withoutTestIdProps } from '../../../platform/test-id';\nimport { useUiTheme } from '../../../provider/use-ui-theme.native';\n\ntype AnimatedStyle = Animated.WithAnimatedValue<ViewStyle>;\nconst nativeDriver = Platform.OS !== 'web';\n\n/** A 0→1 progress that starts on mount when `animate` is set, else sits at 1. */\nfunction useProgress(animate: boolean, duration: number): Animated.Value {\n const progress = React.useRef(new Animated.Value(animate ? 0 : 1)).current;\n React.useEffect(() => {\n if (!animate) return undefined;\n const timing = Animated.timing(progress, { toValue: 1, duration, easing: Easing.out(Easing.ease), useNativeDriver: nativeDriver });\n timing.start();\n return () => timing.stop();\n }, [animate, duration, progress]);\n return progress;\n}\n\n/** The web's `fadeInScale` keyframes: in from 0 opacity, 0.95 scale and 10px above, over 300ms. */\nfunction useFadeIn(animate: boolean): AnimatedStyle | undefined {\n const progress = useProgress(animate, FADE_IN.ms);\n if (!animate) return undefined;\n return {\n opacity: progress,\n transform: [\n { scale: progress.interpolate({ inputRange: [0, 1], outputRange: [FADE_IN.scale, 1] }) },\n { translateY: progress.interpolate({ inputRange: [0, 1], outputRange: [-FADE_IN.lift, 0] }) },\n ],\n };\n}\n\n/** The web's `iconRotate` keyframes: one full turn, 0.8 → 1.1 → 1, over 600ms. */\nfunction useIconSpin(animate: boolean): AnimatedStyle | undefined {\n const progress = useProgress(animate, ICON_SPIN.ms);\n if (!animate) return undefined;\n return {\n transform: [\n { rotate: progress.interpolate({ inputRange: [0, 1], outputRange: ['0deg', '360deg'] }) },\n { scale: progress.interpolate({ inputRange: [0, 0.5, 1], outputRange: [ICON_SPIN.from, ICON_SPIN.mid, 1] }) },\n ],\n };\n}\n\n/** The web's `::after` pulse: a wash of the hue over the card, fading out every two seconds, behind the words. */\nfunction Pulse({ color, radius, testID }: { color: string; radius: number; testID: string }): React.JSX.Element {\n const progress = React.useRef(new Animated.Value(0)).current;\n React.useEffect(() => {\n const loop = Animated.loop(\n Animated.timing(progress, { toValue: 1, duration: PULSE.ms, easing: Easing.linear, useNativeDriver: nativeDriver }),\n );\n loop.start();\n return () => loop.stop();\n }, [progress]);\n return (\n <Animated.View\n testID={testID}\n aria-hidden\n style={[\n StyleSheet.absoluteFill,\n {\n pointerEvents: 'none',\n borderRadius: radius,\n backgroundColor: color,\n opacity: progress.interpolate({ inputRange: [0, 0.7, 1], outputRange: [PULSE.alpha, 0, 0] }),\n },\n ]}\n />\n );\n}\n\n/**\n * MUI's `Collapse`: open, it is a plain wrapper with its overflow visible (so\n * a glow can escape); closing, it clips and shrinks over 300ms, then says so.\n */\nfunction Collapse({ open, onCollapsed, children }: { open: boolean; onCollapsed: () => void; children: React.ReactNode }): React.JSX.Element {\n const [height, setHeight] = React.useState<number | null>(null);\n const progress = React.useRef(new Animated.Value(1)).current;\n React.useEffect(() => {\n if (open) return undefined;\n const timing = Animated.timing(progress, { toValue: 0, duration: COLLAPSE_MS, easing: Easing.inOut(Easing.ease), useNativeDriver: false });\n timing.start(({ finished }) => {\n if (finished) onCollapsed();\n });\n return () => timing.stop();\n }, [open, onCollapsed, progress]);\n const onLayout = (event: LayoutChangeEvent): void => {\n if (open) setHeight(event.nativeEvent.layout.height);\n };\n const shrink: AnimatedStyle = height == null ? {} : { maxHeight: progress.interpolate({ inputRange: [0, 1], outputRange: [0, height] }) };\n return (\n <Animated.View style={[{ overflow: open ? 'visible' : 'hidden', opacity: progress }, shrink]}>\n <View onLayout={onLayout}>{children}</View>\n </Animated.View>\n );\n}\n\ninterface IconSlotProps {\n variant: AlertVariant;\n icon: React.ReactNode;\n color: string;\n animate: boolean;\n testID: string;\n}\n\n/** The icon slot; `glass` and `gradient` have no glyph of their own, so theirs is empty unless an `icon` is given — as on the web. */\nfunction IconSlot({ variant, icon, color, animate, testID }: IconSlotProps): React.JSX.Element {\n const theme = useUiTheme();\n const spin = useIconSpin(animate);\n const glyph = VARIANT_ICON[variant];\n return (\n <Animated.View testID={testID} style={[iconSlotStyle(theme), spin]}>\n {icon || (glyph ? <Icon name={glyph} size={ICON_SLOT.size} color={color} /> : null)}\n </Animated.View>\n );\n}\n\nfunction CloseButton({ label, ink, onPress, testID }: { label: string | undefined; ink: string; onPress: () => void; testID: string }): React.JSX.Element {\n const theme = useUiTheme();\n return (\n <Pressable role=\"button\" aria-label={label} testID={testID} onPress={onPress} style={({ pressed }) => closeButtonStyle(theme, pressed)}>\n <Icon name=\"Close\" size={CLOSE_BUTTON.iconSize} color={ink} />\n </Pressable>\n );\n}\n\ninterface ContentProps {\n title?: string;\n description?: string;\n children?: React.ReactNode;\n ink: string;\n testId: string;\n}\n\nfunction AlertContent({ title, description, children, ink, testId }: ContentProps): React.JSX.Element {\n const theme = useUiTheme();\n return (\n <View style={messageSlotStyle(theme)}>\n {title ? (\n <RNText testID={testIdFor(testId, 'title')} style={titleStyle(theme, ink, Boolean(description))}>\n {title}\n </RNText>\n ) : null}\n {description ? (\n <RNText testID={testIdFor(testId, 'message')} style={descriptionStyle(theme, ink)}>\n {description}\n </RNText>\n ) : null}\n {renderTextChildren(children, messageTextStyle(theme, ink))}\n </View>\n );\n}\n\n/** The dismiss sequence the web runs: mark closing, fire `onClose` 200ms in, stay until the collapse has run. */\nfunction useDismiss(onClose: (() => void) | undefined): { open: boolean; gone: boolean; close: () => void; onCollapsed: () => void } {\n const [closing, setClosing] = React.useState(false);\n const [gone, setGone] = React.useState(false);\n const timer = React.useRef<ReturnType<typeof setTimeout> | null>(null);\n React.useEffect(() => () => {\n if (timer.current) clearTimeout(timer.current);\n }, []);\n const close = (): void => {\n setClosing(true);\n timer.current = setTimeout(() => onClose?.(), CLOSE_DELAY_MS);\n };\n const onCollapsed = React.useCallback(() => setGone(true), []);\n return { open: !closing, gone, close, onCollapsed };\n}\n\nexport const Alert = React.forwardRef<View, AlertProps>((alertProps, ref) => {\n const {\n variant, color, glow, pulse, icon, showIcon, onClose, title, description, children, animate,\n // `role`, `announce` and `aria-live` all leave here and are resolved\n // TOGETHER below, off `alertProps` — see `resolveAnnouncement`.\n role: _role, announce: _announce,\n 'aria-atomic': ariaAtomic, 'aria-live': _ariaLive, closable, closeLabel, style, ...others\n } = resolveAlertProps(alertProps);\n const theme = useUiTheme();\n const testId = resolveTestId(others, 'alert') as string;\n const rest = withoutTestIdProps(others);\n const look = alertLook(theme, { variant, color, glow, pulse });\n const fadeIn = useFadeIn(animate);\n const dismiss = useDismiss(onClose);\n const announcement = resolveAnnouncement(alertProps, variant);\n\n if (dismiss.gone) return null;\n return (\n <Collapse open={dismiss.open} onCollapsed={dismiss.onCollapsed}>\n <Animated.View\n ref={ref}\n role={announcement.role as Role}\n aria-live={announcement['aria-live']}\n {...webAria({ 'aria-atomic': ariaAtomic })}\n tabIndex={0}\n testID={testId}\n style={[look.root, fadeIn, style]}\n {...rest}\n >\n {pulse ? <Pulse color={look.palette.main} radius={look.root.borderRadius as number} testID={testIdFor(testId, 'pulse')} /> : null}\n {showIcon ? <IconSlot variant={variant} icon={icon} color={look.iconColor} animate={animate} testID={testIdFor(testId, 'icon')} /> : null}\n <AlertContent title={title} description={description} ink={look.ink} testId={testId}>\n {children}\n </AlertContent>\n {closable ? (\n <View style={actionSlotStyle(theme)}>\n <CloseButton label={closeLabel} ink={look.ink} onPress={dismiss.close} testID={testIdFor(testId, 'close')} />\n </View>\n ) : null}\n </Animated.View>\n </Collapse>\n );\n});\n\nAlert.displayName = 'Alert';\n","import type { AlertBaseFields, AlertVariant } from './Alert.base';\nimport type { IconName } from '../../../icons/Icon.types';\n\ntype AlertDefaultedKeys = 'variant' | 'glow' | 'pulse' | 'showIcon' | 'animate' | 'role' | 'aria-atomic';\n\nexport const ALERT_DEFAULTS: Required<Pick<AlertBaseFields, AlertDefaultedKeys>> & { closable: false } = {\n variant: 'info',\n glow: false,\n pulse: false,\n showIcon: true,\n closable: false,\n animate: true,\n role: 'alert',\n 'aria-atomic': 'true',\n};\n\n/**\n * Generic over the renderer's own props: the web and the native `Alert` pass\n * different extras through, and both come back out untouched.\n */\nexport type ResolvedAlertProps<P extends AlertBaseFields> = P &\n Required<Pick<AlertBaseFields, AlertDefaultedKeys>>;\n\n// Strips explicitly-undefined props before the merge so `prop={undefined}` still\n// falls back to the default, the way a destructuring default would.\nconst definedProps = <P extends AlertBaseFields>(props: P): Partial<P> =>\n Object.fromEntries(\n Object.entries(props).filter(([, value]) => value !== undefined),\n ) as Partial<P>;\n\n// Through `unknown`: `closable: false` in the defaults belongs to the dismiss\n// union rather than to `AlertBaseFields`, so TypeScript cannot see the merge as\n// comparable to `P` although every field of `P` survives it untouched.\nexport const resolveAlertProps = <P extends AlertBaseFields>(props: P): ResolvedAlertProps<P> =>\n ({ ...ALERT_DEFAULTS, ...definedProps(props) }) as unknown as ResolvedAlertProps<P>;\n\n/** `danger` announces itself; everything else waits its turn. */\nexport const defaultAriaLive = (variant: AlertVariant): 'polite' | 'assertive' =>\n variant === 'danger' ? 'assertive' : 'polite';\n\n/**\n * The ARIA role each `announce` level is spelled with.\n *\n * Both roles carry an IMPLICIT live setting, and that implicit one is what\n * assistive tech acts on — `alert` is assertive, `status` is polite. Pairing\n * them here is what stops `role` and `aria-live` from contradicting each\n * other, which they do by default: every alert is `role=\"alert\"` regardless of\n * variant, so an `info` alert asks to be polite in one attribute and to\n * interrupt in the other.\n */\nexport const ANNOUNCE_ROLE: Record<NonNullable<AlertBaseFields['announce']>, string> = {\n assertive: 'alert',\n polite: 'status',\n};\n\n/**\n * The two attributes that decide whether an alert interrupts, resolved TOGETHER.\n *\n * Both renderers therefore let `role` and `announce` leave their destructure\n * unused (`_role`, `_announce`) and call this instead — the first because the\n * defaults have already answered it, the second because it must never reach\n * the DOM.\n *\n * Reads the caller's own props rather than the defaulted ones, because the\n * whole question is which of them the caller actually spelled:\n * {@link ALERT_DEFAULTS} supplies `role: 'alert'` for everything, so after the\n * merge there is no longer any difference between an alert that asked to\n * interrupt and one that never mentioned it.\n *\n * Precedence, most specific first — an explicit `role` or `aria-live` beats\n * `announce`, so a call site that already spells either by hand is untouched:\n *\n * 1. `role` / `aria-live` as given;\n * 2. {@link AlertBaseFields.announce}, which supplies both;\n * 3. today's behaviour — `ALERT_DEFAULTS.role` and {@link defaultAriaLive}.\n *\n * With none of the three named, the result is byte-for-byte what it was before\n * `announce` existed.\n */\nexport const resolveAnnouncement = (\n props: Pick<AlertBaseFields, 'announce' | 'role' | 'aria-live'>,\n variant: AlertVariant,\n): { role: string; 'aria-live': 'polite' | 'assertive' | 'off' } => {\n const announce = props.announce;\n return {\n role: props.role ?? (announce === undefined ? ALERT_DEFAULTS.role : ANNOUNCE_ROLE[announce]),\n 'aria-live': props['aria-live'] ?? announce ?? defaultAriaLive(variant),\n };\n};\n\nexport const testIdFor = (base: string | undefined, suffix: string): string =>\n base ? `${base}-${suffix}` : `alert-${suffix}`;\n\n/**\n * The glyph each semantic variant carries, by the shared icon set's name.\n * `glass` and `gradient` carry none of their own: the web renders an empty\n * icon slot for them unless the caller passes an `icon`, and so does native.\n */\nexport const VARIANT_ICON: Partial<Record<AlertVariant, IconName>> = {\n info: 'Info',\n success: 'CheckCircle',\n warning: 'Warning',\n danger: 'Error',\n};\n","import type { AlertVariant } from './Alert.base';\nimport { alpha, darken, lighten } from '../../../tokens/color';\nimport { NEUTRAL_RAMP } from '../../../tokens/ink.core';\nimport { contrastText, type UiGreyStep, type UiTheme } from '../../../tokens/theme';\n\n/**\n * THE NUMBERS BOTH `Alert` RENDERERS DRAW WITH.\n *\n * `Alert.styles.tsx` / `Alert.tsx` (MUI) and `Alert.native.tsx` (React\n * Native) read this one table. Spacing is in SPACING UNITS where the web\n * writes `theme.spacing(n)`; durations are ms (the web turns them into `s`\n * through {@link seconds} so its emitted CSS is byte-for-byte what it was);\n * everything else is px, a ratio or an alpha. The hover, active and focus\n * numbers are here too although only the DOM can honour them — a number the\n * web draws with belongs in the table whether or not native can reach it.\n */\n\n/** The root: 12px corners, 14px 16px of padding, one 300ms curve for everything. */\nexport const ALERT_RADIUS_UNITS = 1.5;\nexport const ALERT_PADDING_UNITS = { vertical: 1.75, horizontal: 2 } as const;\nexport const ALERT_TRANSITION_MS = 300;\nexport const ALERT_EASING = 'cubic-bezier(0.4, 0, 0.2, 1)';\n\n/** Mount: the web's `fadeInScale` keyframes and the icon's `iconRotate`. */\nexport const FADE_IN = { ms: 300, scale: 0.95, lift: 10 } as const;\nexport const ICON_SPIN = { ms: 600, from: 0.8, mid: 1.1 } as const;\n/** Dismiss: MUI `Collapse` runs 300ms; `onClose` fires 200ms in. */\nexport const COLLAPSE_MS = 300;\nexport const CLOSE_DELAY_MS = 200;\n\n/** The message column: 8px between title, description and children; 0.95rem body on 1.5. */\nexport const MESSAGE_GAP_UNITS = 1;\nexport const MESSAGE_FONT_SIZE = 15.2;\nexport const MESSAGE_LINE_HEIGHT = 1.5;\n/** A control inside the message gets an edge: 4px above, a hairline at 0.45 of the hue. */\nexport const MESSAGE_BUTTON = { marginTopUnits: 0.5, borderAlpha: 0.45 } as const;\n\n/** The title: 1.05rem at 600; MUI's `AlertTitle` lifts it 2px; 4px below it when a description follows. */\nexport const TITLE = { fontSize: 16.8, fontWeight: 600, marginTop: -2, marginBottomUnits: 0.5 } as const;\n/** The description: 0.925rem, slightly faded. */\nexport const DESCRIPTION = { fontSize: 14.8, opacity: 0.9 } as const;\n\n/** The icon on the title's line (`iconPlacement: 'title'`): 10px from the title, centred on its first line (1.5). */\nexport const TITLE_ICON = { gapUnits: 1.25, lineHeight: 1.5 } as const;\n/** The icon slot: MUI's 22px glyph at 0.9, 14px from the words, 2px down (MUI's 7px stays below). */\nexport const ICON_SLOT = { size: 22, opacity: 0.9, marginRightUnits: 1.75, paddingTopUnits: 0.25, paddingBottom: 7 } as const;\n/** The action slot: MUI's `4px 0 0 16px` with the 16px ours, pushed right, 8px into the padding. */\nexport const ACTION_SLOT = { paddingLeftUnits: 2, paddingTop: 4, marginRight: -8 } as const;\n/** The close button: MUI's small `IconButton` (5px padding, 18px glyph) at 0.7. */\nexport const CLOSE_BUTTON = { padding: 5, iconSize: 18, opacity: 0.7, washAlpha: 0.1 } as const;\n\n/**\n * A semantic Alert's surface and ink: an OPAQUE tint of the hue with a dark\n * ink of the same hue — MUI's own `standard` recipe, at its ratios. See\n * `semanticSurface` in `Alert.styles.tsx` for why not `alpha(main, 0.1)`.\n */\nexport const SEMANTIC_SURFACE = { tint: { light: 0.9, dark: 0.8 }, ink: 0.6, borderAlpha: 0.35 } as const;\n/** `glass`: 85% paper under a 20px blur, a 0.4 divider hairline. */\nexport const GLASS = { backgroundAlpha: 0.85, borderAlpha: 0.4, blur: 20, saturatePercent: 180 } as const;\n/**\n * `gradient`: light→dark at 0.9 along 135°, a 0.2 white shimmer sweeping 1000px every 3s.\n *\n * It carries no hover of its own, and that is load-bearing rather than an\n * omission. `alertVariantStyles` is spread AFTER the root's `'&:hover'` in the\n * same object literal, so a second `'&:hover'` key does not merge with it — it\n * REPLACES it. While this variant had one, `gradient` was the only alert that\n * brightened on hover while every other variant darkened, and the only one to\n * lose the shimmer reveal the root's hover performs.\n */\nexport const GRADIENT = {\n angleDeg: 135,\n stopAlpha: 0.9,\n shimmerAlpha: 0.2,\n shimmerMs: 3000,\n shimmerTravel: 1000,\n} as const;\n\n/** Emphasis: the glow's shadow and brightness, the pulse's wash. */\nexport const GLOW = { blur: 20, spread: 5, alpha: 0.3, brightness: 1.05 } as const;\nexport const PULSE = { alpha: 0.2, ms: 2000, spread: 10 } as const;\n\n/**\n * Pointer states — DOM only, kept so the web derives them.\n *\n * HOVER and ACTIVE carry NO geometry, and that is the point rather than an\n * omission. They used to lift the card 3px, scale it 1.01, grow a 20px shadow\n * and spin the icon 10deg at 1.15 — four things moving at once on a surface\n * that is not a control, which made a page of alerts twitch under the pointer.\n *\n * Both are a TINT now: a flat inset layer over the surface. Two mechanisms\n * came before it and each failed on a case the next had to fix. Dropping the\n * element's `opacity` composites toward the PAGE, so it inverted the hover on\n * a light tint (L* 95.0 idle, 89.1 hovered, 91.1 pressed) and vanished on a\n * dark one. A `filter: brightness()` fixed the direction but is MULTIPLICATIVE,\n * so it moved a near-black `glass` by four counts (ΔE76 1.71, under the JND)\n * and Banner's 10%-alpha wash by ΔE76 0.44. A layer is additive: it reads the\n * same on an opaque tint, a translucent wash and a gradient, and because it\n * paints above the background and below the content the ink keeps its own\n * contrast.\n */\nexport const HOVER = { tintAlpha: 0.06 } as const;\n\n/**\n * The press: a 20% tint LAYER, eased back fast.\n *\n * The layer is the point. The first attempt dropped the whole element's\n * opacity, which composites toward the PAGE and so behaves differently on\n * every surface it is asked about. Measured: over a light page it made a light\n * tint LIGHTER (L* 95.0 idle, 89.1 hovered, 91.1 pressed), so pushing the\n * surface looked like the pointer leaving; over a dark page it landed back on\n * the idle surface (ΔE76 0.82 on `glass`); on `gradient` it washed white body\n * copy to 2.31:1, under AA; and it diluted the ink during a text-selection\n * drag. A `brightness()` step instead of it fixed the direction but not the\n * reach — a multiplier does nothing to a near-black `glass` in dark mode\n * (ΔE76 1.71) and nothing to Banner's 10%-alpha wash (ΔE76 0.44), because it\n * scales only what the element already paints.\n *\n * An inset shadow at 100vmax is a flat tint over the whole surface: ADDITIVE,\n * so it reads the same on an opaque tint, a translucent wash and a gradient;\n * painted above the background and below the content, so the ink keeps its\n * own contrast; and animatable, which `background-image` is not.\n *\n * `ms` is 250 and not the 1000 first asked for, and the reason is that ONE\n * property carries both states. CSS runs a transition from the DESTINATION\n * state's declaration, and entering hover and releasing a press share that\n * destination — so they cannot have different durations without a second\n * animatable property, and both free pseudo-elements are already spent on the\n * `gradient` shimmer and the `pulse` wash. At 1000ms the hover inherited the\n * second: crossing an alert in 300ms peaked at a ≈ 0.024, under the JND, and\n * for ~360ms the alert you had just LEFT was darker than the one under the\n * pointer. A fast press-return is the smaller loss, and it is the call the\n * product owner made when shown both.\n */\nexport const ACTIVE = { tintAlpha: 0.2, ms: 250 } as const;\n\nexport const FOCUS = { ringWidth: 2, ringAlpha: 1, offset: 2 } as const;\n\n/** `neutral` has no palette slot; the web has always drawn it from three greys. */\nexport const NEUTRAL_GREY: Record<'main' | 'light' | 'dark', UiGreyStep> = { main: 500, light: 300, dark: 700 };\n\n/** A duration as the CSS the web has always emitted: `2000` → `2s`, `300` → `0.3s`. */\nexport const seconds = (ms: number): string => `${ms / 1000}s`;\n\n/** The palette shape the web's `getColorFromTheme` returns — a main plus optional shades. */\nexport interface AlertPalette {\n main: string;\n light?: string;\n dark?: string;\n}\n\n/**\n * The renderer-free twin of the web's `getColorFromTheme`: a variant or\n * colour name to its palette, `neutral` from the greys, anything unknown\n * (`glass`, `gradient`) to `info`.\n */\nexport function alertPalette(theme: UiTheme, key: string | undefined): AlertPalette {\n switch (key) {\n case 'info':\n case 'success':\n case 'warning':\n case 'danger':\n case 'primary':\n case 'secondary':\n return theme.palette[key];\n case 'neutral':\n return {\n main: NEUTRAL_RAMP[NEUTRAL_GREY.main],\n light: NEUTRAL_RAMP[NEUTRAL_GREY.light],\n dark: NEUTRAL_RAMP[NEUTRAL_GREY.dark],\n };\n default:\n return theme.palette.info;\n }\n}\n\n/** What a variant paints: its fill, its ink, its hairline if any, and the colour of its glyph. */\nexport interface AlertSurface {\n backgroundColor: string;\n color: string;\n borderColor?: string;\n iconColor: string;\n}\n\nexport const SEMANTIC_VARIANTS: ReadonlySet<AlertVariant> = new Set(['info', 'success', 'warning', 'danger']);\n\n/** The opaque tint and same-hue ink, inverted for dark mode; the hairline keeps its alpha. */\nexport function semanticSurface(theme: UiTheme, palette: AlertPalette): AlertSurface {\n const dark = theme.mode === 'dark';\n return {\n backgroundColor: dark\n ? darken(palette.main, SEMANTIC_SURFACE.tint.dark)\n : lighten(palette.main, SEMANTIC_SURFACE.tint.light),\n color: dark ? lighten(palette.main, SEMANTIC_SURFACE.ink) : darken(palette.main, SEMANTIC_SURFACE.ink),\n borderColor: alpha(palette.main, SEMANTIC_SURFACE.borderAlpha),\n iconColor: palette.main,\n };\n}\n\nexport function glassSurface(theme: UiTheme): AlertSurface {\n return {\n backgroundColor: alpha(theme.palette.background.paper, GLASS.backgroundAlpha),\n color: theme.palette.text.primary,\n borderColor: alpha(theme.palette.divider, GLASS.borderAlpha),\n iconColor: theme.palette.primary.main,\n };\n}\n\n/** The gradient's two stops; a renderer with no gradient fill paints `from`. */\nexport function gradientStops(palette: AlertPalette): { from: string; to: string } {\n return {\n from: alpha(palette.light || palette.main, GRADIENT.stopAlpha),\n to: alpha(palette.dark || palette.main, GRADIENT.stopAlpha),\n };\n}\n\nexport function gradientSurface(palette: AlertPalette): AlertSurface {\n const ink = contrastText(palette.main);\n return { backgroundColor: gradientStops(palette).from, color: ink, iconColor: ink };\n}\n\n/** The surface for a variant, `glass` and `gradient` included. */\nexport function alertSurface(theme: UiTheme, variant: AlertVariant, palette: AlertPalette): AlertSurface {\n if (variant === 'glass') return glassSurface(theme);\n if (variant === 'gradient') return gradientSurface(palette);\n return semanticSurface(theme, palette);\n}\n","import type { TextStyle, ViewStyle } from 'react-native';\n\nimport type { AlertVariant } from './Alert.base';\nimport {\n ACTION_SLOT,\n ALERT_PADDING_UNITS,\n ALERT_RADIUS_UNITS,\n type AlertPalette,\n alertPalette,\n alertSurface,\n CLOSE_BUTTON,\n DESCRIPTION,\n GLOW,\n ICON_SLOT,\n MESSAGE_FONT_SIZE,\n MESSAGE_GAP_UNITS,\n MESSAGE_LINE_HEIGHT,\n TITLE,\n} from './Alert.metrics';\nimport { alpha } from '../../../tokens/color';\nimport { muiTypeStyle } from '../../../tokens/mui-type';\nimport type { UiTheme } from '../../../tokens/theme';\nimport type { ColorValue } from '../../../tokens/vocabulary';\n\n/**\n * THE PAINT, KEPT APART FROM THE STRUCTURE.\n *\n * `Alert.native.tsx` reads as what renders where; this file reads as\n * arithmetic — the same palette slots, alphas and px the web's\n * `Alert.styles.tsx` derives from `Alert.metrics.ts`.\n */\n\nexport interface AlertLookArgs {\n variant: AlertVariant;\n color: ColorValue | undefined;\n glow: boolean;\n pulse: boolean;\n}\n\nexport interface AlertLook {\n palette: AlertPalette;\n /** What the words are set in. */\n ink: string;\n iconColor: string;\n root: ViewStyle;\n}\n\n/**\n * The root's paint. The web keeps `overflow: hidden` (its pulse wash is\n * clipped to the card, as it is here); only the glow opens it, because a\n * view's own shadow is clipped by its own overflow on a device.\n */\nexport function alertLook(theme: UiTheme, a: AlertLookArgs): AlertLook {\n const palette = alertPalette(theme, a.color ?? a.variant);\n const surface = alertSurface(theme, a.variant, palette);\n const root: ViewStyle = {\n flexDirection: 'row',\n paddingVertical: theme.spacing(ALERT_PADDING_UNITS.vertical),\n paddingHorizontal: theme.spacing(ALERT_PADDING_UNITS.horizontal),\n borderRadius: theme.spacing(ALERT_RADIUS_UNITS),\n overflow: a.glow ? 'visible' : 'hidden',\n backgroundColor: surface.backgroundColor,\n ...(surface.borderColor ? { borderWidth: 1, borderColor: surface.borderColor } : {}),\n ...(a.glow\n ? {\n boxShadow: `0 0 ${GLOW.blur}px ${GLOW.spread}px ${alpha(palette.main, GLOW.alpha)}`,\n filter: `brightness(${GLOW.brightness})`,\n }\n : {}),\n };\n return { palette, ink: surface.color, iconColor: surface.iconColor, root };\n}\n\n/** The message column: 8px between its lines, allowed to shrink so long text wraps beside the icon. */\nexport const messageSlotStyle = (theme: UiTheme): ViewStyle => ({\n flexDirection: 'column',\n gap: theme.spacing(MESSAGE_GAP_UNITS),\n flexShrink: 1,\n minWidth: 0,\n});\n\n/** A string child: MUI's `body2` letter-spacing at 0.95rem on the message's 1.5. */\nexport const messageTextStyle = (theme: UiTheme, ink: string): TextStyle => ({\n ...muiTypeStyle(theme, 'body2', MESSAGE_FONT_SIZE),\n lineHeight: MESSAGE_FONT_SIZE * MESSAGE_LINE_HEIGHT,\n color: ink,\n});\n\n/** MUI's `AlertTitle` (a `body1` Typography) at 1.05rem and 600, lifted 2px, 4px above a description. */\nexport const titleStyle = (theme: UiTheme, ink: string, hasDescription: boolean): TextStyle => ({\n ...muiTypeStyle(theme, 'body1', TITLE.fontSize),\n fontWeight: `${TITLE.fontWeight}`,\n color: ink,\n marginTop: TITLE.marginTop,\n marginBottom: hasDescription ? theme.spacing(TITLE.marginBottomUnits) : 0,\n});\n\n/** The description: 0.925rem on the message's 1.5, faded to 0.9. */\nexport const descriptionStyle = (theme: UiTheme, ink: string): TextStyle => ({\n ...muiTypeStyle(theme, 'body2', DESCRIPTION.fontSize),\n lineHeight: DESCRIPTION.fontSize * MESSAGE_LINE_HEIGHT,\n color: ink,\n opacity: DESCRIPTION.opacity,\n});\n\n/** MUI's `.MuiAlert-icon` with the web's overrides: first-line aligned, 14px from the words, 2px down. */\nexport const iconSlotStyle = (theme: UiTheme): ViewStyle => ({\n alignSelf: 'flex-start',\n alignItems: 'center',\n marginRight: theme.spacing(ICON_SLOT.marginRightUnits),\n paddingTop: theme.spacing(ICON_SLOT.paddingTopUnits),\n paddingBottom: ICON_SLOT.paddingBottom,\n opacity: ICON_SLOT.opacity,\n});\n\n/** MUI's `.MuiAlert-action`: top-aligned, pushed to the right edge, 16px off the text. */\nexport const actionSlotStyle = (theme: UiTheme): ViewStyle => ({\n alignItems: 'flex-start',\n paddingTop: ACTION_SLOT.paddingTop,\n paddingLeft: theme.spacing(ACTION_SLOT.paddingLeftUnits),\n marginLeft: 'auto',\n marginRight: ACTION_SLOT.marginRight,\n});\n\n/** MUI's small `IconButton` at 0.7; pressed stands in for the web's hover (full opacity, a faint wash). */\nexport const closeButtonStyle = (theme: UiTheme, pressed: boolean): ViewStyle => ({\n padding: CLOSE_BUTTON.padding,\n borderRadius: theme.radius.full,\n opacity: pressed ? 1 : CLOSE_BUTTON.opacity,\n backgroundColor: pressed ? alpha(theme.palette.action.hover, CLOSE_BUTTON.washAlpha) : 'transparent',\n});\n"],"mappings":"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","names":[]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
EmptyState
|
|
3
|
-
} from "../chunks/chunk-
|
|
4
|
-
import "../chunks/chunk-
|
|
3
|
+
} from "../chunks/chunk-TZPNJ4AU.js";
|
|
4
|
+
import "../chunks/chunk-EZHCNYQO.js";
|
|
5
5
|
import "../chunks/chunk-3JBZE4I6.js";
|
|
6
6
|
import "../chunks/chunk-ZRQHLTYG.js";
|
|
7
7
|
import "../chunks/chunk-DN73KYIZ.js";
|
|
@@ -7,8 +7,8 @@ import {
|
|
|
7
7
|
} from "../chunks/chunk-MJVSQXOD.js";
|
|
8
8
|
import {
|
|
9
9
|
EmptyState
|
|
10
|
-
} from "../chunks/chunk-
|
|
11
|
-
import "../chunks/chunk-
|
|
10
|
+
} from "../chunks/chunk-TZPNJ4AU.js";
|
|
11
|
+
import "../chunks/chunk-EZHCNYQO.js";
|
|
12
12
|
import "../chunks/chunk-3JBZE4I6.js";
|
|
13
13
|
import "../chunks/chunk-ZRQHLTYG.js";
|
|
14
14
|
import {
|