feat: add "show more" to user info status (#5383)

* improve: handle long status text with a collapsible text element

* remove the points from  show_more value

* refactor the path

* add storyshot

* remove comments

* minor tweak at pt-br

* add the e2e  test

* remove fontInfo

* refactor layout

* fix e2e test

* fix the text for both platforms

* add comment

* update detox to 20.11 to accept regex and fix the test for show more
This commit is contained in:
Reinaldo Neto 2023-12-26 10:36:59 -03:00 committed by GitHub
parent ed2edf2008
commit e4d4592145
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 211 additions and 61 deletions

View File

@ -29,6 +29,7 @@ const getStories = () => {
require("../app/containers/markdown/Markdown.stories.tsx"),
require("../app/containers/markdown/new/NewMarkdown.stories.tsx"),
require("../app/containers/message/Components/CollapsibleQuote/CollapsibleQuote.stories.tsx"),
require("../app/containers/CollapsibleText/CollapsibleText.stories.tsx"),
require("../app/containers/message/Message.stories.tsx"),
require("../app/containers/ReactionsList/ReactionsList.stories.tsx"),
require("../app/containers/RoomHeader/RoomHeader.stories.tsx"),

View File

@ -0,0 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Storyshots Collapsible Text Item 1`] = `"{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"padding\\":20}},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"accessibilityLabel\\":\\"Lorem ipsum dolor sit amet\\",\\"style\\":[{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"Inter\\",\\"fontWeight\\":\\"400\\",\\"textAlignVertical\\":\\"center\\"},{\\"color\\":\\"#2f343d\\",\\"height\\":0}],\\"testID\\":\\"collapsible-text-Lorem ipsum dolor sit amet\\"},\\"children\\":[\\"Lorem ipsum dolor sit amet\\"]},{\\"type\\":\\"Text\\",\\"props\\":{\\"accessibilityLabel\\":\\"linesToTruncate: 1 - Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam vel vestibulum neque. Proin dignissim neque in urna nec.\\",\\"style\\":[{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"Inter\\",\\"fontWeight\\":\\"400\\",\\"textAlignVertical\\":\\"center\\"},{\\"color\\":\\"#2f343d\\",\\"height\\":0}],\\"testID\\":\\"collapsible-text-linesToTruncate: 1 - Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam vel vestibulum neque. Proin dignissim neque in urna nec.\\"},\\"children\\":[\\"linesToTruncate: 1 - Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam vel vestibulum neque. Proin dignissim neque in urna nec.\\"]},{\\"type\\":\\"Text\\",\\"props\\":{\\"accessibilityLabel\\":\\"linesToTruncate: 2 - Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam vel vestibulum neque. Proin dignissim neque in urna nec.\\",\\"style\\":[{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"Inter\\",\\"fontWeight\\":\\"400\\",\\"textAlignVertical\\":\\"center\\"},{\\"color\\":\\"#2f343d\\",\\"height\\":0}],\\"testID\\":\\"collapsible-text-linesToTruncate: 2 - Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam vel vestibulum neque. Proin dignissim neque in urna nec.\\"},\\"children\\":[\\"linesToTruncate: 2 - Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam vel vestibulum neque. Proin dignissim neque in urna nec.\\"]}]}"`;

View File

@ -0,0 +1,21 @@
import React from 'react';
import { View } from 'react-native';
import CollapsibleText from '.';
const smallText = 'Lorem ipsum dolor sit amet';
const text120 =
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam vel vestibulum neque. Proin dignissim neque in urna nec.';
export default {
title: 'Collapsible Text'
};
export const Item = () => (
<View style={{ padding: 20 }}>
<CollapsibleText linesToTruncate={1} msg={`${smallText}`} />
<CollapsibleText linesToTruncate={1} msg={`linesToTruncate: 1 - ${text120}`} />
<CollapsibleText linesToTruncate={2} msg={`linesToTruncate: 2 - ${text120}`} />
</View>
);

View File

@ -0,0 +1,86 @@
import React, { useState } from 'react';
import { TextStyle, Text, StyleSheet } from 'react-native';
import sharedStyles from '../../views/Styles';
import { useTheme } from '../../theme';
import { previewFormatText } from '../markdown/previewFormatText';
import I18n from '../../i18n';
interface ICollapsibleText {
msg?: string;
style?: TextStyle[];
linesToTruncate?: number;
}
const styles = StyleSheet.create({
text: {
fontSize: 16,
...sharedStyles.textRegular,
textAlignVertical: 'center'
},
textInfo: {
fontSize: 14,
...sharedStyles.textRegular
}
});
const CollapsibleText = ({ msg, style = [], linesToTruncate = 1 }: ICollapsibleText) => {
const [truncatedText, setTruncatedText] = useState('');
const [showTruncated, setShowTruncated] = useState(true);
const { colors } = useTheme();
if (!msg) {
return null;
}
const m = previewFormatText(msg);
if (truncatedText && showTruncated) {
return (
<Text testID={`collapsible-text-truncated-${m}`}>
<Text accessibilityLabel={truncatedText} style={[styles.text, { color: colors.bodyText }, ...style]}>
{`${truncatedText}... `}
</Text>
<Text onPress={() => setShowTruncated(false)} style={[styles.textInfo, { color: colors.actionTintColor }]}>
{I18n.t('Show_more')}
</Text>
</Text>
);
}
return (
<Text
accessibilityLabel={m}
style={[styles.text, { color: colors.bodyText, height: !showTruncated ? undefined : 0 }, ...style]}
testID={`collapsible-text-${m}`}
onTextLayout={event => {
const { lines } = event.nativeEvent;
if (lines.length > linesToTruncate) {
const text = lines
.splice(0, linesToTruncate)
.map(line => line.text)
.join('');
const truncatedTextLengthWithShowMore = text.length - (4 + I18n.t('Show_more').length);
const clippedText = text.slice(0, truncatedTextLengthWithShowMore);
setTruncatedText(clippedText);
} else {
setShowTruncated(false);
}
}}
>
{m}
{truncatedText ? (
<Text
testID='collapsible-text-show-less'
onPress={() => setShowTruncated(true)}
style={[styles.textInfo, { color: colors.actionTintColor }]}
>
{` ${I18n.t('Show_less')}`}
</Text>
) : null}
</Text>
);
};
export default CollapsibleText;

View File

@ -344,7 +344,7 @@
"Share": "مشاركة",
"Share_Link": "مشاركة رابط",
"Share_this_app": "مشاركة هذا البرنامج",
"Show_more": "إظهار أكثر..",
"Show_more": "إظهار أكثر",
"Sign_Up": "تسجيل جديد",
"Sound": "الصوت",
"Star": "تمييز",

View File

@ -378,7 +378,7 @@
"Share": "Teilen",
"Share_Link": "Link teilen",
"Share_this_app": "App teilen",
"Show_more": "Mehr anzeigen",
"Show_more": "Mehr anzeigen",
"Sign_Up": "Anmelden",
"Sound": "Ton",
"Star": "Favoriten",

View File

@ -378,7 +378,8 @@
"Share": "Share",
"Share_Link": "Share link",
"Share_this_app": "Share this app",
"Show_more": "Show more..",
"Show_more": "Show more",
"Show_less": "Show less",
"Sign_Up": "Sign up",
"Sound": "Sound",
"Star": "Star",

View File

@ -378,7 +378,7 @@
"Share": "Jaa",
"Share_Link": "Jaa linkki",
"Share_this_app": "Jaa tämä sovellus",
"Show_more": "Näytä lisää...",
"Show_more": "Näytä lisää",
"Sign_Up": "Rekisteröidy",
"Sound": "Ääni",
"Star": "Tähti",

View File

@ -353,7 +353,7 @@
"Share": "Partager",
"Share_Link": "Partager le lien",
"Share_this_app": "Partager cette application",
"Show_more": "Afficher plus..",
"Show_more": "Afficher plus",
"Sign_Up": "S'inscrire",
"Sound": "Son",
"Star": "Mettre en favoris",

View File

@ -358,7 +358,7 @@
"Share": "Condividi",
"Share_Link": "Condividi link",
"Share_this_app": "Condividi questa app",
"Show_more": "Mostra altri..",
"Show_more": "Mostra altri",
"Sign_Up": "Registrati",
"Sound": "Suono",
"Star": "Aggiungi ai preferiti",

View File

@ -310,7 +310,6 @@
"Share": "シェア",
"Share_Link": "リンクをシェアする",
"Share_this_app": "このアプリをシェアする",
"Show_more": "Show more..",
"Sign_Up": "登録",
"Sound": "音",
"Star": "お気に入り",

View File

@ -353,7 +353,7 @@
"Share": "Delen",
"Share_Link": "Deel link",
"Share_this_app": "Deel deze app",
"Show_more": "Meer tonen..",
"Show_more": "Meer tonen",
"Sign_Up": "Registreren",
"Sound": "Geluid",
"Star": "Ster",

View File

@ -378,7 +378,8 @@
"Share": "Compartilhar",
"Share_Link": "Compartilhar convite",
"Share_this_app": "Compartilhar esse app",
"Show_more": "Mostrar mais..",
"Show_more": "Mostrar mais",
"Show_less": "Mostrar menos",
"Sign_Up": "Registrar",
"Sound": "Som da notificação",
"Star": "Favorito",

View File

@ -364,7 +364,7 @@
"Share": "Поделиться",
"Share_Link": "Ссылка, чтобы Поделиться",
"Share_this_app": "Рассказать о приложении",
"Show_more": "Показать больше..",
"Show_more": "Показать больше",
"Sign_Up": "Регистрация",
"Sound": "Звук",
"Star": "Отметить",

View File

@ -361,7 +361,7 @@
"Share": "Deliti",
"Share_Link": "Deliti povezavo",
"Share_this_app": "Delite to aplikacijo",
"Show_more": "Prikaži več",
"Show_more": "Prikaži več",
"Sign_Up": "Prijavite se",
"Sound": "Zvok",
"Star": "zvezda",

View File

@ -378,7 +378,7 @@
"Share": "Dela",
"Share_Link": "Dela länk",
"Share_this_app": "Dela den här appen",
"Show_more": "Visa mer.",
"Show_more": "Visa mer",
"Sign_Up": "Registrera dig",
"Sound": "Ljud",
"Star": "Stjärna",

View File

@ -341,7 +341,7 @@
"Share": "Paylaş",
"Share_Link": "Bağlantı paylaş",
"Share_this_app": "Bu uygulamayı paylaş",
"Show_more": "Daha fazla göster..",
"Show_more": "Daha fazla göster",
"Sign_Up": "Kaydol",
"Sound": "Ses",
"Star": "Yıldızla",

View File

@ -4,9 +4,9 @@ import { Text, View } from 'react-native';
import { ISubscription, SubscriptionType } from '../../../definitions';
import styles from '../styles';
import { useTheme } from '../../../theme';
import { MarkdownPreview } from '../../../containers/markdown';
import RoomTypeIcon from '../../../containers/RoomTypeIcon';
import { getRoomTitle } from '../../../lib/methods/helpers';
import CollapsibleText from '../../../containers/CollapsibleText';
interface IRoomInfoViewTitle {
room?: ISubscription;
@ -20,7 +20,7 @@ const RoomInfoViewTitle = ({ room, name, username, statusText, type }: IRoomInfo
const { colors } = useTheme();
if (type === SubscriptionType.DIRECT) {
return (
<>
<View style={styles.roomInfoViewTitleContainer}>
<Text testID='room-info-view-name' style={[styles.roomTitle, { color: colors.titleText }]}>
{name}
</Text>
@ -32,10 +32,14 @@ const RoomInfoViewTitle = ({ room, name, username, statusText, type }: IRoomInfo
)}
{!!statusText && (
<View testID='room-info-view-custom-status'>
<MarkdownPreview msg={statusText} style={[styles.roomUsername, { color: colors.auxiliaryText }]} />
<CollapsibleText
linesToTruncate={2}
msg={statusText}
style={[styles.roomUsername, { color: colors.auxiliaryText }]}
/>
</View>
)}
</>
</View>
);
}
return (

View File

@ -28,18 +28,18 @@ export default StyleSheet.create({
marginHorizontal: 10
},
roomTitleContainer: {
paddingTop: 32,
paddingTop: 16,
marginHorizontal: 16,
alignItems: 'center',
flexDirection: 'row'
},
roomTitle: {
fontSize: 20,
fontSize: 16,
...sharedStyles.textAlignCenter,
...sharedStyles.textMedium
},
roomUsername: {
fontSize: 18,
fontSize: 14,
...sharedStyles.textAlignCenter,
...sharedStyles.textRegular
},
@ -75,7 +75,7 @@ export default StyleSheet.create({
},
roomButtonsContainer: {
flexDirection: 'row',
paddingTop: 30
paddingTop: 16
},
roomButton: {
alignItems: 'center',
@ -84,5 +84,10 @@ export default StyleSheet.create({
},
roomButtonText: {
marginTop: 5
},
roomInfoViewTitleContainer: {
paddingTop: 16,
paddingHorizontal: 20,
alignItems: 'center'
}
});

View File

@ -268,5 +268,33 @@ describe('Room info screen', () => {
.withTimeout(10000);
});
});
describe('Navigate to user status-test', () => {
it('Back to rooms list view', async () => {
await tapBack();
await sleep(300);
await tapBack();
await sleep(300);
await tapBack();
await sleep(300);
});
it('should see the status text with show more label', async () => {
const statusTextExpected =
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam laoreet odio lectus, nec varius nisi semper ut porta ante';
await navigateToRoomInfo('status-test');
await waitFor(element(by.id(`collapsible-text-truncated-${statusTextExpected}`)))
.toBeVisible()
.withTimeout(10000);
await sleep(400);
const textWithShowMoreRegExp = /Lorem[\s\S]+... Show more/i
await waitFor(element(by[textMatcher](textWithShowMoreRegExp)))
.toExist()
.withTimeout(10000);
await element(by.id(`collapsible-text-truncated-${statusTextExpected}`)).tap({ x: 320, y: 24 });
await waitFor(element(by.id(`collapsible-text-${statusTextExpected}`)))
.toBeVisible()
.withTimeout(10000);
});
});
});
});

