Skip to content

Commit

Permalink
feat(Sheet): lazy load sheet implementations (#1250)
Browse files Browse the repository at this point in the history
* `sheet-root` now has the bare minimum to work, it lazy loads
everything when needed, including the native implementation.
* Web implementations of native sheets (defined by the bridge) have been
deprecated. The recommended way to use that predefined sheets is using
the `showSheet` function.

## Pending tasks

* [x] Update documentation
* [x] Verify in webapp
*
https://webapp-sheet.movistar-es-dev.svc.dev.tuenti.io/pages/example-bottom-sheet
    * [x] web
    * [x] android native
    * [x] ios native

## Before 

Bundles from the webview entrypoint


![image](https://github.com/user-attachments/assets/4a2cb8d3-3524-4bbf-8d26-8fccc632e34a)

## After

The arrow points to the sheet-root module


![image](https://github.com/user-attachments/assets/f094f693-0cec-4813-b8ee-ad5f1f1f8ec2)

![image](https://github.com/user-attachments/assets/639a4d1d-c56c-4fc4-b3fb-7b006bee58d2)

---------

Co-authored-by: Pedro Ladaria <[email protected]>
  • Loading branch information
pladaria and Pedro Ladaria authored Sep 27, 2024
1 parent 7a3f0d2 commit 40fecdd
Show file tree
Hide file tree
Showing 26 changed files with 1,832 additions and 1,652 deletions.
134 changes: 61 additions & 73 deletions doc/sheet.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,78 +3,21 @@
Mística provides a sheet component that can be used to display a modal-like content from over the main content
of the screen.

## Basic usage
## Predefined sheets

You can show any content you want inside the sheet by passing it as a child of the component.

```jsx
import {Sheet} from 'mistica';

const MyComponent = () => {
const [showSheet, setShowSheet] = useState(false);
return (
<>
<ButtonPrimary onPress={() => setShowSheet(true)}>show sheet</ButtonPrimary>
{showSheet && (
<Sheet onClose={() => setShowSheet(false)}>
<Placeholder />
</Sheet>
)}
</>
);
};
```

The sheet will close when the user does the swipe down gesture or when the background overlay is touched. The
`onClose` callback is called when the closing animation finishes, that's the right place to unmount the sheet
as shown in the example above.

You can also close the sheet programmatically using the render prop:

```jsx
import {Sheet} from 'mistica';

const MyComponent = () => {
const [showSheet, setShowSheet] = useState(false);
return (
<>
<ButtonPrimary onPress={() => setShowSheet(true)}>show sheet</ButtonPrimary>
{showSheet && (
<Sheet onClose={() => setShowSheet(false)}>
{({closeModal, modalTitleId}) => (
<>
<Title1 id={modalTitleId}>My sheet</Title1>
<Placeholder />
<ButtonPrimary onPress={closeModal}>Close</ButtonPrimary>
</>
)}
</Sheet>
)}
</>
);
};
```

## Sheet with predefined content

Mística predefines some common sheet patterns for you to use: `RadioListSheet`, `ActionsListSheet`,
`InfoSheet` and `ActionsSheet`. You can see examples in the storybook.

## `showSheet` imperative api
Some predefined sheets are available: `RadioListSheet`, `ActionsListSheet`, `InfoSheet` and `ActionsSheet`.
You can see examples in Storybook.

Instead of using React components, there is an alternative way to show a sheet: using the `showSheet`
function. For this to work, you need to render a `<SheetRoot/>` somewhere in your app, typically where you
render the mistica `<ThemeContextProvider/>`, but it could be anywhere.
To use them, first you must configure the `SheetRoot` component in your app:

```jsx
import {SheetRoot} from '@telefonica/mistica';

export const App = () => {
return (
<>
<SheetRoot />
<RestOfYourApp />
</>
<SheetRoot>
<MyApplication />
</SheetRoot>
);
};
```
Expand Down Expand Up @@ -112,22 +55,67 @@ const MyComponent = () => {

### Native implementation

If you are using mistica inside Novum app, you can configure `showSheet` to use the native sheet
implementation with the webview bridge.
If your app is served inside a webview and uses the `webview-bridge` library, the native implementation of the
predefined sheets will be used.

```jsx
import {SheetRoot} from '@telefonica/mistica';
```tsx
import {bottomSheet, isWebViewBridgeAvailable} from '@tef-novum/webview-bridge';

export const App = () => {
// ...

<SheetRoot nativeImplementation={isWebViewBridgeAvailable() ? bottomSheet : undefined}>
```

When possible, always use the native implementation, as it provides a better user experience.

## Custom sheets

You can show any content you want inside the sheet by passing it as a child of the component.

```jsx
import {Sheet} from 'mistica';

const MyComponent = () => {
const [showSheet, setShowSheet] = useState(false);
return (
<>
<SheetRoot nativeImplementation={isWebViewBridgeAvailable() ? bottomSheet : undefined} />
<RestOfYourApp />
<ButtonPrimary onPress={() => setShowSheet(true)}>show sheet</ButtonPrimary>
{showSheet && (
<Sheet onClose={() => setShowSheet(false)}>
<Placeholder />
</Sheet>
)}
</>
);
};
```

Then when you call `showSheet`, if the code is running inside a webview, it will use the native implementation
instead of the web one.
The sheet will close when the user does the swipe down gesture or when the background overlay is touched. The
`onClose` callback is called when the closing animation finishes, that's the right place to unmount the sheet
as shown in the example above.

You can also close the sheet programmatically using the render prop:

```jsx
import {Sheet} from 'mistica';

const MyComponent = () => {
const [showSheet, setShowSheet] = useState(false);
return (
<>
<ButtonPrimary onPress={() => setShowSheet(true)}>show sheet</ButtonPrimary>
{showSheet && (
<Sheet onClose={() => setShowSheet(false)}>
{({closeModal, modalTitleId}) => (
<>
<Title1 id={modalTitleId}>My sheet</Title1>
<Placeholder />
<ButtonPrimary onPress={closeModal}>Close</ButtonPrimary>
</>
)}
</Sheet>
)}
</>
);
};
```
51 changes: 20 additions & 31 deletions doc/texts.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,39 +2,9 @@

Some components use some default texts that you can customize using [`theme` prop](./theme-config.md)

These are the customizable texts and their default values:

- `expirationDatePlaceholder`: `'MM/AA'`
- `enablePasswordVisibility`: `'Mostrar contraseña'`,
- `disablePasswordVisibility`: `'Ocultar contraseña'`,
- `loading`: `'Cargando'`
- `linkOpensInNewTab`: `'Se abre en ventana nueva'`
- `modalClose`: `'Cerrar'`
- `dialogCancelButton`: `'Cancelar'`
- `dialogAcceptButton`: `'Aceptar'`
- `formFieldOptionalLabelSuffix`: `'opcional'`
- `formFieldErrorIsMandatory`: `'Este campo es obligatorio'`
- `formCreditCardNumberLabel`: `'Número de tarjeta'`
- `formCreditCardExpirationLabel`: `'Caducidad'`
- `formCreditCardCvvLabel`: `'CVV'`
- `formCreditCardCvvError`: `'CVV incorrecto'`
- `formCreditCardCvvTooltipVisaMcButton`: `'Mostrar ayuda CVV'`
- `formCreditCardCvvTooltipVisaMc`: `'El CVV son los 3 últimos dígitos del reverso de tu tarjeta'`
- `formCreditCardCvvTooltipAmex`: `'Si es American Express, añade los 4 dígitos del anverso'`
- `formCreditCardExpirationError`: `'Fecha no válida'`
- `formCreditCardNumberError`: `'No es un número de tarjeta válido'`
- `formDateOutOfRangeError`: `'Fecha no permitida'`
- `formEmailError`: `'Email incorrecto'`
- `formIbanError`: `'IBAN incorrecto'`
- `closeButtonLabel`: `'Cerrar'`
- `formSearchClear`: `'Borrar búsqueda'`
- `menuLabelSuffix`: `'menú'`
- `openNavigationMenu`: `'Abrir menú de navegación'`
- `closeNavigationMenu`: `'Cerrar menú de navegación'`

You can customize them in your page. For example:

```js
```tsx
<ThemeContextProvider
theme={{
skin: getMovistarSkin(),
Expand All @@ -49,5 +19,24 @@ You can customize them in your page. For example:
</ThemeContextProvider>
```

See the `Dictionary` type to known all the available texts.

If your application supports multi language, you may need to override all the texts and use localized
translation tokens depending on your user preferred language.

## Using Mística text tokens

You can use Mística tokens in your texts. The translate function `t` will translate the token using the
configured locale in the `ThemeContextProvider`.

Example:

```tsx
import {textTokens} from '@telefonica/mistica';

const MyComponent = () => {
const {t} = useTheme();

return <div>{t(textTokens.formCreditCardExpirationError)}</div>;
};
```
4 changes: 3 additions & 1 deletion doc/theme-config.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,9 @@ Here is a description of every attribute:
- `userAgent:` **IMPORTANT** In case you are using SSR, you should set this value with the user-agent header
you receive on every request to your server, otherwise the server-side render won't take the user agent
into account.
- `texts?`: some copies you can customize. See [customizable texts doc](./texts.md).
- `texts?`: some copies you can customize. See [texts doc](./texts.md).
- `t`: this is the translate funtion. It accepts a token as exported by `textTokens`. See
[texts doc](./texts.md).
- `analytics?`: see [analytics docs](./analytics.md).
- `Link?`: the `Link` component you want to use by Touchables that use the prop `to`. By default, the lib uses
an anchor tag (`<a>`). Use this prop to use the Link component from ReactRouter, Next.js or any other
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
"ts-check": "tsc --project tsconfig.json --noEmit",
"build": "yarn clean && node scripts/build.js",
"compile": "node scripts/compile.js",
"clean": "rimraf dist && rimraf dist-es && rimraf dist-ts && rimraf css/mistica.css && rimraf community.d.ts && rimraf community.js && rimraf node_modules/.cache",
"clean": "rimraf dist && rimraf dist-es && rimraf dist-ts && rimraf css/mistica.css && rimraf community.d.ts && rimraf community.js && rimraf node_modules/.cache && bash -c 'yarn jest --clearCache > /dev/null 2>&1'",
"prepublishOnly": "node scripts/prepublish-only.js",
"prepack": "yarn build",
"storybook": "storybook dev -p 6006",
Expand Down
Loading

1 comment on commit 40fecdd

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deploy preview for mistica-web ready!

✅ Preview
https://mistica-3xbhxiiuf-flows-projects-65bb050e.vercel.app

Built with commit 40fecdd.
This pull request is being automatically deployed with vercel-action

Please sign in to comment.