@oxyhq/bloom 0.15.0 → 0.16.1
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/lib/commonjs/alert-dialog/AlertDialog.js +35 -27
- package/lib/commonjs/alert-dialog/AlertDialog.js.map +1 -1
- package/lib/commonjs/alert-dialog/index.js +1 -1
- package/lib/commonjs/alert-dialog/index.js.map +1 -1
- package/lib/commonjs/alert-dialog/index.web.js +1 -1
- package/lib/commonjs/alert-dialog/index.web.js.map +1 -1
- package/lib/commonjs/command/Command.js +27 -16
- package/lib/commonjs/command/Command.js.map +1 -1
- package/lib/commonjs/command/index.js +1 -1
- package/lib/commonjs/command/index.js.map +1 -1
- package/lib/commonjs/command/index.web.js +1 -1
- package/lib/commonjs/command/index.web.js.map +1 -1
- package/lib/commonjs/dialog/Dialog.js +39 -152
- package/lib/commonjs/dialog/Dialog.js.map +1 -1
- package/lib/commonjs/dialog/Dialog.web.js +61 -196
- package/lib/commonjs/dialog/Dialog.web.js.map +1 -1
- package/lib/commonjs/dialog/DialogBottomSheet.js +205 -0
- package/lib/commonjs/dialog/DialogBottomSheet.js.map +1 -0
- package/lib/commonjs/dialog/DialogContent.js +155 -0
- package/lib/commonjs/dialog/DialogContent.js.map +1 -0
- package/lib/commonjs/dialog/index.js +0 -13
- package/lib/commonjs/dialog/index.js.map +1 -1
- package/lib/commonjs/dialog/index.web.js +0 -19
- package/lib/commonjs/dialog/index.web.js.map +1 -1
- package/lib/commonjs/index.js +0 -29
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/index.web.js +6 -35
- package/lib/commonjs/index.web.js.map +1 -1
- package/lib/module/alert-dialog/AlertDialog.js +35 -27
- package/lib/module/alert-dialog/AlertDialog.js.map +1 -1
- package/lib/module/alert-dialog/index.js +2 -2
- package/lib/module/alert-dialog/index.js.map +1 -1
- package/lib/module/alert-dialog/index.web.js +2 -2
- package/lib/module/alert-dialog/index.web.js.map +1 -1
- package/lib/module/command/Command.js +27 -16
- package/lib/module/command/Command.js.map +1 -1
- package/lib/module/command/index.js +2 -2
- package/lib/module/command/index.js.map +1 -1
- package/lib/module/command/index.web.js +2 -2
- package/lib/module/command/index.web.js.map +1 -1
- package/lib/module/dialog/Dialog.js +42 -155
- package/lib/module/dialog/Dialog.js.map +1 -1
- package/lib/module/dialog/Dialog.web.js +63 -198
- package/lib/module/dialog/Dialog.web.js.map +1 -1
- package/lib/module/dialog/DialogBottomSheet.js +200 -0
- package/lib/module/dialog/DialogBottomSheet.js.map +1 -0
- package/lib/module/dialog/DialogContent.js +148 -0
- package/lib/module/dialog/DialogContent.js.map +1 -0
- package/lib/module/dialog/index.js +0 -1
- package/lib/module/dialog/index.js.map +1 -1
- package/lib/module/dialog/index.web.js +0 -1
- package/lib/module/dialog/index.web.js.map +1 -1
- package/lib/module/index.js +1 -3
- package/lib/module/index.js.map +1 -1
- package/lib/module/index.web.js +1 -3
- package/lib/module/index.web.js.map +1 -1
- package/lib/typescript/commonjs/alert-dialog/AlertDialog.d.ts +13 -12
- package/lib/typescript/commonjs/alert-dialog/AlertDialog.d.ts.map +1 -1
- package/lib/typescript/commonjs/alert-dialog/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/alert-dialog/index.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/command/Command.d.ts +8 -8
- package/lib/typescript/commonjs/command/Command.d.ts.map +1 -1
- package/lib/typescript/commonjs/command/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/command/index.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/dialog/Dialog.d.ts +2 -3
- package/lib/typescript/commonjs/dialog/Dialog.d.ts.map +1 -1
- package/lib/typescript/commonjs/dialog/Dialog.web.d.ts +11 -8
- package/lib/typescript/commonjs/dialog/Dialog.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/dialog/DialogBottomSheet.d.ts +29 -0
- package/lib/typescript/commonjs/dialog/DialogBottomSheet.d.ts.map +1 -0
- package/lib/typescript/commonjs/dialog/DialogContent.d.ts +32 -0
- package/lib/typescript/commonjs/dialog/DialogContent.d.ts.map +1 -0
- package/lib/typescript/commonjs/dialog/index.d.ts +0 -2
- package/lib/typescript/commonjs/dialog/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/dialog/index.web.d.ts +0 -2
- package/lib/typescript/commonjs/dialog/index.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/index.d.ts +2 -4
- package/lib/typescript/commonjs/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/index.web.d.ts +2 -4
- package/lib/typescript/commonjs/index.web.d.ts.map +1 -1
- package/lib/typescript/module/alert-dialog/AlertDialog.d.ts +13 -12
- package/lib/typescript/module/alert-dialog/AlertDialog.d.ts.map +1 -1
- package/lib/typescript/module/alert-dialog/index.d.ts.map +1 -1
- package/lib/typescript/module/alert-dialog/index.web.d.ts.map +1 -1
- package/lib/typescript/module/command/Command.d.ts +8 -8
- package/lib/typescript/module/command/Command.d.ts.map +1 -1
- package/lib/typescript/module/command/index.d.ts.map +1 -1
- package/lib/typescript/module/command/index.web.d.ts.map +1 -1
- package/lib/typescript/module/dialog/Dialog.d.ts +2 -3
- package/lib/typescript/module/dialog/Dialog.d.ts.map +1 -1
- package/lib/typescript/module/dialog/Dialog.web.d.ts +11 -8
- package/lib/typescript/module/dialog/Dialog.web.d.ts.map +1 -1
- package/lib/typescript/module/dialog/DialogBottomSheet.d.ts +29 -0
- package/lib/typescript/module/dialog/DialogBottomSheet.d.ts.map +1 -0
- package/lib/typescript/module/dialog/DialogContent.d.ts +32 -0
- package/lib/typescript/module/dialog/DialogContent.d.ts.map +1 -0
- package/lib/typescript/module/dialog/index.d.ts +0 -2
- package/lib/typescript/module/dialog/index.d.ts.map +1 -1
- package/lib/typescript/module/dialog/index.web.d.ts +0 -2
- package/lib/typescript/module/dialog/index.web.d.ts.map +1 -1
- package/lib/typescript/module/index.d.ts +2 -4
- package/lib/typescript/module/index.d.ts.map +1 -1
- package/lib/typescript/module/index.web.d.ts +2 -4
- package/lib/typescript/module/index.web.d.ts.map +1 -1
- package/package.json +1 -18
- package/src/__tests__/AlertDialog.test.tsx +122 -0
- package/src/__tests__/BottomSheetGesture.test.tsx +135 -0
- package/src/__tests__/Command.test.tsx +107 -0
- package/src/__tests__/DialogBottomSheet.test.tsx +130 -0
- package/src/alert-dialog/AlertDialog.tsx +46 -36
- package/src/alert-dialog/index.ts +2 -2
- package/src/alert-dialog/index.web.ts +2 -2
- package/src/command/Command.tsx +30 -19
- package/src/command/index.ts +2 -2
- package/src/command/index.web.ts +2 -2
- package/src/dialog/Dialog.tsx +35 -168
- package/src/dialog/Dialog.web.tsx +52 -209
- package/src/dialog/DialogBottomSheet.tsx +235 -0
- package/src/dialog/DialogContent.tsx +157 -0
- package/src/dialog/index.ts +0 -2
- package/src/dialog/index.web.ts +0 -6
- package/src/index.ts +0 -11
- package/src/index.web.ts +0 -11
- package/lib/commonjs/dialog/CenteredDialog.js +0 -252
- package/lib/commonjs/dialog/CenteredDialog.js.map +0 -1
- package/lib/commonjs/dialog/CenteredDialog.web.js +0 -330
- package/lib/commonjs/dialog/CenteredDialog.web.js.map +0 -1
- package/lib/commonjs/dialog/centered-dialog-tokens.js +0 -62
- package/lib/commonjs/dialog/centered-dialog-tokens.js.map +0 -1
- package/lib/commonjs/dialog/centered-dialog-types.js +0 -6
- package/lib/commonjs/dialog/centered-dialog-types.js.map +0 -1
- package/lib/commonjs/responsive-sheet/ResponsiveSheet.js +0 -97
- package/lib/commonjs/responsive-sheet/ResponsiveSheet.js.map +0 -1
- package/lib/commonjs/responsive-sheet/ResponsiveSheet.web.js +0 -84
- package/lib/commonjs/responsive-sheet/ResponsiveSheet.web.js.map +0 -1
- package/lib/commonjs/responsive-sheet/index.js +0 -19
- package/lib/commonjs/responsive-sheet/index.js.map +0 -1
- package/lib/commonjs/responsive-sheet/index.web.js +0 -19
- package/lib/commonjs/responsive-sheet/index.web.js.map +0 -1
- package/lib/commonjs/responsive-sheet/types.js +0 -6
- package/lib/commonjs/responsive-sheet/types.js.map +0 -1
- package/lib/module/dialog/CenteredDialog.js +0 -246
- package/lib/module/dialog/CenteredDialog.js.map +0 -1
- package/lib/module/dialog/CenteredDialog.web.js +0 -324
- package/lib/module/dialog/CenteredDialog.web.js.map +0 -1
- package/lib/module/dialog/centered-dialog-tokens.js +0 -58
- package/lib/module/dialog/centered-dialog-tokens.js.map +0 -1
- package/lib/module/dialog/centered-dialog-types.js +0 -4
- package/lib/module/dialog/centered-dialog-types.js.map +0 -1
- package/lib/module/responsive-sheet/ResponsiveSheet.js +0 -90
- package/lib/module/responsive-sheet/ResponsiveSheet.js.map +0 -1
- package/lib/module/responsive-sheet/ResponsiveSheet.web.js +0 -77
- package/lib/module/responsive-sheet/ResponsiveSheet.web.js.map +0 -1
- package/lib/module/responsive-sheet/index.js +0 -4
- package/lib/module/responsive-sheet/index.js.map +0 -1
- package/lib/module/responsive-sheet/index.web.js +0 -12
- package/lib/module/responsive-sheet/index.web.js.map +0 -1
- package/lib/module/responsive-sheet/types.js +0 -4
- package/lib/module/responsive-sheet/types.js.map +0 -1
- package/lib/typescript/commonjs/dialog/CenteredDialog.d.ts +0 -22
- package/lib/typescript/commonjs/dialog/CenteredDialog.d.ts.map +0 -1
- package/lib/typescript/commonjs/dialog/CenteredDialog.web.d.ts +0 -31
- package/lib/typescript/commonjs/dialog/CenteredDialog.web.d.ts.map +0 -1
- package/lib/typescript/commonjs/dialog/centered-dialog-tokens.d.ts +0 -47
- package/lib/typescript/commonjs/dialog/centered-dialog-tokens.d.ts.map +0 -1
- package/lib/typescript/commonjs/dialog/centered-dialog-types.d.ts +0 -74
- package/lib/typescript/commonjs/dialog/centered-dialog-types.d.ts.map +0 -1
- package/lib/typescript/commonjs/responsive-sheet/ResponsiveSheet.d.ts +0 -22
- package/lib/typescript/commonjs/responsive-sheet/ResponsiveSheet.d.ts.map +0 -1
- package/lib/typescript/commonjs/responsive-sheet/ResponsiveSheet.web.d.ts +0 -16
- package/lib/typescript/commonjs/responsive-sheet/ResponsiveSheet.web.d.ts.map +0 -1
- package/lib/typescript/commonjs/responsive-sheet/index.d.ts +0 -3
- package/lib/typescript/commonjs/responsive-sheet/index.d.ts.map +0 -1
- package/lib/typescript/commonjs/responsive-sheet/index.web.d.ts +0 -3
- package/lib/typescript/commonjs/responsive-sheet/index.web.d.ts.map +0 -1
- package/lib/typescript/commonjs/responsive-sheet/types.d.ts +0 -58
- package/lib/typescript/commonjs/responsive-sheet/types.d.ts.map +0 -1
- package/lib/typescript/module/dialog/CenteredDialog.d.ts +0 -22
- package/lib/typescript/module/dialog/CenteredDialog.d.ts.map +0 -1
- package/lib/typescript/module/dialog/CenteredDialog.web.d.ts +0 -31
- package/lib/typescript/module/dialog/CenteredDialog.web.d.ts.map +0 -1
- package/lib/typescript/module/dialog/centered-dialog-tokens.d.ts +0 -47
- package/lib/typescript/module/dialog/centered-dialog-tokens.d.ts.map +0 -1
- package/lib/typescript/module/dialog/centered-dialog-types.d.ts +0 -74
- package/lib/typescript/module/dialog/centered-dialog-types.d.ts.map +0 -1
- package/lib/typescript/module/responsive-sheet/ResponsiveSheet.d.ts +0 -22
- package/lib/typescript/module/responsive-sheet/ResponsiveSheet.d.ts.map +0 -1
- package/lib/typescript/module/responsive-sheet/ResponsiveSheet.web.d.ts +0 -16
- package/lib/typescript/module/responsive-sheet/ResponsiveSheet.web.d.ts.map +0 -1
- package/lib/typescript/module/responsive-sheet/index.d.ts +0 -3
- package/lib/typescript/module/responsive-sheet/index.d.ts.map +0 -1
- package/lib/typescript/module/responsive-sheet/index.web.d.ts +0 -3
- package/lib/typescript/module/responsive-sheet/index.web.d.ts.map +0 -1
- package/lib/typescript/module/responsive-sheet/types.d.ts +0 -58
- package/lib/typescript/module/responsive-sheet/types.d.ts.map +0 -1
- package/src/__tests__/CenteredDialog.test.tsx +0 -108
- package/src/__tests__/ResponsiveSheet.test.tsx +0 -88
- package/src/dialog/CenteredDialog.stories.tsx +0 -125
- package/src/dialog/CenteredDialog.tsx +0 -305
- package/src/dialog/CenteredDialog.web.tsx +0 -374
- package/src/dialog/centered-dialog-tokens.ts +0 -68
- package/src/dialog/centered-dialog-types.ts +0 -74
- package/src/responsive-sheet/ResponsiveSheet.stories.tsx +0 -54
- package/src/responsive-sheet/ResponsiveSheet.tsx +0 -88
- package/src/responsive-sheet/ResponsiveSheet.web.tsx +0 -76
- package/src/responsive-sheet/index.ts +0 -6
- package/src/responsive-sheet/index.web.ts +0 -14
- package/src/responsive-sheet/types.ts +0 -60
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.web.d.ts","sourceRoot":"","sources":["../../../src/index.web.ts"],"names":[],"mappings":"AAMA,cAAc,SAAS,CAAC;AAGxB,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAC3D,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAC7D,OAAO,KAAK,MAAM,MAAM,iBAAiB,CAAC;AAC1C,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAGhF,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAG9D,OAAO,KAAK,KAAK,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,KAAK,KAAK,IAAI,SAAS,EAAE,KAAK,IAAI,SAAS,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAGhG,cAAc,oBAAoB,CAAC;AACnC,OAAO,EACL,MAAM,EACN,4BAA4B,EAC5B,
|
|
1
|
+
{"version":3,"file":"index.web.d.ts","sourceRoot":"","sources":["../../../src/index.web.ts"],"names":[],"mappings":"AAMA,cAAc,SAAS,CAAC;AAGxB,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAC3D,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAC7D,OAAO,KAAK,MAAM,MAAM,iBAAiB,CAAC;AAC1C,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAGhF,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAG9D,OAAO,KAAK,KAAK,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,KAAK,KAAK,IAAI,SAAS,EAAE,KAAK,IAAI,SAAS,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAGhG,cAAc,oBAAoB,CAAC;AACnC,OAAO,EACL,MAAM,EACN,4BAA4B,EAC5B,mBAAmB,EACnB,KAAK,EACL,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EACV,WAAW,EACX,gBAAgB,EAChB,YAAY,EACZ,iBAAiB,EACjB,kBAAkB,EAClB,kBAAkB,EAClB,WAAW,EACX,eAAe,EACf,WAAW,EACX,yBAAyB,GAC1B,MAAM,oBAAoB,CAAC;AAC5B,cAAc,oBAAoB,CAAC;AACnC,OAAO,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AACtC,YAAY,EAAE,QAAQ,EAAE,UAAU,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACnF,cAAc,mBAAmB,CAAC;AAClC,cAAc,WAAW,CAAC;AAC1B,cAAc,mBAAmB,CAAC;AAClC,cAAc,eAAe,CAAC;AAC9B,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,YAAY,EACV,kBAAkB,EAClB,qBAAqB,EACrB,4BAA4B,GAC7B,MAAM,kBAAkB,CAAC;AAC1B,cAAc,UAAU,CAAC;AACzB,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAClF,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,YAAY,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAC/E,cAAc,qBAAqB,CAAC;AACpC,OAAO,KAAK,WAAW,MAAM,gBAAgB,CAAC;AAC9C,cAAc,UAAU,CAAC;AACzB,OAAO,EAAE,KAAK,EAAE,KAAK,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAGtD,OAAO,KAAK,UAAU,MAAM,cAAc,CAAC;AAG3C,OAAO,KAAK,QAAQ,MAAM,YAAY,CAAC;AACvC,OAAO,KAAK,IAAI,MAAM,QAAQ,CAAC;AAC/B,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAG3C,OAAO,KAAK,SAAS,MAAM,cAAc,CAAC;AAC1C,OAAO,KAAK,gBAAgB,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,YAAY,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAC3E,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,YAAY,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAG1E,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,YAAY,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAGvE,cAAc,QAAQ,CAAC;AACvB,cAAc,SAAS,CAAC;AACxB,cAAc,QAAQ,CAAC;AACvB,OAAO,KAAK,IAAI,MAAM,QAAQ,CAAC;AAC/B,cAAc,YAAY,CAAC;AAC3B,OAAO,KAAK,SAAS,MAAM,aAAa,CAAC;AAGzC,cAAc,iBAAiB,CAAC;AAChC,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,YAAY,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACxC,OAAO,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAC5B,YAAY,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAGtC,OAAO,KAAK,UAAU,MAAM,cAAc,CAAC;AAC3C,OAAO,KAAK,IAAI,MAAM,kBAAkB,CAAC;AACzC,OAAO,KAAK,OAAO,MAAM,qBAAqB,CAAC;AAC/C,OAAO,KAAK,MAAM,MAAM,oBAAoB,CAAC;AAC7C,OAAO,KAAK,WAAW,MAAM,0BAA0B,CAAC;AACxD,OAAO,KAAK,OAAO,MAAM,qBAAqB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AACjF,YAAY,EACV,gBAAgB,EAChB,sBAAsB,EACtB,cAAc,GACf,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAC9C,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAGrE,OAAO,KAAK,IAAI,MAAM,QAAQ,CAAC;AAG/B,OAAO,KAAK,KAAK,MAAM,mBAAmB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oxyhq/bloom",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.16.1",
|
|
4
4
|
"description": "Bloom UI — Oxy ecosystem component library for React Native + Expo + Web",
|
|
5
5
|
"main": "lib/commonjs/index.js",
|
|
6
6
|
"module": "lib/module/index.js",
|
|
@@ -463,22 +463,6 @@
|
|
|
463
463
|
"default": "./lib/commonjs/bottom-sheet/index.js"
|
|
464
464
|
}
|
|
465
465
|
},
|
|
466
|
-
"./responsive-sheet": {
|
|
467
|
-
"react-native": "./src/responsive-sheet/index.ts",
|
|
468
|
-
"browser": {
|
|
469
|
-
"types": "./lib/typescript/module/responsive-sheet/index.web.d.ts",
|
|
470
|
-
"import": "./lib/module/responsive-sheet/index.web.js",
|
|
471
|
-
"require": "./lib/commonjs/responsive-sheet/index.web.js"
|
|
472
|
-
},
|
|
473
|
-
"import": {
|
|
474
|
-
"types": "./lib/typescript/module/responsive-sheet/index.d.ts",
|
|
475
|
-
"default": "./lib/module/responsive-sheet/index.js"
|
|
476
|
-
},
|
|
477
|
-
"require": {
|
|
478
|
-
"types": "./lib/typescript/commonjs/responsive-sheet/index.d.ts",
|
|
479
|
-
"default": "./lib/commonjs/responsive-sheet/index.js"
|
|
480
|
-
}
|
|
481
|
-
},
|
|
482
466
|
"./context-menu": {
|
|
483
467
|
"react-native": "./src/context-menu/index.tsx",
|
|
484
468
|
"browser": {
|
|
@@ -782,7 +766,6 @@
|
|
|
782
766
|
"select",
|
|
783
767
|
"context-menu",
|
|
784
768
|
"bottom-sheet",
|
|
785
|
-
"responsive-sheet",
|
|
786
769
|
"card",
|
|
787
770
|
"badge",
|
|
788
771
|
"chip",
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { act, fireEvent, render } from '@testing-library/react-native';
|
|
3
|
+
|
|
4
|
+
import { AlertDialog } from '../alert-dialog';
|
|
5
|
+
import { BloomThemeProvider } from '../theme/BloomThemeProvider';
|
|
6
|
+
|
|
7
|
+
function renderWithTheme(ui: React.ReactElement) {
|
|
8
|
+
return render(
|
|
9
|
+
<BloomThemeProvider mode="light" colorPreset="teal">
|
|
10
|
+
{ui}
|
|
11
|
+
</BloomThemeProvider>,
|
|
12
|
+
);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// `AlertDialog` is now a thin wrapper over `<Dialog placement="center">`. These
|
|
16
|
+
// tests assert the public-API contract it owns (controlled visibility, the
|
|
17
|
+
// title/description copy, the confirm/cancel action row, and the
|
|
18
|
+
// confirm/cancel/dismiss callbacks) holds on the native Dialog surface.
|
|
19
|
+
describe('AlertDialog (built on Dialog)', () => {
|
|
20
|
+
it('renders nothing when not visible', () => {
|
|
21
|
+
const { queryByText } = renderWithTheme(
|
|
22
|
+
<AlertDialog
|
|
23
|
+
visible={false}
|
|
24
|
+
onClose={() => {}}
|
|
25
|
+
title="Delete app?"
|
|
26
|
+
description="This cannot be undone."
|
|
27
|
+
/>,
|
|
28
|
+
);
|
|
29
|
+
expect(queryByText('Delete app?')).toBeNull();
|
|
30
|
+
expect(queryByText('This cannot be undone.')).toBeNull();
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it('renders title, description and the confirm/cancel row when visible', () => {
|
|
34
|
+
const { getByText } = renderWithTheme(
|
|
35
|
+
<AlertDialog
|
|
36
|
+
visible
|
|
37
|
+
onClose={() => {}}
|
|
38
|
+
title="Delete app?"
|
|
39
|
+
description="This cannot be undone."
|
|
40
|
+
confirmLabel="Delete"
|
|
41
|
+
cancelLabel="Keep"
|
|
42
|
+
/>,
|
|
43
|
+
);
|
|
44
|
+
expect(getByText('Delete app?')).toBeTruthy();
|
|
45
|
+
expect(getByText('This cannot be undone.')).toBeTruthy();
|
|
46
|
+
expect(getByText('Delete')).toBeTruthy();
|
|
47
|
+
expect(getByText('Keep')).toBeTruthy();
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it('runs onConfirm then onClose when the confirm button is pressed', () => {
|
|
51
|
+
const onConfirm = jest.fn();
|
|
52
|
+
const onClose = jest.fn();
|
|
53
|
+
const { getByText } = renderWithTheme(
|
|
54
|
+
<AlertDialog
|
|
55
|
+
visible
|
|
56
|
+
onClose={onClose}
|
|
57
|
+
title="Confirm?"
|
|
58
|
+
confirmLabel="Yes"
|
|
59
|
+
onConfirm={onConfirm}
|
|
60
|
+
/>,
|
|
61
|
+
);
|
|
62
|
+
act(() => {
|
|
63
|
+
fireEvent.press(getByText('Yes'));
|
|
64
|
+
});
|
|
65
|
+
expect(onConfirm).toHaveBeenCalledTimes(1);
|
|
66
|
+
expect(onClose).toHaveBeenCalledTimes(1);
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
it('runs onCancel then onClose when the cancel button is pressed', () => {
|
|
70
|
+
const onCancel = jest.fn();
|
|
71
|
+
const onClose = jest.fn();
|
|
72
|
+
const { getByText } = renderWithTheme(
|
|
73
|
+
<AlertDialog
|
|
74
|
+
visible
|
|
75
|
+
onClose={onClose}
|
|
76
|
+
title="Confirm?"
|
|
77
|
+
cancelLabel="No"
|
|
78
|
+
onCancel={onCancel}
|
|
79
|
+
/>,
|
|
80
|
+
);
|
|
81
|
+
act(() => {
|
|
82
|
+
fireEvent.press(getByText('No'));
|
|
83
|
+
});
|
|
84
|
+
expect(onCancel).toHaveBeenCalledTimes(1);
|
|
85
|
+
expect(onClose).toHaveBeenCalledTimes(1);
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
it('hides the cancel button when hideCancel is set', () => {
|
|
89
|
+
const { queryByText, getByText } = renderWithTheme(
|
|
90
|
+
<AlertDialog
|
|
91
|
+
visible
|
|
92
|
+
onClose={() => {}}
|
|
93
|
+
title="Acknowledge"
|
|
94
|
+
confirmLabel="OK"
|
|
95
|
+
cancelLabel="Cancel"
|
|
96
|
+
hideCancel
|
|
97
|
+
/>,
|
|
98
|
+
);
|
|
99
|
+
expect(getByText('OK')).toBeTruthy();
|
|
100
|
+
expect(queryByText('Cancel')).toBeNull();
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
it('renders a destructive confirm action', () => {
|
|
104
|
+
const onConfirm = jest.fn();
|
|
105
|
+
const { getByText } = renderWithTheme(
|
|
106
|
+
<AlertDialog
|
|
107
|
+
visible
|
|
108
|
+
onClose={() => {}}
|
|
109
|
+
title="Sign out everywhere?"
|
|
110
|
+
confirmLabel="Sign out"
|
|
111
|
+
destructive
|
|
112
|
+
onConfirm={onConfirm}
|
|
113
|
+
/>,
|
|
114
|
+
);
|
|
115
|
+
const confirm = getByText('Sign out');
|
|
116
|
+
expect(confirm).toBeTruthy();
|
|
117
|
+
act(() => {
|
|
118
|
+
fireEvent.press(confirm);
|
|
119
|
+
});
|
|
120
|
+
expect(onConfirm).toHaveBeenCalledTimes(1);
|
|
121
|
+
});
|
|
122
|
+
});
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import React, { createRef } from 'react';
|
|
2
|
+
import { Text } from 'react-native';
|
|
3
|
+
import { act, render } from '@testing-library/react-native';
|
|
4
|
+
|
|
5
|
+
import { BloomThemeProvider } from '../theme/BloomThemeProvider';
|
|
6
|
+
import BottomSheet, { type BottomSheetRef } from '../bottom-sheet';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Pan-to-dismiss is the whole point of routing the Dialog `bottom` placement
|
|
10
|
+
* through `BottomSheet` on BOTH platforms. These tests assert the pan gesture
|
|
11
|
+
* is actually wired (an `onEnd` worklet is registered) and that the
|
|
12
|
+
* dismiss-threshold logic inside it runs end-to-end — i.e. a fast/far downward
|
|
13
|
+
* swipe commits the close and fires `onDismiss`, while a small drag springs the
|
|
14
|
+
* sheet back without dismissing.
|
|
15
|
+
*
|
|
16
|
+
* This file overrides the default gesture-handler mock (which discards the
|
|
17
|
+
* registered callbacks) with a RECORDING mock that captures the pan gesture's
|
|
18
|
+
* handlers. Invoking the captured `onEnd` exercises the real threshold math
|
|
19
|
+
* from `bottom-sheet/index.tsx` — there is no `Platform.OS` gating around the
|
|
20
|
+
* `<GestureDetector>` or the pan builder, so this is the SAME code path web
|
|
21
|
+
* runs (drag-to-dismiss is active on web).
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
interface PanEndEvent {
|
|
25
|
+
velocityY: number;
|
|
26
|
+
translationY: number;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
interface RecordedGesture {
|
|
30
|
+
onEnd?: (event: PanEndEvent) => void;
|
|
31
|
+
onUpdate?: (event: { translationY: number }) => void;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Recorded `Gesture.Pan()` instances from the most recent render. Must be
|
|
35
|
+
// `mock`-prefixed so the hoisted `jest.mock` factory may reference it.
|
|
36
|
+
const mockPanGestures: RecordedGesture[] = [];
|
|
37
|
+
|
|
38
|
+
jest.mock('react-native-gesture-handler', () => {
|
|
39
|
+
const builder = (record?: RecordedGesture) => {
|
|
40
|
+
const self = {
|
|
41
|
+
enabled: () => self,
|
|
42
|
+
simultaneousWithExternalGesture: () => self,
|
|
43
|
+
withRef: () => self,
|
|
44
|
+
manualActivation: () => self,
|
|
45
|
+
activeOffsetY: () => self,
|
|
46
|
+
activeOffsetX: () => self,
|
|
47
|
+
onStart: () => self,
|
|
48
|
+
onUpdate: (fn: RecordedGesture['onUpdate']) => {
|
|
49
|
+
if (record) record.onUpdate = fn;
|
|
50
|
+
return self;
|
|
51
|
+
},
|
|
52
|
+
onEnd: (fn: RecordedGesture['onEnd']) => {
|
|
53
|
+
if (record) record.onEnd = fn;
|
|
54
|
+
return self;
|
|
55
|
+
},
|
|
56
|
+
onTouchesDown: () => self,
|
|
57
|
+
onTouchesMove: () => self,
|
|
58
|
+
onTouchesUp: () => self,
|
|
59
|
+
onTouchesCancelled: () => self,
|
|
60
|
+
};
|
|
61
|
+
return self;
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
return {
|
|
65
|
+
Gesture: {
|
|
66
|
+
Pan: () => {
|
|
67
|
+
const record: RecordedGesture = {};
|
|
68
|
+
mockPanGestures.push(record);
|
|
69
|
+
return builder(record);
|
|
70
|
+
},
|
|
71
|
+
Native: () => builder(),
|
|
72
|
+
},
|
|
73
|
+
GestureDetector: ({ children }: { children: React.ReactNode }) => children,
|
|
74
|
+
GestureHandlerRootView: ({ children }: { children: React.ReactNode }) => children,
|
|
75
|
+
};
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
function renderSheet(onDismiss: () => void) {
|
|
79
|
+
const ref = createRef<BottomSheetRef>();
|
|
80
|
+
const utils = render(
|
|
81
|
+
<BloomThemeProvider mode="light" colorPreset="teal">
|
|
82
|
+
<BottomSheet ref={ref} onDismiss={onDismiss}>
|
|
83
|
+
<Text>Body</Text>
|
|
84
|
+
</BottomSheet>
|
|
85
|
+
</BloomThemeProvider>,
|
|
86
|
+
);
|
|
87
|
+
// Present so the sheet mounts and the pan gesture is constructed.
|
|
88
|
+
act(() => {
|
|
89
|
+
ref.current?.present();
|
|
90
|
+
});
|
|
91
|
+
return utils;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
describe('BottomSheet pan-to-dismiss gesture', () => {
|
|
95
|
+
beforeEach(() => {
|
|
96
|
+
mockPanGestures.length = 0;
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
it('wires a pan gesture with an onEnd handler (drag is active, not web-gated)', () => {
|
|
100
|
+
renderSheet(() => {});
|
|
101
|
+
// A pan gesture must have been constructed with an onEnd worklet — proof the
|
|
102
|
+
// drag pipeline is built unconditionally (the source has no
|
|
103
|
+
// `Platform.OS !== 'web'` guard around the GestureDetector or pan builder).
|
|
104
|
+
expect(mockPanGestures.length).toBeGreaterThan(0);
|
|
105
|
+
const bodyPan = mockPanGestures.find((g) => typeof g.onEnd === 'function');
|
|
106
|
+
expect(bodyPan).toBeDefined();
|
|
107
|
+
expect(typeof bodyPan?.onEnd).toBe('function');
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
it('dismisses when a fast downward swipe crosses the close threshold', () => {
|
|
111
|
+
const onDismiss = jest.fn();
|
|
112
|
+
renderSheet(onDismiss);
|
|
113
|
+
const bodyPan = mockPanGestures.find((g) => typeof g.onEnd === 'function');
|
|
114
|
+
|
|
115
|
+
// A high downward velocity is past `fastSwipeThreshold` (900) → the onEnd
|
|
116
|
+
// worklet commits the close, which (under the reanimated mock that runs
|
|
117
|
+
// withTiming callbacks synchronously) drains through to `onDismiss`.
|
|
118
|
+
act(() => {
|
|
119
|
+
bodyPan?.onEnd?.({ velocityY: 1500, translationY: 50 });
|
|
120
|
+
});
|
|
121
|
+
expect(onDismiss).toHaveBeenCalledTimes(1);
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
it('does not dismiss on a small, slow drag below the threshold', () => {
|
|
125
|
+
const onDismiss = jest.fn();
|
|
126
|
+
renderSheet(onDismiss);
|
|
127
|
+
const bodyPan = mockPanGestures.find((g) => typeof g.onEnd === 'function');
|
|
128
|
+
|
|
129
|
+
// Tiny translation + near-zero velocity → springs back, no close.
|
|
130
|
+
act(() => {
|
|
131
|
+
bodyPan?.onEnd?.({ velocityY: 10, translationY: 12 });
|
|
132
|
+
});
|
|
133
|
+
expect(onDismiss).not.toHaveBeenCalled();
|
|
134
|
+
});
|
|
135
|
+
});
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { act, fireEvent, render } from '@testing-library/react-native';
|
|
3
|
+
|
|
4
|
+
import { Command } from '../command';
|
|
5
|
+
import type { CommandItem } from '../command';
|
|
6
|
+
import { BloomThemeProvider } from '../theme/BloomThemeProvider';
|
|
7
|
+
|
|
8
|
+
function renderWithTheme(ui: React.ReactElement) {
|
|
9
|
+
return render(
|
|
10
|
+
<BloomThemeProvider mode="light" colorPreset="teal">
|
|
11
|
+
{ui}
|
|
12
|
+
</BloomThemeProvider>,
|
|
13
|
+
);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function makeItems(onSelect: () => void): CommandItem[] {
|
|
17
|
+
return [
|
|
18
|
+
{ id: 'profile', label: 'Go to profile', group: 'Navigation', onSelect },
|
|
19
|
+
{ id: 'settings', label: 'Open settings', group: 'Navigation', onSelect },
|
|
20
|
+
{
|
|
21
|
+
id: 'new-app',
|
|
22
|
+
label: 'Create application',
|
|
23
|
+
description: 'Register a new OAuth client',
|
|
24
|
+
group: 'Actions',
|
|
25
|
+
keywords: ['oauth', 'client'],
|
|
26
|
+
onSelect,
|
|
27
|
+
},
|
|
28
|
+
];
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// `Command` is now a ⌘K palette built on `<Dialog placement="center">`. These
|
|
32
|
+
// tests assert the public-API contract it owns (controlled visibility, the
|
|
33
|
+
// grouped results list, query filtering, the empty state, and select →
|
|
34
|
+
// onClose) holds on the native Dialog surface.
|
|
35
|
+
describe('Command (built on Dialog)', () => {
|
|
36
|
+
it('renders nothing when not visible', () => {
|
|
37
|
+
const { queryByText } = renderWithTheme(
|
|
38
|
+
<Command visible={false} onClose={() => {}} items={makeItems(() => {})} />,
|
|
39
|
+
);
|
|
40
|
+
expect(queryByText('Go to profile')).toBeNull();
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it('renders grouped items and their group headers when visible', () => {
|
|
44
|
+
const { getByText } = renderWithTheme(
|
|
45
|
+
<Command visible onClose={() => {}} items={makeItems(() => {})} />,
|
|
46
|
+
);
|
|
47
|
+
expect(getByText('Go to profile')).toBeTruthy();
|
|
48
|
+
expect(getByText('Open settings')).toBeTruthy();
|
|
49
|
+
expect(getByText('Create application')).toBeTruthy();
|
|
50
|
+
// Group headers are rendered above their items.
|
|
51
|
+
expect(getByText('Navigation')).toBeTruthy();
|
|
52
|
+
expect(getByText('Actions')).toBeTruthy();
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it('filters items by a controlled query (label, description, keywords)', () => {
|
|
56
|
+
const { getByText, queryByText, rerender } = renderWithTheme(
|
|
57
|
+
<Command
|
|
58
|
+
visible
|
|
59
|
+
onClose={() => {}}
|
|
60
|
+
items={makeItems(() => {})}
|
|
61
|
+
query="settings"
|
|
62
|
+
/>,
|
|
63
|
+
);
|
|
64
|
+
expect(getByText('Open settings')).toBeTruthy();
|
|
65
|
+
expect(queryByText('Go to profile')).toBeNull();
|
|
66
|
+
|
|
67
|
+
// A keyword on a different item matches that item.
|
|
68
|
+
rerender(
|
|
69
|
+
<BloomThemeProvider mode="light" colorPreset="teal">
|
|
70
|
+
<Command
|
|
71
|
+
visible
|
|
72
|
+
onClose={() => {}}
|
|
73
|
+
items={makeItems(() => {})}
|
|
74
|
+
query="oauth"
|
|
75
|
+
/>
|
|
76
|
+
</BloomThemeProvider>,
|
|
77
|
+
);
|
|
78
|
+
expect(getByText('Create application')).toBeTruthy();
|
|
79
|
+
expect(queryByText('Open settings')).toBeNull();
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
it('shows the empty state when nothing matches', () => {
|
|
83
|
+
const { getByText } = renderWithTheme(
|
|
84
|
+
<Command
|
|
85
|
+
visible
|
|
86
|
+
onClose={() => {}}
|
|
87
|
+
items={makeItems(() => {})}
|
|
88
|
+
query="zzz-no-match"
|
|
89
|
+
emptyText="Nothing here"
|
|
90
|
+
/>,
|
|
91
|
+
);
|
|
92
|
+
expect(getByText('Nothing here')).toBeTruthy();
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
it('invokes onSelect then onClose when an item is pressed', () => {
|
|
96
|
+
const onSelect = jest.fn();
|
|
97
|
+
const onClose = jest.fn();
|
|
98
|
+
const { getByText } = renderWithTheme(
|
|
99
|
+
<Command visible onClose={onClose} items={makeItems(onSelect)} />,
|
|
100
|
+
);
|
|
101
|
+
act(() => {
|
|
102
|
+
fireEvent.press(getByText('Open settings'));
|
|
103
|
+
});
|
|
104
|
+
expect(onSelect).toHaveBeenCalledTimes(1);
|
|
105
|
+
expect(onClose).toHaveBeenCalledTimes(1);
|
|
106
|
+
});
|
|
107
|
+
});
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import React, { createRef } from 'react';
|
|
2
|
+
import { Text, type View } from 'react-native';
|
|
3
|
+
import { act, fireEvent, render } from '@testing-library/react-native';
|
|
4
|
+
|
|
5
|
+
import { Dialog, useDialogControl } from '../dialog';
|
|
6
|
+
import { BloomThemeProvider } from '../theme/BloomThemeProvider';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* The Dialog `bottom` placement must delegate to the shared cross-platform
|
|
10
|
+
* `BottomSheet` (via `DialogBottomSheet`) — the SAME surface native and web use
|
|
11
|
+
* — instead of a bespoke CSS slide-up sheet. These tests pin that delegation:
|
|
12
|
+
* the declarative content renders through the sheet, the close lifecycle bridges
|
|
13
|
+
* `open`/`onClose` correctly, and brand theming (`panelStyle` surface paint +
|
|
14
|
+
* `containerStyle` theme scope) threads through to the sheet surface.
|
|
15
|
+
*
|
|
16
|
+
* The jest environment resolves `../dialog` to the native barrel (`Dialog.tsx`),
|
|
17
|
+
* which routes `bottom` through `DialogBottomSheet` → `BottomSheet`. The web
|
|
18
|
+
* fork (`Dialog.web.tsx`) routes through the EXACT same `DialogBottomSheet`, so
|
|
19
|
+
* this delegation is one shared code path across platforms.
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
function renderWithTheme(ui: React.ReactElement) {
|
|
23
|
+
return render(
|
|
24
|
+
<BloomThemeProvider mode="light" colorPreset="teal">
|
|
25
|
+
{ui}
|
|
26
|
+
</BloomThemeProvider>,
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function Harness({
|
|
31
|
+
children,
|
|
32
|
+
}: {
|
|
33
|
+
children: (control: ReturnType<typeof useDialogControl>) => React.ReactNode;
|
|
34
|
+
}) {
|
|
35
|
+
const control = useDialogControl();
|
|
36
|
+
return <>{children(control)}</>;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
describe('Dialog bottom placement delegates to BottomSheet', () => {
|
|
40
|
+
it('does not render bottom-sheet content until opened', () => {
|
|
41
|
+
const { queryByText } = renderWithTheme(
|
|
42
|
+
<Harness>
|
|
43
|
+
{(control) => (
|
|
44
|
+
<Dialog control={control} placement="bottom" title="Sheet title">
|
|
45
|
+
<Text>Sheet body</Text>
|
|
46
|
+
</Dialog>
|
|
47
|
+
)}
|
|
48
|
+
</Harness>,
|
|
49
|
+
);
|
|
50
|
+
// BottomSheet keeps its subtree unmounted until present() — proof the bottom
|
|
51
|
+
// placement is the sheet, not an always-mounted CSS panel.
|
|
52
|
+
expect(queryByText('Sheet title')).toBeNull();
|
|
53
|
+
expect(queryByText('Sheet body')).toBeNull();
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it('renders declarative title + description + actions through the sheet when opened', () => {
|
|
57
|
+
let control: ReturnType<typeof useDialogControl> | undefined;
|
|
58
|
+
const { getByText } = renderWithTheme(
|
|
59
|
+
<Harness>
|
|
60
|
+
{(c) => {
|
|
61
|
+
control = c;
|
|
62
|
+
return (
|
|
63
|
+
<Dialog
|
|
64
|
+
control={c}
|
|
65
|
+
placement="bottom"
|
|
66
|
+
title="Delete item?"
|
|
67
|
+
description="This cannot be undone."
|
|
68
|
+
actions={[{ label: 'Delete', color: 'destructive' }, { label: 'Cancel', color: 'cancel' }]}
|
|
69
|
+
/>
|
|
70
|
+
);
|
|
71
|
+
}}
|
|
72
|
+
</Harness>,
|
|
73
|
+
);
|
|
74
|
+
act(() => {
|
|
75
|
+
control?.open();
|
|
76
|
+
});
|
|
77
|
+
expect(getByText('Delete item?')).toBeTruthy();
|
|
78
|
+
expect(getByText('This cannot be undone.')).toBeTruthy();
|
|
79
|
+
expect(getByText('Delete')).toBeTruthy();
|
|
80
|
+
expect(getByText('Cancel')).toBeTruthy();
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
it('requests close via onClose exactly once on action press in controlled mode (no double-fire)', () => {
|
|
84
|
+
const onClose = jest.fn();
|
|
85
|
+
const { getByText } = renderWithTheme(
|
|
86
|
+
<Dialog open onClose={onClose} placement="bottom" title="Confirm" actions={[{ label: 'Done' }]} />,
|
|
87
|
+
);
|
|
88
|
+
act(() => {
|
|
89
|
+
fireEvent.press(getByText('Done'));
|
|
90
|
+
});
|
|
91
|
+
// Controlled mode: the action's close() requests dismissal via onClose once;
|
|
92
|
+
// the host (not the dialog) then flips `open`. It must not fire the
|
|
93
|
+
// close-completion onClose a second time.
|
|
94
|
+
expect(onClose).toHaveBeenCalledTimes(1);
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
it('threads panelStyle (brand surface) and containerStyle (theme scope) onto the sheet content', () => {
|
|
98
|
+
let control: ReturnType<typeof useDialogControl> | undefined;
|
|
99
|
+
const panelRef = createRef<View>();
|
|
100
|
+
const { getByTestId } = renderWithTheme(
|
|
101
|
+
<Harness>
|
|
102
|
+
{(c) => {
|
|
103
|
+
control = c;
|
|
104
|
+
return (
|
|
105
|
+
<Dialog
|
|
106
|
+
control={c}
|
|
107
|
+
placement="bottom"
|
|
108
|
+
testID="brand-sheet"
|
|
109
|
+
panelStyle={{ backgroundColor: 'rebeccapurple' }}
|
|
110
|
+
containerStyle={{ paddingTop: 7 }}
|
|
111
|
+
>
|
|
112
|
+
<Text ref={panelRef}>Branded</Text>
|
|
113
|
+
</Dialog>
|
|
114
|
+
);
|
|
115
|
+
}}
|
|
116
|
+
</Harness>,
|
|
117
|
+
);
|
|
118
|
+
act(() => {
|
|
119
|
+
control?.open();
|
|
120
|
+
});
|
|
121
|
+
const content = getByTestId('brand-sheet');
|
|
122
|
+
const flattened = Array.isArray(content.props.style)
|
|
123
|
+
? Object.assign({}, ...content.props.style.filter(Boolean))
|
|
124
|
+
: content.props.style;
|
|
125
|
+
// panelStyle paints the surface; containerStyle (theme-var scope) wraps the
|
|
126
|
+
// content subtree. Both land on the sheet content container.
|
|
127
|
+
expect(flattened.backgroundColor).toBe('rebeccapurple');
|
|
128
|
+
expect(flattened.paddingTop).toBe(7);
|
|
129
|
+
});
|
|
130
|
+
});
|
|
@@ -2,28 +2,32 @@ import React, { memo, useCallback } from 'react';
|
|
|
2
2
|
import { StyleSheet, View } from 'react-native';
|
|
3
3
|
|
|
4
4
|
import { Button } from '../button';
|
|
5
|
+
import type { DialogProps } from '../dialog';
|
|
5
6
|
import { useTheme } from '../theme/use-theme';
|
|
6
7
|
import { Text } from '../typography';
|
|
7
8
|
import { fontSize, space } from '../styles/tokens';
|
|
8
|
-
import type { CenteredDialogProps } from '../dialog';
|
|
9
9
|
import type { AlertDialogProps } from './types';
|
|
10
10
|
|
|
11
|
-
type
|
|
11
|
+
type DialogComponent = React.ComponentType<DialogProps>;
|
|
12
|
+
|
|
13
|
+
/** Centered alert-card max width (px). Matches the legacy AlertDialog card. */
|
|
14
|
+
const ALERT_DIALOG_MAX_WIDTH = 440;
|
|
12
15
|
|
|
13
16
|
/**
|
|
14
|
-
* Build the `AlertDialog` component bound to a platform `
|
|
17
|
+
* Build the `AlertDialog` component bound to a platform `Dialog`.
|
|
15
18
|
*
|
|
16
|
-
* `
|
|
17
|
-
* overlay), and this repo never
|
|
18
|
-
*
|
|
19
|
-
* `
|
|
19
|
+
* `Dialog` is platform-forked (native `BottomSheet`-backed surface vs pure-DOM
|
|
20
|
+
* web overlay) through its `./dialog` export conditions, and this repo never
|
|
21
|
+
* relies on implicit `.web` resolution — the platform entry files
|
|
22
|
+
* (`index.ts` / `index.web.ts`) inject the correct `Dialog` here. The body
|
|
23
|
+
* below is single-source, no duplication.
|
|
20
24
|
*
|
|
21
|
-
* `AlertDialog` is a thin wrapper over
|
|
22
|
-
* description and a confirm/cancel action row. Reach for the
|
|
23
|
-
* `confirm()` helper + `<AlertDialogHost />` to trigger a confirm
|
|
24
|
-
* event handler without owning visible state.
|
|
25
|
+
* `AlertDialog` is a thin wrapper over `<Dialog placement="center">` that lays
|
|
26
|
+
* out a title, description and a confirm/cancel action row. Reach for the
|
|
27
|
+
* imperative `confirm()` helper + `<AlertDialogHost />` to trigger a confirm
|
|
28
|
+
* from an event handler without owning visible state.
|
|
25
29
|
*/
|
|
26
|
-
export function createAlertDialog(
|
|
30
|
+
export function createAlertDialog(Dialog: DialogComponent) {
|
|
27
31
|
const AlertDialogComponent = function AlertDialog({
|
|
28
32
|
visible,
|
|
29
33
|
onClose,
|
|
@@ -52,16 +56,31 @@ export function createAlertDialog(CenteredDialog: CenteredDialogComponent) {
|
|
|
52
56
|
}, [onConfirm, onClose]);
|
|
53
57
|
|
|
54
58
|
return (
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
59
|
+
<Dialog
|
|
60
|
+
open={visible}
|
|
61
|
+
onClose={onClose}
|
|
62
|
+
placement="center"
|
|
63
|
+
// Alert dialogs are blocking by default — the backdrop only dismisses
|
|
64
|
+
// when the caller opts in via `dismissible`.
|
|
65
|
+
dismissOnBackdrop={dismissible}
|
|
66
|
+
maxWidth={ALERT_DIALOG_MAX_WIDTH}
|
|
67
|
+
title={title}
|
|
68
|
+
label={title}
|
|
69
|
+
style={cardStyle}
|
|
70
|
+
testID={testID}
|
|
71
|
+
>
|
|
72
|
+
{description ? (
|
|
73
|
+
<Text
|
|
74
|
+
style={{
|
|
75
|
+
fontSize: fontSize.md,
|
|
76
|
+
lineHeight: fontSize.md * 1.4,
|
|
77
|
+
color: theme.colors.textSecondary,
|
|
78
|
+
paddingBottom: space.lg,
|
|
79
|
+
}}
|
|
80
|
+
>
|
|
81
|
+
{description}
|
|
82
|
+
</Text>
|
|
83
|
+
) : null}
|
|
65
84
|
<View style={styles.actions}>
|
|
66
85
|
{!hideCancel ? (
|
|
67
86
|
<Button
|
|
@@ -69,7 +88,8 @@ export function createAlertDialog(CenteredDialog: CenteredDialogComponent) {
|
|
|
69
88
|
size="medium"
|
|
70
89
|
onPress={handleCancel}
|
|
71
90
|
style={styles.action}
|
|
72
|
-
accessibilityLabel={cancelLabel}
|
|
91
|
+
accessibilityLabel={cancelLabel}
|
|
92
|
+
>
|
|
73
93
|
{cancelLabel}
|
|
74
94
|
</Button>
|
|
75
95
|
) : null}
|
|
@@ -82,22 +102,12 @@ export function createAlertDialog(CenteredDialog: CenteredDialogComponent) {
|
|
|
82
102
|
destructive && { backgroundColor: theme.colors.negative },
|
|
83
103
|
]}
|
|
84
104
|
textStyle={destructive ? { color: theme.colors.negativeForeground } : undefined}
|
|
85
|
-
accessibilityLabel={confirmLabel}
|
|
105
|
+
accessibilityLabel={confirmLabel}
|
|
106
|
+
>
|
|
86
107
|
{confirmLabel}
|
|
87
108
|
</Button>
|
|
88
109
|
</View>
|
|
89
|
-
|
|
90
|
-
{description ? (
|
|
91
|
-
<Text
|
|
92
|
-
style={{
|
|
93
|
-
fontSize: fontSize.md,
|
|
94
|
-
lineHeight: fontSize.md * 1.4,
|
|
95
|
-
color: theme.colors.textSecondary,
|
|
96
|
-
}}>
|
|
97
|
-
{description}
|
|
98
|
-
</Text>
|
|
99
|
-
) : null}
|
|
100
|
-
</CenteredDialog>
|
|
110
|
+
</Dialog>
|
|
101
111
|
);
|
|
102
112
|
};
|
|
103
113
|
|