View File

@ -192,7 +192,7 @@
"babel-loader": "8.3.0",
"babel-plugin-transform-remove-console": "^6.9.4",
"codecov": "^3.8.3",
"detox": "^20.1.2",
"detox": "20.11.0",
"eslint": "^7.32.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-import": "2.26.0",

View File

@ -3368,9 +3368,9 @@
regenerator-runtime "^0.13.4"
"@babel/runtime@^7.21.0":
version "7.22.11"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.22.11.tgz#7a9ba3bbe406ad6f9e8dd4da2ece453eb23a77a4"
integrity sha512-ee7jVNlWN09+KftVOu9n7S8gQzD/Z6hN/I8VBRXW4P1+Xe7kJGXMwu8vds4aGIMHZnNbdpSWCfZZtinytpcAvA==
version "7.23.6"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.6.tgz#c05e610dc228855dc92ef1b53d07389ed8ab521d"
integrity sha512-zHd0eUrf5GZoOWVCXp6koAKQTfZV07eit6bGPmJgnZdnSAvvZee6zniW2XMF7Cmc4ISOOnPy3QaSiIJGJkVEDQ==
dependencies:
regenerator-runtime "^0.14.0"
@ -10143,19 +10143,20 @@ detect-port@^1.3.0:
address "^1.0.1"
debug "^2.6.0"
detox@^20.1.2:
version "20.1.2"
resolved "https://registry.yarnpkg.com/detox/-/detox-20.1.2.tgz#a66c709080b53a80f3b6ba1671f5c0dbf5ae6dc7"
integrity sha512-SGxLyuzE8TjIc4Lg49YKD0buj3JLaX+KtprSeFvn7ZTdWd4fH6o5Szd4KM21uBSpnYEEgXTgiCypPQst6dt5mQ==
detox@20.11.0:
version "20.11.0"
resolved "https://registry.yarnpkg.com/detox/-/detox-20.11.0.tgz#f240e01db12334e0706b7f3477e59b8a5e4358c8"
integrity sha512-01LpETlZwfo2V7Awo+5ccUbee7E1lvH3ldLlmXxsx3mQ0pEA65f9CaO+FWhtUGYh7vQRMOQ9SnzYdej/ydQ7iQ==
dependencies:
ajv "^8.6.3"
bunyan "^1.8.12"
bunyan-debug-stream "^3.1.0"
caf "^15.0.1"
chalk "^2.4.2"
chalk "^4.0.0"
child-process-promise "^2.2.0"
find-up "^4.1.0"
fs-extra "^4.0.2"
execa "^5.1.1"
find-up "^5.0.0"
fs-extra "^11.0.0"
funpermaproxy "^1.1.0"
glob "^8.0.3"
ini "^1.3.4"
@ -10163,7 +10164,7 @@ detox@^20.1.2:
lodash "^4.17.11"
multi-sort-stream "^1.0.3"
multipipe "^4.0.0"
node-ipc "^9.2.1"
node-ipc "9.2.1"
proper-lockfile "^3.0.2"
resolve-from "^5.0.0"
sanitize-filename "^1.6.1"
@ -10178,8 +10179,8 @@ detox@^20.1.2:
trace-event-lib "^1.3.1"
which "^1.3.1"
ws "^7.0.0"
yargs "^16.0.3"
yargs-parser "^20.2.9"
yargs "^17.0.0"
yargs-parser "^21.0.0"
yargs-unparser "^2.0.0"
diff-sequences@^25.2.6:
@ -11120,7 +11121,7 @@ execa@^2.0.3:
signal-exit "^3.0.2"
strip-final-newline "^2.0.0"
execa@^5.0.0:
execa@^5.0.0, execa@^5.1.1:
version "5.1.1"
resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd"
integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==
@ -11925,14 +11926,14 @@ fs-extra@^10.1.0:
jsonfile "^6.0.1"
universalify "^2.0.0"
fs-extra@^4.0.2:
version "4.0.3"
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-4.0.3.tgz#0d852122e5bc5beb453fb028e9c0c9bf36340c94"
integrity sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==
fs-extra@^11.0.0:
version "11.2.0"
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.2.0.tgz#e70e17dfad64232287d01929399e0ea7c86b0e5b"
integrity sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==
dependencies:
graceful-fs "^4.1.2"
jsonfile "^4.0.0"
universalify "^0.1.0"
graceful-fs "^4.2.0"
jsonfile "^6.0.1"
universalify "^2.0.0"
fs-extra@^8.1.0, fs-extra@~8.1.0:
version "8.1.0"
@ -15926,7 +15927,7 @@ node-int64@^0.4.0:
resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b"
integrity sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=
node-ipc@^9.2.1:
node-ipc@9.2.1:
version "9.2.1"
resolved "https://registry.yarnpkg.com/node-ipc/-/node-ipc-9.2.1.tgz#b32f66115f9d6ce841dc4ec2009d6a733f98bb6b"
integrity sha512-mJzaM6O3xHf9VT8BULvJSbdVbmHUKRNOH7zDDkCrA1/T+CVjq2WVIDfLt0azZRXpgArJtl3rtmEozrbXPZ9GaQ==
@ -18363,9 +18364,9 @@ regenerator-runtime@^0.13.7:
integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==
regenerator-runtime@^0.14.0:
version "0.14.0"
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz#5e19d68eb12d486f797e15a3c6a918f7cec5eb45"
integrity sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==
version "0.14.1"
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz#356ade10263f685dda125100cd862c1db895327f"
integrity sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==
regenerator-transform@^0.14.2:
version "0.14.4"
@ -21636,7 +21637,7 @@ yargs@^15.1.0, yargs@^15.3.1:
y18n "^4.0.0"
yargs-parser "^18.1.2"
yargs@^16.0.3, yargs@^16.1.1, yargs@^16.2.0:
yargs@^16.1.1, yargs@^16.2.0:
version "16.2.0"
resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66"
integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==
@ -21649,6 +21650,19 @@ yargs@^16.0.3, yargs@^16.1.1, yargs@^16.2.0:
y18n "^5.0.5"
yargs-parser "^20.2.2"
yargs@^17.0.0, yargs@^17.5.1:
version "17.7.2"
resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269"
integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==
dependencies:
cliui "^8.0.1"
escalade "^3.1.1"
get-caller-file "^2.0.5"
require-directory "^2.1.1"
string-width "^4.2.3"
y18n "^5.0.5"
yargs-parser "^21.1.1"
yargs@^17.3.1:
version "17.5.1"
resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.5.1.tgz#e109900cab6fcb7fd44b1d8249166feb0b36e58e"
@ -21662,19 +21676,6 @@ yargs@^17.3.1:
y18n "^5.0.5"
yargs-parser "^21.0.0"
yargs@^17.5.1:
version "17.7.2"
resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269"
integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==
dependencies:
cliui "^8.0.1"
escalade "^3.1.1"
get-caller-file "^2.0.5"
require-directory "^2.1.1"
string-width "^4.2.3"
y18n "^5.0.5"
yargs-parser "^21.1.1"
yn@3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50"