├── .husky ├── .gitignore ├── .npmignore ├── commit-msg └── pre-commit ├── src ├── index.tsx ├── hooks │ ├── index.ts │ ├── usePrevious.ts │ └── useToggle.ts ├── ClippedShrunkText.tsx └── MoreOrLess.tsx ├── babel.config.ts ├── .gitattributes ├── tsconfig.build.json ├── example ├── assets │ ├── icon.png │ ├── favicon.png │ ├── splash.png │ └── adaptive-icon.png ├── babel.config.ts ├── tsconfig.json ├── .gitignore ├── package.json ├── app.json ├── CustomText.tsx └── App.tsx ├── tsconfig.spec.json ├── .yarnrc ├── .yarnrc.yml ├── .prettierrc ├── legacy-package └── package.json ├── .editorconfig ├── tsconfig.json ├── jest.config.ts ├── CHANGELOG.md ├── scripts └── bootstrap.ts ├── LICENSE ├── .gitignore ├── eslint.config.mjs ├── .circleci └── config.yml ├── README.md ├── package.json └── CONTRIBUTING.md /.husky/.gitignore: -------------------------------------------------------------------------------- 1 | _ 2 | -------------------------------------------------------------------------------- /.husky/.npmignore: -------------------------------------------------------------------------------- 1 | _ 2 | -------------------------------------------------------------------------------- /.husky/commit-msg: -------------------------------------------------------------------------------- 1 | npx commitlint --edit 2 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | yarn lint && yarn typescript 2 | -------------------------------------------------------------------------------- /src/index.tsx: -------------------------------------------------------------------------------- 1 | export { default as MoreOrLess } from './MoreOrLess'; 2 | -------------------------------------------------------------------------------- /babel.config.ts: -------------------------------------------------------------------------------- 1 | export default { presets: ['module:@react-native/babel-preset'] }; 2 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.pbxproj -text 2 | # specific for windows script files 3 | *.bat text eol=crlf -------------------------------------------------------------------------------- /tsconfig.build.json: -------------------------------------------------------------------------------- 1 | 2 | { 3 | "extends": "./tsconfig", 4 | "exclude": ["example"] 5 | } 6 | -------------------------------------------------------------------------------- /src/hooks/index.ts: -------------------------------------------------------------------------------- 1 | export { usePrevious } from './usePrevious'; 2 | export { useToggle } from './useToggle'; 3 | -------------------------------------------------------------------------------- /example/assets/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rarenatoe/react-native-more-or-less-text/HEAD/example/assets/icon.png -------------------------------------------------------------------------------- /tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "jsx": "react" 5 | } 6 | } -------------------------------------------------------------------------------- /example/assets/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rarenatoe/react-native-more-or-less-text/HEAD/example/assets/favicon.png -------------------------------------------------------------------------------- /example/assets/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rarenatoe/react-native-more-or-less-text/HEAD/example/assets/splash.png -------------------------------------------------------------------------------- /example/assets/adaptive-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rarenatoe/react-native-more-or-less-text/HEAD/example/assets/adaptive-icon.png -------------------------------------------------------------------------------- /.yarnrc: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | yarn-path ".yarn/releases/yarn-1.22.19.cjs" 6 | -------------------------------------------------------------------------------- /.yarnrc.yml: -------------------------------------------------------------------------------- 1 | compressionLevel: mixed 2 | 3 | enableGlobalCache: false 4 | 5 | nodeLinker: node-modules 6 | 7 | yarnPath: .yarn/releases/yarn-4.9.2.cjs 8 | -------------------------------------------------------------------------------- /example/babel.config.ts: -------------------------------------------------------------------------------- 1 | module.exports = function(api) { 2 | api.cache(true); 3 | return { 4 | presets: ['babel-preset-expo'], 5 | }; 6 | }; 7 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 100, 3 | "quoteProps": "consistent", 4 | "singleQuote": true, 5 | "tabWidth": 2, 6 | "trailingComma": "es5", 7 | "useTabs": false 8 | } 9 | -------------------------------------------------------------------------------- /legacy-package/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@rntext/more-or-less", 3 | "version": "2.1.0", 4 | "description": "Alias for react-native-more-or-less-text", 5 | "dependencies": { 6 | "react-native-more-or-less-text": "^2.0.0" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/hooks/usePrevious.ts: -------------------------------------------------------------------------------- 1 | import { useEffect, useRef } from 'react'; 2 | 3 | export const usePrevious = (value: T): T | undefined => { 4 | const ref = useRef(); 5 | useEffect(() => { 6 | ref.current = value; 7 | }); 8 | return ref.current; 9 | }; 10 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig helps developers define and maintain consistent 2 | # coding styles between different editors and IDEs 3 | # editorconfig.org 4 | 5 | root = true 6 | 7 | [*] 8 | 9 | indent_style = space 10 | indent_size = 2 11 | 12 | end_of_line = lf 13 | charset = utf-8 14 | trim_trailing_whitespace = true 15 | insert_final_newline = true 16 | -------------------------------------------------------------------------------- /example/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "allowJs": true, 4 | "allowSyntheticDefaultImports": true, 5 | "esModuleInterop": true, 6 | "isolatedModules": true, 7 | "jsx": "react-native", 8 | "moduleResolution": "node", 9 | "noEmit": true, 10 | "resolveJsonModule": true, 11 | "skipLibCheck": true, 12 | "strict": true 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /example/.gitignore: -------------------------------------------------------------------------------- 1 | # Learn more https://docs.github.com/en/get-started/getting-started-with-git/ignoring-files 2 | 3 | # dependencies 4 | node_modules/ 5 | 6 | # Expo 7 | .expo/ 8 | dist/ 9 | web-build/ 10 | 11 | # Native 12 | *.orig.* 13 | *.jks 14 | *.p8 15 | *.p12 16 | *.key 17 | *.mobileprovision 18 | 19 | # Metro 20 | .metro-health-check* 21 | 22 | # debug 23 | npm-debug.* 24 | yarn-debug.* 25 | yarn-error.* 26 | 27 | # macOS 28 | .DS_Store 29 | *.pem 30 | 31 | # local env files 32 | .env*.local 33 | 34 | # typescript 35 | *.tsbuildinfo 36 | -------------------------------------------------------------------------------- /example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example", 3 | "version": "1.0.0", 4 | "main": "expo/AppEntry.js", 5 | "scripts": { 6 | "start": "expo start", 7 | "android": "expo start --android", 8 | "ios": "expo start --ios", 9 | "web": "expo start --web" 10 | }, 11 | "dependencies": { 12 | "expo": "~51.0.28", 13 | "expo-status-bar": "~1.12.1", 14 | "react": "18.3.1", 15 | "react-native": "0.74.5", 16 | "react-native-more-or-less-text": "^3.0.0" 17 | }, 18 | "devDependencies": { 19 | "@babel/core": "^7.20.0", 20 | "@types/react": "~18.3.5", 21 | "typescript": "^5.1.3" 22 | }, 23 | "private": true 24 | } 25 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": "./", 4 | "allowUnreachableCode": false, 5 | "allowUnusedLabels": false, 6 | "esModuleInterop": true, 7 | "forceConsistentCasingInFileNames": true, 8 | "jsx": "react-jsx", 9 | "lib": ["esnext", "dom"], 10 | "module": "esnext", 11 | "moduleResolution": "node", 12 | "noFallthroughCasesInSwitch": true, 13 | "noImplicitReturns": true, 14 | "noUnusedLocals": true, 15 | "noUnusedParameters": true, 16 | "resolveJsonModule": true, 17 | "skipLibCheck": true, 18 | "strict": true, 19 | "target": "esnext" 20 | }, 21 | "include": ["src/**/*"] 22 | } 23 | -------------------------------------------------------------------------------- /src/hooks/useToggle.ts: -------------------------------------------------------------------------------- 1 | import { useState, useMemo } from 'react'; 2 | 3 | export function useToggle(initialValue = false) { 4 | const [value, setValue] = useState(initialValue); 5 | 6 | // Defined once, so guaranteed stability 7 | const setters = useMemo( 8 | () => ({ 9 | toggle: () => setValue((v) => !v), 10 | setFalse: () => setValue(false), 11 | setTrue: () => setValue(true), 12 | setValue, 13 | }), 14 | [setValue] 15 | ); 16 | 17 | // Defined each time the value changes, so less than every render. 18 | return useMemo( 19 | () => ({ 20 | ...setters, 21 | value, 22 | }), 23 | [value, setters] 24 | ); 25 | } 26 | -------------------------------------------------------------------------------- /jest.config.ts: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | preset: '@testing-library/react-native', 3 | globals: { 4 | 'ts-jest': { 5 | tsconfig: 'tsconfig.spec.json', 6 | }, 7 | }, 8 | modulePathIgnorePatterns: ['/example/node_modules', '/lib/'], 9 | transform: { 10 | '^.+\\.jsx$': 'babel-jest', 11 | '^.+\\.tsx?$': 'ts-jest', 12 | }, 13 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'], 14 | testRegex: '(/__tests__/.*|\\.(test|spec))\\.(ts|tsx|js)$', 15 | cacheDirectory: '.jest/cache', 16 | moduleNameMapper: { 17 | src: '/src', 18 | }, 19 | setupFilesAfterEnv: ['@testing-library/jest-native/extend-expect'], 20 | }; 21 | -------------------------------------------------------------------------------- /example/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "expo": { 3 | "name": "example", 4 | "slug": "example", 5 | "entryPoint": "./src/App.tsx", 6 | "version": "1.0.0", 7 | "orientation": "portrait", 8 | "icon": "./assets/icon.png", 9 | "userInterfaceStyle": "light", 10 | "splash": { 11 | "image": "./assets/splash.png", 12 | "resizeMode": "contain", 13 | "backgroundColor": "#ffffff" 14 | }, 15 | "ios": { 16 | "supportsTablet": true 17 | }, 18 | "android": { 19 | "adaptiveIcon": { 20 | "foregroundImage": "./assets/adaptive-icon.png", 21 | "backgroundColor": "#ffffff" 22 | } 23 | }, 24 | "web": { 25 | "favicon": "./assets/favicon.png" 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## [v0.3.0](https://github.com/rarenatoe/more-or-less/tree/v0.3.0) (2022-05-19) 4 | 5 | [Full Changelog](https://github.com/rarenatoe/more-or-less/compare/v0.1.0...v0.3.0) 6 | 7 | ## [v0.1.0](https://github.com/rarenatoe/more-or-less/tree/v0.1.0) (2022-05-19) 8 | 9 | [Full Changelog](https://github.com/rarenatoe/more-or-less/compare/0.0.0...v0.1.0) 10 | 11 | ## [0.0.0](https://github.com/rarenatoe/more-or-less/tree/0.0.0) (2022-05-19) 12 | 13 | [Full Changelog](https://github.com/rarenatoe/more-or-less/compare/9adca20394369c339d95bb5fc957a448d871c957...0.0.0) 14 | 15 | 16 | 17 | \* *This Changelog was automatically generated by [github_changelog_generator](https://github.com/github-changelog-generator/github-changelog-generator)* 18 | -------------------------------------------------------------------------------- /example/CustomText.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Platform, StyleSheet, Text, TextProps, TextStyle } from 'react-native'; 3 | 4 | const DefaultText = React.forwardRef(({ style: customStyle, ...props }, ref) => ( 5 | 10 | )); 11 | 12 | export type PressableStyles = { default: TextStyle; pressable: TextStyle }; 13 | 14 | export const styles = StyleSheet.create({ 15 | default: { 16 | fontFamily: Platform.select({ ios: 'Palatino', android: 'Roboto' }), 17 | }, 18 | pressable: { 19 | color: '#800080', 20 | fontWeight: 'bold', 21 | }, 22 | }); 23 | 24 | export default DefaultText; 25 | -------------------------------------------------------------------------------- /scripts/bootstrap.ts: -------------------------------------------------------------------------------- 1 | import * as os from 'os'; 2 | import * as path from 'path'; 3 | import * as child_process from 'child_process'; 4 | 5 | const root = path.resolve(__dirname, '..'); 6 | const args = process.argv.slice(2); 7 | 8 | type Options = { 9 | cwd: string; 10 | env: NodeJS.ProcessEnv; 11 | stdio: 'inherit'; 12 | encoding: 'utf-8'; 13 | shell?: boolean; 14 | }; 15 | 16 | const options: Options = { 17 | cwd: process.cwd(), 18 | env: process.env, 19 | stdio: 'inherit', 20 | encoding: 'utf-8', 21 | }; 22 | 23 | if (os.type() === 'Windows_NT') { 24 | options.shell = true; 25 | } 26 | 27 | let result; 28 | 29 | if (process.cwd() !== root || args.length) { 30 | // We're not in the root of the project, or additional arguments were passed 31 | // In this case, forward the command to `yarn` 32 | result = child_process.spawnSync('yarn', args, options); 33 | } else { 34 | // If `yarn` is run without arguments, perform bootstrap 35 | result = child_process.spawnSync('yarn', ['bootstrap'], options); 36 | } 37 | 38 | process.exitCode = result.status; 39 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Renato Alegre 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # XDE 6 | .expo/ 7 | 8 | # VSCode 9 | .vscode/ 10 | jsconfig.json 11 | 12 | # Xcode 13 | # 14 | build/ 15 | *.pbxuser 16 | !default.pbxuser 17 | *.mode1v3 18 | !default.mode1v3 19 | *.mode2v3 20 | !default.mode2v3 21 | *.perspectivev3 22 | !default.perspectivev3 23 | xcuserdata 24 | *.xccheckout 25 | *.moved-aside 26 | DerivedData 27 | *.hmap 28 | *.ipa 29 | *.xcuserstate 30 | ios/.xcode.env.local 31 | project.xcworkspace 32 | 33 | # Android/IJ 34 | # 35 | .classpath 36 | .cxx 37 | .gradle 38 | .idea 39 | .project 40 | .settings 41 | local.properties 42 | android.iml 43 | *.hprof 44 | .cxx/ 45 | *.keystore 46 | !debug.keystore 47 | 48 | # Ruby / CocoaPods 49 | # 50 | example/ios/Pods 51 | /vendor/bundle/ 52 | 53 | # Temporary files created by Metro to check the health of the file watcher 54 | .metro-health-check* 55 | # testing 56 | /coverage 57 | 58 | # node.js 59 | # 60 | node_modules/ 61 | npm-debug.log 62 | yarn-debug.log 63 | yarn-error.log 64 | 65 | # Expo 66 | .expo/* 67 | 68 | # generated by bob 69 | lib/ 70 | 71 | # Jest 72 | .jest/ 73 | 74 | ### Yarn 75 | .pnp.* 76 | .yarn 77 | !.yarn/patches 78 | !.yarn/plugins 79 | !.yarn/releases 80 | !.yarn/sdks 81 | !.yarn/versions -------------------------------------------------------------------------------- /src/ClippedShrunkText.tsx: -------------------------------------------------------------------------------- 1 | import { ComponentType, PropsWithChildren, useMemo } from 'react'; 2 | import { Platform, TextLayoutLine, TextProps, TextStyle } from 'react-native'; 3 | 4 | type ClippedShrunkTextProps = PropsWithChildren<{ 5 | linesToRender: TextLayoutLine[]; 6 | numberOfLines: number; 7 | textComponent: ComponentType; 8 | textStyle?: TextStyle; 9 | }>; 10 | 11 | const ClippedShrunkText = ({ 12 | children, 13 | linesToRender, 14 | numberOfLines, 15 | textComponent: TextComponent, 16 | textStyle, 17 | }: ClippedShrunkTextProps) => { 18 | const text = useMemo( 19 | () => 20 | Platform.select({ 21 | ios: linesToRender.slice(0, linesToRender.length - 1).map((line) => line.text), 22 | android: children, 23 | default: children, 24 | }), 25 | [children, linesToRender] 26 | ); 27 | 28 | const numberOfLinesToClip = useMemo( 29 | () => Math.min(numberOfLines, linesToRender.length) - 1, 30 | [linesToRender.length, numberOfLines] 31 | ); 32 | 33 | if (linesToRender.length < 2) return null; 34 | 35 | return ( 36 | 37 | {text} 38 | 39 | ); 40 | }; 41 | 42 | export default ClippedShrunkText; 43 | -------------------------------------------------------------------------------- /eslint.config.mjs: -------------------------------------------------------------------------------- 1 | import eslintReact from '@eslint-react/eslint-plugin'; 2 | import eslintJs from '@eslint/js'; 3 | import tseslint from 'typescript-eslint'; 4 | 5 | export default tseslint.config( 6 | // Ignore build artifacts and compiled files 7 | { 8 | ignores: ['lib/**/*', 'dist/**/*', 'node_modules/**/*'], 9 | }, 10 | // Basic JavaScript linting for all JS files 11 | { 12 | files: ['**/*.js', '**/*.mjs', '**/*.cjs'], 13 | extends: [eslintJs.configs.recommended], 14 | }, 15 | 16 | // TypeScript linting for TS files in src directory (with type checking) 17 | { 18 | files: ['src/**/*.ts', 'src/**/*.tsx'], 19 | extends: [ 20 | eslintJs.configs.recommended, 21 | tseslint.configs.recommended, 22 | eslintReact.configs['recommended-type-checked'], 23 | ], 24 | languageOptions: { 25 | parser: tseslint.parser, 26 | parserOptions: { 27 | projectService: true, 28 | tsconfigRootDir: import.meta.dirname, 29 | }, 30 | }, 31 | }, 32 | 33 | // TypeScript linting for config files (without type checking) 34 | { 35 | files: ['*.ts', '*.tsx', 'scripts/**/*.ts', 'example/**/*.ts', 'example/**/*.tsx'], 36 | extends: [eslintJs.configs.recommended, tseslint.configs.recommended], 37 | languageOptions: { 38 | parser: tseslint.parser, 39 | parserOptions: { 40 | // Don't use project service for config files to avoid the error 41 | projectService: false, 42 | }, 43 | }, 44 | } 45 | ); 46 | -------------------------------------------------------------------------------- /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | version: 2.1 2 | 3 | executors: 4 | default: 5 | docker: 6 | - image: circleci/node:10 7 | working_directory: ~/project 8 | 9 | commands: 10 | attach_project: 11 | steps: 12 | - attach_workspace: 13 | at: ~/project 14 | 15 | jobs: 16 | install-dependencies: 17 | executor: default 18 | steps: 19 | - checkout 20 | - attach_project 21 | - restore_cache: 22 | keys: 23 | - dependencies-{{ checksum "package.json" }} 24 | - dependencies- 25 | - restore_cache: 26 | keys: 27 | - dependencies-example-{{ checksum "example/package.json" }} 28 | - dependencies-example- 29 | - run: 30 | name: Install dependencies 31 | command: | 32 | yarn install --cwd example --frozen-lockfile 33 | yarn install --frozen-lockfile 34 | - save_cache: 35 | key: dependencies-{{ checksum "package.json" }} 36 | paths: node_modules 37 | - save_cache: 38 | key: dependencies-example-{{ checksum "example/package.json" }} 39 | paths: example/node_modules 40 | - persist_to_workspace: 41 | root: . 42 | paths: . 43 | 44 | lint: 45 | executor: default 46 | steps: 47 | - attach_project 48 | - run: 49 | name: Lint files 50 | command: | 51 | yarn lint 52 | 53 | typescript: 54 | executor: default 55 | steps: 56 | - attach_project 57 | - run: 58 | name: Typecheck files 59 | command: | 60 | yarn typescript 61 | 62 | unit-tests: 63 | executor: default 64 | steps: 65 | - attach_project 66 | - run: 67 | name: Run unit tests 68 | command: | 69 | yarn test --coverage 70 | - store_artifacts: 71 | path: coverage 72 | destination: coverage 73 | 74 | build-package: 75 | executor: default 76 | steps: 77 | - attach_project 78 | - run: 79 | name: Build package 80 | command: | 81 | yarn prepare 82 | 83 | workflows: 84 | build-and-test: 85 | jobs: 86 | - install-dependencies 87 | - lint: 88 | requires: 89 | - install-dependencies 90 | - typescript: 91 | requires: 92 | - install-dependencies 93 | - unit-tests: 94 | requires: 95 | - install-dependencies 96 | - build-package: 97 | requires: 98 | - install-dependencies 99 | -------------------------------------------------------------------------------- /example/App.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import { MoreOrLess } from 'react-native-more-or-less-text'; 4 | import { Button, Platform, SafeAreaView, StyleSheet, View } from 'react-native'; 5 | import CustomText from './CustomText'; 6 | 7 | const text1 = `Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem.`; 8 | const text2 = 9 | "There are many variations of passages of Lorem Ipsum available, but the majority have suffered alteration in some form, by injected humour, or randomised words which don't look even slightly believable. If you are going to use a passage of Lorem Ipsum, you need to be sure there isn't anything embarrassing hidden in the middle of text. All the Lorem Ipsum generators on the Internet tend to repeat predefined chunks as necessary, making this the first true generator on the Internet. It uses a dictionary of over 200 Latin words, combined with a handful of model sentence structures."; 10 | export default function App() { 11 | const [flag, setFlag] = React.useState(true); 12 | 13 | return ( 14 | 15 |