From 0b33ea4d252ab22fdd729daf5be15f52fea35c3a Mon Sep 17 00:00:00 2001 From: Lizzi Lindboe Date: Wed, 28 Aug 2024 11:49:50 -0700 Subject: [PATCH] master->v10 merge up (#2760) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: Add a contributing home page (#2718 by @lindboe) [skip ci] * Add a contributing home page This entry point is intended for quick instruction on how to accomplish development tasks, and then links out to deeper guides on contributing from there. Not sure why I had to add that full path to _category_.json when that wasn't there before, but this was the only way to make it work locally with ir-docs * Link to contributing docs from README * Shorter path Earlier test failed because IDs are case-sensitive and the casing on the article didn't match Tour-of-Ignite --------- Co-authored-by: Frank Calise * feat(doc): add repo URL for ir-docs (#2734) * chore(release): 9.8.0 [skip ci] # [9.8.0](https://github.com/infinitered/ignite/compare/v9.7.2...v9.8.0) (2024-08-09) ### Features * **doc:** add repo URL for ir-docs ([#2734](https://github.com/infinitered/ignite/issues/2734)) ([4f59af8](https://github.com/infinitered/ignite/commit/4f59af8d79b6b0a36b85e0a95e4d19414423d4a9)) * Remove demo patches along with dependencies (#2736) * Add logic to remove patches for any demo dependencies that are also removed * Add lint improvement --------- Co-authored-by: Felipe Peña * docs: add component screenshots (#2739 by @jmejiamu) Co-authored-by: Frank Calise * fix(boilerplate): remove GestureHandlerRootView (#2738 by @frankcalise) [skip ci] * fix: support component testing (#2740 by @lindboe) There were some issues with out-of-date config when setting up component testing for the first time. This PR removes old configuration that's no longer necessary, and adds tests to ensure component testing continues to work. * chore(release): 9.8.1 [skip ci] ## [9.8.1](https://github.com/infinitered/ignite/compare/v9.8.0...v9.8.1) (2024-08-13) ### Bug Fixes * support component testing ([#2740](https://github.com/infinitered/ignite/issues/2740) by [@lindboe](https://github.com/lindboe)) ([c7edf45](https://github.com/infinitered/ignite/commit/c7edf450a06c440039a8abe8b900e55d19fd4eee)) * **boilerplate:** remove GestureHandlerRootView ([#2738](https://github.com/infinitered/ignite/issues/2738) by [@frankcalise](https://github.com/frankcalise)) ([437e755](https://github.com/infinitered/ignite/commit/437e755827c26919e68f3421ba720845ff2e23b3)) * docs: add Robin's CR 2024 talk link (#2741 by @frankcalise) Co-authored-by: Jamon Holmgren [skip ci] * fix(cli): address outdated pkg vulnerabilities (#2733 by @frankcalise) [skip ci] * fix(cli): address outdated pkg vulnerabilities * fix(cli): fix sharp * fix(boilerplate): upgrade i18n-js (#2735 by @lindboe and @frankcalise) * fix(boilerplate): upgrade i18n-js * fix(boilerplate): i18n jest mock * docs(intl): update adding languages with doc link * docs(fix): RTL removal steps * chore(release): 9.8.2 [skip ci] ## [9.8.2](https://github.com/infinitered/ignite/compare/v9.8.1...v9.8.2) (2024-08-13) ### Bug Fixes * **boilerplate:** upgrade i18n-js ([#2735](https://github.com/infinitered/ignite/issues/2735) by [@lindboe](https://github.com/lindboe) and [@frankcalise](https://github.com/frankcalise)) ([a171eae](https://github.com/infinitered/ignite/commit/a171eaec0034d868fd78ac8f2fc55c5c540b3351)) * **cli:** address outdated pkg vulnerabilities ([#2733](https://github.com/infinitered/ignite/issues/2733) by [@frankcalise](https://github.com/frankcalise)) ([c06d493](https://github.com/infinitered/ignite/commit/c06d493541d6e7c82f824a231aaaef59aac13a9a)) * feat(boilerplate): Make texts on demo components based on i18n (#2721 by @kei95) * chore(release): 9.9.0 [skip ci] # [9.9.0](https://github.com/infinitered/ignite/compare/v9.8.2...v9.9.0) (2024-08-20) ### Features * **boilerplate:** Make texts on demo components based on i18n ([#2721](https://github.com/infinitered/ignite/issues/2721) by [@kei95](https://github.com/kei95)) ([9695670](https://github.com/infinitered/ignite/commit/96956707e9dcdf23cfcf256d9d80109bdbd853e8)) * docs(boilerplate): Punjabi is not RTL 😅 (#2751 by @jamonholmgren) Via: https://twitter.com/IndicGames/status/1825949273147716072 * docs: Fixed documentation link in Button (#2755 by @softwarebyze) * Missed merge conflict * Update snapshot for v10 format * Remove vim swap file * Some prettier fixes --------- Co-authored-by: Frank Calise Co-authored-by: Leon Kim Co-authored-by: semantic-release-bot Co-authored-by: Felipe Peña Co-authored-by: Jose Mejia Munoz Co-authored-by: Kei Yamashita <44686790+kei95@users.noreply.github.com> Co-authored-by: Jamon Holmgren Co-authored-by: Zachary Ebenfeld --- README.md | 47 +- boilerplate/app/app.tsx | 16 +- boilerplate/app/components/Button.tsx | 2 +- boilerplate/app/components/ListView.tsx | 2 +- boilerplate/app/components/Text.test.tsx | 16 + boilerplate/app/i18n/ar.ts | 3 + boilerplate/app/i18n/demo-ar.ts | 464 +++++++++++++++++ boilerplate/app/i18n/demo-en.ts | 462 +++++++++++++++++ boilerplate/app/i18n/demo-fr.ts | 471 ++++++++++++++++++ boilerplate/app/i18n/demo-jp.ts | 464 +++++++++++++++++ boilerplate/app/i18n/demo-ko.ts | 457 +++++++++++++++++ boilerplate/app/i18n/en.ts | 4 + boilerplate/app/i18n/fr.ts | 3 + boilerplate/app/i18n/i18n.ts | 15 +- boilerplate/app/i18n/jp.ts | 11 +- boilerplate/app/i18n/ko.ts | 3 + boilerplate/app/i18n/translate.ts | 6 +- .../DemoShowroomScreen/DemoShowroomScreen.tsx | 8 +- .../DemoShowroomScreen/DemoUseCase.tsx | 10 +- .../demos/DemoAutoImage.tsx | 18 +- .../DemoShowroomScreen/demos/DemoButton.tsx | 61 ++- .../DemoShowroomScreen/demos/DemoCard.tsx | 77 +-- .../demos/DemoEmptyState.tsx | 26 +- .../DemoShowroomScreen/demos/DemoHeader.tsx | 72 ++- .../DemoShowroomScreen/demos/DemoIcon.tsx | 25 +- .../DemoShowroomScreen/demos/DemoListItem.tsx | 80 +-- .../DemoShowroomScreen/demos/DemoText.tsx | 100 ++-- .../demos/DemoTextField.tsx | 99 ++-- .../DemoShowroomScreen/demos/DemoToggle.tsx | 69 +-- boilerplate/app/utils/formatDate.ts | 5 +- .../app/utils/gestureHandler.native.ts | 3 + boilerplate/app/utils/gestureHandler.ts | 2 + boilerplate/jest.config.js | 29 -- boilerplate/package.json | 5 +- boilerplate/test/setup.ts | 10 + docs/README.md | 49 +- docs/_category_.json | 1 + docs/boilerplate/app/components/AutoImage.md | 2 + docs/boilerplate/app/components/Button.md | 2 + docs/boilerplate/app/components/Card.md | 6 + docs/boilerplate/app/components/EmptyState.md | 1 + docs/boilerplate/app/components/Header.md | 2 + docs/boilerplate/app/components/Icon.md | 2 + docs/boilerplate/app/components/ListItem.md | 2 + docs/boilerplate/app/components/Text.md | 2 + docs/boilerplate/app/components/TextField.md | 2 + .../app/components/_toggle_props.mdx | 2 + .../app/i18n/Internationalization.md | 19 +- docs/contributing/Contributing-To-Ignite.md | 29 ++ docs/contributing/Tour-of-Ignite.md | 6 +- docs/contributing/_category_.json | 2 +- package.json | 9 +- src/commands/new.ts | 5 +- src/tools/demo.ts | 23 + .../ignite-remove-demo.test.ts.snap | 10 + test/vanilla/ignite-new.test.ts | 45 ++ yarn.lock | 358 +++++-------- 57 files changed, 3148 insertions(+), 576 deletions(-) create mode 100644 boilerplate/app/components/Text.test.tsx create mode 100644 boilerplate/app/i18n/demo-ar.ts create mode 100644 boilerplate/app/i18n/demo-en.ts create mode 100644 boilerplate/app/i18n/demo-fr.ts create mode 100644 boilerplate/app/i18n/demo-jp.ts create mode 100644 boilerplate/app/i18n/demo-ko.ts create mode 100644 boilerplate/app/utils/gestureHandler.native.ts create mode 100644 boilerplate/app/utils/gestureHandler.ts create mode 100644 docs/contributing/Contributing-To-Ignite.md diff --git a/README.md b/README.md index c89720596..cb0c8f9c5 100644 --- a/README.md +++ b/README.md @@ -15,9 +15,46 @@ This is the React Native boilerplate that the [Infinite Red](https://infinite.re ## Intro Videos -- Check out the [Getting Started with Ignite](https://www.youtube.com/watch?v=KOSvDlFyg20) video for a 13 minute overview! -- Jamon's Code Quest on [Ignite 9](https://www.youtube.com/watch?v=QmkMsUYrTlk) -- Jamon's Code Quest on [MobX-State-Tree](https://www.youtube.com/watch?v=n_VjjJxyd8Q) +Here are a few videos / talks that introduce Ignite and show off some of its features. Check them out! + + + + + + + + + + +
+
+ + Getting Started with Ignite
+
Getting Started with Ignite
+
+
+
+
+ + Sweetening React Native Development With Ignite
+
Ignite talk at Chain React 2024 - Robin Heinze
+
+
+
+
+ + Jamon's Code Quest on Ignite 9
+
What's new in Ignite 9
+
+
+
+
+ + Jamon's Code Quest on MobX-State-Tree
+
Intro to MobX-State-Tree
+
+
+
## [Full Documentation](https://github.com/infinitered/ignite/blob/master/docs/README.md) @@ -89,6 +126,10 @@ If you run into problems, first search the issues and discussions in this reposi If you still need help after reaching out to the proper channels, feel free to open a new GitHub issue via `npx ignite-cli issue "Unable to Ignite new app"` (as an example). This will help start writing your issue with the correct diagnostic information included. +## Contributing to Ignite + +Want to contribute to Ignite? Check out [the contributing guide](./docs/contributing/Contributing-To-Ignite.md) for more info on how to work with the codebase. + ## Need Inspiration? If you need battle-tested solutions from Infinite Red experts on everything from Accessibility, to CI/CD configuration, head to [Ignite Cookbook](https://ignitecookbook.com) for code snippets from our team and the community! diff --git a/boilerplate/app/app.tsx b/boilerplate/app/app.tsx index b58dc8e64..9a193a666 100644 --- a/boilerplate/app/app.tsx +++ b/boilerplate/app/app.tsx @@ -16,6 +16,7 @@ if (__DEV__) { // If you turn it off in metro.config.js, you'll have to manually import it. require("./devtools/ReactotronConfig.ts") } +import "./utils/gestureHandler" import "./i18n" import "./utils/ignoreWarnings" import { useFonts } from "expo-font" @@ -26,9 +27,8 @@ import { useInitialRootStore } from "./models" // @mst remove-current-line import { AppNavigator, useNavigationPersistence } from "./navigators" import { ErrorBoundary } from "./screens/ErrorScreen/ErrorBoundary" import * as storage from "./utils/storage" -import { $styles, customFontsToLoad } from "./theme" +import { customFontsToLoad } from "./theme" import Config from "./config" -import { GestureHandlerRootView } from "react-native-gesture-handler" export const NAVIGATION_PERSISTENCE_KEY = "NAVIGATION_STATE" @@ -106,13 +106,11 @@ function App(props: AppProps) { return ( - - - + ) diff --git a/boilerplate/app/components/Button.tsx b/boilerplate/app/components/Button.tsx index 16ce93144..b561b9d88 100644 --- a/boilerplate/app/components/Button.tsx +++ b/boilerplate/app/components/Button.tsx @@ -86,7 +86,7 @@ export interface ButtonProps extends PressableProps { /** * A component that allows users to take actions and make choices. * Wraps the Text component with a Pressable component. - * @see [Documentation and Examples]{@link https://docs.infinite.red/ignite-cli/boilerplate/components/Button/} + * @see [Documentation and Examples]{@link https://docs.infinite.red/ignite-cli/boilerplate/app/components/Button/} * @param {ButtonProps} props - The props for the `Button` component. * @returns {JSX.Element} The rendered `Button` component. * @example diff --git a/boilerplate/app/components/ListView.tsx b/boilerplate/app/components/ListView.tsx index ef3406a01..5840b28f0 100644 --- a/boilerplate/app/components/ListView.tsx +++ b/boilerplate/app/components/ListView.tsx @@ -10,7 +10,7 @@ export type ListViewProps = PropsWithoutRef> /** * This is a Higher Order Component meant to ease the pain of using @shopify/flash-list * when there is a chance that a user would have their device language set to an - * RTL language like Arabic or Punjabi. This component will use react-native's + * RTL language like Arabic or Persian. This component will use react-native's * FlatList if the user's language is RTL or FlashList if the user's language is LTR. * * Because FlashList's props are a superset of FlatList's, you must pass estimatedItemSize diff --git a/boilerplate/app/components/Text.test.tsx b/boilerplate/app/components/Text.test.tsx new file mode 100644 index 000000000..7368b7b5f --- /dev/null +++ b/boilerplate/app/components/Text.test.tsx @@ -0,0 +1,16 @@ +import { render } from "@testing-library/react-native" +import React from "react" + +import { Text } from "./Text" + +/* This is an example component test using react-native-testing-library. For more + * information on how to write your own, see the documentation here: + * https://callstack.github.io/react-native-testing-library/ */ +const testText = "Test string" + +describe("Text", () => { + it("should render the component", () => { + const { getByText } = render() + expect(getByText(testText)).toBeDefined() + }) +}) diff --git a/boilerplate/app/i18n/ar.ts b/boilerplate/app/i18n/ar.ts index 7a9126abb..9ba002f5f 100644 --- a/boilerplate/app/i18n/ar.ts +++ b/boilerplate/app/i18n/ar.ts @@ -1,3 +1,4 @@ +import demoAr from "./demo-ar" import { Translations } from "./en" const ar: Translations = { @@ -117,6 +118,8 @@ const ar: Translations = { "لم تتم اضافة اي مفضلات حتى الان. اضغط على القلب في إحدى الحلقات لإضافته الى المفضلة.", }, }, + // @demo remove-block-start + ...demoAr, // @demo remove-block-end } diff --git a/boilerplate/app/i18n/demo-ar.ts b/boilerplate/app/i18n/demo-ar.ts new file mode 100644 index 000000000..408dcc540 --- /dev/null +++ b/boilerplate/app/i18n/demo-ar.ts @@ -0,0 +1,464 @@ +import { DemoTranslations } from "./demo-en" + +export const demoAr: DemoTranslations = { + demoIcon: { + description: + "مكون لعرض أيقونة مسجلة.يتم تغليفه في يتم توفير 'OnPress'، وإلا يتم توفير if `onPress` is provided, otherwise a .", + useCase: { + icons: { + name: "Icons", + description: "List of icons registered inside the component.", + }, + size: { + name: "Size", + description: "There's a size prop.", + }, + color: { + name: "Color", + description: "There's a color prop.", + }, + styling: { + name: "Styling", + description: "The component can be styled easily.", + }, + }, + }, + demoTextField: { + description: "TextField component allows for the entering and editing of text.", + useCase: { + statuses: { + name: "Statuses", + description: + "There is a status prop - similar to `preset` in other components, but affects component functionality as well.", + noStatus: { + label: "No Status", + helper: "This is the default status", + placeholder: "Text goes here", + }, + error: { + label: "Error Status", + helper: "Status to use when there is an error", + placeholder: "Text goes here", + }, + disabled: { + label: "Disabled Status", + helper: "Disables the editability and mutes text", + placeholder: "Text goes here", + }, + }, + passingContent: { + name: "Passing Content", + description: "There are a few different ways to pass content.", + viaLabel: { + labelTx: "Via `label` prop", + helper: "Via `helper` prop", + placeholder: "Via `placeholder` prop", + }, + rightAccessory: { + label: "RightAccessory", + helper: "This prop takes a function that returns a React element.", + }, + leftAccessory: { + label: "LeftAccessory", + helper: "This prop takes a function that returns a React element.", + }, + supportsMultiline: { + label: "Supports Multiline", + helper: "Enables a taller input for multiline text.", + }, + }, + styling: { + name: "Styling", + description: "The component can be styled easily.", + styleInput: { + label: "Style Input", + helper: "Via `style` prop", + }, + styleInputWrapper: { + label: "Style Input Wrapper", + helper: "Via `inputWrapperStyle` prop", + }, + styleContainer: { + label: "Style Container", + helper: "Via `containerStyle` prop", + }, + styleLabel: { + label: "Style Label & Helper", + helper: "Via `LabelTextProps` & `HelperTextProps` style prop", + }, + styleAccessories: { + label: "Style Accessories", + helper: "Via `RightAccessory` & `LeftAccessory` style prop", + }, + }, + }, + }, + demoToggle: { + description: + "Renders a boolean input. This is a controlled component that requires an onValueChange callback that updates the value prop in order for the component to reflect user actions. If the value prop is not updated, the component will continue to render the supplied value prop instead of the expected result of any user actions.", + useCase: { + variants: { + name: "Variants", + description: + "The component supports a few different variants. If heavy customization of a specific variant is needed, it can be easily refactored. The default is `checkbox`.", + checkbox: { + label: "`checkbox` variant", + helper: "This can be used for a single on/off input.", + }, + radio: { + label: "`radio` variant", + helper: "Use this when you have multiple options.", + }, + switch: { + label: "`switch` variant", + helper: "A more prominent on/off input. Has better accessibility support.", + }, + }, + statuses: { + name: "Statuses", + description: + "There is a status prop - similar to `preset` in other components, but affects component functionality as well.", + noStatus: "No status - this is the default", + errorStatus: "Error status - use when there is an error", + disabledStatus: "Disabled status - disables the editability and mutes input", + }, + passingContent: { + name: "Passing Content", + description: "There are a few different ways to pass content.", + useCase: { + checkBox: { + label: "Via `labelTx` prop", + helper: "Via `helperTx` prop.", + }, + checkBoxMultiLine: { + helper: "Supports multiline - Nulla proident consectetur labore sunt ea labore. ", + }, + radioChangeSides: { + helper: "You can change sides - Laborum labore adipisicing in eu ipsum deserunt.", + }, + customCheckBox: { + label: "Pass in a custom checkbox icon.", + }, + switch: { + label: "Switches can be read as text", + helper: + "By default, this option doesn't use `Text` since depending on the font, the on/off characters might look weird. Customize as needed.", + }, + switchAid: { + label: "Or aided with an icon", + }, + }, + }, + styling: { + name: "Styling", + description: "The component can be styled easily.", + outerWrapper: "1 - style the input outer wrapper", + innerWrapper: "2 - style the input inner wrapper", + inputDetail: "3 - style the input detail", + labelTx: "You can also style the labelTx", + styleContainer: "Or, style the entire container", + }, + }, + }, + demoButton: { + description: + "A component that allows users to take actions and make choices. Wraps the Text component with a Pressable component.", + useCase: { + presets: { + name: "Presets", + description: "There are a few presets that are preconfigured.", + }, + passingContent: { + name: "Passing Content", + description: "There are a few different ways to pass content.", + viaTextProps: "Via `text` Prop - Billum In", + children: "Children - Irure Reprehenderit", + rightAccessory: "RightAccessory - Duis Quis", + leftAccessory: "LeftAccessory - Duis Proident", + nestedChildren: "Nested children - proident veniam.", + nestedChildren2: "Ullamco cupidatat officia exercitation velit non ullamco nisi..", + nestedChildren3: "Occaecat aliqua irure proident veniam.", + multiLine: + "Multiline - consequat veniam veniam reprehenderit. Fugiat id nisi quis duis sunt proident mollit dolor mollit adipisicing proident deserunt.", + }, + styling: { + name: "Styling", + description: "The component can be styled easily.", + styleContainer: "Style Container - Exercitation", + styleText: "Style Text - Ea Anim", + styleAccessories: "Style Accessories - enim ea id fugiat anim ad.", + pressedState: "Style Pressed State - fugiat anim", + }, + disabling: { + name: "Disabling", + description: + "The component can be disabled, and styled based on that. Press behavior will be disabled.", + standard: "Disabled - standard", + filled: "Disabled - filled", + reversed: "Disabled - reversed", + accessory: "Disabled accessory style", + textStyle: "Disabled text style", + }, + }, + }, + demoListItem: { + description: "A styled row component that can be used in FlatList, SectionList, or by itself.", + useCase: { + height: { + name: "Height", + description: "The row can be different heights.", + defaultHeight: "Default height (56px)", + customHeight: "Custom height via `height` prop", + textHeight: + "Height determined by text content - Reprehenderit incididunt deserunt do do ea labore.", + longText: + "Limit long text to one line - Reprehenderit incididunt deserunt do do ea labore.", + }, + separators: { + name: "Separators", + description: "The separator / divider is preconfigured and optional.", + topSeparator: "Only top separator", + topAndBottomSeparator: "Top and bottom separators", + bottomSeparator: "Only bottom separator", + }, + icons: { + name: "Icons", + description: "You can customize the icons on the left or right.", + leftIcon: "Left icon", + rightIcon: "Right Icon", + leftRightIcons: "Left & Right Icons", + }, + customLeftRight: { + name: "Custom Left/Right Components", + description: "If you need a custom left/right component, you can pass it in.", + customLeft: "Custom left component", + customRight: "Custom right component", + }, + passingContent: { + name: "Passing Content", + description: "There are a few different ways to pass content.", + text: "Via `text` prop - reprehenderit sint", + children: "Children - mostrud mollit", + nestedChildren1: "Nested children - proident veniam.", + nestedChildren2: "Ullamco cupidatat officia exercitation velit non ullamco nisi..", + }, + listIntegration: { + name: "Integrating w/ FlatList & FlashList", + description: "The component can be easily integrated with your favorite list interface.", + }, + styling: { + name: "Styling", + description: "The component can be styled easily.", + styledText: "Styled Text", + styledContainer: "Styled Container (separators)", + tintedIcons: "Tinted Icons", + }, + }, + }, + demoCard: { + description: + "Cards are useful for displaying related information in a contained way. If a ListItem displays content horizontally, a Card can be used to display content vertically.", + useCase: { + presets: { + name: "Presets", + description: "There are a few presets that are preconfigured.", + default: { + heading: "Default Preset (default)", + content: "Incididunt magna ut aliquip consectetur mollit dolor.", + footer: "Consectetur nulla non aliquip velit.", + }, + reversed: { + heading: "Reversed Preset", + content: "Reprehenderit occaecat proident amet id laboris.", + footer: "Consectetur tempor ea non labore anim .", + }, + }, + verticalAlignment: { + name: "Vertical Alignment", + description: + "Depending on what's required, the card comes preconfigured with different alignment strategies.", + top: { + heading: "Top (default)", + content: "All content is automatically aligned to the top.", + footer: "Even the footer", + }, + center: { + heading: "Center", + content: "Content is centered relative to the card's height.", + footer: "Me too!", + }, + spaceBetween: { + heading: "Space Between", + content: "All content is spaced out evenly.", + footer: "I am where I want to be.", + }, + reversed: { + heading: "Force Footer Bottom", + content: "This pushes the footer where it belongs.", + footer: "I'm so lonely down here.", + }, + }, + passingContent: { + name: "Passing Content", + description: "There are a few different ways to pass content.", + heading: "Via `heading` Prop", + content: "Via `content` Prop", + footer: "I'm so lonely down here.", + }, + customComponent: { + name: "Custom Components", + description: + "Any of the preconfigured components can be replaced with your own. You can also add additional ones.", + rightComponent: "RightComponent", + leftComponent: "LeftComponent", + }, + style: { + name: "Styling", + description: "The component can be styled easily.", + heading: "Style the Heading", + content: "Style the Content", + footer: "Style the Footer", + }, + }, + }, + demoAutoImage: { + description: "An Image component that automatically sizes a remote or data-uri image.", + useCase: { + remoteUri: { name: "Remote URI" }, + base64Uri: { name: "Base64 URI" }, + scaledToFitDimensions: { + name: "Scaled to Fit Dimensions", + description: + "Providing a `maxWidth` and/or `maxHeight` props, the image will automatically scale while retaining it's aspect ratio. How is this different from `resizeMode: 'contain'`? Firstly, you can specify only one side's size (not both). Secondly, the image will scale to fit the desired dimensions instead of just being contained within its image-container.", + heightAuto: "width: 60 / height: auto", + widthAuto: "width: auto / height: 32", + bothManual: "width: 60 / height: 60", + }, + }, + }, + demoText: { + description: + "For your text displaying needs. This component is a HOC over the built-in React Native one.", + useCase: { + presets: { + name: "Presets", + description: "There are a few presets that are preconfigured.", + default: + "default preset - Cillum eu laboris in labore. Excepteur mollit tempor reprehenderit fugiat elit et eu consequat laborum.", + bold: "bold preset - Tempor et ullamco cupidatat in officia. Nulla ea duis elit id sunt ipsum cillum duis deserunt nostrud ut nostrud id.", + subheading: "subheading preset - In Cupidatat Cillum.", + heading: "heading preset - Voluptate Adipis.", + }, + sizes: { + name: "Sizes", + description: "There's a size prop.", + xs: "xs - Ea ipsum est ea ex sunt.", + sm: "sm - Lorem sunt adipisicin.", + md: "md - Consequat id do lorem.", + lg: "lg - Nostrud ipsum ea.", + xl: "xl - Eiusmod ex excepteur.", + xxl: "xxl - Cillum eu laboris.", + }, + weights: { + name: "Weights", + description: "There's a weight prop.", + light: + "light - Nulla magna incididunt excepteur est occaecat duis culpa dolore cupidatat enim et.", + normal: + "normal - Magna incididunt dolor ut veniam veniam laboris aliqua velit ea incididunt.", + medium: "medium - Non duis laborum quis laboris occaecat culpa cillum.", + semibold: "semiBold - Exercitation magna nostrud pariatur laborum occaecat aliqua.", + bold: "bold - Eiusmod ullamco magna exercitation est excepteur.", + }, + passingContent: { + name: "Passing Content", + description: "There are a few different ways to pass content.", + viaText: + "via `text` prop - Billum in aute fugiat proident nisi pariatur est. Cupidatat anim cillum eiusmod ad. Officia eu magna aliquip labore dolore consequat.", + viaTx: "via `tx` prop -", + children: "children - Aliqua velit irure reprehenderit eu qui amet veniam consectetur.", + nestedChildren: "Nested children -", + nestedChildren2: "Occaecat aliqua irure proident veniam.", + nestedChildren3: "Ullamco cupidatat officia exercitation velit non ullamco nisi..", + nestedChildren4: "Occaecat aliqua irure proident veniam.", + }, + styling: { + name: "Styling", + description: "The component can be styled easily.", + text: "Consequat ullamco veniam velit mollit proident excepteur aliquip id culpa ipsum velit sint nostrud.", + text2: + "Eiusmod occaecat laboris eu ex veniam ipsum adipisicing consectetur. Magna ullamco adipisicing tempor adipisicing.", + text3: + "Eiusmod occaecat laboris eu ex veniam ipsum adipisicing consectetur. Magna ullamco adipisicing tempor adipisicing.", + }, + }, + }, + demoHeader: { + description: + "Component that appears on many screens. Will hold navigation buttons and screen title.", + useCase: { + actionIcons: { + name: "Action Icons", + description: "You can easily pass in icons to the left or right action components.", + leftIconTitle: "Left Icon", + rightIconTitle: "Right Icon", + bothIconsTitle: "Both Icons", + }, + actionText: { + name: "Action Text", + description: "You can easily pass in text to the left or right action components.", + leftTxTitle: "Via `leftTx`", + rightTextTitle: "Via `rightText`", + }, + customActionComponents: { + name: "Custom Action Components", + description: + "If the icon or text options are not enough, you can pass in your own custom action component.", + customLeftActionTitle: "Custom Left Action", + }, + titleModes: { + name: "Title Modes", + description: + "Title can be forced to stay in center (default) but may be cut off if it's too long. You can optionally make it adjust to the action buttons.", + centeredTitle: "Centered Title", + flexTitle: "Flex Title", + }, + styling: { + name: "Styling", + description: "The component can be styled easily.", + styledTitle: "Styled Title", + styledWrapperTitle: "Styled Wrapper", + tintedIconsTitle: "Tinted Icons", + }, + }, + }, + demoEmptyState: { + description: + "A component to use when there is no data to display. It can be utilized to direct the user what to do next", + useCase: { + presets: { + name: "Presets", + description: + "You can create different text/image sets. One is predefined called `generic`. Note, there's no default in case you want to have a completely custom EmptyState.", + }, + passingContent: { + name: "Passing Content", + description: "There are a few different ways to pass content.", + customizeImageHeading: "Customize Image", + customizeImageContent: "You can pass in any image source.", + viaHeadingProp: "Via `heading` Prop", + viaContentProp: "Via `content` prop.", + viaButtonProp: "Via `button` Prop", + }, + styling: { + name: "Styling", + description: "The component can be styled easily.", + }, + }, + }, +} + +export default demoEn +export type DemoTranslations = typeof demoEn + +// @demo remove-file diff --git a/boilerplate/app/i18n/demo-fr.ts b/boilerplate/app/i18n/demo-fr.ts new file mode 100644 index 000000000..dc07cb17e --- /dev/null +++ b/boilerplate/app/i18n/demo-fr.ts @@ -0,0 +1,471 @@ +import { DemoTranslations } from "./demo-en" + +export const demoFr: DemoTranslations = { + demoIcon: { + description: + "Un composant pour faire le rendu d’une icône enregistrée. Il est enveloppé dans un si `onPress` est fourni, sinon dans une .", + useCase: { + icons: { + name: "Icônes", + description: "Liste des icônes enregistrées dans le composant.", + }, + size: { + name: "Taille", + description: "Il y a une prop de taille.", + }, + color: { + name: "Couleur", + description: "Il y a une prop de couleur.", + }, + styling: { + name: "Style", + description: "Le composant peut être facilement stylisé.", + }, + }, + }, + demoTextField: { + description: "Le composant permet la saisie et l'édition de texte.", + useCase: { + statuses: { + name: "Statuts", + description: + "Il y a une prop de statut - similaire à `preset` dans d'autres composants, mais affecte également la fonctionnalité du composant.", + noStatus: { + label: "Pas de statut", + helper: "C'est le statut par défaut", + placeholder: "Le texte passe par là", + }, + error: { + label: "Statut d'erreur", + helper: "Statut à utiliser en cas d’erreur", + placeholder: "Le texte passe par ici", + }, + disabled: { + label: "Statut désactivé", + helper: "Désactive l’édition et atténue le texte", + placeholder: "Le texte repasse par là", + }, + }, + passingContent: { + name: "Transfert de contenu", + description: "Il y a plusieurs façons de transmettre du contenu.", + viaLabel: { + labelTx: "Via la prop `label`", + helper: "Via la prop `helper`", + placeholder: "Via la prop `placeholder`", + }, + rightAccessory: { + label: "Accessoire droit", + helper: "Cette prop demande une fonction qui retourne un élément React.", + }, + leftAccessory: { + label: "Accessoire gauche", + helper: "Cette prop demande une fonction qui retourne un élément React.", + }, + supportsMultiline: { + label: "Supporte le multiligne", + helper: "Permet une saisie plus longue pour le texte multiligne.", + }, + }, + styling: { + name: "Style", + description: "Le composant peut être facilement stylisé.", + styleInput: { + label: "Style de saisie", + helper: "Via la prop `style`", + }, + styleInputWrapper: { + label: "Style du wrapper de saisie", + helper: "Via la prop `inputWrapperStyle`", + }, + styleContainer: { + label: "Style du conteneur", + helper: "Via la prop `containerStyle`", + }, + styleLabel: { + label: "Style du label et de l’aide", + helper: "Via les props de style `LabelTextProps` et `HelperTextProps`", + }, + styleAccessories: { + label: "Style des accessoires", + helper: "Via les props de style `RightAccessory` et `LeftAccessory`", + }, + }, + }, + }, + demoToggle: { + description: + "Fait le rendu d’un booléen. Ce composant contrôlé nécessite un callback `onValueChange` qui met à jour la prop `value` pour que le composant reflète les actions de l'utilisateur. Si la prop `value` n'est pas mise à jour, le composant continuera à rendre la prop `value` fournie au lieu du résultat attendu des actions de l'utilisateur.", + useCase: { + variants: { + name: "Variantes", + description: + "Le composant supporte différentes variantes. Si une personnalisation poussée d'une variante spécifique est nécessaire, elle peut être facilement refactorisée. La valeur par défaut est `checkbox`.", + checkbox: { + label: "Variante `checkbox`", + helper: "Peut être utilisée pour une seule valeure on/off.", + }, + radio: { + label: "Variante `radio`", + helper: "Utilisez ceci quand vous avez plusieurs options.", + }, + switch: { + label: "Variante `switch`", + helper: + "Une entrée on/off plus proéminente. Possède un meilleur support d’accessibilité.", + }, + }, + statuses: { + name: "Statuts", + description: + "Il y a une prop de statut - similaire à `preset` dans d'autres composants, mais affecte également la fonctionnalité du composant.", + noStatus: "Pas de statut - c'est le défaut", + errorStatus: "Statut d’erreur - à utiliser quand il y a une erreur", + disabledStatus: "Statut désactivé - désactive l’édition et atténue le style", + }, + passingContent: { + name: "Transfert de contenu", + description: "Il y a plusieurs façons de transmettre du contenu.", + useCase: { + checkBox: { + label: "Via la prop `labelTx`", + helper: "Via la prop `helperTx`.", + }, + checkBoxMultiLine: { + helper: "Supporte le multiligne - Nulla proident consectetur labore sunt ea labore. ", + }, + radioChangeSides: { + helper: + "Vous pouvez changer de côté - Laborum labore adipisicing in eu ipsum deserunt.", + }, + customCheckBox: { + label: "Passez une icône de case à cocher personnalisée.", + }, + switch: { + label: "Les interrupteurs peuvent être lus comme du texte", + helper: + "Par défaut, cette option n’utilise pas `Text` car selon la police, les caractères on/off pourraient paraître étranges. Personnalisez selon vos besoins.", + }, + switchAid: { + label: "Ou aidé d’une icône", + }, + }, + }, + styling: { + name: "Style", + description: "Le composant peut être facilement stylisé.", + outerWrapper: "1 - styliser le wrapper extérieur de l’entrée", + innerWrapper: "2 - styliser le wrapper intérieur de l’entrée", + inputDetail: "3 - styliser le détail de l’entrée", + labelTx: "Vous pouvez aussi styliser le labelTx", + styleContainer: "Ou, styliser le conteneur entier", + }, + }, + }, + demoButton: { + description: + "Un composant qui permet aux utilisateurs d’effectuer des actions et de faire des choix. Enveloppe le composant Text avec un composant Pressable.", + useCase: { + presets: { + name: "Préréglages", + description: "Il y a quelques préréglages préconfigurés.", + }, + passingContent: { + name: "Transfert de contenu", + description: "Il y a plusieurs façons de transmettre du contenu.", + viaTextProps: "Via la prop `text` - Billum In", + children: "Enfants - Irure Reprehenderit", + rightAccessory: "Accessoire droit - Duis Quis", + leftAccessory: "Accessoire gauche - Duis Proident", + nestedChildren: "Enfants imbriqués - proident veniam.", + nestedChildren2: "Ullamco cupidatat officia exercitation velit non ullamco nisi..", + nestedChildren3: "Occaecat aliqua irure proident veniam.", + multiLine: + "Multiligne - consequat veniam veniam reprehenderit. Fugiat id nisi quis duis sunt proident mollit dolor mollit adipisicing proident deserunt.", + }, + styling: { + name: "Style", + description: "Le composant peut être facilement stylisé.", + styleContainer: "Style du conteneur - Exercitation", + styleText: "Style du texte - Ea Anim", + styleAccessories: "Style des accessoires - enim ea id fugiat anim ad.", + pressedState: "Style de l’état pressé - fugiat anim", + }, + disabling: { + name: "Désactivation", + description: + "Le composant peut être désactivé et stylisé en conséquence. Le comportement de pression sera désactivé.", + standard: "Désactivé - standard", + filled: "Désactivé - rempli", + reversed: "Désactivé - inversé", + accessory: "Style d’accessoire désactivé", + textStyle: "Style de texte désactivé", + }, + }, + }, + demoListItem: { + description: + "Un composant de ligne stylisé qui peut être utilisé dans FlatList, SectionList, ou seul.", + useCase: { + height: { + name: "Hauteur", + description: "La ligne peut avoir différentes hauteurs.", + defaultHeight: "Hauteur par défaut (56px)", + customHeight: "Hauteur personnalisée via la prop `height`", + textHeight: + "Hauteur déterminée par le contenu du texte - Reprehenderit incididunt deserunt do do ea labore.", + longText: + "Limiter le texte long à une ligne - Reprehenderit incididunt deserunt do do ea labore.", + }, + separators: { + name: "Séparateurs", + description: "Le séparateur / diviseur est préconfiguré et optionnel.", + topSeparator: "Séparateur uniquement en haut", + topAndBottomSeparator: "Séparateurs en haut et en bas", + bottomSeparator: "Séparateur uniquement en bas", + }, + icons: { + name: "Icônes", + description: "Vous pouvez personnaliser les icônes à gauche ou à droite.", + leftIcon: "Icône gauche", + rightIcon: "Icône droite", + leftRightIcons: "Icônes gauche et droite", + }, + customLeftRight: { + name: "Composants personnalisés gauche/droite", + description: + "Si vous avez besoin d’un composant personnalisé à gauche/droite, vous pouvez le passer.", + customLeft: "Composant personnalisé à gauche", + customRight: "Composant personnalisé à droite", + }, + passingContent: { + name: "Transfert de contenu", + description: "Il y a plusieurs façons de transmettre du contenu.", + text: "Via la prop `text` - reprehenderit sint", + children: "Enfants - mostrud mollit", + nestedChildren1: "Enfants imbriqués - proident veniam.", + nestedChildren2: "Ullamco cupidatat officia exercitation velit non ullamco nisi..", + }, + listIntegration: { + name: "Intégration avec FlatList & FlashList", + description: + "Le composant peut être facilement intégré avec votre interface de liste préférée.", + }, + styling: { + name: "Style", + description: "Le composant peut être facilement stylisé.", + styledText: "Texte stylisé", + styledContainer: "Conteneur stylisé (séparateurs)", + tintedIcons: "Icônes teintées", + }, + }, + }, + demoCard: { + description: + "Les cartes sont utiles pour afficher des informations connexes de manière contenue. Si un ListItem affiche le contenu horizontalement, une Card peut être utilisée pour afficher le contenu verticalement.", + useCase: { + presets: { + name: "Préréglages", + description: "Il y a quelques préréglages préconfigurés.", + default: { + heading: "Préréglage par défaut (default)", + content: "Incididunt magna ut aliquip consectetur mollit dolor.", + footer: "Consectetur nulla non aliquip velit.", + }, + reversed: { + heading: "Préréglage inversé", + content: "Reprehenderit occaecat proident amet id laboris.", + footer: "Consectetur tempor ea non labore anim .", + }, + }, + verticalAlignment: { + name: "Alignement vertical", + description: + "Selon les besoins, la carte est préconfigurée avec différentes stratégies d’alignement.", + top: { + heading: "Haut (par défaut)", + content: "Tout le contenu est automatiquement aligné en haut.", + footer: "Même le pied de page", + }, + center: { + heading: "Centre", + content: "Le contenu est centré par rapport à la hauteur de la carte.", + footer: "Moi aussi !", + }, + spaceBetween: { + heading: "Espace entre", + content: "Tout le contenu est espacé uniformément.", + footer: "Je suis là où je veux être.", + }, + reversed: { + heading: "Forcer le pied de page en bas", + content: "Cela pousse le pied de page là où il appartient.", + footer: "Je suis si seul ici en bas.", + }, + }, + passingContent: { + name: "Transfert de contenu", + description: "Il y a plusieurs façons de transmettre du contenu.", + heading: "Via la prop `heading`", + content: "Via la prop `content`", + footer: "Je suis si seul ici en bas.", + }, + customComponent: { + name: "Composants personnalisés", + description: + "N’importe quels composants préconfigurés peuvent être remplacé par le vôtre. Vous pouvez également en ajouter d’autres.", + rightComponent: "Composant droit", + leftComponent: "Composant gauche", + }, + style: { + name: "Style", + description: "Le composant peut être facilement stylisé.", + heading: "Styliser l’en-tête", + content: "Styliser le contenu", + footer: "Styliser le pied de page", + }, + }, + }, + demoAutoImage: { + description: + "Un composant Image qui dimensionne automatiquement une image distante ou data-uri.", + useCase: { + remoteUri: { name: "URI distante" }, + base64Uri: { name: "URI Base64" }, + scaledToFitDimensions: { + name: "Mis à l’échelle pour s’adapter aux dimensions", + description: + "En fournissant les props `maxWidth` et/ou `maxHeight`, l’image se redimensionnera automatiquement à l’échelle tout en conservant son rapport d’aspect. En quoi est-ce différent de `resizeMode: 'contain'` ? Premièrement, vous pouvez spécifier la taille d'un seul côté (pas les deux). Deuxièmement, l'image s'adaptera aux dimensions souhaitées au lieu d'être simplement contenue dans son conteneur d'image.", + heightAuto: "largeur: 60 / hauteur: auto", + widthAuto: "largeur: auto / hauteur: 32", + bothManual: "largeur: 60 / hauteur: 60", + }, + }, + }, + demoText: { + description: + "Pour vos besoins d'affichage de texte. Ce composant est un HOC sur celui intégré à React Native.", + useCase: { + presets: { + name: "Préréglages", + description: "Il y a quelques réglages préconfigurés.", + default: + "préréglage par défaut - Cillum eu laboris in labore. Excepteur mollit tempor reprehenderit fugiat elit et eu consequat laborum.", + bold: "préréglage gras - Tempor et ullamco cupidatat in officia. Nulla ea duis elit id sunt ipsum cillum duis deserunt nostrud ut nostrud id.", + subheading: "préréglage sous-titre - In Cupidatat Cillum.", + heading: "préréglage titre - Voluptate Adipis.", + }, + sizes: { + name: "Tailles", + description: "Il y a une prop de taille.", + xs: "xs - Ea ipsum est ea ex sunt.", + sm: "sm - Lorem sunt adipisicin.", + md: "md - Consequat id do lorem.", + lg: "lg - Nostrud ipsum ea.", + xl: "xl - Eiusmod ex excepteur.", + xxl: "xxl - Cillum eu laboris.", + }, + weights: { + name: "Graisse", + description: "Il y a une prop de graisse.", + light: + "léger - Nulla magna incididunt excepteur est occaecat duis culpa dolore cupidatat enim et.", + normal: + "normal - Magna incididunt dolor ut veniam veniam laboris aliqua velit ea incididunt.", + medium: "moyen - Non duis laborum quis laboris occaecat culpa cillum.", + semibold: "demi-gras - Exercitation magna nostrud pariatur laborum occaecat aliqua.", + bold: "gras - Eiusmod ullamco magna exercitation est excepteur.", + }, + passingContent: { + name: "Transfert de contenu", + description: "Il y a plusieurs façons de transférer du contenu.", + viaText: + "via la prop `text` - Billum in aute fugiat proident nisi pariatur est. Cupidatat anim cillum eiusmod ad. Officia eu magna aliquip labore dolore consequat.", + viaTx: "via la prop `tx` -", + children: "enfants - Aliqua velit irure reprehenderit eu qui amet veniam consectetur.", + nestedChildren: "Enfants imbriqués -", + nestedChildren2: "Occaecat aliqua irure proident veniam.", + nestedChildren3: "Ullamco cupidatat officia exercitation velit non ullamco nisi..", + nestedChildren4: "Occaecat aliqua irure proident veniam.", + }, + styling: { + name: "Style", + description: "Le composant peut être facilement stylisé.", + text: "Consequat ullamco veniam velit mollit proident excepteur aliquip id culpa ipsum velit sint nostrud.", + text2: + "Eiusmod occaecat laboris eu ex veniam ipsum adipisicing consectetur. Magna ullamco adipisicing tempor adipisicing.", + text3: + "Eiusmod occaecat laboris eu ex veniam ipsum adipisicing consectetur. Magna ullamco adipisicing tempor adipisicing.", + }, + }, + }, + demoHeader: { + description: + "Composant qui apparaît sur de nombreux écrans. Contiendra les boutons de navigation et le titre de l’écran.", + useCase: { + actionIcons: { + name: "Icônes d’action", + description: + "Vous pouvez facilement passer des icônes aux composants d’action gauche ou droit.", + leftIconTitle: "Icône gauche", + rightIconTitle: "Icône droite", + bothIconsTitle: "Les deux icônes", + }, + actionText: { + name: "Texte d’action", + description: + "Vous pouvez facilement passer du texte aux composants d’action gauche ou droit.", + leftTxTitle: "Via `leftTx`", + rightTextTitle: "Via `rightText`", + }, + customActionComponents: { + name: "Composants d’action personnalisés", + description: + "Si les options d’icône ou de texte ne suffisent pas, vous pouvez passer votre propre composant d’action personnalisé.", + customLeftActionTitle: "Action gauche personnalisée", + }, + titleModes: { + name: "Modes de titre", + description: + "Le titre peut être forcé à rester au centre (par défaut) mais peut être coupé s’il est trop long. Vous pouvez éventuellement le faire s’ajuster aux boutons d’action.", + centeredTitle: "Titre centré", + flexTitle: "Titre flexible", + }, + styling: { + name: "Style", + description: "Le composant peut être facilement stylisé.", + styledTitle: "Titre stylisé", + styledWrapperTitle: "Wrapper stylisé", + tintedIconsTitle: "Icônes teintées", + }, + }, + }, + demoEmptyState: { + description: + "Un composant à utiliser lorsqu’il n’y a pas de données à afficher. Il peut être utilisé pour diriger l’utilisateur sur ce qu’il faut faire ensuite.", + useCase: { + presets: { + name: "Préréglages", + description: + "Vous pouvez créer différents ensembles de texte/image. Un est prédéfini appelé `generic`. Notez qu’il n’y a pas de valeur par défaut au cas où vous voudriez avoir un EmptyState complètement personnalisé.", + }, + passingContent: { + name: "Transfert de contenu", + description: "Il y a plusieurs façons de transférer du contenu.", + customizeImageHeading: "Personnaliser l’image", + customizeImageContent: "Vous pouvez passer n’importe quelle source d'image.", + viaHeadingProp: "Via la prop `heading`", + viaContentProp: "Via la prop `content`.", + viaButtonProp: "Via la prop `button`", + }, + styling: { + name: "Style", + description: "Le composant peut être facilement stylisé.", + }, + }, + }, +} + +export default demoFr + +// @demo remove-file diff --git a/boilerplate/app/i18n/demo-jp.ts b/boilerplate/app/i18n/demo-jp.ts new file mode 100644 index 000000000..350f2600b --- /dev/null +++ b/boilerplate/app/i18n/demo-jp.ts @@ -0,0 +1,464 @@ +import { DemoTranslations } from "./demo-en" + +export const demoJp: DemoTranslations = { + demoIcon: { + description: + "あらかじめ登録されたアイコンを描画するコンポーネントです。 `onPress` が提供されている場合は にラップされますが、それ以外の場合は にラップされます。", + useCase: { + icons: { + name: "アイコン", + description: "登録されたアイコンのリストです。", + }, + size: { + name: "サイズ", + description: "sizeのpropsです。", + }, + color: { + name: "カラー", + description: "colorのpropsです。", + }, + styling: { + name: "スタイリング", + description: "このコンポーネントはスタイリングの変更ができます。", + }, + }, + }, + demoTextField: { + description: "このコンポーネントはテキストの入力と編集ができます。", + useCase: { + statuses: { + name: "ステータス", + description: + "status - これは他コンポーネントの`preset`の似ていますが、これはコンポーネントの機能も変えるpropsです。", + noStatus: { + label: "ステータスなし", + helper: "デフォルトのステータスです", + placeholder: "テキストが入力されます", + }, + error: { + label: "エラーステータス", + helper: "エラーが発生した場合に使用されるステータスです", + placeholder: "ここにテキストが入力されます", + }, + disabled: { + label: "無効(disabled)ステータス", + helper: "編集不可となるステータスです", + placeholder: "ここにテキストが入力されます", + }, + }, + passingContent: { + name: "コンテントを渡す", + description: "コンテントを渡す方法はいくつかあります。", + viaLabel: { + labelTx: "`label` から", + helper: "`helper` から", + placeholder: "`placeholder` から", + }, + rightAccessory: { + label: "右側にアクセサリー", + helper: "このpropsはReact要素を返す関数をうけとります。", + }, + leftAccessory: { + label: "左側にアクセサリー", + helper: "このpropsはReact要素を返す関数をうけとります。", + }, + supportsMultiline: { + label: "複数行サポート", + helper: "複数行の入力が出来るようになります。", + }, + }, + styling: { + name: "スタイリング", + description: "このコンポーネントはスタイリングの変更ができます。", + styleInput: { + label: "インプットのスタイル", + helper: "`style`から", + }, + styleInputWrapper: { + label: "インプットラッパーのスタイル", + helper: "`inputWrapperStyle`から", + }, + styleContainer: { + label: "スタイルコンテナのスタイル", + helper: "`containerStyle`から", + }, + styleLabel: { + label: "ラベルとヘルパーのスタイル", + helper: "`LabelTextProps` & `HelperTextProps`から", + }, + styleAccessories: { + label: "アクセサリーのスタイル", + helper: "`RightAccessory` & `LeftAccessory`から", + }, + }, + }, + }, + demoToggle: { + description: + "ブーリアンの入力を表示するコンポーネントです。コンポーネントはvalueの値を使用して描画するので、onValueChangeコールバックを使って値を変更し、valueを更新する必要があります。valueの値が変更されていない場合は、描画が更新されません。", + useCase: { + variants: { + name: "バリエーション", + description: + "このコンポーネントは数種類のバリエーションをサポートしています。もしカスタマイズが必要な場合、これらのバリエーションをリファクタリングできます。デフォルトは`checkbox`です。", + checkbox: { + label: "`checkbox`バリエーション", + helper: "シンプルなon/offのインプットに使えます。", + }, + radio: { + label: "`radio`バリエーション", + helper: "数個のオプションがある場合に使えます。", + }, + switch: { + label: "`switch`バリエーション", + helper: + "代表的なon/offのインプットです。他と比べアクセシビリティのサポートが充実しています。", + }, + }, + statuses: { + name: "ステータス", + description: + "status - これは他コンポーネントの`preset`の似ていますが、これはコンポーネントの機能も変えるpropsです。", + noStatus: "ステータスなし - デフォルトです。", + errorStatus: "エラー - エラーがある際に使えるステータスです。", + disabledStatus: "無効(disabled) - 編集不可となるステータスです", + }, + passingContent: { + name: "コンテントを渡す", + description: "コンテントを渡す方法はいくつかあります。", + useCase: { + checkBox: { + label: "`labelTx`から", + helper: "`helperTx`から", + }, + checkBoxMultiLine: { + helper: "複数行サポート - Nulla proident consectetur labore sunt ea labore. ", + }, + radioChangeSides: { + helper: "左右に変更 - Laborum labore adipisicing in eu ipsum deserunt.", + }, + customCheckBox: { + label: "カスタムアイコンも渡せます", + }, + switch: { + label: "スイッチはテキストとして読むこともできます。", + helper: + "デフォルトでは、このオプションはフォントの影響を受け、見た目が見苦しくなる可能性がある為`Text`コンポーネントを使用していません。必要に応じてカスタマイズしてください。", + }, + switchAid: { + label: "または補助アイコンもつけられます", + }, + }, + }, + styling: { + name: "スタイリング", + description: "このコンポーネントはスタイリングの変更ができます。", + outerWrapper: "1 - インプットの外側のラッパー", + innerWrapper: "2 - インプットの内側のラッパー", + inputDetail: "3 - インプットのそのもの", + labelTx: "ラベルのスタイルも変更できます。", + styleContainer: "もしくは、コンポーネントのコンテナ全体をスタイルすることもできます。", + }, + }, + }, + demoButton: { + description: + "ユーザーにアクションや選択を促すコンポーネントです。`Text`コンポーネントを`Pressable`コンポーネントでラップしています。", + useCase: { + presets: { + name: "プリセット", + description: "数種類のプリセットが用意されています。", + }, + passingContent: { + name: "コンテントを渡す", + description: "コンテントを渡す方法はいくつかあります。", + viaTextProps: "`text`から - Billum In", + children: "Childrenから - Irure Reprehenderit", + rightAccessory: "RightAccessoryから - Duis Quis", + leftAccessory: "LeftAccessoryから - Duis Proident", + nestedChildren: "ネストされたchildrenから - proident veniam.", + nestedChildren2: "Ullamco cupidatat officia exercitation velit non ullamco nisi..", + nestedChildren3: "Occaecat aliqua irure proident veniam.", + multiLine: + "Multilineから - consequat veniam veniam reprehenderit. Fugiat id nisi quis duis sunt proident mollit dolor mollit adipisicing proident deserunt.", + }, + styling: { + name: "スタイリング", + description: "このコンポーネントはスタイリングの変更ができます。", + styleContainer: "コンテナのスタイル - Exercitation", + styleText: "テキストのスタイル - Ea Anim", + styleAccessories: "アクセサリーのスタイル - enim ea id fugiat anim ad.", + pressedState: "押された状態のスタイル - fugiat anim", + }, + disabling: { + name: "無効化", + description: + "このコンポーネントは無効化できます。スタイルも同時に変更され、押した際の挙動も無効化されます。", + standard: "無効化 - standard", + filled: "無効化 - filled", + reversed: "無効化 - reversed", + accessory: "無効化されたアクセサリーのスタイル", + textStyle: "無効化されたテキストのスタイル", + }, + }, + }, + demoListItem: { + description: + "スタイルを指定されたリストの行のコンポーネントです。FlatListやSectionListなどのコンポーネントを使用することもできますし、単体でも使用できます。", + useCase: { + height: { + name: "高さ", + description: "高さの指定ができます。", + defaultHeight: "デフォルトの高さ (56px)", + customHeight: "`height`を使ったカスタムの高さ", + textHeight: + "テキストによって決まった高さ - Reprehenderit incididunt deserunt do do ea labore.", + longText: "テキストを1行に制限する- Reprehenderit incididunt deserunt do do ea labore.", + }, + separators: { + name: "セパレーター", + description: "セパレーター/ディバイダーは用意されてるかつ任意です。", + topSeparator: "トップセパレーターのみ", + topAndBottomSeparator: "トップとボトムのセパレーター", + bottomSeparator: "ボトムのセパレーター", + }, + icons: { + name: "アイコン", + description: "右または左のアイコンをカスタマイズすることができます。", + leftIcon: "左のアイコン", + rightIcon: "右のアイコン", + leftRightIcons: "左右のアイコン", + }, + customLeftRight: { + name: "左右のコンポーネントのカスタマイズ", + description: "左右のコンポーネントをカスタマイズすることができます。", + customLeft: "カスタムされた左コンポーネント", + customRight: "カスタムされた右コンポーネント", + }, + passingContent: { + name: "コンテントを渡す", + description: "コンテントを渡す方法はいくつかあります。", + text: "`text`から - reprehenderit sint", + children: "Childrenから - mostrud mollit", + nestedChildren1: "ネストされたchildrenから - proident veniam.", + nestedChildren2: "Ullamco cupidatat officia exercitation velit non ullamco nisi..", + }, + listIntegration: { + name: "FlatList & FlashListに組みこむ場合", + description: + "このコンポーネントはお好みのリスト系のコンポーネントへ容易に組み込むことができます。", + }, + styling: { + name: "スタイリング", + description: "このコンポーネントはスタイリングの変更ができます。", + styledText: "スタイルされたテキスト", + styledContainer: "スタイルされたコンテナ(セパレーター)", + tintedIcons: "アイコンに色をつける", + }, + }, + }, + demoCard: { + description: + "カードは関連する情報同士をまとめるのに役立ちます。ListItemが横に情報を表示するのに使え、こちらは縦に表示するのに使えます。", + useCase: { + presets: { + name: "プリセット", + description: "数種類のプリセットが用意されています。", + default: { + heading: "デフォルトのプリセット", + content: "Incididunt magna ut aliquip consectetur mollit dolor.", + footer: "Consectetur nulla non aliquip velit.", + }, + reversed: { + heading: "リバースのプリセット", + content: "Reprehenderit occaecat proident amet id laboris.", + footer: "Consectetur tempor ea non labore anim .", + }, + }, + verticalAlignment: { + name: "縦の位置調整", + description: "カードは用意されたプリセットを使っての縦位置調整ができます。", + top: { + heading: "Top(デフォルト)", + content: "全てのコンテンツは自動的に上に配置されます。", + footer: "Footerも同じように上に配置されます。", + }, + center: { + heading: "センター", + content: "全てのコンテンツはカードの高さから見て中央に配置されます。", + footer: "Footerである私も!", + }, + spaceBetween: { + heading: "Space Between", + content: "全てのコンテンツは均等に分配されます。", + footer: "Footerの私はここが一番落ち着くね", + }, + reversed: { + heading: "Footerのみを下に配置する", + content: "その名の通り、Footerのみを下に配置することができます。", + footer: "Footerは一人で寂しい", + }, + }, + passingContent: { + name: "コンテントを渡す", + description: "コンテントを渡す方法はいくつかあります。", + heading: "`heading`から", + content: "`content`から", + footer: "`footer`から", + }, + customComponent: { + name: "カスタムコンポーネント", + description: + "全てのプリセットはカスタムコンポーネントを使って拡張/変更することができます。", + rightComponent: "右コンポーネント", + leftComponent: "左コンポーネント", + }, + style: { + name: "スタイリング", + description: "このコンポーネントはスタイリングの変更ができます。", + heading: "ヘディングのスタイル", + content: "コンテントのスタイル", + footer: "フッターのスタイル", + }, + }, + }, + demoAutoImage: { + description: "リモートまたはデータURIによって自動的にサイズを変更する画像コンポーネントです。", + useCase: { + remoteUri: { name: "リモート URI" }, + base64Uri: { name: "Base64 URI" }, + scaledToFitDimensions: { + name: "ディメンションにフィットするように拡大する", + description: + "`maxWidth` と/または `maxHeight`を指定することで、アスペクト比を維持したままサイズを変更することができます。`resizeMode: 'contain'`との違いとしては: \n1. 一方のサイズの指定でも良い(両方の指定の必要がない)。 \n2. 画像のコンテナに押し込められるのではなく、画像のディメンションを保ったまま指定したサイズに拡大、縮小を行うことができます。", + heightAuto: "width: 60 / height: auto", + widthAuto: "width: auto / height: 32", + bothManual: "width: 60 / height: 60", + }, + }, + }, + demoText: { + description: + "テキストを表示する為のコンポーネントです。これはReact NativeのTextコンポーネントを内包する高階コンポーネント(Higher Order Component)です。", + useCase: { + presets: { + name: "プリセット", + description: "数種類のプリセットが用意されています。", + default: + "デフォルトのプリセット - Cillum eu laboris in labore. Excepteur mollit tempor reprehenderit fugiat elit et eu consequat laborum.", + bold: "ボールドのプリセット - Tempor et ullamco cupidatat in officia. Nulla ea duis elit id sunt ipsum cillum duis deserunt nostrud ut nostrud id.", + subheading: "サブヘディングのプリセット - In Cupidatat Cillum.", + heading: "ヘディングのプリセット - Voluptate Adipis.", + }, + sizes: { + name: "サイズ", + description: "サイズ用のpropsです.", + xs: "xs - Ea ipsum est ea ex sunt.", + sm: "sm - Lorem sunt adipisicin.", + md: "md - Consequat id do lorem.", + lg: "lg - Nostrud ipsum ea.", + xl: "xl - Eiusmod ex excepteur.", + xxl: "xxl - Cillum eu laboris.", + }, + weights: { + name: "ウエイト", + description: "ウエイト用のpropです。", + light: + "ライト - Nulla magna incididunt excepteur est occaecat duis culpa dolore cupidatat enim et.", + normal: + "ノーマル - Magna incididunt dolor ut veniam veniam laboris aliqua velit ea incididunt.", + medium: "ミディアム - Non duis laborum quis laboris occaecat culpa cillum.", + semibold: "セミボールド - Exercitation magna nostrud pariatur laborum occaecat aliqua.", + bold: "ボールド - Eiusmod ullamco magna exercitation est excepteur.", + }, + passingContent: { + name: "コンテントを渡す", + description: "コンテントを渡す方法はいくつかあります。", + viaText: + "`text`から - Billum in aute fugiat proident nisi pariatur est. Cupidatat anim cillum eiusmod ad. Officia eu magna aliquip labore dolore consequat.", + viaTx: "`tx`から -", + children: "childrenから - Aliqua velit irure reprehenderit eu qui amet veniam consectetur.", + nestedChildren: "ネストされたchildrenから -", + nestedChildren2: "Occaecat aliqua irure proident veniam.", + nestedChildren3: "Ullamco cupidatat officia exercitation velit non ullamco nisi..", + nestedChildren4: "Occaecat aliqua irure proident veniam.", + }, + styling: { + name: "スタイリング", + description: "このコンポーネントはスタイリングの変更ができます。", + text: "Consequat ullamco veniam velit mollit proident excepteur aliquip id culpa ipsum velit sint nostrud.", + text2: + "Eiusmod occaecat laboris eu ex veniam ipsum adipisicing consectetur. Magna ullamco adipisicing tempor adipisicing.", + text3: + "Eiusmod occaecat laboris eu ex veniam ipsum adipisicing consectetur. Magna ullamco adipisicing tempor adipisicing.", + }, + }, + }, + demoHeader: { + description: + "様々なスクリーンで登場するコンポーネントです。ナビゲーションのボタンとスクリーンタイトルを含みます。", + useCase: { + actionIcons: { + name: "アクションアイコン", + description: "左右にアイコンを表示させることができます。", + leftIconTitle: "左アイコン", + rightIconTitle: "右アイコン", + bothIconsTitle: "両方のアイコン", + }, + actionText: { + name: "アクションテキスト", + description: "左右にテキストを表示させることができます。", + leftTxTitle: "`leftTx`から", + rightTextTitle: "`rightText`から", + }, + customActionComponents: { + name: "カスタムアクションコンポーネント", + description: + "アイコンまたはテキスト以外のものが必要な場合は、カスタムのアクションコンポーネントを渡すことができます。", + customLeftActionTitle: "カスタムの左アクション", + }, + titleModes: { + name: "タイトルモード", + description: + "タイトルはデフォルトで中央に配置されますが、長すぎるとカットされてしまいます。Flexを使うことでアクションボタンから自動的にポジションを調整することもできます。", + centeredTitle: "Centered Title", + flexTitle: "Flex Title", + }, + styling: { + name: "スタイリング", + description: "このコンポーネントはスタイリングの変更ができます。", + styledTitle: "スタイルされたタイトル", + styledWrapperTitle: "スタイルされたラッパー", + tintedIconsTitle: "色付けされたアイコン", + }, + }, + }, + demoEmptyState: { + description: + "表示する為のデータが存在しない場合に使えるコンポーネントです。ユーザーに取るべきアクションをお勧めする際に有用です。", + useCase: { + presets: { + name: "プリセット", + description: + "text/imageのセットを使ってカスタマイズすることができます。これは`generic`のものです。カスタマイズが必要になることを想定して、このコンポーネントにデフォルトのプリセットは存在しません。", + }, + passingContent: { + name: "コンテントを渡す", + description: "コンテントを渡す方法はいくつかあります。", + customizeImageHeading: "画像をカスタマイズ", + customizeImageContent: "画像のソースを渡すことができます。", + viaHeadingProp: "`heading`から", + viaContentProp: "`content`から", + viaButtonProp: "`button`から", + }, + styling: { + name: "スタイリング", + description: "このコンポーネントはスタイリングの変更ができます。", + }, + }, + }, +} + +export default demoJp + +// @demo remove-file diff --git a/boilerplate/app/i18n/demo-ko.ts b/boilerplate/app/i18n/demo-ko.ts new file mode 100644 index 000000000..a76d9ee0e --- /dev/null +++ b/boilerplate/app/i18n/demo-ko.ts @@ -0,0 +1,457 @@ +import { DemoTranslations } from "./demo-en" + +export const demoKo: DemoTranslations = { + demoIcon: { + description: + "등록된 아이콘을 렌더링하는 컴포넌트입니다. `onPress`가 구현되어 있으면 로, 그렇지 않으면 로 감쌉니다.", + useCase: { + icons: { + name: "아이콘", + description: "컴포넌트에 등록된 아이콘 목록입니다.", + }, + size: { + name: "크기", + description: "크기 속성이 있습니다.", + }, + color: { + name: "색상", + description: "색상 속성이 있습니다.", + }, + styling: { + name: "스타일링", + description: "컴포넌트는 쉽게 스타일링할 수 있습니다.", + }, + }, + }, + demoTextField: { + description: "TextField 컴포넌트는 텍스트 입력 및 편집을 허용합니다.", + useCase: { + statuses: { + name: "상태", + description: + "다른 컴포넌트의 `preset`과 유사한 상태 속성이 있으며, 컴포넌트의 기능에도 영향을 미칩니다.", + noStatus: { + label: "상태 없음", + helper: "이것이 기본 상태입니다", + placeholder: "텍스트가 여기에 들어갑니다", + }, + error: { + label: "오류 상태", + helper: "오류가 있을 때 사용하는 상태입니다", + placeholder: "텍스트가 여기에 들어갑니다", + }, + disabled: { + label: "비활성 상태", + helper: "편집 기능을 비활성화하고 텍스트를 표시하지 않습니다", + placeholder: "텍스트가 여기에 들어갑니다", + }, + }, + passingContent: { + name: "내용 전달", + description: "내용을 전달하는 몇 가지 방법이 있습니다.", + viaLabel: { + labelTx: "`label` 속성으로", + helper: "`helper` 속성으로", + placeholder: "`placeholder` 속성으로", + }, + rightAccessory: { + label: "오른쪽 액세서리", + helper: "이 속성은 React 요소를 반환하는 함수를 받습니다.", + }, + leftAccessory: { + label: "왼쪽 액세서리", + helper: "이 속성은 React 요소를 반환하는 함수를 받습니다.", + }, + supportsMultiline: { + label: "멀티라인 지원", + helper: "멀티라인 텍스트를 위한 더 높은 입력을 활성화합니다.", + }, + }, + styling: { + name: "스타일링", + description: "컴포넌트는 쉽게 스타일링할 수 있습니다.", + styleInput: { + label: "입력 스타일", + helper: "`style` 속성으로", + }, + styleInputWrapper: { + label: "입력 래퍼 스타일", + helper: "`inputWrapperStyle` 속성으로", + }, + styleContainer: { + label: "컨테이너 스타일", + helper: "`containerStyle` 속성으로", + }, + styleLabel: { + label: "레이블 및 헬퍼 스타일", + helper: "`LabelTextProps` 및 `HelperTextProps` 스타일 속성으로", + }, + styleAccessories: { + label: "액세서리 스타일", + helper: "`RightAccessory` 및 `LeftAccessory` 스타일 속성으로", + }, + }, + }, + }, + demoToggle: { + description: + "불리언 입력을 렌더링합니다. 사용자가 수행한 작업을 반영하기 위해 값 속성을 업데이트하는 onValueChange 콜백이 필요한 제어된 컴포넌트입니다. 값 속성이 업데이트되지 않으면, 컴포넌트는 사용자 작업의 예상 결과 대신 제공된 값 속성을 계속 렌더링합니다.", + useCase: { + variants: { + name: "변형", + description: + "이 컴포넌트는 몇 가지 변형을 지원합니다. 특정 변형을 대폭 커스터마이즈해야 하는 경우에는 쉽게 리팩토링할 수 있습니다. 기본값은 `체크박스`입니다.", + checkbox: { + label: "`체크박스` 변형", + helper: "단일 켜기/끄기 입력에 사용할 수 있습니다.", + }, + radio: { + label: "`라디오` 변형", + helper: "여러 옵션이 있는 경우 사용하십시오.", + }, + switch: { + label: "`스위치` 변형", + helper: "더 눈에 띄는 켜기/끄기 입력입니다. 접근성 지원이 더 좋습니다.", + }, + }, + statuses: { + name: "상태", + description: + "다른 컴포넌트의 `preset`과 유사한 상태 속성이 있으며, 컴포넌트의 기능에도 영향을 미칩니다.", + noStatus: "상태 없음 - 기본 상태", + errorStatus: "오류 상태 - 오류가 있을 때 사용", + disabledStatus: "비활성 상태 - 편집 기능을 비활성화하고 입력을 표시하지 않음", + }, + passingContent: { + name: "내용 전달", + description: "내용을 전달하는 몇 가지 방법이 있습니다.", + useCase: { + checkBox: { + label: "`labelTx` 속성으로", + helper: "`helperTx` 속성으로", + }, + checkBoxMultiLine: { + helper: "멀티라인 지원 - 멀티라인 지원을 위한 예제 문장입니다. 하나 둘 셋.", + }, + radioChangeSides: { + helper: "양쪽을 변경할 수 있습니다 - 양쪽 변경을 위한 예제 문장입니다. 하나 둘 셋.", + }, + customCheckBox: { + label: "맞춤 체크박스 아이콘 전달.", + }, + switch: { + label: "스위치는 텍스트로 읽을 수 있습니다", + helper: + "기본적으로 이 옵션은 `Text`를 사용하지 않습니다. 폰트에 따라 켜기/끄기 문자가 이상하게 보일 수 있기 때문입니다. 필요에 따라 커스터마이즈하세요.", + }, + switchAid: { + label: "또는 아이콘으로 보조", + }, + }, + }, + styling: { + name: "스타일링", + description: "컴포넌트는 쉽게 스타일링할 수 있습니다.", + outerWrapper: "1 - 입력 외부 래퍼 스타일링", + innerWrapper: "2 - 입력 내부 래퍼 스타일링", + inputDetail: "3 - 입력 디테일 스타일링", + labelTx: "labelTx도 스타일링할 수 있습니다", + styleContainer: "또는 전체 컨테이너 스타일링", + }, + }, + }, + demoButton: { + description: + "사용자가 작업을 수행하고 선택을 할 수 있도록 하는 컴포넌트입니다. Text 컴포넌트를 Pressable 컴포넌트로 감쌉니다.", + useCase: { + presets: { + name: "프리셋", + description: "사전 구성된 몇 가지 프리셋이 있습니다.", + }, + passingContent: { + name: "내용 전달", + description: "내용을 전달하는 몇 가지 방법이 있습니다.", + viaTextProps: "`text` 속성으로 - 예제 문장입니다.", + children: "자식 - 또 다른 예제 문장입니다.", + rightAccessory: "오른쪽 액세서리 - 예제 문장입니다.", + leftAccessory: "왼쪽 액세서리 - 예제 문장입니다.", + nestedChildren: "중첩 자식 - 별 하나에 추억과 별 하나에 사랑과 별 하나에 쓸쓸함과", + nestedChildren2: "별 하나에 동경과 별 하나에 시와 ", + nestedChildren3: "별 하나에 어머니, 어머니.", + multiLine: + "멀티라인 - 죽는 날까지 하늘을 우러러 한 점 부끄럼이 없기를, 잎새에 이는 바람에도 나는 괴로워했다. 별을 노래하는 마음으로 모든 죽어 가는 것을 사랑해야지 그리고 나한테 주어진 길을 걸어가야겠다. 오늘 밤에도 별이 바람에 스치운다.", + }, + styling: { + name: "스타일링", + description: "컴포넌트는 쉽게 스타일링할 수 있습니다.", + styleContainer: "스타일 컨테이너 - 예제 문장", + styleText: "스타일 텍스트 - 예제 문장", + styleAccessories: "스타일 액세서리 - 또 다른 예제 문장", + pressedState: "스타일 눌린 상태 - 예제 문장", + }, + disabling: { + name: "비활성화", + description: + "컴포넌트는 비활성화할 수 있으며, 그에 따라 스타일링할 수 있습니다. 누르는 동작이 비활성화됩니다.", + standard: "비활성화 - 표준", + filled: "비활성화 - 채워진", + reversed: "비활성화 - 역방향", + accessory: "비활성화된 액세서리 스타일", + textStyle: "비활성화된 텍스트 스타일", + }, + }, + }, + demoListItem: { + description: "FlatList, SectionList 또는 자체적으로 사용할 수 있는 스타일된 행 컴포넌트입니다.", + useCase: { + height: { + name: "높이", + description: "행은 다른 높이를 가질 수 있습니다.", + defaultHeight: "기본 높이 (56px)", + customHeight: "`height` 속성을 통해 사용자 정의 높이", + textHeight: + "텍스트 내용에 의해 결정된 높이 - 예제를 위한 긴 문장입니다. 하나 둘 셋. 안녕하세요.", + longText: + "긴 텍스트를 한 줄로 제한 - 이것 역시 예제를 위한 긴 문장입니다. 오늘 날씨는 어떤가요?", + }, + separators: { + name: "구분선", + description: "구분선 / 디바이더가 사전 구성되어 있으며 선택 사항입니다.", + topSeparator: "상단 구분선만", + topAndBottomSeparator: "상단 및 하단 구분선", + bottomSeparator: "하단 구분선만", + }, + icons: { + name: "아이콘", + description: "왼쪽 또는 오른쪽 아이콘을 사용자 정의할 수 있습니다.", + leftIcon: "왼쪽 아이콘", + rightIcon: "오른쪽 아이콘", + leftRightIcons: "왼쪽 및 오른쪽 아이콘", + }, + customLeftRight: { + name: "사용자 정의 왼쪽/오른쪽 컴포넌트", + description: "필요시에는 사용자가 정의한 왼쪽/오른쪽 컴포넌트를 전달할 수 있습니다.", + customLeft: "사용자 정의 왼쪽 컴포넌트", + customRight: "사용자 정의 오른쪽 컴포넌트", + }, + passingContent: { + name: "내용 전달", + description: "내용을 전달하는 몇 가지 방법이 있습니다.", + text: "`text` 속성으로 - 예제 문장입니다.", + children: "자식 - 또 다른 예제 문장입니다.", + nestedChildren1: "중첩 자식 - 이것도 예제 문장입니다..", + nestedChildren2: "또 다른 예제 문장, 중첩이 된 형태입니다.", + }, + listIntegration: { + name: "FlatList 및 FlashList 통합", + description: "이 컴포넌트는 선호하는 리스트 인터페이스와 쉽게 통합할 수 있습니다.", + }, + styling: { + name: "스타일링", + description: "컴포넌트는 쉽게 스타일링할 수 있습니다.", + styledText: "스타일된 텍스트", + styledContainer: "스타일된 컨테이너 (구분선)", + tintedIcons: "색이 입혀진 아이콘", + }, + }, + }, + demoCard: { + description: + "카드는 관련 정보를 컨테이너에 담아 표시하는 데 유용합니다. ListItem이 내용을 수평으로 표시한다면, 카드는 내용을 수직으로 표시할 수 있습니다.", + useCase: { + presets: { + name: "프리셋", + description: "사전 구성된 몇 가지 프리셋이 있습니다.", + default: { + heading: "기본 프리셋 (기본값)", + content: "예제 문장입니다. 그믐밤 반디불은 부서진 달조각", + footer: "숲으로 가자 달조각을 주으려 숲으로 가자.", + }, + reversed: { + heading: "역방향 프리셋", + content: "예제 문장입니다. 그믐밤 반디불은 부서진 달조각", + footer: "숲으로 가자 달조각을 주으려 숲으로 가자.", + }, + }, + verticalAlignment: { + name: "수직 정렬", + description: "카드는 필요에 따라 미리 구성된 다양한 정렬방법으로 제공됩니다.", + top: { + heading: "상단 (기본값)", + content: "모든 콘텐츠가 자동으로 상단에 정렬됩니다.", + footer: "심지어 푸터도", + }, + center: { + heading: "중앙", + content: "콘텐츠는 카드 높이에 상대적으로 중앙에 배치됩니다.", + footer: "나도!", + }, + spaceBetween: { + heading: "공간 사이", + content: "모든 콘텐츠가 고르게 간격을 둡니다.", + footer: "나는 내가 있고 싶은 곳에 있어요.", + }, + reversed: { + heading: "푸터 강제 하단", + content: "푸터를 원하는 위치에 밀어 넣습니다.", + footer: "여기 너무 외로워요.", + }, + }, + passingContent: { + name: "내용 전달", + description: "내용을 전달하는 몇 가지 방법이 있습니다.", + heading: "`heading` 속성으로", + content: "`content` 속성으로", + footer: "푸터도 외로워요.", + }, + customComponent: { + name: "사용자 정의 컴포넌트", + description: + "사전 구성된 컴포넌트 중 하나를 직접 만든 자신의 컴포넌트로 대체할 수 있습니다. 추가 컴포넌트도 덧붙여 넣을 수 있습니다.", + rightComponent: "오른쪽 컴포넌트", + leftComponent: "왼쪽 컴포넌트", + }, + style: { + name: "스타일링", + description: "컴포넌트는 쉽게 스타일링할 수 있습니다.", + heading: "헤딩 스타일링", + content: "컨텐츠 스타일링", + footer: "푸터 스타일링", + }, + }, + }, + demoAutoImage: { + description: "원격 또는 data-uri 이미지의 크기를 자동으로 조정하는 Image 컴포넌트입니다.", + useCase: { + remoteUri: { name: "원격 URI" }, + base64Uri: { name: "Base64 URI" }, + scaledToFitDimensions: { + name: "치수에 맞게 조정", + description: + "`maxWidth` 단독으로, 혹은 `maxHeight` 속성과 함께 제공하면, 이미지는 비율을 유지하면서 자동으로 크기가 조정됩니다. 이것이 `resizeMode: 'contain'`과 다른 점은 무엇일까요? 첫째, 한쪽 크기만 지정할 수 있습니다. 둘째, 이미지가 이미지 컨테이너 내에 포함되는 대신 원하는 치수에 맞게 조정됩니다.", + heightAuto: "너비: 60 / 높이: 자동", + widthAuto: "너비: 자동 / 높이: 32", + bothManual: "너비: 60 / 높이: 60", + }, + }, + }, + demoText: { + description: + "텍스트 표시가 필요한 경우를 위해, 이 컴포넌트는 기본 React Native 컴포넌트 위에 HOC로 제작되었습니다.", + useCase: { + presets: { + name: "프리셋", + description: "사전 구성된 몇 가지 프리셋이 있습니다.", + default: "기본 프리셋 - 예제 문장입니다. 하나 둘 셋.", + bold: "볼드 프리셋 - 예제 문장입니다. 하나 둘 셋.", + subheading: "서브헤딩 프리셋 - 예제 문장입니다. 하나 둘 셋.", + heading: "헤딩 프리셋 - 예제 문장입니다. 하나 둘 셋.", + }, + sizes: { + name: "크기", + description: "크기 속성이 있습니다.", + xs: "xs - 조금 더 작은 크기 속성입니다.", + sm: "sm - 작은 크기 속성입니다.", + md: "md - 중간 크기 속성입니다.", + lg: "lg - 큰 크기 속성입니다.", + xl: "xl - 조금 더 큰 크기 속성입니다.", + xxl: "xxl - 아주 큰 크기 속성입니다.", + }, + weights: { + name: "굵기", + description: "굵기 속성이 있습니다.", + light: "가벼움 - 예제 문장입니다. 안녕하세요. 하나 둘 셋.", + normal: "보통 - 예제 문장입니다. 안녕하세요. 하나 둘 셋.", + medium: "중간 - 예제 문장입니다. 안녕하세요. 하나 둘 셋.", + semibold: "세미볼드 - 예제 문장입니다. 안녕하세요. 하나 둘 셋.", + bold: "볼드 - 예제 문장입니다. 안녕하세요. 하나 둘 셋.", + }, + passingContent: { + name: "내용 전달", + description: "내용을 전달하는 몇 가지 방법이 있습니다.", + viaText: + "`text` 속성으로 - 죽는 날까지 하늘을 우러러 한 점 부끄럼이 없기를, 잎새에 이는 바람에도 나는 괴로워했다. 별을 노래하는 마음으로 모든 죽어 가는 것을 사랑해야지 그리고 나한테 주어진 길을 걸어가야겠다. 오늘 밤에도 별이 바람에 스치운다.", + viaTx: "`tx` 속성으로", + children: "자식 - 또 다른 예제 문장입니다. 하나 둘 셋.", + nestedChildren: "중첩 자식", + nestedChildren2: "죽는 날까지 하늘을 우러러 한 점 부끄럼이 없기를, ", + nestedChildren3: "잎새에 이는 바람에도 나는 괴로워했다.", + nestedChildren4: "별을 노래하는 마음으로 모든 죽어 가는 것을 사랑해야지.", + }, + styling: { + name: "스타일링", + description: "컴포넌트는 쉽게 스타일링할 수 있습니다.", + text: "그리고 나한테 주어진 길을 걸어가야겠다.", + text2: "오늘 밤에도 별이 바람에 스치운다.", + text3: "계속 이어지는 예제 문장입니다. 하나 둘 셋.", + }, + }, + }, + demoHeader: { + description: + "여러 화면에 나타나는 컴포넌트입니다. 네비게이션 버튼과 화면 제목을 포함할 것입니다.", + useCase: { + actionIcons: { + name: "액션 아이콘", + description: "왼쪽 또는 오른쪽 액션 컴포넌트에 아이콘을 쉽게 전달할 수 있습니다.", + leftIconTitle: "왼쪽 아이콘", + rightIconTitle: "오른쪽 아이콘", + bothIconsTitle: "양쪽 아이콘", + }, + actionText: { + name: "액션 텍스트", + description: "왼쪽 또는 오른쪽 액션 컴포넌트에 텍스트를 쉽게 전달할 수 있습니다.", + leftTxTitle: "`leftTx`를 통해", + rightTextTitle: "`rightText`를 통해", + }, + customActionComponents: { + name: "사용자 정의 액션 컴포넌트", + description: + "아이콘이나 텍스트 옵션이 충분하지 않은 경우, 사용자 정의 액션 컴포넌트를 전달할 수 있습니다.", + customLeftActionTitle: "사용자 정의 왼쪽 액션", + }, + titleModes: { + name: "제목 모드", + description: + "제목은 기본적으로 중앙에 고정되지만 너무 길면 잘릴 수 있습니다. 액션 버튼에 맞춰 조정할 수 있습니다.", + centeredTitle: "중앙 제목", + flexTitle: "유연한 제목", + }, + styling: { + name: "스타일링", + description: "컴포넌트는 쉽게 스타일링할 수 있습니다.", + styledTitle: "스타일된 제목", + styledWrapperTitle: "스타일된 래퍼", + tintedIconsTitle: "색이 입혀진 아이콘", + }, + }, + }, + demoEmptyState: { + description: + "표시할 데이터가 없을 때 사용할 수 있는 컴포넌트입니다. 사용자가 다음에 무엇을 할지 안내할 수 있습니다.", + useCase: { + presets: { + name: "프리셋", + description: + "다양한 텍스트/이미지 세트를 만들 수 있습니다. `generic`이라는 사전 정의된 세트가 하나 있습니다. 기본값이 없으므로 완전히 사용자 정의된 EmptyState를 원할 경우 사용할 수 있습니다.", + }, + passingContent: { + name: "내용 전달", + description: "내용을 전달하는 몇 가지 방법이 있습니다.", + customizeImageHeading: "이미지 맞춤 설정", + customizeImageContent: "어떤 이미지 소스도 전달할 수 있습니다.", + viaHeadingProp: "`heading` 속성으로", + viaContentProp: "`content` 속성으로", + viaButtonProp: "`button` 속성으로", + }, + styling: { + name: "스타일링", + description: "컴포넌트는 쉽게 스타일링할 수 있습니다.", + }, + }, + }, +} + +export default demoKo + +// @demo remove-file diff --git a/boilerplate/app/i18n/en.ts b/boilerplate/app/i18n/en.ts index 40a8663bf..e0c23e7bf 100644 --- a/boilerplate/app/i18n/en.ts +++ b/boilerplate/app/i18n/en.ts @@ -1,3 +1,5 @@ +import demoEn from "./demo-en" + const en = { common: { ok: "OK!", @@ -119,6 +121,8 @@ const en = { "No favorites have been added yet. Tap the heart on an episode to add it to your favorites!", }, }, + // @demo remove-block-start + ...demoEn, // @demo remove-block-end } diff --git a/boilerplate/app/i18n/fr.ts b/boilerplate/app/i18n/fr.ts index d15981f96..2c549a206 100644 --- a/boilerplate/app/i18n/fr.ts +++ b/boilerplate/app/i18n/fr.ts @@ -1,3 +1,4 @@ +import demoFr from "./demo-fr" import { Translations } from "./en" const fr: Translations = { @@ -123,6 +124,8 @@ const fr: Translations = { "Aucun favori n'a été ajouté pour le moment. Appuyez sur le cœur d'un épisode pour l'ajouter à vos favoris !", }, }, + // @demo remove-block-start + ...demoFr, // @demo remove-block-end } diff --git a/boilerplate/app/i18n/i18n.ts b/boilerplate/app/i18n/i18n.ts index ee09968d4..be45a5bd0 100644 --- a/boilerplate/app/i18n/i18n.ts +++ b/boilerplate/app/i18n/i18n.ts @@ -1,5 +1,5 @@ import * as Localization from "expo-localization" -import i18n from "i18n-js" +import { I18n } from "i18n-js" import { I18nManager } from "react-native" // if English isn't your default language, move Translations to the appropriate language file. @@ -9,14 +9,19 @@ import ko from "./ko" import fr from "./fr" import jp from "./jp" -i18n.fallbacks = true +// Migration guide from i18n 3.x -> 4.x: +// https://github.com/fnando/i18n-js/blob/main/MIGRATING_FROM_V3_TO_V4.md +// https://github.com/fnando/i18n/discussions/24 // to use regional locales use { "en-US": enUS } etc -i18n.translations = { ar, en, "en-US": en, ko, fr, jp } - const fallbackLocale = "en-US" +export const i18n = new I18n( + { ar, en, "en-US": en, ko, fr, jp }, + { locale: fallbackLocale, defaultLocale: fallbackLocale, enableFallback: true }, +) + const systemLocale = Localization.getLocales()[0] -const systemLocaleTag = systemLocale?.languageTag ?? "en-US" +const systemLocaleTag = systemLocale?.languageTag ?? fallbackLocale if (Object.prototype.hasOwnProperty.call(i18n.translations, systemLocaleTag)) { // if specific locales like en-FI or en-US is available, set it diff --git a/boilerplate/app/i18n/jp.ts b/boilerplate/app/i18n/jp.ts index ac632f062..97442fc3d 100644 --- a/boilerplate/app/i18n/jp.ts +++ b/boilerplate/app/i18n/jp.ts @@ -1,3 +1,4 @@ +import demoJp from "./demo-jp" import { Translations } from "./en" const jp: Translations = { @@ -34,14 +35,14 @@ const jp: Translations = { invalidEmail: "有効なメールアドレスを入力してください.", }, loginScreen: { - logIn: "サインイン", + logIn: "ログイン", enterDetails: "ここにあなたの情報を入力してトップシークレットをアンロックしましょう。何が待ち構えているか予想もつかないはずです。はたまたそうでも無いかも - ロケットサイエンスほど複雑なものではありません。", emailFieldLabel: "メールアドレス", passwordFieldLabel: "パスワード", emailFieldPlaceholder: "メールアドレスを入力してください", passwordFieldPlaceholder: "パスワードを入力してください", - tapToLogIn: "タップしてサインインしよう!", + tapToLogIn: "タップしてログインしよう!", hint: "ヒント: お好みのメールアドレスとパスワードを使ってください :)", }, demoNavigator: { @@ -78,8 +79,8 @@ const jp: Translations = { lorem2Sentences: "Nulla cupidatat deserunt amet quis aliquip nostrud do adipisicing. Adipisicing excepteur elit laborum Lorem adipisicing do duis.", demoHeaderTxExample: "Yay", - demoViaTxProp: "`tx` Propから", - demoViaSpecifiedTxProp: "`{{prop}}Tx` Propから", + demoViaTxProp: "`tx`から", + demoViaSpecifiedTxProp: "`{{prop}}Tx`から", }, demoDebugScreen: { howTo: "ハウツー", @@ -121,6 +122,8 @@ const jp: Translations = { "お気に入りのエピソードがまだありません。エピソードにあるハートマークにタップして、お気に入りに追加しましょう!", }, }, + // @demo remove-block-start + ...demoJp, // @demo remove-block-end } diff --git a/boilerplate/app/i18n/ko.ts b/boilerplate/app/i18n/ko.ts index 48f51737b..ff0e9f6fa 100644 --- a/boilerplate/app/i18n/ko.ts +++ b/boilerplate/app/i18n/ko.ts @@ -1,3 +1,4 @@ +import demoKo from "./demo-ko" import { Translations } from "./en" const ko: Translations = { @@ -120,6 +121,8 @@ const ko: Translations = { content: "즐겨찾기가 없습니다. 에피소드에 있는 하트를 눌러서 즐겨찾기에 추가하세요.", }, }, + // @demo remove-block-start + ...demoKo, // @demo remove-block-end } diff --git a/boilerplate/app/i18n/translate.ts b/boilerplate/app/i18n/translate.ts index 084fdcdfa..00c1c1e06 100644 --- a/boilerplate/app/i18n/translate.ts +++ b/boilerplate/app/i18n/translate.ts @@ -1,5 +1,5 @@ -import i18n from "i18n-js" -import { TxKeyPath } from "./i18n" +import { TranslateOptions } from "i18n-js" +import { i18n, TxKeyPath } from "./i18n" /** * Translates text. @@ -23,6 +23,6 @@ import { TxKeyPath } from "./i18n" * // => "Hello world!" * ``` */ -export function translate(key: TxKeyPath, options?: i18n.TranslateOptions): string { +export function translate(key: TxKeyPath, options?: TranslateOptions): string { return i18n.t(key, options) } diff --git a/boilerplate/app/screens/DemoShowroomScreen/DemoShowroomScreen.tsx b/boilerplate/app/screens/DemoShowroomScreen/DemoShowroomScreen.tsx index bea282963..570262e3b 100644 --- a/boilerplate/app/screens/DemoShowroomScreen/DemoShowroomScreen.tsx +++ b/boilerplate/app/screens/DemoShowroomScreen/DemoShowroomScreen.tsx @@ -4,7 +4,7 @@ import { Image, ImageStyle, Platform, SectionList, TextStyle, View, ViewStyle } import { Drawer } from "react-native-drawer-layout" import { type ContentStyle } from "@shopify/flash-list" import { ListItem, ListView, ListViewRef, Screen, Text } from "../../components" -import { isRTL } from "../../i18n" +import { TxKeyPath, isRTL, translate } from "../../i18n" import { DemoTabParamList, DemoTabScreenProps } from "../../navigators/DemoNavigator" import type { Theme, ThemedStyle } from "app/theme" import { $styles } from "app/theme" @@ -17,7 +17,7 @@ const logo = require("../../../assets/images/logo.png") export interface Demo { name: string - description: string + description: TxKeyPath data: ({ themed, theme }: { themed: any; theme: Theme }) => ReactElement[] } @@ -171,7 +171,7 @@ export const DemoShowroomScreen: FC> = estimatedItemSize={250} data={Object.values(Demos).map((d) => ({ name: d.name, - useCases: d.data({ theme, themed }).map((u) => u.props.name as string), + useCases: d.data({ theme, themed }).map((u) => translate(u.props.name)), }))} keyExtractor={(item) => item.name} renderItem={({ item, index: sectionIndex }) => ( @@ -210,7 +210,7 @@ export const DemoShowroomScreen: FC> = {section.name} - {section.description} + {translate(section.description)} ) }} diff --git a/boilerplate/app/screens/DemoShowroomScreen/DemoUseCase.tsx b/boilerplate/app/screens/DemoShowroomScreen/DemoUseCase.tsx index dd5b07175..5f19b596a 100644 --- a/boilerplate/app/screens/DemoShowroomScreen/DemoUseCase.tsx +++ b/boilerplate/app/screens/DemoShowroomScreen/DemoUseCase.tsx @@ -1,13 +1,14 @@ import React, { ReactNode } from "react" import { TextStyle, View, ViewStyle } from "react-native" +import { TxKeyPath, translate } from "app/i18n" import { Text } from "../../components" import type { ThemedStyle } from "app/theme" import { useAppTheme } from "app/utils/useAppTheme" import { $styles } from "app/theme" interface DemoUseCaseProps { - name: string - description?: string + name: TxKeyPath + description?: TxKeyPath layout?: "column" | "row" itemStyle?: ViewStyle children: ReactNode @@ -23,9 +24,8 @@ export function DemoUseCase(props: DemoUseCaseProps) { return ( - {name} - - {description && {description}} + {translate(name)} + {description && {translate(description)}} {children} diff --git a/boilerplate/app/screens/DemoShowroomScreen/demos/DemoAutoImage.tsx b/boilerplate/app/screens/DemoShowroomScreen/demos/DemoAutoImage.tsx index 5b15d1957..5fe32d81e 100644 --- a/boilerplate/app/screens/DemoShowroomScreen/demos/DemoAutoImage.tsx +++ b/boilerplate/app/screens/DemoShowroomScreen/demos/DemoAutoImage.tsx @@ -7,6 +7,7 @@ import { $styles } from "../../../theme" import { Demo } from "../DemoShowroomScreen" import { DemoDivider } from "../DemoDivider" import { DemoUseCase } from "../DemoUseCase" +import { translate } from "app/i18n" const $imageContainer: ViewStyle = { alignItems: "center", @@ -37,9 +38,9 @@ const $aspectRatioBox: ThemedStyle = (theme) => ({ export const DemoAutoImage: Demo = { name: "AutoImage", - description: "An Image component that automatically sizes a remote or data-uri image.", + description: "demoAutoImage.description", data: ({ theme, themed }) => [ - + , - + , - width: 60 / height: auto + {translate("demoAutoImage.useCase.scaledToFitDimensions.heightAuto")} @@ -163,7 +163,7 @@ export const DemoAutoImage: Demo = { - width: auto / height: 32 + {translate("demoAutoImage.useCase.scaledToFitDimensions.widthAuto")} @@ -219,7 +219,7 @@ export const DemoAutoImage: Demo = { - width: 60 / height: 60 + {translate("demoAutoImage.useCase.scaledToFitDimensions.bothManual")} , ], diff --git a/boilerplate/app/screens/DemoShowroomScreen/demos/DemoButton.tsx b/boilerplate/app/screens/DemoShowroomScreen/demos/DemoButton.tsx index 171c0ff15..a3834409d 100644 --- a/boilerplate/app/screens/DemoShowroomScreen/demos/DemoButton.tsx +++ b/boilerplate/app/screens/DemoShowroomScreen/demos/DemoButton.tsx @@ -6,6 +6,7 @@ import type { ThemedStyle } from "../../../theme" import { Demo } from "../DemoShowroomScreen" import { DemoDivider } from "../DemoDivider" import { DemoUseCase } from "../DemoUseCase" +import { translate } from "app/i18n" const $iconStyle: ImageStyle = { width: 30, height: 30 } const $customButtonStyle: ThemedStyle = ({ colors }) => ({ @@ -44,10 +45,12 @@ const $disabledButtonTextStyle: ThemedStyle = ({ colors }) => ({ export const DemoButton: Demo = { name: "Button", - description: - "A component that allows users to take actions and make choices. Wraps the Text component with a Pressable component.", + description: "demoButton.description", data: ({ themed }) => [ - + @@ -58,16 +61,16 @@ export const DemoButton: Demo = { , - + @@ -86,19 +89,21 @@ export const DemoButton: Demo = { )} > - LeftAccessory - Duis Proident + {translate("demoButton.useCase.passingContent.leftAccessory")} @@ -112,17 +117,21 @@ export const DemoButton: Demo = { )} > - Multiline - consequat veniam veniam reprehenderit. Fugiat id nisi quis duis sunt proident - mollit dolor mollit adipisicing proident deserunt. + {translate("demoButton.useCase.passingContent.multiLine")} , - - + + @@ -130,7 +139,7 @@ export const DemoButton: Demo = { preset="reversed" RightAccessory={() => } > - Style Accessories - enim ea id fugiat anim ad. + {translate("demoButton.useCase.styling.styleAccessories")} @@ -148,13 +157,13 @@ export const DemoButton: Demo = { /> )} > - Style Pressed State - fugiat anim + {translate("demoButton.useCase.styling.pressedState")} , @@ -173,7 +182,7 @@ export const DemoButton: Demo = { pressedStyle={themed($customButtonPressedStyle)} pressedTextStyle={themed($customButtonPressedTextStyle)} > - Disabled - filled + {translate("demoButton.useCase.disabling.filled")} @@ -184,7 +193,7 @@ export const DemoButton: Demo = { pressedStyle={themed($customButtonPressedStyle)} pressedTextStyle={themed($customButtonPressedTextStyle)} > - Disabled - reversed + {translate("demoButton.useCase.disabling.reversed")} @@ -202,7 +211,7 @@ export const DemoButton: Demo = { /> )} > - Disabled accessory style + {translate("demoButton.useCase.disabling.accessory")} @@ -213,7 +222,7 @@ export const DemoButton: Demo = { pressedStyle={themed($customButtonPressedStyle)} pressedTextStyle={themed($customButtonPressedTextStyle)} > - Disabled text style + {translate("demoButton.useCase.disabling.textStyle")} , ], diff --git a/boilerplate/app/screens/DemoShowroomScreen/demos/DemoCard.tsx b/boilerplate/app/screens/DemoShowroomScreen/demos/DemoCard.tsx index 1415fe415..c3216cff2 100644 --- a/boilerplate/app/screens/DemoShowroomScreen/demos/DemoCard.tsx +++ b/boilerplate/app/screens/DemoShowroomScreen/demos/DemoCard.tsx @@ -7,67 +7,73 @@ import { DemoUseCase } from "../DemoUseCase" export const DemoCard: Demo = { name: "Card", - description: - "Cards are useful for displaying related information in a contained way. If a ListItem displays content horizontally, a Card can be used to display content vertically.", + description: "demoCard.description", data: ({ theme }) => [ - + , , - + , , - + [ , @@ -47,7 +46,10 @@ export const DemoEmptyState: Demo = { /> , - + = ({ colors }) => ({ export const DemoHeader: Demo = { name: "Header", - description: - "Component that appears on many screens. Will hold navigation buttons and screen title.", + description: "demoHeader.description", data: ({ theme, themed }) => [ -
+
-
+
-
+
,
-
+
,
, -
+
, - -
+ +
= ({ colors }) => ({ export const DemoIcon: Demo = { name: "Icon", - description: - "A component to render a registered icon. It is wrapped in a if `onPress` is provided, otherwise a .", + description: "demoIcon.description", data: ({ theme, themed }) => [ @@ -53,14 +52,22 @@ export const DemoIcon: Demo = { ))} , - + , - + , - + = ({ colors, spacing }) => ({ export const DemoListItem: Demo = { name: "ListItem", - description: "A styled row component that can be used in FlatList, SectionList, or by itself.", + description: "demoListItem.description", data: ({ theme, themed }) => [ - - Default height (56px) + + {translate("demoListItem.useCase.height.defaultHeight")} - Custom height via `height` prop + {translate("demoListItem.useCase.height.customHeight")} - - Height determined by text content - Reprehenderit incididunt deserunt do do ea labore. - + {translate("demoListItem.useCase.height.textHeight")} - Limit long text to one line - Reprehenderit incididunt deserunt do do ea labore. + {translate("demoListItem.useCase.height.longText")} , - Only top separator + {translate("demoListItem.useCase.separators.topSeparator")} - Top and bottom separators + {translate("demoListItem.useCase.separators.topAndBottomSeparator")} - Only bottom separator + + {translate("demoListItem.useCase.separators.bottomSeparator")} + , - + - Left icon + {translate("demoListItem.useCase.icons.leftIcon")} - Right Icon + {translate("demoListItem.useCase.icons.rightIcon")} - Left & Right Icons + {translate("demoListItem.useCase.icons.leftRightIcons")} , } > - Custom left component + {translate("demoListItem.useCase.customLeftRight.customLeft")} } > - Custom right component + {translate("demoListItem.useCase.customLeftRight.customRight")} , - + - Children - mostrud mollit + {translate("demoListItem.useCase.passingContent.children")} - Nested children - proident veniam. + + {translate("demoListItem.useCase.passingContent.nestedChildren1")} + {` `} - Ullamco cupidatat officia exercitation velit non ullamco nisi.. + {translate("demoListItem.useCase.passingContent.nestedChildren2")} , @@ -162,9 +171,12 @@ export const DemoListItem: Demo = { , - + - Styled Text + {translate("demoListItem.useCase.styling.styledText")} - Styled Text + {translate("demoListItem.useCase.styling.styledText")} - Styled Container (separators) + {translate("demoListItem.useCase.styling.styledContainer")} - Tinted Icons + {translate("demoListItem.useCase.styling.tintedIcons")} , ], diff --git a/boilerplate/app/screens/DemoShowroomScreen/demos/DemoText.tsx b/boilerplate/app/screens/DemoShowroomScreen/demos/DemoText.tsx index d4b264cdb..9e1c45e46 100644 --- a/boilerplate/app/screens/DemoShowroomScreen/demos/DemoText.tsx +++ b/boilerplate/app/screens/DemoShowroomScreen/demos/DemoText.tsx @@ -4,127 +4,126 @@ import { Text } from "../../../components" import { Demo } from "../DemoShowroomScreen" import { DemoDivider } from "../DemoDivider" import { DemoUseCase } from "../DemoUseCase" +import { translate } from "app/i18n" export const DemoText: Demo = { name: "Text", - description: - "For your text displaying needs. This component is a HOC over the built-in React Native one.", + description: "demoText.description", data: ({ theme }) => [ - - - default preset - Cillum eu laboris in labore. Excepteur mollit tempor reprehenderit fugiat - elit et eu consequat laborum. - + + {translate("demoText.useCase.presets.default")} - - bold preset - Tempor et ullamco cupidatat in officia. Nulla ea duis elit id sunt ipsum - cillum duis deserunt nostrud ut nostrud id. - + {translate("demoText.useCase.presets.bold")} - subheading preset - In Cupidatat Cillum. + {translate("demoText.useCase.presets.subheading")} - heading preset - Voluptate Adipis. + {translate("demoText.useCase.presets.heading")} , - - xs - Ea ipsum est ea ex sunt. + + {translate("demoText.useCase.sizes.xs")} - sm - Lorem sunt adipisicin. + {translate("demoText.useCase.sizes.sm")} - md - Consequat id do lorem. + {translate("demoText.useCase.sizes.md")} - lg - Nostrud ipsum ea. + {translate("demoText.useCase.sizes.lg")} - xl - Eiusmod ex excepteur. + {translate("demoText.useCase.sizes.xl")} - xxl - Cillum eu laboris. + {translate("demoText.useCase.sizes.xxl")} , - - - light - Nulla magna incididunt excepteur est occaecat duis culpa dolore cupidatat enim et. - + + {translate("demoText.useCase.weights.light")} - - normal - Magna incididunt dolor ut veniam veniam laboris aliqua velit ea incididunt. - + {translate("demoText.useCase.weights.normal")} - medium - Non duis laborum quis laboris occaecat culpa cillum. + {translate("demoText.useCase.weights.medium")} - - semiBold - Exercitation magna nostrud pariatur laborum occaecat aliqua. - + {translate("demoText.useCase.weights.semibold")} - bold - Eiusmod ullamco magna exercitation est excepteur. + {translate("demoText.useCase.weights.bold")} , - + - + - children - Aliqua velit irure reprehenderit eu qui amet veniam consectetur. + {translate("demoText.useCase.passingContent.children")} - nested children - - Occaecat aliqua irure proident veniam. + {translate("demoText.useCase.passingContent.nestedChildren")} + {translate("demoText.useCase.passingContent.nestedChildren2")} {` `} - - Ullamco cupidatat officia exercitation velit non ullamco nisi.. - + {translate("demoText.useCase.passingContent.nestedChildren3")} {` `} - Occaecat aliqua irure proident veniam. + {translate("demoText.useCase.passingContent.nestedChildren4")} , - + - Consequat ullamco veniam velit mollit proident excepteur aliquip id culpa ipsum velit sint - nostrud. + {translate("demoText.useCase.styling.text")} {` `} - Eiusmod occaecat laboris eu ex veniam ipsum adipisicing consectetur. Magna ullamco - adipisicing tempor adipisicing. + {translate("demoText.useCase.styling.text2")} {` `} - Eiusmod occaecat laboris eu ex veniam ipsum adipisicing consectetur. Magna ullamco - adipisicing tempor adipisicing. + {translate("demoText.useCase.styling.text3")} , diff --git a/boilerplate/app/screens/DemoShowroomScreen/demos/DemoTextField.tsx b/boilerplate/app/screens/DemoShowroomScreen/demos/DemoTextField.tsx index b398a422e..7f03de1e7 100644 --- a/boilerplate/app/screens/DemoShowroomScreen/demos/DemoTextField.tsx +++ b/boilerplate/app/screens/DemoShowroomScreen/demos/DemoTextField.tsx @@ -43,17 +43,20 @@ const $customRightAccessoryStyle: ThemedStyle = ({ colors }) => ({ export const DemoTextField: Demo = { name: "TextField", - description: "TextField component allows for the entering and editing of text.", + description: "demoTextField.description", data: ({ themed }) => [ @@ -61,9 +64,12 @@ export const DemoTextField: Demo = { @@ -71,20 +77,26 @@ export const DemoTextField: Demo = { , @@ -101,17 +113,21 @@ export const DemoTextField: Demo = { } /> } /> @@ -119,18 +135,25 @@ export const DemoTextField: Demo = { } /> , - + @@ -138,8 +161,10 @@ export const DemoTextField: Demo = { ( diff --git a/boilerplate/app/screens/DemoShowroomScreen/demos/DemoToggle.tsx b/boilerplate/app/screens/DemoShowroomScreen/demos/DemoToggle.tsx index 2ef6e8710..8842e9db5 100644 --- a/boilerplate/app/screens/DemoShowroomScreen/demos/DemoToggle.tsx +++ b/boilerplate/app/screens/DemoShowroomScreen/demos/DemoToggle.tsx @@ -14,6 +14,7 @@ import { Demo } from "../DemoShowroomScreen" import { DemoDivider } from "../DemoDivider" import { DemoUseCase } from "../DemoUseCase" import type { ThemedStyle } from "app/theme" +import { translate } from "app/i18n" function ControlledCheckbox(props: CheckboxToggleProps) { const [value, setValue] = React.useState(props.value || false) @@ -43,29 +44,31 @@ const $centeredText: ThemedStyle = ({ spacing }) => ({ export const DemoToggle: Demo = { name: "Toggle", - description: - "Renders a boolean input. This is a controlled component that requires an onValueChange callback that updates the value prop in order for the component to reflect user actions. If the value prop is not updated, the component will continue to render the supplied value prop instead of the expected result of any user actions.", + description: "demoToggle.description", data: ({ theme, themed }) => [ - + , @@ -76,7 +79,7 @@ export const DemoToggle: Demo = { - No status - this is the default + {translate("demoToggle.useCase.statuses.noStatus")} @@ -89,7 +92,7 @@ export const DemoToggle: Demo = { - Error status - use when there is an error + {translate("demoToggle.useCase.statuses.errorStatus")} @@ -102,15 +105,19 @@ export const DemoToggle: Demo = { - Disabled status - disables the editability and mutes input + {translate("demoToggle.useCase.statuses.disabledStatus")} , - + @@ -136,26 +143,30 @@ export const DemoToggle: Demo = { value status="error" icon="ladybug" - label="Pass in a custom checkbox icon." + labelTx="demoToggle.useCase.passingContent.useCase.customCheckBox.label" /> , - + - 1 - style the input outer wrapper + {translate("demoToggle.useCase.styling.outerWrapper")} @@ -235,7 +246,7 @@ export const DemoToggle: Demo = { }} /> - 2 - style the input inner wrapper + {translate("demoToggle.useCase.styling.innerWrapper")} @@ -305,7 +316,7 @@ export const DemoToggle: Demo = { /> - 3 - style the input detail + {translate("demoToggle.useCase.styling.inputDetail")} @@ -313,7 +324,7 @@ export const DemoToggle: Demo = { diff --git a/boilerplate/app/utils/formatDate.ts b/boilerplate/app/utils/formatDate.ts index 5f87b893a..1e2a89ee3 100644 --- a/boilerplate/app/utils/formatDate.ts +++ b/boilerplate/app/utils/formatDate.ts @@ -1,5 +1,3 @@ -import I18n from "i18n-js" - // Note the syntax of these imports from the date-fns library. // If you import with the syntax: import { format } from "date-fns" the ENTIRE library // will be included in your production bundle (even if you only use one function). @@ -10,11 +8,12 @@ import parseISO from "date-fns/parseISO" import ar from "date-fns/locale/ar-SA" import ko from "date-fns/locale/ko" import en from "date-fns/locale/en-US" +import { i18n } from "app/i18n" type Options = Parameters[2] const getLocale = (): Locale => { - const locale = I18n.currentLocale().split("-")[0] + const locale = i18n.locale.split("-")[0] return locale === "ar" ? ar : locale === "ko" ? ko : en } diff --git a/boilerplate/app/utils/gestureHandler.native.ts b/boilerplate/app/utils/gestureHandler.native.ts new file mode 100644 index 000000000..b72fc9463 --- /dev/null +++ b/boilerplate/app/utils/gestureHandler.native.ts @@ -0,0 +1,3 @@ +// Only import react-native-gesture-handler on native platforms +// https://reactnavigation.org/docs/drawer-navigator/#installation +import "react-native-gesture-handler" diff --git a/boilerplate/app/utils/gestureHandler.ts b/boilerplate/app/utils/gestureHandler.ts new file mode 100644 index 000000000..172371fd0 --- /dev/null +++ b/boilerplate/app/utils/gestureHandler.ts @@ -0,0 +1,2 @@ +// Don't import react-native-gesture-handler on web +// https://reactnavigation.org/docs/drawer-navigator/#installation diff --git a/boilerplate/jest.config.js b/boilerplate/jest.config.js index 426d6adc4..8b5505b41 100644 --- a/boilerplate/jest.config.js +++ b/boilerplate/jest.config.js @@ -1,34 +1,5 @@ -const { defaults: tsjPreset } = require("ts-jest/presets") - -const thirdPartyIgnorePatterns = [ - "((jest-)?react-native|@react-native(-community)?)", - "expo(nent)?", - "@expo(nent)?/.*", - "@expo-google-fonts/.*", - "react-navigation", - "@react-navigation/.*", - "@unimodules/.*", - "unimodules", - "sentry-expo", - "native-base", - "react-native-svg", - "react-clone-referenced-element", - "react-native-code-push", -] - /** @type {import('@jest/types').Config.ProjectConfig} */ module.exports = { - ...tsjPreset, preset: "jest-expo", - transformIgnorePatterns: [ - `/node_modules/(?!${thirdPartyIgnorePatterns.join("|")})`, - "jest-runner", - ], - testPathIgnorePatterns: ["/node_modules/", "/.maestro/", "@react-native"], setupFiles: ["/test/setup.ts"], - transform:{ - '^.+\\.test.tsx?$': ['ts-jest', { - tsconfig: '/test/test-tsconfig.json' - }] - } } diff --git a/boilerplate/package.json b/boilerplate/package.json index 2f86e6082..4b61398ec 100644 --- a/boilerplate/package.json +++ b/boilerplate/package.json @@ -48,7 +48,7 @@ "expo-splash-screen": "~0.27.4", "expo-status-bar": "~1.12.1", "expo-system-ui": "~3.0.7", - "i18n-js": "3.9.2", + "i18n-js": "^4.4.3", "mobx": "6.10.2", "mobx-react-lite": "4.0.5", "mobx-state-tree": "5.3.0", @@ -70,10 +70,10 @@ "@babel/plugin-transform-template-literals": "^7.0.0", "@babel/preset-env": "^7.20.0", "@babel/runtime": "^7.20.0", + "@testing-library/react-native": "^12.5.2", "@types/i18n-js": "3.8.2", "@types/jest": "^29.2.1", "@types/react": "~18.2.14", - "@types/react-test-renderer": "^18.0.0", "@typescript-eslint/eslint-plugin": "^5.59.0", "@typescript-eslint/parser": "^5.59.0", "babel-jest": "^29.2.1", @@ -91,7 +91,6 @@ "patch-package": "^8.0.0", "postinstall-prepare": "1.0.1", "prettier": "2.8.8", - "react-test-renderer": "18.2.0", "reactotron-core-client": "^2.8.13", "reactotron-mst": "^3.1.7", "reactotron-react-js": "^3.3.11", diff --git a/boilerplate/test/setup.ts b/boilerplate/test/setup.ts index 62bdd66c7..c1a6b6a5c 100644 --- a/boilerplate/test/setup.ts +++ b/boilerplate/test/setup.ts @@ -35,6 +35,16 @@ jest.mock("expo-localization", () => ({ getLocales: () => [{ languageTag: "en-US", textDirection: "ltr" }], })) +jest.mock("../app/i18n/i18n.ts", () => ({ + i18n: { + locale: "en", + t: (key: string, params: Record) => { + return `${key} ${JSON.stringify(params)}` + }, + numberToCurrency: jest.fn(), + }, +})) + declare const tron // eslint-disable-line @typescript-eslint/no-unused-vars declare global { diff --git a/docs/README.md b/docs/README.md index 735cc1d25..a3c452d9a 100644 --- a/docs/README.md +++ b/docs/README.md @@ -25,11 +25,52 @@ Prerequisites: ### Intro to Ignite -If you're new to Ignite, check out these resources: +#### Resources -- Check out the [Getting Started with Ignite](https://www.youtube.com/watch?v=KOSvDlFyg20) video for a 13 minute overview! -- Jamon's Code Quest on [What's new in Ignite 9](https://www.youtube.com/watch?v=QmkMsUYrTlk) -- Check out our [Guide](./Guide.md) for a walkthrough of the boilerplate project and how to use it +Here are a few videos / talks that introduce Ignite and show off some of its features. Check them out! + + + + + + + + + + +
+
+ + Getting Started with Ignite
+
Getting Started with Ignite
+
+
+
+
+ + Sweetening React Native Development With Ignite
+
Ignite talk at Chain React 2024 - Robin Heinze
+
+
+
+
+ + Jamon's Code Quest on Ignite 9
+
What's new in Ignite 9
+
+
+
+
+ + Jamon's Code Quest on MobX-State-Tree
+
Intro to MobX-State-Tree
+
+
+
+ +#### Boilerplate Guide + +Check out our [Guide](./Guide.md) for a walkthrough of the boilerplate project and how to use it diff --git a/docs/_category_.json b/docs/_category_.json index 38fcbc41b..cc453c4ae 100644 --- a/docs/_category_.json +++ b/docs/_category_.json @@ -4,6 +4,7 @@ "customProps": { "description": "", "projectName": "ignite-cli", + "repoUrl": "https://github.com/infinitered/ignite", "sidebar": { "type": "autogenerated", "dirName": "ignite-cli" diff --git a/docs/boilerplate/app/components/AutoImage.md b/docs/boilerplate/app/components/AutoImage.md index b53d6aa55..00b7d4ad0 100644 --- a/docs/boilerplate/app/components/AutoImage.md +++ b/docs/boilerplate/app/components/AutoImage.md @@ -6,6 +6,8 @@ sidebar_position: 30 Ignite's `AutoImage` Component is an enhanced version of the built-in React Native [Image](https://reactnative.dev/docs/image) component. It automatically resizes the image view to fit a max width or height constraint +![autoimage-component](https://github.com/user-attachments/assets/8fba1f1d-81d2-4f0d-84bb-8286b048ff16) + ```tsx ``` @@ -38,6 +40,8 @@ The `preset` prop is used to set the preset container style of the card. This af The `verticalAlignment` prop is used to set the vertical alignment of the card's content. This affects the alignment of the heading, content, and footer. There are four preconfigured alignments: `top`, `center`, `space-between`, and `force-footer-bottom`. `force-footer-bottom` behaves like `top`, but will force the footer to the bottom of the card. +![card-component-02](https://github.com/user-attachments/assets/e5e9f331-6c4d-4ce3-833d-a00fdf7244f1) + ```tsx diff --git a/docs/boilerplate/app/components/Header.md b/docs/boilerplate/app/components/Header.md index 16faa2f65..d09c0cfc5 100644 --- a/docs/boilerplate/app/components/Header.md +++ b/docs/boilerplate/app/components/Header.md @@ -6,6 +6,8 @@ sidebar_position: 34 The `Header` component is a component that will appear at the top of your screen. It is used to hold navigation buttons and the screen title. +![header-component](https://github.com/user-attachments/assets/ab308ec1-21e8-41dc-a7f3-bbc6cac866e0) + ```tsx
Alert.alert("Hello")} /> ``` diff --git a/docs/boilerplate/app/components/ListItem.md b/docs/boilerplate/app/components/ListItem.md index be2c87a2f..d8505383b 100644 --- a/docs/boilerplate/app/components/ListItem.md +++ b/docs/boilerplate/app/components/ListItem.md @@ -6,6 +6,8 @@ sidebar_position: 36 The `ListItem` component is a component that is used to display a single item in a list. It provides a lot of flexibility in terms of what you can do with it. It can be used to display a simple piece text, or a complex component with multiple actionable and custom styled elements inside. +![listitem-component](https://github.com/user-attachments/assets/009aed59-5597-4d0b-b861-972608ddb8ea) + ```tsx ``` diff --git a/docs/boilerplate/app/components/Text.md b/docs/boilerplate/app/components/Text.md index f7539fb47..efd00c60d 100644 --- a/docs/boilerplate/app/components/Text.md +++ b/docs/boilerplate/app/components/Text.md @@ -8,6 +8,8 @@ Ignite's `Text` Component is an enhanced version of the built-in React Native [` By enhancing the Ignite Text component and using it across your app, you can make sure the right fonts, font weight, and other styles and behaviors are shared across your whole app. +![text-component](https://github.com/user-attachments/assets/61277e64-c530-4043-93fe-5da41c9e9351) + ## Props ### `text` diff --git a/docs/boilerplate/app/components/TextField.md b/docs/boilerplate/app/components/TextField.md index fc4df40ed..ad9ef2a13 100644 --- a/docs/boilerplate/app/components/TextField.md +++ b/docs/boilerplate/app/components/TextField.md @@ -8,6 +8,8 @@ Ignite's `TextField` Component is an enhanced version of the built-in React Nati With this component you will be able to standardise TextInput component across your app. +![textfield-component](https://github.com/user-attachments/assets/cfdc97dc-5692-4286-8682-9243ee0e7650) + ```tsx import { TextField } from '../components'; diff --git a/docs/boilerplate/app/components/_toggle_props.mdx b/docs/boilerplate/app/components/_toggle_props.mdx index b4b4b9cdb..881e81065 100644 --- a/docs/boilerplate/app/components/_toggle_props.mdx +++ b/docs/boilerplate/app/components/_toggle_props.mdx @@ -2,6 +2,8 @@ import CodeBlock from "@theme/CodeBlock" ## Toggle Props +![toggle-component](https://github.com/user-attachments/assets/ffbbe61e-9aea-4895-ab19-d38f76b3e379) + {`\<${props.componentName} value={value} onValueChange={setValue} />`} ### `status` diff --git a/docs/boilerplate/app/i18n/Internationalization.md b/docs/boilerplate/app/i18n/Internationalization.md index e08051b0f..6216ac3ab 100644 --- a/docs/boilerplate/app/i18n/Internationalization.md +++ b/docs/boilerplate/app/i18n/Internationalization.md @@ -14,16 +14,21 @@ Since Ignite already comes with an RTL language, Arabic, adding any new ones wou To remove RTL support, follow the following steps: -1. `/app/i18n/i18n.ts` +1. In `/app/i18n/i18n.ts` -- remove your RTL `.json` file from the `i18n.translations` object -- remove lines 19-21 where we allow and force RTL on the native layer +- Remove your RTL language imports +- Remove references to those language objects +- Remove lines where we allow and force RTL on the native layer -2. remove all other associated logic that uses the exported `isRTL` variable -3. remove any `tx="some.i18n.key"` from your components and use `text="Some Text"` instead +```ts +I18nManager.allowRTL(isRTL) +I18nManager.forceRTL(isRTL) +``` + +2. Remove all other associated logic that uses the exported `isRTL` variable +3. Remove any `tx="some.i18n.key"` from your components and use `text="Some Text"` instead (e.g. `` ## Adding more languages -1. add your language `.json` file to `app/i18n/`, e.g. `app/i18n/fr.json` -2. update `app/i18n/i18n.ts` `i18n.translations` object to include the newly imported language, e.g. `i18n.translations = { en, "en-US": en, ja, fr }` +See the [i18n-js Documentation](https://github.com/fnando/i18n?tab=readme-ov-file#base-translations) to add languages to `app/i18n/i18n.ts`. diff --git a/docs/contributing/Contributing-To-Ignite.md b/docs/contributing/Contributing-To-Ignite.md new file mode 100644 index 000000000..aa70d8d7f --- /dev/null +++ b/docs/contributing/Contributing-To-Ignite.md @@ -0,0 +1,29 @@ +--- +sidebar_position: 150 +--- + +# Contributing to Ignite + +## Documentation + +We include a `README.md`, `LICENSE`, and `CODE_OF_CONDUCT.md` in the root of the folder. You should read all three of them. The license is a standard MIT permissive license, and the code of conduct ensures that people are to treat each other with respect. + +## Testing changes from your local copy of Ignite + +If you want to test changes to the Ignite CLI that you have in a local git repo, that haven't been published to NPM, you can run the `bin/ignite` script via node. + +```sh +# Generate a new Ignite app from your local copy of the Ignite CLI +node your-ignite-repo-clone/bin/ignite new PizzaApp + +# Use a built-in generator from your local copy +node your-ignite-repo-clone/bin/ignite generate component OrderButton +``` + +In addition, we have automated tests you can run with `yarn test`. + +## Further reading + +Check out [A Tour of the Ignite CLI Code Base](./Tour-of-Ignite.md) for more information about Ignite's structure and features. + +We also have a guide to [Releasing Ignite](./Releasing-Ignite.md). diff --git a/docs/contributing/Tour-of-Ignite.md b/docs/contributing/Tour-of-Ignite.md index d219637a9..86de9f543 100644 --- a/docs/contributing/Tour-of-Ignite.md +++ b/docs/contributing/Tour-of-Ignite.md @@ -1,5 +1,5 @@ --- -sidebar_position: 150 +sidebar_position: 151 --- # A Tour of the Ignite CLI Code Base @@ -22,9 +22,9 @@ Prettier is also used in this project. You won't find terminal semicolons, gener ## Documentation -We include a `README.md`, `LICENSE`, and `CODE_OF_CONDUCT.md` in the root of the folder. You should read all three of them. The license is a standard MIT permissive license, and the code of conduct ensures that people are to treat each other with respect. +The `docs` folder contains all of our documentation, including this file. They're all written in Markdown for a better/simpler developer authoring experience. -There's also a `docs` folder which contains more documentation, including this file. They're all written in Markdown for a better/simpler developer authoring experience. +The docs are rolled up and published to https://docs.infinite.red by the [ir-docs project](https://github.com/infinitered/ir-docs). To learn how to see your documentation changes locally before they're published, see [the guide in ir-docs](https://github.com/infinitered/ir-docs?tab=readme-ov-file#testing-docs-locally). ## CircleCI and GitHub diff --git a/docs/contributing/_category_.json b/docs/contributing/_category_.json index 5140da060..d649571df 100644 --- a/docs/contributing/_category_.json +++ b/docs/contributing/_category_.json @@ -3,6 +3,6 @@ "position": 99, "link": { "type": "doc", - "id": "Tour-of-Ignite" + "id": "Contributing-To-Ignite" } } diff --git a/package.json b/package.json index 1f02b5fe3..76b8622ae 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ignite-cli", - "version": "9.7.2", + "version": "9.9.0", "description": "Infinite Red's hottest boilerplate for React Native.", "bin": { "ignite": "bin/ignite", @@ -47,17 +47,14 @@ }, "dependencies": { "deepmerge-json": "^1.1.0", - "gluegun": "5.1.2", - "sharp": "^0.30.4", + "gluegun": "5.1.6", + "sharp": "0.32.6", "yaml": "^1.10.0" }, "devDependencies": { - "@rnx-kit/metro-config": "^1.2.26", - "@rnx-kit/metro-resolver-symlinks": "^0.1.15", "@semantic-release/git": "^9.0.0", "@types/jest": "^27.0.1", "@types/node": "16.6.1", - "@types/sharp": "^0.30.2", "@typescript-eslint/eslint-plugin": "^5.59.0", "@typescript-eslint/parser": "^5.59.0", "babel-eslint": "^10.1.0", diff --git a/src/commands/new.ts b/src/commands/new.ts index b9f0e24ce..30414e14c 100644 --- a/src/commands/new.ts +++ b/src/commands/new.ts @@ -28,7 +28,7 @@ import { boolFlag } from "../tools/flag" import { cache } from "../tools/cache" import { mstDependenciesToRemove } from "../tools/mst" import { findAndRemoveDependencies } from "../tools/dependencies" -import { demoDependenciesToRemove } from "../tools/demo" +import { demoDependenciesToRemove, findDemoPatches } from "../tools/demo" type Workflow = "cng" | "manual" @@ -587,6 +587,9 @@ module.exports = { if (removeDemo) { log(`Removing demo dependencies... ${demoDependenciesToRemove.join(", ")}`) packageJsonRaw = findAndRemoveDependencies(packageJsonRaw, demoDependenciesToRemove) + const patchesToRemove = findDemoPatches() + log(`Removing demo patches... ${patchesToRemove}`) + patchesToRemove.forEach((patch) => filesystem.remove(patch)) } if (!includeMST) { diff --git a/src/tools/demo.ts b/src/tools/demo.ts index 8568db39c..2d3285433 100644 --- a/src/tools/demo.ts +++ b/src/tools/demo.ts @@ -1,3 +1,5 @@ +import { filesystem } from "gluegun" + export const DEMO_MARKUP_PREFIX = "@demo" export const demoDependenciesToRemove = [ @@ -5,3 +7,24 @@ export const demoDependenciesToRemove = [ "expo-application", "react-native-drawer-layout", ] + +export function findDemoPatches(): string[] { + const globs = demoDependenciesToRemove.map((dep) => `${dep}*.patch`) + const filePaths = filesystem.cwd("./patches").find({ + matching: globs, + }) + return filePaths +} + +// This function takes a package.json file as a string and removes the dependencies +// specified in demoDependenciesToRemove and returns the updated package.json as a string. +export function findAndRemoveDemoDependencies(packageJsonRaw: string): string { + let updatedPackageJson = packageJsonRaw + + demoDependenciesToRemove.forEach((depName) => { + const regex = new RegExp(`"${depName}"\\s*:\\s*"[^"]+",?`, "g") + updatedPackageJson = updatedPackageJson.replace(regex, "") + }) + + return updatedPackageJson +} diff --git a/test/vanilla/__snapshots__/ignite-remove-demo.test.ts.snap b/test/vanilla/__snapshots__/ignite-remove-demo.test.ts.snap index f4bd4df4d..a87ac3b86 100644 --- a/test/vanilla/__snapshots__/ignite-remove-demo.test.ts.snap +++ b/test/vanilla/__snapshots__/ignite-remove-demo.test.ts.snap @@ -5,6 +5,11 @@ exports[`ignite-cli remove-demo should print the expected response 1`] = ` Removing demo code from '/user/home/ignite' removing file /user/home/ignite/.maestro/FavoritePodcast.yaml removing file /user/home/ignite/.maestro/Login.yaml +removing file /user/home/ignite/app/i18n/demo-ar.ts +removing file /user/home/ignite/app/i18n/demo-en.ts +removing file /user/home/ignite/app/i18n/demo-fr.ts +removing file /user/home/ignite/app/i18n/demo-jp.ts +removing file /user/home/ignite/app/i18n/demo-ko.ts removing file /user/home/ignite/app/models/AuthenticationStore.ts removing file /user/home/ignite/app/models/Episode.test.ts removing file /user/home/ignite/app/models/Episode.ts @@ -33,6 +38,11 @@ removing file /user/home/ignite/app/screens/LoginScreen.tsx Found 'remove-file' in /user/home/ignite/.maestro/Login.yaml Found '@demo remove-current-line' in /user/home/ignite/app/components/Icon.tsx Found '@demo remove-current-line', '@demo remove-block-start', '@demo remove-block-end' in /user/home/ignite/app/i18n/ar.ts + Found 'remove-file' in /user/home/ignite/app/i18n/demo-ar.ts + Found 'remove-file' in /user/home/ignite/app/i18n/demo-en.ts + Found 'remove-file' in /user/home/ignite/app/i18n/demo-fr.ts + Found 'remove-file' in /user/home/ignite/app/i18n/demo-jp.ts + Found 'remove-file' in /user/home/ignite/app/i18n/demo-ko.ts Found '@demo remove-current-line', '@demo remove-block-start', '@demo remove-block-end' in /user/home/ignite/app/i18n/en.ts Found '@demo remove-current-line', '@demo remove-block-start', '@demo remove-block-end' in /user/home/ignite/app/i18n/fr.ts Found '@demo remove-current-line', '@demo remove-block-start', '@demo remove-block-end' in /user/home/ignite/app/i18n/jp.ts diff --git a/test/vanilla/ignite-new.test.ts b/test/vanilla/ignite-new.test.ts index 3a6e108bf..e39064f01 100644 --- a/test/vanilla/ignite-new.test.ts +++ b/test/vanilla/ignite-new.test.ts @@ -271,6 +271,51 @@ describe("ignite new", () => { // we're done! }) }) + + // Yarn (only testing what might be affected by a different package manager: dependency installation, running commands) + describe(`ignite new ${APP_NAME} --debug --packager=yarn --yes`, () => { + let tempDir: string + let result: string + let appPath: string + beforeAll(async () => { + tempDir = tempy.directory({ prefix: "ignite-" }) + + result = await runIgnite(`new ${APP_NAME} --debug --packager=yarn --workflow=cng --yes`, { + pre: `cd ${tempDir}`, + post: `cd ${originalDir}`, + }) + + appPath = filesystem.path(tempDir, APP_NAME) + }) + + afterAll(() => { + // console.log(tempDir) // uncomment for debugging, then run `code ` to see the generated app + filesystem.remove(tempDir) // clean up our mess + }) + + it("should print success message", () => { + // at some point this should probably be a snapshot? + expect(result).toContain("Now get cooking! 🍽") + }) + + it("should be able to use `generate` command and have pass output pass yarn test, yarn lint, and yarn compile scripts", async () => { + // other common test operations + const runOpts = { + pre: `cd ${appPath}`, + post: `cd ${originalDir}`, + } + + // #region Assert package.json Scripts Can Be Run + // run the tests; if they fail, run will raise and this test will fail + await run(`yarn test`, runOpts) + await run(`yarn lint`, runOpts) + await run(`yarn compile`, runOpts) + expect(await run("git diff HEAD --no-ext-diff", runOpts)).toBe("") + }) + // #endregion + + // we're done! + }) }) async function checkForLeftoverHelloWorld(filePath: string) { diff --git a/yarn.lock b/yarn.lock index c19451cdc..270fa5d48 100644 --- a/yarn.lock +++ b/yarn.lock @@ -256,7 +256,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-syntax-typescript@^7.3.3", "@babel/plugin-syntax-typescript@^7.7.2": +"@babel/plugin-syntax-typescript@^7.7.2": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.22.5.tgz#aac8d383b062c5072c647a31ef990c1d0af90272" integrity sha512-1mS2o03i7t1c6VzH6fdQ3OA8tcEIxwG18zIPRp+UY1Ihv6W+XZzBCVxExF9upussPXJ0xE9XRHwMoNs1ep/nRQ== @@ -272,7 +272,7 @@ "@babel/parser" "^7.22.15" "@babel/types" "^7.22.15" -"@babel/traverse@^7.16.0", "@babel/traverse@^7.22.15", "@babel/traverse@^7.22.20", "@babel/traverse@^7.7.0", "@babel/traverse@^7.7.2": +"@babel/traverse@^7.22.15", "@babel/traverse@^7.22.20", "@babel/traverse@^7.7.0", "@babel/traverse@^7.7.2": version "7.22.20" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.22.20.tgz#db572d9cb5c79e02d83e5618b82f6991c07584c9" integrity sha512-eU260mPZbU7mZ0N+X10pxXhQFMGTeLb9eFS0mxehS8HZp9o1uSnFeWQuG1UPrlxgA7QoUzFhOnilHDp0AXCyHw== @@ -864,72 +864,6 @@ dependencies: "@octokit/openapi-types" "^12.11.0" -"@rnx-kit/babel-preset-metro-react-native@^1.1.4": - version "1.1.4" - resolved "https://registry.yarnpkg.com/@rnx-kit/babel-preset-metro-react-native/-/babel-preset-metro-react-native-1.1.4.tgz#7c526987208547614f7fc43ed6e001b183083dd7" - integrity sha512-ev82sa8Q5Z4a7kQ9pfCKYvpPpPesn0bgOFX8mNx5Gb3uZENb1i1oqySsmw1Qrrf/1KCMi4DKXOI7KezUl8Kf4g== - dependencies: - babel-plugin-const-enum "^1.0.0" - -"@rnx-kit/console@^1.0.0": - version "1.0.12" - resolved "https://registry.yarnpkg.com/@rnx-kit/console/-/console-1.0.12.tgz#997e370afdeee49344663c1ae017ba0b4966a5c9" - integrity sha512-egjvLiXFJwS5TznWnb5I6vLJ2kYW/lYZPa3E1awam+datbyf/elAH4h1ZCfOd/aiTBQur91HwX07k0WgOHJSow== - dependencies: - chalk "^4.1.0" - -"@rnx-kit/metro-config@^1.2.26": - version "1.3.9" - resolved "https://registry.yarnpkg.com/@rnx-kit/metro-config/-/metro-config-1.3.9.tgz#5deefd9652ba6e553a8f1d102b200371d6ae2755" - integrity sha512-jAnMv11P+hknBz3fAkw0wK4ytf7ROr3kD6mwBdX6ggL2q85e3bozTm7PIymF4uI17tjgBbOGNsgZnU76Lu3SSw== - dependencies: - "@rnx-kit/babel-preset-metro-react-native" "^1.1.4" - "@rnx-kit/console" "^1.0.0" - "@rnx-kit/tools-node" "^2.0.0" - "@rnx-kit/tools-react-native" "^1.3.1" - "@rnx-kit/tools-workspaces" "^0.1.3" - -"@rnx-kit/metro-resolver-symlinks@^0.1.15": - version "0.1.32" - resolved "https://registry.yarnpkg.com/@rnx-kit/metro-resolver-symlinks/-/metro-resolver-symlinks-0.1.32.tgz#cdc2b936d79c13a49330ad9599327f32efcb31d6" - integrity sha512-Qno15y1pGTTAhQXmM/CKWLjjzDCQxNQH3zw/el20bZWJWn5ve6cSyJb86Me5/AOb0pq3bBzwswtnqtm5v6ZskQ== - dependencies: - "@rnx-kit/tools-node" "^2.0.0" - "@rnx-kit/tools-react-native" "^1.3.2" - enhanced-resolve "^5.8.3" - -"@rnx-kit/tools-language@^2.0.1": - version "2.0.1" - resolved "https://registry.yarnpkg.com/@rnx-kit/tools-language/-/tools-language-2.0.1.tgz#1d815966faea816b98a2a57c3e41851b3404838e" - integrity sha512-2A9O3frfTXgIaJXOjpeXDTUInXD46XX1YFeUgGw90c2Dyx4sgqED3LX4hRz9lXW0SFV8q7JqDo/G3Hhn2WZBng== - -"@rnx-kit/tools-node@^2.0.0", "@rnx-kit/tools-node@^2.0.1": - version "2.0.1" - resolved "https://registry.yarnpkg.com/@rnx-kit/tools-node/-/tools-node-2.0.1.tgz#0f34033731b721179323fa49b882e922abe0f5f3" - integrity sha512-OHv7ongwxALIzkS+Xf1FxrpRlcbNTin5Rw3Qbhgy9855ivv4TyOoime8eBB5rnu12PZOicV1tyOXXIpsxOJg5g== - dependencies: - "@rnx-kit/tools-language" "^2.0.1" - find-up "^5.0.0" - pkg-dir "^5.0.0" - pkg-up "^3.1.0" - -"@rnx-kit/tools-react-native@^1.3.1", "@rnx-kit/tools-react-native@^1.3.2": - version "1.3.3" - resolved "https://registry.yarnpkg.com/@rnx-kit/tools-react-native/-/tools-react-native-1.3.3.tgz#0370852afde68dda5c63076b4d1fdf9177787548" - integrity sha512-Fm32sURdEtkrjfEuG/V19lOnWj5uVKI2hAA1B7pg7kV1bESeAR4k7wpGd5cTgOyYFhE8cG/prYcTM2z8MnWbiQ== - dependencies: - "@rnx-kit/tools-node" "^2.0.1" - -"@rnx-kit/tools-workspaces@^0.1.3": - version "0.1.5" - resolved "https://registry.yarnpkg.com/@rnx-kit/tools-workspaces/-/tools-workspaces-0.1.5.tgz#bd602e68818d668216265bede5fd358dd854a68f" - integrity sha512-f0qJg70NxlLIrdmbbVAcavIQtpYGYE6iqDi81u/Ipyq7CmwCbsHK3uUnFrXBsfigF3Bl2gIiBJlfF96MfqVOkg== - dependencies: - fast-glob "^3.2.7" - find-up "^5.0.0" - read-yaml-file "^2.1.0" - strip-json-comments "^3.1.1" - "@semantic-release/commit-analyzer@^8.0.0": version "8.0.1" resolved "https://registry.yarnpkg.com/@semantic-release/commit-analyzer/-/commit-analyzer-8.0.1.tgz#5d2a37cd5a3312da0e3ac05b1ca348bf60b90bca" @@ -1175,13 +1109,6 @@ resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.2.tgz#31f6eec1ed7ec23f4f05608d3a2d381df041f564" integrity sha512-7aqorHYgdNO4DM36stTiGO3DvKoex9TQRwsJU6vMaFGyqpBA1MNZkz+PG3gaNUPpTAOYhT1WR7M1JyA3fbS9Cw== -"@types/sharp@^0.30.2": - version "0.30.5" - resolved "https://registry.yarnpkg.com/@types/sharp/-/sharp-0.30.5.tgz#d75d91f7acf5260525aeae229845046dcff6d17a" - integrity sha512-EhO29617AIBqxoVtpd1qdBanWpspk/kD2B6qTFRJ31Q23Rdf+DNU1xlHSwtqvwq1vgOqBwq1i38SX+HGCymIQg== - dependencies: - "@types/node" "*" - "@types/stack-utils@^2.0.0": version "2.0.1" resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.1.tgz#20f18294f797f2209b5f65c8e3b5c8e8261d127c" @@ -1500,11 +1427,6 @@ argparse@^1.0.7: dependencies: sprintf-js "~1.0.2" -argparse@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" - integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== - argv-formatter@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/argv-formatter/-/argv-formatter-1.0.0.tgz#a0ca0cbc29a5b73e836eebe1cbf6c5e0e4eb82f9" @@ -1642,6 +1564,11 @@ axios@^0.21.4: dependencies: follow-redirects "^1.14.0" +b4a@^1.6.4: + version "1.6.6" + resolved "https://registry.yarnpkg.com/b4a/-/b4a-1.6.6.tgz#a4cc349a3851987c3c4ac2d7785c18744f6da9ba" + integrity sha512-5Tk1HLk6b6ctmjIkAcU/Ujv/1WqiDl0F0JdRCR80VsOcUlHcu7pWeWRlOqQLHfDEsVx9YH/aif5AG4ehoCtTmg== + babel-eslint@^10.1.0: version "10.1.0" resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-10.1.0.tgz#6968e568a910b78fb3779cdd8b6ac2f479943232" @@ -1668,15 +1595,6 @@ babel-jest@^27.5.1: graceful-fs "^4.2.9" slash "^3.0.0" -babel-plugin-const-enum@^1.0.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/babel-plugin-const-enum/-/babel-plugin-const-enum-1.2.0.tgz#3d25524106f68f081e187829ba736b251c289861" - integrity sha512-o1m/6iyyFnp9MRsK1dHF3bneqyf3AlM2q3A/YbgQr2pCat6B6XJVDv2TXqzfY2RYUi4mak6WAksSBPlyYGx9dg== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-typescript" "^7.3.3" - "@babel/traverse" "^7.16.0" - babel-plugin-istanbul@^6.1.1: version "6.1.1" resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz#fa88ec59232fd9b4e36dbbc540a8ec9a9b47da73" @@ -1729,6 +1647,39 @@ balanced-match@^1.0.0: resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== +bare-events@^2.0.0, bare-events@^2.2.0: + version "2.4.2" + resolved "https://registry.yarnpkg.com/bare-events/-/bare-events-2.4.2.tgz#3140cca7a0e11d49b3edc5041ab560659fd8e1f8" + integrity sha512-qMKFd2qG/36aA4GwvKq8MxnPgCQAmBWmSyLWsJcbn8v03wvIPQ/hG1Ms8bPzndZxMDoHpxez5VOS+gC9Yi24/Q== + +bare-fs@^2.1.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/bare-fs/-/bare-fs-2.3.1.tgz#cdbd63dac7a552dfb2b87d18c822298d1efd213d" + integrity sha512-W/Hfxc/6VehXlsgFtbB5B4xFcsCl+pAh30cYhoFyXErf6oGrwjh8SwiPAdHgpmWonKuYpZgGywN0SXt7dgsADA== + dependencies: + bare-events "^2.0.0" + bare-path "^2.0.0" + bare-stream "^2.0.0" + +bare-os@^2.1.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/bare-os/-/bare-os-2.4.0.tgz#5de5e3ba7704f459c9656629edca7cc736e06608" + integrity sha512-v8DTT08AS/G0F9xrhyLtepoo9EJBJ85FRSMbu1pQUlAf6A8T0tEEQGMVObWeqpjhSPXsE0VGlluFBJu2fdoTNg== + +bare-path@^2.0.0, bare-path@^2.1.0: + version "2.1.3" + resolved "https://registry.yarnpkg.com/bare-path/-/bare-path-2.1.3.tgz#594104c829ef660e43b5589ec8daef7df6cedb3e" + integrity sha512-lh/eITfU8hrj9Ru5quUp0Io1kJWIk1bTjzo7JH1P5dWmQ2EL4hFUlfI8FonAhSlgIfhn63p84CDY/x+PisgcXA== + dependencies: + bare-os "^2.1.0" + +bare-stream@^2.0.0: + version "2.1.3" + resolved "https://registry.yarnpkg.com/bare-stream/-/bare-stream-2.1.3.tgz#070b69919963a437cc9e20554ede079ce0a129b2" + integrity sha512-tiDAH9H/kP+tvNO5sczyn9ZAA7utrSMobyDchsnyyXBuUe2FSQWbxhtuHB8jwpHYYevVo2UJpcmvvjrbHboUUQ== + dependencies: + streamx "^2.18.0" + base64-js@^1.3.1: version "1.5.1" resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" @@ -2398,10 +2349,10 @@ deprecation@^2.0.0, deprecation@^2.3.1: resolved "https://registry.yarnpkg.com/deprecation/-/deprecation-2.3.1.tgz#6368cbdb40abf3373b525ac87e4a260c3a700919" integrity sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ== -detect-libc@^2.0.0, detect-libc@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.0.2.tgz#8ccf2ba9315350e1241b88d0ac3b0e1fbd99605d" - integrity sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw== +detect-libc@^2.0.0, detect-libc@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.0.3.tgz#f0cd503b40f9939b894697d19ad50895e30cf700" + integrity sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw== detect-newline@^3.0.0: version "3.1.0" @@ -2481,12 +2432,12 @@ ecc-jsbn@~0.1.1: jsbn "~0.1.0" safer-buffer "^2.1.0" -ejs@3.1.6: - version "3.1.6" - resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.6.tgz#5bfd0a0689743bb5268b3550cceeebbc1702822a" - integrity sha512-9lt9Zse4hPucPkoP7FHDF0LQAlGyF9JVpnClFLFH3aSSbxmyoqINRpp/9wePWJTUl4KOQwRL72Iw3InHPDkoGw== +ejs@3.1.8: + version "3.1.8" + resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.8.tgz#758d32910c78047585c7ef1f92f9ee041c1c190b" + integrity sha512-/sXZeMlhS0ArkfX2Aw780gJzXSMPnKjtspYZv+f3NiKLlubezAHDU5+9xz6gd3/NhG3txQCo6xlglmTS+oTGEQ== dependencies: - jake "^10.6.1" + jake "^10.8.5" electron-to-chromium@^1.4.477: version "1.4.525" @@ -2517,14 +2468,6 @@ end-of-stream@^1.1.0, end-of-stream@^1.4.1: dependencies: once "^1.4.0" -enhanced-resolve@^5.8.3: - version "5.15.0" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz#1af946c7d93603eb88e9896cee4904dc012e9c35" - integrity sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg== - dependencies: - graceful-fs "^4.2.4" - tapable "^2.2.0" - enquirer@2.3.6: version "2.3.6" resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" @@ -2915,7 +2858,12 @@ fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== -fast-glob@^3.2.7, fast-glob@^3.2.9: +fast-fifo@^1.2.0, fast-fifo@^1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/fast-fifo/-/fast-fifo-1.3.2.tgz#286e31de96eb96d38a97899815740ba2a4f3640c" + integrity sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ== + +fast-glob@^3.2.9: version "3.3.1" resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.1.tgz#784b4e897340f3dbbef17413b3f11acf03c874c4" integrity sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg== @@ -2997,13 +2945,6 @@ find-up@^2.0.0: dependencies: locate-path "^2.0.0" -find-up@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" - integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== - dependencies: - locate-path "^3.0.0" - find-up@^4.0.0, find-up@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" @@ -3012,14 +2953,6 @@ find-up@^4.0.0, find-up@^4.1.0: locate-path "^5.0.0" path-exists "^4.0.0" -find-up@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" - integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== - dependencies: - locate-path "^6.0.0" - path-exists "^4.0.0" - find-versions@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/find-versions/-/find-versions-4.0.0.tgz#3c57e573bf97769b8cb8df16934b627915da4965" @@ -3294,10 +3227,10 @@ globby@^11.0.0, globby@^11.0.1, globby@^11.1.0: merge2 "^1.4.1" slash "^3.0.0" -gluegun@5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/gluegun/-/gluegun-5.1.2.tgz#ffa0beda0fb6bbc089a867157b08602beae2c8cf" - integrity sha512-Cwx/8S8Z4YQg07a6AFsaGnnnmd8mN17414NcPS3OoDtZRwxgsvwRNJNg69niD6fDa8oNwslCG0xH7rEpRNNE/g== +gluegun@5.1.6: + version "5.1.6" + resolved "https://registry.yarnpkg.com/gluegun/-/gluegun-5.1.6.tgz#74ec13193913dc610f5c1a4039972c70c96a7bad" + integrity sha512-9zbi4EQWIVvSOftJWquWzr9gLX2kaDgPkNR5dYWbM53eVvCI3iKuxLlnKoHC0v4uPoq+Kr/+F569tjoFbA4DSA== dependencies: apisauce "^2.1.5" app-module-path "^2.2.0" @@ -3305,7 +3238,7 @@ gluegun@5.1.2: colors "1.4.0" cosmiconfig "7.0.1" cross-spawn "7.0.3" - ejs "3.1.6" + ejs "3.1.8" enquirer "2.3.6" execa "5.1.1" fs-jetpack "4.3.1" @@ -3926,10 +3859,10 @@ istanbul-reports@^3.1.3: html-escaper "^2.0.0" istanbul-lib-report "^3.0.0" -jake@^10.6.1: - version "10.8.7" - resolved "https://registry.yarnpkg.com/jake/-/jake-10.8.7.tgz#63a32821177940c33f356e0ba44ff9d34e1c7d8f" - integrity sha512-ZDi3aP+fG/LchyBzUM804VjddnwfSfsdeYkwt8NcbKRvo4rFkjhs456iLFn3k2ZUWvNe4i48WACDbza8fhq2+w== +jake@^10.8.5: + version "10.9.2" + resolved "https://registry.yarnpkg.com/jake/-/jake-10.9.2.tgz#6ae487e6a69afec3a5e167628996b59f35ae2b7f" + integrity sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA== dependencies: async "^3.2.3" chalk "^4.0.2" @@ -4359,13 +4292,6 @@ js-yaml@^3.13.1: argparse "^1.0.7" esprima "^4.0.0" -js-yaml@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" - integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== - dependencies: - argparse "^2.0.1" - jsbn@~0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" @@ -4663,14 +4589,6 @@ locate-path@^2.0.0: p-locate "^2.0.0" path-exists "^3.0.0" -locate-path@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" - integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== - dependencies: - p-locate "^3.0.0" - path-exists "^3.0.0" - locate-path@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" @@ -4678,13 +4596,6 @@ locate-path@^5.0.0: dependencies: p-locate "^4.1.0" -locate-path@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" - integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== - dependencies: - p-locate "^5.0.0" - lodash.camelcase@^4.3.0: version "4.3.0" resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" @@ -5131,16 +5042,16 @@ nerf-dart@^1.0.0: integrity sha512-EZSPZB70jiVsivaBLYDCyntd5eH8NTSMOn3rB+HxwdmKThGELLdYv8qVIMWvZEFy9w8ZZpW9h9OB32l1rGtj7g== node-abi@^3.3.0: - version "3.47.0" - resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-3.47.0.tgz#6cbfa2916805ae25c2b7156ca640131632eb05e8" - integrity sha512-2s6B2CWZM//kPgwnuI0KrYwNjfdByE25zvAaEpq9IH4zcNsarH8Ihu/UuX6XMPEogDAxkuUFeZn60pXNHAqn3A== + version "3.65.0" + resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-3.65.0.tgz#ca92d559388e1e9cab1680a18c1a18757cdac9d3" + integrity sha512-ThjYBfoDNr08AWx6hGaRbfPwxKV9kVzAzOzlLKbk2CuqXE2xnCh+cbAGnwM3t8Lq4v9rUB7VfondlkBckcJrVA== dependencies: semver "^7.3.5" -node-addon-api@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-5.1.0.tgz#49da1ca055e109a23d537e9de43c09cca21eb762" - integrity sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA== +node-addon-api@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-6.1.0.tgz#ac8470034e58e67d0c6f1204a18ae6995d9c0d76" + integrity sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA== node-emoji@^1.10.0: version "1.11.0" @@ -5537,20 +5448,13 @@ p-limit@^1.1.0: dependencies: p-try "^1.0.0" -p-limit@^2.0.0, p-limit@^2.2.0: +p-limit@^2.2.0: version "2.3.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== dependencies: p-try "^2.0.0" -p-limit@^3.0.2: - version "3.1.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" - integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== - dependencies: - yocto-queue "^0.1.0" - p-locate@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" @@ -5558,13 +5462,6 @@ p-locate@^2.0.0: dependencies: p-limit "^1.1.0" -p-locate@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" - integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== - dependencies: - p-limit "^2.0.0" - p-locate@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" @@ -5572,13 +5469,6 @@ p-locate@^4.1.0: dependencies: p-limit "^2.2.0" -p-locate@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" - integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== - dependencies: - p-limit "^3.0.2" - p-map@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/p-map/-/p-map-2.1.0.tgz#310928feef9c9ecc65b68b17693018a665cea175" @@ -5748,29 +5638,15 @@ pkg-dir@^4.2.0: dependencies: find-up "^4.0.0" -pkg-dir@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-5.0.0.tgz#a02d6aebe6ba133a928f74aec20bafdfe6b8e760" - integrity sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA== - dependencies: - find-up "^5.0.0" - -pkg-up@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-3.1.0.tgz#100ec235cc150e4fd42519412596a28512a0def5" - integrity sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA== - dependencies: - find-up "^3.0.0" - pluralize@^8.0.0: version "8.0.0" resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-8.0.0.tgz#1a6fa16a38d12a1901e0320fa017051c539ce3b1" integrity sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA== prebuild-install@^7.1.1: - version "7.1.1" - resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-7.1.1.tgz#de97d5b34a70a0c81334fd24641f2a1702352e45" - integrity sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw== + version "7.1.2" + resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-7.1.2.tgz#a5fd9986f5a6251fbc47e1e5c65de71e68c0a056" + integrity sha512-UnNke3IQb6sgarcZIDU3gbMeTp/9SSU1DAIkil7PrqG1vZlBtY5msYccSKSHDqa3hNg436IXK+SNImReuA1wEQ== dependencies: detect-libc "^2.0.0" expand-template "^2.0.3" @@ -5900,6 +5776,11 @@ queue-microtask@^1.2.2: resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== +queue-tick@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/queue-tick/-/queue-tick-1.0.1.tgz#f6f07ac82c1fd60f82e098b417a80e52f1f4c142" + integrity sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag== + quick-lru@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-4.0.1.tgz#5b8878f113a58217848c6482026c73e1ba57727f" @@ -5962,14 +5843,6 @@ read-pkg@^5.0.0, read-pkg@^5.2.0: parse-json "^5.0.0" type-fest "^0.6.0" -read-yaml-file@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/read-yaml-file/-/read-yaml-file-2.1.0.tgz#c5866712db9ef5343b4d02c2413bada53c41c4a9" - integrity sha512-UkRNRIwnhG+y7hpqnycCL/xbTk7+ia9VuVTC0S+zVbwd65DI9eUpRMfsWIGrCWxTU/mi+JW8cHQCrv+zfCbEPQ== - dependencies: - js-yaml "^4.0.0" - strip-bom "^4.0.0" - read@1, read@^1.0.7, read@~1.0.1, read@~1.0.7: version "1.0.7" resolved "https://registry.yarnpkg.com/read/-/read-1.0.7.tgz#b3da19bd052431a97671d44a42634adf710b40c4" @@ -6272,6 +6145,11 @@ semver@^6.0.0, semver@^6.1.0, semver@^6.3.0, semver@^6.3.1: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== +semver@^7.5.4: + version "7.6.3" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.3.tgz#980f7b5550bc175fb4dc09403085627f9eb33143" + integrity sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A== + set-blocking@^2.0.0, set-blocking@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" @@ -6286,18 +6164,18 @@ set-function-name@^2.0.0: functions-have-names "^1.2.3" has-property-descriptors "^1.0.0" -sharp@^0.30.4: - version "0.30.7" - resolved "https://registry.yarnpkg.com/sharp/-/sharp-0.30.7.tgz#7862bda98804fdd1f0d5659c85e3324b90d94c7c" - integrity sha512-G+MY2YW33jgflKPTXXptVO28HvNOo9G3j0MybYAHeEmby+QuD2U98dT6ueht9cv/XDqZspSpIhoSW+BAKJ7Hig== +sharp@0.32.6: + version "0.32.6" + resolved "https://registry.yarnpkg.com/sharp/-/sharp-0.32.6.tgz#6ad30c0b7cd910df65d5f355f774aa4fce45732a" + integrity sha512-KyLTWwgcR9Oe4d9HwCwNM2l7+J0dUQwn/yf7S0EnTtb0eVS4RxO0eUSvxPtzT4F3SY+C4K6fqdv/DO27sJ/v/w== dependencies: color "^4.2.3" - detect-libc "^2.0.1" - node-addon-api "^5.0.0" + detect-libc "^2.0.2" + node-addon-api "^6.1.0" prebuild-install "^7.1.1" - semver "^7.3.7" + semver "^7.5.4" simple-get "^4.0.1" - tar-fs "^2.1.1" + tar-fs "^3.0.4" tunnel-agent "^0.6.0" shebang-command@^2.0.0: @@ -6509,6 +6387,17 @@ stream-combiner2@~1.1.1: duplexer2 "~0.1.0" readable-stream "^2.0.2" +streamx@^2.15.0, streamx@^2.18.0: + version "2.18.0" + resolved "https://registry.yarnpkg.com/streamx/-/streamx-2.18.0.tgz#5bc1a51eb412a667ebfdcd4e6cf6a6fc65721ac7" + integrity sha512-LLUC1TWdjVdn1weXGcSxyTR3T4+acB6tVGXT95y0nGbca4t4o/ng1wKAGTljm9VicuCVLvRlqFYXYy5GwgM7sQ== + dependencies: + fast-fifo "^1.3.2" + queue-tick "^1.0.1" + text-decoder "^1.1.0" + optionalDependencies: + bare-events "^2.2.0" + string-length@^4.0.1: version "4.0.2" resolved "https://registry.yarnpkg.com/string-length/-/string-length-4.0.2.tgz#a8a8dc7bd5c1a82b9b3c8b87e125f66871b6e57a" @@ -6699,12 +6588,7 @@ table@^6.0.9: string-width "^4.2.3" strip-ansi "^6.0.1" -tapable@^2.2.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" - integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== - -tar-fs@^2.0.0, tar-fs@^2.1.1: +tar-fs@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.1.1.tgz#489a15ab85f1f0befabb370b7de4f9eb5cbe8784" integrity sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng== @@ -6714,6 +6598,17 @@ tar-fs@^2.0.0, tar-fs@^2.1.1: pump "^3.0.0" tar-stream "^2.1.4" +tar-fs@^3.0.4: + version "3.0.6" + resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-3.0.6.tgz#eaccd3a67d5672f09ca8e8f9c3d2b89fa173f217" + integrity sha512-iokBDQQkUyeXhgPYaZxmczGPhnhXZ0CmrqI+MOb/WFGS9DW5wnfrLgtjUJBvz50vQ3qfRwJ62QVoCFu8mPVu5w== + dependencies: + pump "^3.0.0" + tar-stream "^3.1.5" + optionalDependencies: + bare-fs "^2.1.1" + bare-path "^2.1.0" + tar-stream@^2.1.4: version "2.2.0" resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.2.0.tgz#acad84c284136b060dc3faa64474aa9aebd77287" @@ -6725,6 +6620,15 @@ tar-stream@^2.1.4: inherits "^2.0.3" readable-stream "^3.1.1" +tar-stream@^3.1.5: + version "3.1.7" + resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-3.1.7.tgz#24b3fb5eabada19fe7338ed6d26e5f7c482e792b" + integrity sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ== + dependencies: + b4a "^1.6.4" + fast-fifo "^1.2.0" + streamx "^2.15.0" + tar@^6.0.2, tar@^6.1.0, tar@^6.1.11: version "6.2.0" resolved "https://registry.yarnpkg.com/tar/-/tar-6.2.0.tgz#b14ce49a79cb1cd23bc9b016302dea5474493f73" @@ -6770,6 +6674,13 @@ test-exclude@^6.0.0: glob "^7.1.4" minimatch "^3.0.4" +text-decoder@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/text-decoder/-/text-decoder-1.1.1.tgz#5df9c224cebac4a7977720b9f083f9efa1aefde8" + integrity sha512-8zll7REEv4GDD3x4/0pW+ppIxSNs7H1J10IKFZsuOMscumCdM2a+toDGLPA3T+1+fLBql4zbt5z83GEQGGV5VA== + dependencies: + b4a "^1.6.4" + text-extensions@^1.0.0: version "1.9.0" resolved "https://registry.yarnpkg.com/text-extensions/-/text-extensions-1.9.0.tgz#1853e45fee39c945ce6f6c36b2d659b5aabc2a26" @@ -7373,8 +7284,3 @@ yn@3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== - -yocto-queue@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" - integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==