diff --git a/.eslintignore b/.eslintignore
new file mode 100644
index 000000000..f22b51307
--- /dev/null
+++ b/.eslintignore
@@ -0,0 +1,2 @@
+# eslint-plugin-import의 no-unused-modules 규칙이 FileEnumerator 내부 API를 사용할 때
+# .eslintignore 파일의 존재를 필요로 합니다. 내용이 없어도 파일이 있어야 정상 동작합니다.
diff --git a/.github/workflows/assign-reviewer.yml b/.github/workflows/assign-reviewer.yml
deleted file mode 100644
index 743b83c93..000000000
--- a/.github/workflows/assign-reviewer.yml
+++ /dev/null
@@ -1,14 +0,0 @@
-name: Assign Reviewer
-
-on:
- pull_request:
- types: [opened, ready_for_review]
-
-jobs:
- assign:
- runs-on: ubuntu-latest
- steps:
- - uses: hkusu/review-assign-action@v1
- with:
- assignees: ${{ github.actor }}
- # reviewers: TODO: 팀 전체 리뷰어 목록으로 업데이트
diff --git a/.github/workflows/chromatic.yml b/.github/workflows/chromatic.yml
index af450a784..0d8036031 100644
--- a/.github/workflows/chromatic.yml
+++ b/.github/workflows/chromatic.yml
@@ -37,6 +37,9 @@ jobs:
cp apps/playground/.env.development apps/playground/.env.local
echo "${{ vars.PLAYGROUND_DEVELOPMENT_ENV }}" >> apps/playground/.env.local
+ - name: Build packages
+ run: yarn turbo run build --filter=@sopt/ui
+
- name: Publish Chromatic
id: publish_chromatic
uses: chromaui/action@v1
diff --git a/.github/workflows/crew-deploy-development.yml b/.github/workflows/crew-deploy-development.yml
index f9893483d..fe839992b 100644
--- a/.github/workflows/crew-deploy-development.yml
+++ b/.github/workflows/crew-deploy-development.yml
@@ -4,14 +4,11 @@ on:
push:
branches: [develop]
paths:
- - "apps/crew/**"
- - "packages/**"
- - "package.json"
- - "yarn.lock"
+ - 'apps/crew/**'
+ - 'packages/**'
+ - 'package.json'
+ - 'yarn.lock'
pull_request:
- paths:
- - "apps/crew/**"
- - "packages/**"
workflow_dispatch:
jobs:
diff --git a/.github/workflows/label.yml b/.github/workflows/label.yml
index fceff3694..9c3540b84 100644
--- a/.github/workflows/label.yml
+++ b/.github/workflows/label.yml
@@ -16,7 +16,7 @@ jobs:
- name: Label PR
run: |
PR=${{ github.event.pull_request.number }}
- changed_files=$(gh pr diff $PR --name-only)
+ changed_files=$(gh api "repos/${{ github.repository }}/pulls/$PR/files" --paginate -q '.[].filename')
current_labels=$(gh pr view $PR --json labels -q '.labels[].name')
diff --git a/.github/workflows/playground-deploy-development.yml b/.github/workflows/playground-deploy-development.yml
index e68945a23..71a9bc6c8 100644
--- a/.github/workflows/playground-deploy-development.yml
+++ b/.github/workflows/playground-deploy-development.yml
@@ -4,14 +4,11 @@ on:
push:
branches: [develop]
paths:
- - "apps/playground/**"
- - "packages/**"
- - "package.json"
- - "yarn.lock"
+ - 'apps/playground/**'
+ - 'packages/**'
+ - 'package.json'
+ - 'yarn.lock'
pull_request:
- paths:
- - "apps/playground/**"
- - "packages/**"
workflow_dispatch:
jobs:
@@ -84,8 +81,8 @@ jobs:
id: find_comment
with:
issue-number: ${{ github.event.pull_request.number }}
- comment-author: "github-actions[bot]"
- body-includes: "Playground 프리뷰 배포 확인하기"
+ comment-author: 'github-actions[bot]'
+ body-includes: 'Playground 프리뷰 배포 확인하기'
- name: Create or update comment
if: github.event_name == 'pull_request'
diff --git a/.gitignore b/.gitignore
index 638f571d5..d9301268a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,25 +1,57 @@
+# yarn
.yarn/*
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/sdks
!.yarn/versions
+.pnp.*
+install-state.gz
-# Whether you use PnP or not, the node_modules folder is often used to store
-# build artifacts that should be gitignored
+# dependencies
node_modules
-# Swap the comments on the following lines if you wish to use zero-installs
-# In that case, don't forget to run `yarn config set enableGlobalCache false`!
-# Documentation here: https://yarnpkg.com/features/caching#zero-installs
+# next.js
+.next/
+out/
-#!.yarn/cache
-.pnp.*
+# production
+build/
+coverage/
+
+# storybook
+storybook-static
+
+# misc
+.DS_Store
+*.pem
+
+# debug
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+.pnpm-debug.log*
-.env.local
+# local env files
+.env*.local
+.env
+
+# vercel
+.vercel
+
+# typescript
+*.tsbuildinfo
+next-env.d.ts
+
+# editor
+.vscode/
+.idea
# Turbo
.turbo
# Build outputs
-packages/ui/dist
\ No newline at end of file
+packages/ui/dist/**/*
+
+# crew generated
+apps/crew/src/__generated__/open-api-specification.json
\ No newline at end of file
diff --git a/.husky/pre-commit b/.husky/pre-commit
new file mode 100755
index 000000000..5a182ef10
--- /dev/null
+++ b/.husky/pre-commit
@@ -0,0 +1,4 @@
+#!/usr/bin/env sh
+. "$(dirname -- "$0")/_/husky.sh"
+
+yarn lint-staged
diff --git a/.lintstagedrc b/.lintstagedrc
new file mode 100644
index 000000000..e6f1510ef
--- /dev/null
+++ b/.lintstagedrc
@@ -0,0 +1,5 @@
+{
+ "apps/crew/**/*.{ts,tsx}": ["eslint --fix", "yarn workspace crew typecheck"],
+ "apps/playground/**/*.{ts,tsx}": ["eslint --fix", "yarn workspace playground typecheck"],
+ "**/*.{ts,tsx,js,jsx,json,css,md}": "prettier --write --ignore-path .prettierignore"
+}
diff --git a/.prettierignore b/.prettierignore
new file mode 100644
index 000000000..0320b1d27
--- /dev/null
+++ b/.prettierignore
@@ -0,0 +1,10 @@
+# dependencies
+node_modules
+
+# build outputs
+.next
+out
+dist
+
+# docs
+**/*.md
diff --git a/apps/playground/.prettierrc.json b/.prettierrc
similarity index 92%
rename from apps/playground/.prettierrc.json
rename to .prettierrc
index c476eb116..19ad21a3c 100644
--- a/apps/playground/.prettierrc.json
+++ b/.prettierrc
@@ -4,6 +4,7 @@
"jsxSingleQuote": true,
"printWidth": 120,
"quoteProps": "consistent",
+ "semi": true,
"singleQuote": true,
"tabWidth": 2,
"trailingComma": "all"
diff --git a/apps/crew/.eslintignore b/apps/crew/.eslintignore
index 3d85ec336..f22b51307 100644
--- a/apps/crew/.eslintignore
+++ b/apps/crew/.eslintignore
@@ -1 +1,2 @@
-src/__generated__
\ No newline at end of file
+# eslint-plugin-import의 no-unused-modules 규칙이 FileEnumerator 내부 API를 사용할 때
+# .eslintignore 파일의 존재를 필요로 합니다. 내용이 없어도 파일이 있어야 정상 동작합니다.
diff --git a/apps/crew/.eslintrc.json b/apps/crew/.eslintrc.json
index 4f2b100b4..382ebeeda 100644
--- a/apps/crew/.eslintrc.json
+++ b/apps/crew/.eslintrc.json
@@ -1,38 +1,4 @@
{
"root": true,
- "parser": "@typescript-eslint/parser",
- "env": {
- "es6": true,
- "node": true,
- "browser": true
- },
- "plugins": ["@typescript-eslint", "prettier", "import"],
- "extends": [
- "eslint:recommended",
- "plugin:prettier/recommended",
- "plugin:@typescript-eslint/eslint-recommended",
- "plugin:@typescript-eslint/recommended",
- "plugin:react-hooks/recommended",
- "plugin:storybook/recommended"
- ],
- "rules": {
- "@typescript-eslint/no-var-requires": "off",
- "@typescript-eslint/explicit-module-boundary-types": "off",
- "@typescript-eslint/no-empty-function": "off",
- "react-hooks/rules-of-hooks": "error",
- "react-hooks/exhaustive-deps": "warn",
- "react-hooks/set-state-in-effect": "warn",
- "react-hooks/static-components": "warn",
- "react-hooks/immutability": "warn",
- "react-hooks/refs": "warn",
- "react-hooks/incompatible-library": "warn",
- "prettier/prettier": [
- "error",
- {
- "endOfLine": "auto"
- }
- ],
- "import/no-unused-modules": [1, { "unusedExports": true }],
- "react/no-unstable-nested-components": "off"
- }
+ "extends": ["@sopt-makers/eslint-config/next"]
}
diff --git a/apps/crew/.gitignore b/apps/crew/.gitignore
deleted file mode 100644
index f1c8bc791..000000000
--- a/apps/crew/.gitignore
+++ /dev/null
@@ -1,46 +0,0 @@
-# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
-
-# dependencies
-/node_modules
-/.pnp
-.pnp.js
-
-# testing
-/coverage
-
-# next.js
-/.next/
-/out/
-
-# production
-/build
-
-# misc
-.DS_Store
-*.pem
-
-# debug
-npm-debug.log*
-yarn-debug.log*
-yarn-error.log*
-.pnpm-debug.log*
-
-# local env files
-.env*.local
-
-# vercel
-.vercel
-
-# typescript
-*.tsbuildinfo
-next-env.d.ts
-
-# vscode
-.vscode/
-.idea
-
-# __generated__
-src/__generated__/open-api-specification.json
-
-# 최적화 관련 파일이기 때문에 애초에 커밋할 필요 없음
-install-state.gz
diff --git a/apps/crew/.prettierrc b/apps/crew/.prettierrc
deleted file mode 100644
index c7d04dcd9..000000000
--- a/apps/crew/.prettierrc
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "trailingComma": "es5",
- "tabWidth": 2,
- "semi": true,
- "singleQuote": true,
- "arrowParens": "avoid",
- "printWidth": 120
-}
diff --git a/apps/crew/.storybook/main.ts b/apps/crew/.storybook/main.ts
index 34d024b08..8422354ad 100644
--- a/apps/crew/.storybook/main.ts
+++ b/apps/crew/.storybook/main.ts
@@ -11,7 +11,7 @@ const config: StorybookConfig = {
autodocs: 'tag',
},
webpackFinal(config) {
- const imageRule = config.module!.rules!.find(rule => {
+ const imageRule = config.module!.rules!.find((rule) => {
if (rule && typeof rule !== 'string' && rule.test instanceof RegExp) {
return rule.test.test('.svg');
}
diff --git a/apps/crew/.storybook/preview.tsx b/apps/crew/.storybook/preview.tsx
index 5fd694263..5c5b440c2 100644
--- a/apps/crew/.storybook/preview.tsx
+++ b/apps/crew/.storybook/preview.tsx
@@ -1,5 +1,5 @@
import type { Preview } from '@storybook/react';
-import { OverlayProvider } from '../src/hooks/useOverlay/OverlayProvider';
+import { OverlayProvider } from '../src/hook/useOverlay/OverlayProvider';
import React from 'react';
import '../styles/globals.css';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
@@ -24,7 +24,7 @@ const preview: Preview = {
},
},
decorators: [
- Story => {
+ (Story) => {
const queryClient = new QueryClient();
return (
diff --git a/apps/crew/ampli.json b/apps/crew/ampli.json
index 2d54d6d63..ad3b3acfe 100644
--- a/apps/crew/ampli.json
+++ b/apps/crew/ampli.json
@@ -11,4 +11,4 @@
"Language": "TypeScript",
"SDK": "@amplitude/analytics-browser@^1.0",
"Path": "./src/ampli"
-}
\ No newline at end of file
+}
diff --git a/apps/crew/next.config.js b/apps/crew/next.config.js
index 5772047b3..f46818f26 100644
--- a/apps/crew/next.config.js
+++ b/apps/crew/next.config.js
@@ -5,7 +5,7 @@ const nextConfig = {
output: 'export',
reactStrictMode: true,
swcMinify: true,
- webpack: config => {
+ webpack: (config) => {
config.module.rules.push({
test: /\.svg$/,
oneOf: [
diff --git a/apps/crew/package.json b/apps/crew/package.json
index f824b06ce..95d479182 100644
--- a/apps/crew/package.json
+++ b/apps/crew/package.json
@@ -3,18 +3,19 @@
"version": "0.1.0",
"private": true,
"scripts": {
- "dev": "next dev",
"build": "next build",
- "start": "next start",
- "lint": "next lint",
- "typecheck": "tsc --noemit -p .",
- "storybook": "storybook dev -p 6006",
"build-storybook": "storybook build",
+ "dev": "next dev",
+ "format": "prettier --write . --ignore-path ../../.prettierignore",
+ "generate-types": "cat ./src/__generated__/schema1.d.ts ./src/__generated__/schema2.d.ts > ./src/__generated__/schema.d.ts",
"generate-types-v1": "openapi-typescript https://crew.api.dev.sopt.org/api-docs-json -o ./src/__generated__/schema1.d.ts",
"generate-types-v2": "openapi-typescript https://crew.api.dev.sopt.org/api-docs/json -o ./src/__generated__/schema2.d.ts",
- "generate-types": "cat ./src/__generated__/schema1.d.ts ./src/__generated__/schema2.d.ts > ./src/__generated__/schema.d.ts",
- "wrangler": "wrangler",
- "where": "sh -c 'export IP=`ipconfig getifaddr en0` && echo [info] we are in ... http://${IP}:3000'"
+ "lint": "next lint",
+ "start": "next start",
+ "storybook": "storybook dev -p 6006",
+ "typecheck": "tsc --noemit -p .",
+ "where": "sh -c 'export IP=`ipconfig getifaddr en0` && echo [info] we are in ... http://${IP}:3000'",
+ "wrangler": "wrangler"
},
"dependencies": {
"@amplitude/ampli": "^1.35.0",
@@ -52,12 +53,7 @@
"@hookform/devtools": "^4.3.1",
"@types/react-mentions": "4.1.13",
"@types/react-responsive": "^8.0.5",
- "eslint": "^8.57.0",
- "eslint-plugin-import": "^2.32.0",
- "eslint-plugin-prettier": "^5.5.5",
- "eslint-plugin-react-hooks": "^7.0.1",
"openapi-typescript": "^6.3.9",
- "prettier": "^3.0.0",
"wrangler": "^3.0.0"
}
}
diff --git a/apps/crew/packages/react-mentions/src/Highlighter.js b/apps/crew/packages/react-mentions/src/Highlighter.js
index 3a51fe190..3bc5555bb 100644
--- a/apps/crew/packages/react-mentions/src/Highlighter.js
+++ b/apps/crew/packages/react-mentions/src/Highlighter.js
@@ -1,22 +1,17 @@
-import React, { Children, useState, useEffect } from 'react'
-import PropTypes from 'prop-types'
-import { defaultStyle } from './utils'
+import React, { Children, useState, useEffect } from 'react';
+import PropTypes from 'prop-types';
+import { defaultStyle } from './utils';
-import {
- iterateMentionsMarkup,
- mapPlainTextIndex,
- readConfigFromChildren,
- isNumber,
-} from './utils'
+import { iterateMentionsMarkup, mapPlainTextIndex, readConfigFromChildren, isNumber } from './utils';
const _generateComponentKey = (usedKeys, id) => {
if (!usedKeys.hasOwnProperty(id)) {
- usedKeys[id] = 0
+ usedKeys[id] = 0;
} else {
- usedKeys[id]++
+ usedKeys[id]++;
}
- return id + '_' + usedKeys[id]
-}
+ return id + '_' + usedKeys[id];
+};
function Highlighter({
selectionStart,
@@ -31,46 +26,41 @@ function Highlighter({
const [position, setPosition] = useState({
left: undefined,
top: undefined,
- })
- const [caretElement, setCaretElement] = useState()
+ });
+ const [caretElement, setCaretElement] = useState();
useEffect(() => {
- notifyCaretPosition()
- })
+ notifyCaretPosition();
+ });
const notifyCaretPosition = () => {
if (!caretElement) {
- return
+ return;
}
- const { offsetLeft, offsetTop } = caretElement
+ const { offsetLeft, offsetTop } = caretElement;
if (position.left === offsetLeft && position.top === offsetTop) {
- return
+ return;
}
- const newPosition = { left: offsetLeft, top: offsetTop }
- setPosition(newPosition)
+ const newPosition = { left: offsetLeft, top: offsetTop };
+ setPosition(newPosition);
- onCaretPositionChange(newPosition)
- }
+ onCaretPositionChange(newPosition);
+ };
- const config = readConfigFromChildren(children)
- let caretPositionInMarkup
+ const config = readConfigFromChildren(children);
+ let caretPositionInMarkup;
if (selectionEnd === selectionStart) {
- caretPositionInMarkup = mapPlainTextIndex(
- value,
- config,
- selectionStart,
- 'START'
- )
+ caretPositionInMarkup = mapPlainTextIndex(value, config, selectionStart, 'START');
}
- const resultComponents = []
- const componentKeys = {}
- let components = resultComponents
- let substringComponentKey = 0
+ const resultComponents = [];
+ const componentKeys = {};
+ let components = resultComponents;
+ let substringComponentKey = 0;
const textIteratee = (substr, index, indexInPlainText) => {
// check whether the caret element has to be inserted inside the current plain substring
@@ -80,35 +70,21 @@ function Highlighter({
caretPositionInMarkup <= index + substr.length
) {
// if yes, split substr at the caret position and insert the caret component
- const splitIndex = caretPositionInMarkup - index
- components.push(
- renderSubstring(substr.substring(0, splitIndex), substringComponentKey)
- )
+ const splitIndex = caretPositionInMarkup - index;
+ components.push(renderSubstring(substr.substring(0, splitIndex), substringComponentKey));
// add all following substrings and mention components as children of the caret component
- components = [
- renderSubstring(substr.substring(splitIndex), substringComponentKey),
- ]
+ components = [renderSubstring(substr.substring(splitIndex), substringComponentKey)];
} else {
- components.push(renderSubstring(substr, substringComponentKey))
+ components.push(renderSubstring(substr, substringComponentKey));
}
- substringComponentKey++
- }
+ substringComponentKey++;
+ };
- const mentionIteratee = (
- markup,
- index,
- indexInPlainText,
- id,
- display,
- mentionChildIndex,
- lastMentionEndIndex
- ) => {
- const key = _generateComponentKey(componentKeys, id)
- components.push(
- getMentionComponentForMatch(id, display, mentionChildIndex, key)
- )
- }
+ const mentionIteratee = (markup, index, indexInPlainText, id, display, mentionChildIndex, lastMentionEndIndex) => {
+ const key = _generateComponentKey(componentKeys, id);
+ components.push(getMentionComponentForMatch(id, display, mentionChildIndex, key));
+ };
const renderSubstring = (string, key) => {
// set substring span to hidden, so that Emojis are not shown double in Mobile Safari
@@ -116,38 +92,38 @@ function Highlighter({
{string}
- )
- }
+ );
+ };
const getMentionComponentForMatch = (id, display, mentionChildIndex, key) => {
- const props = { id, display, key }
- const child = Children.toArray(children)[mentionChildIndex]
- return React.cloneElement(child, props)
- }
+ const props = { id, display, key };
+ const child = Children.toArray(children)[mentionChildIndex];
+ return React.cloneElement(child, props);
+ };
const renderHighlighterCaret = (children) => {
return (
-
+
{children}
- )
- }
+ );
+ };
- iterateMentionsMarkup(value, config, mentionIteratee, textIteratee)
+ iterateMentionsMarkup(value, config, mentionIteratee, textIteratee);
// append a span containing a space, to ensure the last text line has the correct height
- components.push(' ')
+ components.push(' ');
if (components !== resultComponents) {
// if a caret component is to be rendered, add all components that followed as its children
- resultComponents.push(renderHighlighterCaret(components))
+ resultComponents.push(renderHighlighterCaret(components));
}
return (
{resultComponents}
- )
+ );
}
Highlighter.propTypes = {
@@ -158,42 +134,36 @@ Highlighter.propTypes = {
containerRef: PropTypes.oneOfType([
PropTypes.func,
PropTypes.shape({
- current:
- typeof Element === 'undefined'
- ? PropTypes.any
- : PropTypes.instanceOf(Element),
+ current: typeof Element === 'undefined' ? PropTypes.any : PropTypes.instanceOf(Element),
}),
]),
- children: PropTypes.oneOfType([
- PropTypes.element,
- PropTypes.arrayOf(PropTypes.element),
- ]).isRequired,
-}
+ children: PropTypes.oneOfType([PropTypes.element, PropTypes.arrayOf(PropTypes.element)]).isRequired,
+};
const styled = defaultStyle(
{
- position: 'relative',
- boxSizing: 'border-box',
- width: '100%',
- color: 'transparent',
- overflow: 'hidden',
- whiteSpace: 'pre-wrap',
- wordWrap: 'break-word',
- border: '1px solid transparent',
- textAlign: 'start',
+ 'position': 'relative',
+ 'boxSizing': 'border-box',
+ 'width': '100%',
+ 'color': 'transparent',
+ 'overflow': 'hidden',
+ 'whiteSpace': 'pre-wrap',
+ 'wordWrap': 'break-word',
+ 'border': '1px solid transparent',
+ 'textAlign': 'start',
'&singleLine': {
whiteSpace: 'pre',
wordWrap: null,
},
- substring: {
+ 'substring': {
visibility: 'hidden',
},
},
(props) => ({
'&singleLine': props.singleLine,
- })
-)
+ }),
+);
-export default styled(Highlighter)
+export default styled(Highlighter);
diff --git a/apps/crew/packages/react-mentions/src/Highlighter.spec.js b/apps/crew/packages/react-mentions/src/Highlighter.spec.js
index 06ef762db..a8ae12268 100644
--- a/apps/crew/packages/react-mentions/src/Highlighter.spec.js
+++ b/apps/crew/packages/react-mentions/src/Highlighter.spec.js
@@ -1,7 +1,7 @@
describe('Highlighter', () => {
- it.todo('should notify about the current caret position when mounted.')
- it.todo('should notify about the current care position whenever it changes.')
- it.todo('should render the current matched mentions.')
- it.todo('should only show the matched mentions.')
- it.todo('should be possible to style the mentions.')
-})
+ it.todo('should notify about the current caret position when mounted.');
+ it.todo('should notify about the current care position whenever it changes.');
+ it.todo('should render the current matched mentions.');
+ it.todo('should only show the matched mentions.');
+ it.todo('should be possible to style the mentions.');
+});
diff --git a/apps/crew/packages/react-mentions/src/LoadingIndicator.js b/apps/crew/packages/react-mentions/src/LoadingIndicator.js
index ed9a42aa0..ab94b3519 100644
--- a/apps/crew/packages/react-mentions/src/LoadingIndicator.js
+++ b/apps/crew/packages/react-mentions/src/LoadingIndicator.js
@@ -1,9 +1,9 @@
-import React from 'react'
-import useStyles from 'substyle'
+import React from 'react';
+import useStyles from 'substyle';
function LoadingIndicator({ style, className, classNames }) {
- const styles = useStyles(defaultstyle, { style, className, classNames })
- const spinnerStyles = styles('spinner')
+ const styles = useStyles(defaultstyle, { style, className, classNames });
+ const spinnerStyles = styles('spinner');
return (
@@ -14,9 +14,9 @@ function LoadingIndicator({ style, className, classNames }) {
- )
+ );
}
-const defaultstyle = {}
+const defaultstyle = {};
-export default LoadingIndicator
+export default LoadingIndicator;
diff --git a/apps/crew/packages/react-mentions/src/Mention.js b/apps/crew/packages/react-mentions/src/Mention.js
index 36bdc6875..445d10ca3 100644
--- a/apps/crew/packages/react-mentions/src/Mention.js
+++ b/apps/crew/packages/react-mentions/src/Mention.js
@@ -1,15 +1,15 @@
-import React from 'react'
-import PropTypes from 'prop-types'
-import useStyles from 'substyle'
+import React from 'react';
+import PropTypes from 'prop-types';
+import useStyles from 'substyle';
const defaultStyle = {
fontWeight: 'inherit',
-}
+};
const Mention = ({ display, style, className, classNames }) => {
- const styles = useStyles(defaultStyle, { style, className, classNames })
- return {display}
-}
+ const styles = useStyles(defaultStyle, { style, className, classNames });
+ return {display};
+};
Mention.propTypes = {
/**
@@ -28,10 +28,7 @@ Mention.propTypes = {
renderSuggestion: PropTypes.func,
- trigger: PropTypes.oneOfType([
- PropTypes.string,
- PropTypes.instanceOf(RegExp),
- ]),
+ trigger: PropTypes.oneOfType([PropTypes.string, PropTypes.instanceOf(RegExp)]),
markup: PropTypes.string,
displayTransform: PropTypes.func,
/**
@@ -40,19 +37,19 @@ Mention.propTypes = {
allowSpaceInQuery: PropTypes.bool,
isLoading: PropTypes.bool,
-}
+};
Mention.defaultProps = {
trigger: '@',
markup: '@[__display__](__id__)',
- displayTransform: function(id, display) {
- return display || id
+ displayTransform: function (id, display) {
+ return display || id;
},
onAdd: () => null,
onRemove: () => null,
renderSuggestion: null,
isLoading: false,
appendSpaceOnAdd: false,
-}
+};
-export default Mention
+export default Mention;
diff --git a/apps/crew/packages/react-mentions/src/MentionsInput.js b/apps/crew/packages/react-mentions/src/MentionsInput.js
index 124999b0a..69047f335 100755
--- a/apps/crew/packages/react-mentions/src/MentionsInput.js
+++ b/apps/crew/packages/react-mentions/src/MentionsInput.js
@@ -1,4 +1,4 @@
-import React, { Children } from 'react'
+import React, { Children } from 'react';
import {
applyChangeToValue,
countSuggestions,
@@ -17,53 +17,49 @@ import {
keys,
omit,
getSuggestionHtmlId,
-} from './utils'
+} from './utils';
-import Highlighter from './Highlighter'
-import PropTypes from 'prop-types'
-import ReactDOM from 'react-dom'
-import SuggestionsOverlay from './SuggestionsOverlay'
-import { defaultStyle } from './utils'
+import Highlighter from './Highlighter';
+import PropTypes from 'prop-types';
+import ReactDOM from 'react-dom';
+import SuggestionsOverlay from './SuggestionsOverlay';
+import { defaultStyle } from './utils';
-export const makeTriggerRegex = function(trigger, options = {}) {
+export const makeTriggerRegex = function (trigger, options = {}) {
if (trigger instanceof RegExp) {
- return trigger
+ return trigger;
} else {
- const { allowSpaceInQuery } = options
- const escapedTriggerChar = escapeRegex(trigger)
+ const { allowSpaceInQuery } = options;
+ const escapedTriggerChar = escapeRegex(trigger);
// first capture group is the part to be replaced on completion
// second capture group is for extracting the search query
- return new RegExp(
- `(?:^|\\s)(${escapedTriggerChar}([^${
- allowSpaceInQuery ? '' : '\\s'
- }${escapedTriggerChar}]*))$`
- )
+ return new RegExp(`(?:^|\\s)(${escapedTriggerChar}([^${allowSpaceInQuery ? '' : '\\s'}${escapedTriggerChar}]*))$`);
}
-}
+};
-const getDataProvider = function(data, ignoreAccents) {
+const getDataProvider = function (data, ignoreAccents) {
if (data instanceof Array) {
// if data is an array, create a function to query that
- return function(query, callback) {
- const results = []
+ return function (query, callback) {
+ const results = [];
for (let i = 0, l = data.length; i < l; ++i) {
- const display = data[i].display || data[i].id
+ const display = data[i].display || data[i].id;
if (getSubstringIndex(display, query, ignoreAccents) >= 0) {
- results.push(data[i])
+ results.push(data[i]);
}
}
- return results
- }
+ return results;
+ };
} else {
// expect data to be a query function
- return data
+ return data;
}
-}
+};
-const KEY = { TAB: 9, RETURN: 13, ESC: 27, UP: 38, DOWN: 40 }
+const KEY = { TAB: 9, RETURN: 13, ESC: 27, UP: 38, DOWN: 40 };
-let isComposing = false
+let isComposing = false;
const propTypes = {
/**
@@ -83,28 +79,19 @@ const propTypes = {
onSelect: PropTypes.func,
onBlur: PropTypes.func,
onChange: PropTypes.func,
- suggestionsPortalHost:
- typeof Element === 'undefined'
- ? PropTypes.any
- : PropTypes.PropTypes.instanceOf(Element),
+ suggestionsPortalHost: typeof Element === 'undefined' ? PropTypes.any : PropTypes.PropTypes.instanceOf(Element),
inputRef: PropTypes.oneOfType([
PropTypes.func,
PropTypes.shape({
- current:
- typeof Element === 'undefined'
- ? PropTypes.any
- : PropTypes.instanceOf(Element),
+ current: typeof Element === 'undefined' ? PropTypes.any : PropTypes.instanceOf(Element),
}),
]),
- children: PropTypes.oneOfType([
- PropTypes.element,
- PropTypes.arrayOf(PropTypes.element),
- ]).isRequired,
-}
+ children: PropTypes.oneOfType([PropTypes.element, PropTypes.arrayOf(PropTypes.element)]).isRequired,
+};
class MentionsInput extends React.Component {
- static propTypes = propTypes
+ static propTypes = propTypes;
static defaultProps = {
ignoreAccents: false,
@@ -113,18 +100,16 @@ class MentionsInput extends React.Component {
onKeyDown: () => null,
onSelect: () => null,
onBlur: () => null,
- }
+ };
constructor(props) {
- super(props)
- this.suggestions = {}
- this.uuidSuggestionsOverlay = Math.random()
- .toString(16)
- .substring(2)
+ super(props);
+ this.suggestions = {};
+ this.uuidSuggestionsOverlay = Math.random().toString(16).substring(2);
- this.handleCopy = this.handleCopy.bind(this)
- this.handleCut = this.handleCut.bind(this)
- this.handlePaste = this.handlePaste.bind(this)
+ this.handleCopy = this.handleCopy.bind(this);
+ this.handleCut = this.handleCut.bind(this);
+ this.handlePaste = this.handlePaste.bind(this);
this.state = {
focusIndex: 0,
@@ -138,40 +123,40 @@ class MentionsInput extends React.Component {
suggestionsPosition: {},
setSelectionAfterHandlePaste: false,
- }
+ };
}
componentDidMount() {
- document.addEventListener('copy', this.handleCopy)
- document.addEventListener('cut', this.handleCut)
- document.addEventListener('paste', this.handlePaste)
+ document.addEventListener('copy', this.handleCopy);
+ document.addEventListener('cut', this.handleCut);
+ document.addEventListener('paste', this.handlePaste);
- this.updateSuggestionsPosition()
+ this.updateSuggestionsPosition();
}
componentDidUpdate(prevProps, prevState) {
// Update position of suggestions unless this componentDidUpdate was
// triggered by an update to suggestionsPosition.
if (prevState.suggestionsPosition === this.state.suggestionsPosition) {
- this.updateSuggestionsPosition()
+ this.updateSuggestionsPosition();
}
// maintain selection in case a mention is added/removed causing
// the cursor to jump to the end
if (this.state.setSelectionAfterMentionChange) {
- this.setState({ setSelectionAfterMentionChange: false })
- this.setSelection(this.state.selectionStart, this.state.selectionEnd)
+ this.setState({ setSelectionAfterMentionChange: false });
+ this.setSelection(this.state.selectionStart, this.state.selectionEnd);
}
if (this.state.setSelectionAfterHandlePaste) {
- this.setState({ setSelectionAfterHandlePaste: false })
- this.setSelection(this.state.selectionStart, this.state.selectionEnd)
+ this.setState({ setSelectionAfterHandlePaste: false });
+ this.setSelection(this.state.selectionStart, this.state.selectionEnd);
}
}
componentWillUnmount() {
- document.removeEventListener('copy', this.handleCopy)
- document.removeEventListener('cut', this.handleCut)
- document.removeEventListener('paste', this.handlePaste)
+ document.removeEventListener('copy', this.handleCopy);
+ document.removeEventListener('cut', this.handleCut);
+ document.removeEventListener('paste', this.handlePaste);
}
render() {
@@ -180,22 +165,22 @@ class MentionsInput extends React.Component {
{this.renderControl()}
{this.renderSuggestionsOverlay()}
- )
+ );
}
setContainerElement = (el) => {
- this.containerElement = el
- }
+ this.containerElement = el;
+ };
getInputProps = () => {
- let { readOnly, disabled, style } = this.props
+ let { readOnly, disabled, style } = this.props;
// pass all props that neither we, nor substyle, consume through to the input control
let props = omit(
this.props,
['style', 'classNames', 'className'], // substyle props
- keys(propTypes)
- )
+ keys(propTypes),
+ );
return {
...props,
@@ -215,63 +200,58 @@ class MentionsInput extends React.Component {
}),
...(this.isOpened() && {
- role: 'combobox',
+ 'role': 'combobox',
'aria-controls': this.uuidSuggestionsOverlay,
'aria-expanded': true,
'aria-autocomplete': 'list',
'aria-haspopup': 'listbox',
- 'aria-activedescendant': getSuggestionHtmlId(
- this.uuidSuggestionsOverlay,
- this.state.focusIndex
- ),
+ 'aria-activedescendant': getSuggestionHtmlId(this.uuidSuggestionsOverlay, this.state.focusIndex),
}),
- }
- }
+ };
+ };
renderControl = () => {
- let { singleLine, style } = this.props
- let inputProps = this.getInputProps()
+ let { singleLine, style } = this.props;
+ let inputProps = this.getInputProps();
return (
{this.renderHighlighter()}
- {singleLine
- ? this.renderInput(inputProps)
- : this.renderTextarea(inputProps)}
+ {singleLine ? this.renderInput(inputProps) : this.renderTextarea(inputProps)}
- )
- }
+ );
+ };
renderInput = (props) => {
- return
- }
+ return ;
+ };
renderTextarea = (props) => {
- return
- }
+ return ;
+ };
setInputRef = (el) => {
- this.inputElement = el
- const { inputRef } = this.props
+ this.inputElement = el;
+ const { inputRef } = this.props;
if (typeof inputRef === 'function') {
- inputRef(el)
+ inputRef(el);
} else if (inputRef) {
- inputRef.current = el
+ inputRef.current = el;
}
- }
+ };
setSuggestionsElement = (el) => {
- this.suggestionsElement = el
- }
+ this.suggestionsElement = el;
+ };
renderSuggestionsOverlay = () => {
- console.log("STATE", this.state);
+ console.log('STATE', this.state);
if (!isNumber(this.state.selectionStart)) {
// do not show suggestions when the input does not have the focus
- return null
+ return null;
}
- const { position, left, top, right } = this.state.suggestionsPosition
+ const { position, left, top, right } = this.state.suggestionsPosition;
const suggestionsNode = (
{this.props.children}
- )
+ );
if (this.props.suggestionsPortalHost) {
- return ReactDOM.createPortal(
- suggestionsNode,
- this.props.suggestionsPortalHost
- )
+ return ReactDOM.createPortal(suggestionsNode, this.props.suggestionsPortalHost);
} else {
- return suggestionsNode
+ return suggestionsNode;
}
- }
+ };
renderHighlighter = () => {
- const { selectionStart, selectionEnd } = this.state
- const { singleLine, children, value, style } = this.props
+ const { selectionStart, selectionEnd } = this.state;
+ const { singleLine, children, value, style } = this.props;
return (
{children}
- )
- }
+ );
+ };
setHighlighterElement = (el) => {
- this.highlighterElement = el
- }
+ this.highlighterElement = el;
+ };
handleCaretPositionChange = (position) => {
- this.setState({ caretPosition: position })
- }
+ this.setState({ caretPosition: position });
+ };
// Returns the text to set as the value of the textarea with all markups removed
getPlainText = () => {
- return getPlainText(
- this.props.value || '',
- readConfigFromChildren(this.props.children)
- )
- }
+ return getPlainText(this.props.value || '', readConfigFromChildren(this.props.children));
+ };
executeOnChange = (event, ...args) => {
if (this.props.onChange) {
- return this.props.onChange(event, ...args)
+ return this.props.onChange(event, ...args);
}
if (this.props.valueLink) {
- return this.props.valueLink.requestChange(event.target.value, ...args)
+ return this.props.valueLink.requestChange(event.target.value, ...args);
}
- }
+ };
handlePaste(event) {
if (event.target !== this.inputElement) {
- return
+ return;
}
if (!this.supportsClipboardActions(event)) {
- return
+ return;
}
- event.preventDefault()
+ event.preventDefault();
- const { selectionStart, selectionEnd } = this.state
- const { value, children } = this.props
+ const { selectionStart, selectionEnd } = this.state;
+ const { value, children } = this.props;
- const config = readConfigFromChildren(children)
+ const config = readConfigFromChildren(children);
- const markupStartIndex = mapPlainTextIndex(
- value,
- config,
- selectionStart,
- 'START'
- )
- const markupEndIndex = mapPlainTextIndex(value, config, selectionEnd, 'END')
+ const markupStartIndex = mapPlainTextIndex(value, config, selectionStart, 'START');
+ const markupEndIndex = mapPlainTextIndex(value, config, selectionEnd, 'END');
- const pastedMentions = event.clipboardData.getData('text/react-mentions')
- const pastedData = event.clipboardData.getData('text/plain')
+ const pastedMentions = event.clipboardData.getData('text/react-mentions');
+ const pastedData = event.clipboardData.getData('text/plain');
- const newValue = spliceString(
- value,
- markupStartIndex,
- markupEndIndex,
- pastedMentions || pastedData
- ).replace(/\r/g, '')
+ const newValue = spliceString(value, markupStartIndex, markupEndIndex, pastedMentions || pastedData).replace(
+ /\r/g,
+ '',
+ );
- const newPlainTextValue = getPlainText(newValue, config)
+ const newPlainTextValue = getPlainText(newValue, config);
- const eventMock = { target: { ...event.target, value: newValue } }
+ const eventMock = { target: { ...event.target, value: newValue } };
- this.executeOnChange(
- eventMock,
- newValue,
- newPlainTextValue,
- getMentions(newValue, config)
- )
+ this.executeOnChange(eventMock, newValue, newPlainTextValue, getMentions(newValue, config));
// Move the cursor position to the end of the pasted data
- const startOfMention = findStartOfMentionInPlainText(
- value,
- config,
- selectionStart
- )
- const nextPos =
- (startOfMention || selectionStart) +
- getPlainText(pastedMentions || pastedData, config).length
+ const startOfMention = findStartOfMentionInPlainText(value, config, selectionStart);
+ const nextPos = (startOfMention || selectionStart) + getPlainText(pastedMentions || pastedData, config).length;
this.setState({
selectionStart: nextPos,
selectionEnd: nextPos,
setSelectionAfterHandlePaste: true,
- })
+ });
}
saveSelectionToClipboard(event) {
// use the actual selectionStart & selectionEnd instead of the one stored
// in state to ensure copy & paste also works on disabled inputs & textareas
- const selectionStart = this.inputElement.selectionStart
- const selectionEnd = this.inputElement.selectionEnd
- const { children, value } = this.props
+ const selectionStart = this.inputElement.selectionStart;
+ const selectionEnd = this.inputElement.selectionEnd;
+ const { children, value } = this.props;
- const config = readConfigFromChildren(children)
+ const config = readConfigFromChildren(children);
- const markupStartIndex = mapPlainTextIndex(
- value,
- config,
- selectionStart,
- 'START'
- )
- const markupEndIndex = mapPlainTextIndex(value, config, selectionEnd, 'END')
-
- event.clipboardData.setData(
- 'text/plain',
- event.target.value.slice(selectionStart, selectionEnd)
- )
- event.clipboardData.setData(
- 'text/react-mentions',
- value.slice(markupStartIndex, markupEndIndex)
- )
+ const markupStartIndex = mapPlainTextIndex(value, config, selectionStart, 'START');
+ const markupEndIndex = mapPlainTextIndex(value, config, selectionEnd, 'END');
+
+ event.clipboardData.setData('text/plain', event.target.value.slice(selectionStart, selectionEnd));
+ event.clipboardData.setData('text/react-mentions', value.slice(markupStartIndex, markupEndIndex));
}
supportsClipboardActions(event) {
- return !!event.clipboardData
+ return !!event.clipboardData;
}
handleCopy(event) {
if (event.target !== this.inputElement) {
- return
+ return;
}
if (!this.supportsClipboardActions(event)) {
- return
+ return;
}
- event.preventDefault()
+ event.preventDefault();
- this.saveSelectionToClipboard(event)
+ this.saveSelectionToClipboard(event);
}
handleCut(event) {
if (event.target !== this.inputElement) {
- return
+ return;
}
if (!this.supportsClipboardActions(event)) {
- return
+ return;
}
- event.preventDefault()
+ event.preventDefault();
- this.saveSelectionToClipboard(event)
+ this.saveSelectionToClipboard(event);
- const { selectionStart, selectionEnd } = this.state
- const { children, value } = this.props
+ const { selectionStart, selectionEnd } = this.state;
+ const { children, value } = this.props;
- const config = readConfigFromChildren(children)
+ const config = readConfigFromChildren(children);
- const markupStartIndex = mapPlainTextIndex(
- value,
- config,
- selectionStart,
- 'START'
- )
- const markupEndIndex = mapPlainTextIndex(value, config, selectionEnd, 'END')
+ const markupStartIndex = mapPlainTextIndex(value, config, selectionStart, 'START');
+ const markupEndIndex = mapPlainTextIndex(value, config, selectionEnd, 'END');
- const newValue = [
- value.slice(0, markupStartIndex),
- value.slice(markupEndIndex),
- ].join('')
- const newPlainTextValue = getPlainText(newValue, config)
+ const newValue = [value.slice(0, markupStartIndex), value.slice(markupEndIndex)].join('');
+ const newPlainTextValue = getPlainText(newValue, config);
const eventMock = {
target: { ...event.target, value: newPlainTextValue },
- }
+ };
- this.executeOnChange(
- eventMock,
- newValue,
- newPlainTextValue,
- getMentions(value, config)
- )
+ this.executeOnChange(eventMock, newValue, newPlainTextValue, getMentions(value, config));
}
// Handle input element's change event
handleChange = (ev) => {
- isComposing = false
+ isComposing = false;
if (isIE()) {
// if we are inside iframe, we need to find activeElement within its contentDocument
- const currentDocument =
- (document.activeElement && document.activeElement.contentDocument) ||
- document
+ const currentDocument = (document.activeElement && document.activeElement.contentDocument) || document;
if (currentDocument.activeElement !== ev.target) {
// fix an IE bug (blur from empty input element with placeholder attribute trigger "input" event)
- return
+ return;
}
}
- const value = this.props.value || ''
- const config = readConfigFromChildren(this.props.children)
+ const value = this.props.value || '';
+ const config = readConfigFromChildren(this.props.children);
- let newPlainTextValue = ev.target.value
+ let newPlainTextValue = ev.target.value;
let selectionStartBefore = this.state.selectionStart;
- if(selectionStartBefore == null) {
+ if (selectionStartBefore == null) {
selectionStartBefore = ev.target.selectionStart;
}
let selectionEndBefore = this.state.selectionEnd;
- if(selectionEndBefore == null) {
+ if (selectionEndBefore == null) {
selectionEndBefore = ev.target.selectionEnd;
}
@@ -537,54 +467,46 @@ class MentionsInput extends React.Component {
selectionEndBefore,
selectionEndAfter: ev.target.selectionEnd,
},
- config
- )
+ config,
+ );
// In case a mention is deleted, also adjust the new plain text value
- newPlainTextValue = getPlainText(newValue, config)
+ newPlainTextValue = getPlainText(newValue, config);
// Save current selection after change to be able to restore caret position after rerendering
- let selectionStart = ev.target.selectionStart
- let selectionEnd = ev.target.selectionEnd
- let setSelectionAfterMentionChange = false
+ let selectionStart = ev.target.selectionStart;
+ let selectionEnd = ev.target.selectionEnd;
+ let setSelectionAfterMentionChange = false;
// Adjust selection range in case a mention will be deleted by the characters outside of the
// selection range that are automatically deleted
- let startOfMention = findStartOfMentionInPlainText(
- value,
- config,
- selectionStart
- )
+ let startOfMention = findStartOfMentionInPlainText(value, config, selectionStart);
- if (
- startOfMention !== undefined &&
- this.state.selectionEnd > startOfMention
- ) {
+ if (startOfMention !== undefined && this.state.selectionEnd > startOfMention) {
// only if a deletion has taken place
- selectionStart =
- startOfMention + (ev.nativeEvent.data ? ev.nativeEvent.data.length : 0)
- selectionEnd = selectionStart
- setSelectionAfterMentionChange = true
+ selectionStart = startOfMention + (ev.nativeEvent.data ? ev.nativeEvent.data.length : 0);
+ selectionEnd = selectionStart;
+ setSelectionAfterMentionChange = true;
}
this.setState({
selectionStart,
selectionEnd,
setSelectionAfterMentionChange: setSelectionAfterMentionChange,
- })
+ });
- let mentions = getMentions(newValue, config)
+ let mentions = getMentions(newValue, config);
if (ev.nativeEvent.isComposing && selectionStart === selectionEnd) {
- this.updateMentionsQueries(this.inputElement.value, selectionStart)
+ this.updateMentionsQueries(this.inputElement.value, selectionStart);
}
// Propagate change
// let handleChange = this.getOnChange(this.props) || emptyFunction;
- let eventMock = { target: { value: newValue } }
+ let eventMock = { target: { value: newValue } };
// this.props.onChange.call(this, eventMock, newValue, newPlainTextValue, mentions);
- this.executeOnChange(eventMock, newValue, newPlainTextValue, mentions)
- }
+ this.executeOnChange(eventMock, newValue, newPlainTextValue, mentions);
+ };
// Handle input element's select event
handleSelect = (ev) => {
@@ -592,98 +514,94 @@ class MentionsInput extends React.Component {
this.setState({
selectionStart: ev.target.selectionStart,
selectionEnd: ev.target.selectionEnd,
- })
+ });
// do nothing while a IME composition session is active
- if (isComposing) return
+ if (isComposing) return;
// refresh suggestions queries
- const el = this.inputElement
+ const el = this.inputElement;
if (ev.target.selectionStart === ev.target.selectionEnd) {
- this.updateMentionsQueries(el.value, ev.target.selectionStart)
+ this.updateMentionsQueries(el.value, ev.target.selectionStart);
} else {
- this.clearSuggestions()
+ this.clearSuggestions();
}
// sync highlighters scroll position
- this.updateHighlighterScroll()
+ this.updateHighlighterScroll();
- this.props.onSelect(ev)
- }
+ this.props.onSelect(ev);
+ };
handleKeyDown = (ev) => {
// do not intercept key events if the suggestions overlay is not shown
- const suggestionsCount = countSuggestions(this.state.suggestions)
+ const suggestionsCount = countSuggestions(this.state.suggestions);
if (suggestionsCount === 0 || !this.suggestionsElement) {
- this.props.onKeyDown(ev)
+ this.props.onKeyDown(ev);
- return
+ return;
}
if (Object.values(KEY).indexOf(ev.keyCode) >= 0) {
- ev.preventDefault()
- ev.stopPropagation()
+ ev.preventDefault();
+ ev.stopPropagation();
}
switch (ev.keyCode) {
case KEY.ESC: {
- this.clearSuggestions()
- return
+ this.clearSuggestions();
+ return;
}
case KEY.DOWN: {
- this.shiftFocus(+1)
- return
+ this.shiftFocus(+1);
+ return;
}
case KEY.UP: {
- this.shiftFocus(-1)
- return
+ this.shiftFocus(-1);
+ return;
}
case KEY.RETURN: {
- this.selectFocused()
- return
+ this.selectFocused();
+ return;
}
case KEY.TAB: {
- this.selectFocused()
- return
+ this.selectFocused();
+ return;
}
default: {
- return
+ return;
}
}
- }
+ };
shiftFocus = (delta) => {
- const suggestionsCount = countSuggestions(this.state.suggestions)
+ const suggestionsCount = countSuggestions(this.state.suggestions);
this.setState({
- focusIndex:
- (suggestionsCount + this.state.focusIndex + delta) % suggestionsCount,
+ focusIndex: (suggestionsCount + this.state.focusIndex + delta) % suggestionsCount,
scrollFocusedIntoView: true,
- })
- }
+ });
+ };
selectFocused = () => {
- const { suggestions, focusIndex } = this.state
+ const { suggestions, focusIndex } = this.state;
const { result, queryInfo } = Object.values(suggestions).reduce(
- (acc, { results, queryInfo }) => [
- ...acc,
- ...results.map((result) => ({ result, queryInfo })),
- ],
- []
- )[focusIndex]
+ (acc, { results, queryInfo }) => [...acc, ...results.map((result) => ({ result, queryInfo }))],
+ [],
+ )[focusIndex];
- this.addMention(result, queryInfo)
+ this.addMention(result, queryInfo);
this.setState({
focusIndex: 0,
- })
- }
+ });
+ };
handleBlur = (ev) => {
- const clickedSuggestion = this._suggestionsMouseDown
- this._suggestionsMouseDown = false
+ const clickedSuggestion = this._suggestionsMouseDown;
+ this._suggestionsMouseDown = false;
// only reset selection if the mousedown happened on an element
// other than the suggestions overlay
@@ -691,79 +609,69 @@ class MentionsInput extends React.Component {
this.setState({
selectionStart: null,
selectionEnd: null,
- })
+ });
}
window.setTimeout(() => {
- this.updateHighlighterScroll()
- }, 1)
+ this.updateHighlighterScroll();
+ }, 1);
- this.props.onBlur(ev, clickedSuggestion)
- }
+ this.props.onBlur(ev, clickedSuggestion);
+ };
handleSuggestionsMouseDown = (ev) => {
- this._suggestionsMouseDown = true
- }
+ this._suggestionsMouseDown = true;
+ };
handleSuggestionsMouseEnter = (focusIndex) => {
this.setState({
focusIndex,
scrollFocusedIntoView: false,
- })
- }
+ });
+ };
updateSuggestionsPosition = () => {
- let { caretPosition } = this.state
- const {
- suggestionsPortalHost,
- allowSuggestionsAboveCursor,
- forceSuggestionsAboveCursor,
- } = this.props
+ let { caretPosition } = this.state;
+ const { suggestionsPortalHost, allowSuggestionsAboveCursor, forceSuggestionsAboveCursor } = this.props;
if (!caretPosition || !this.suggestionsElement) {
- return
+ return;
}
- let suggestions = this.suggestionsElement
- let highlighter = this.highlighterElement
+ let suggestions = this.suggestionsElement;
+ let highlighter = this.highlighterElement;
// first get viewport-relative position (highlighter is offsetParent of caret):
- const caretOffsetParentRect = highlighter.getBoundingClientRect()
- const caretHeight = getComputedStyleLengthProp(highlighter, 'font-size')
+ const caretOffsetParentRect = highlighter.getBoundingClientRect();
+ const caretHeight = getComputedStyleLengthProp(highlighter, 'font-size');
const viewportRelative = {
left: caretOffsetParentRect.left + caretPosition.left,
top: caretOffsetParentRect.top + caretPosition.top + caretHeight,
- }
- const viewportHeight = Math.max(
- document.documentElement.clientHeight,
- window.innerHeight || 0
- )
+ };
+ const viewportHeight = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
if (!suggestions) {
- return
+ return;
}
- let position = {}
+ let position = {};
// if suggestions menu is in a portal, update position to be releative to its portal node
if (suggestionsPortalHost) {
- position.position = 'fixed'
- let left = viewportRelative.left
- let top = viewportRelative.top
+ position.position = 'fixed';
+ let left = viewportRelative.left;
+ let top = viewportRelative.top;
// absolute/fixed positioned elements are positioned according to their entire box including margins; so we remove margins here:
- left -= getComputedStyleLengthProp(suggestions, 'margin-left')
- top -= getComputedStyleLengthProp(suggestions, 'margin-top')
+ left -= getComputedStyleLengthProp(suggestions, 'margin-left');
+ top -= getComputedStyleLengthProp(suggestions, 'margin-top');
// take into account highlighter/textinput scrolling:
- left -= highlighter.scrollLeft
- top -= highlighter.scrollTop
+ left -= highlighter.scrollLeft;
+ top -= highlighter.scrollTop;
// guard for mentions suggestions list clipped by right edge of window
- const viewportWidth = Math.max(
- document.documentElement.clientWidth,
- window.innerWidth || 0
- )
+ const viewportWidth = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
if (left + suggestions.offsetWidth > viewportWidth) {
- position.left = Math.max(0, viewportWidth - suggestions.offsetWidth)
+ position.left = Math.max(0, viewportWidth - suggestions.offsetWidth);
} else {
- position.left = left
+ position.left = left;
}
// guard for mentions suggestions list clipped by bottom edge of window if allowSuggestionsAboveCursor set to true.
// Move the list up above the caret if it's getting cut off by the bottom of the window, provided that the list height
@@ -774,35 +682,31 @@ class MentionsInput extends React.Component {
suggestions.offsetHeight < top - caretHeight) ||
forceSuggestionsAboveCursor
) {
- position.top = Math.max(0, top - suggestions.offsetHeight - caretHeight)
+ position.top = Math.max(0, top - suggestions.offsetHeight - caretHeight);
} else {
- position.top = top
+ position.top = top;
}
} else {
- let left = caretPosition.left - highlighter.scrollLeft
- let top = caretPosition.top - highlighter.scrollTop
+ let left = caretPosition.left - highlighter.scrollLeft;
+ let top = caretPosition.top - highlighter.scrollTop;
// guard for mentions suggestions list clipped by right edge of window
if (left + suggestions.offsetWidth > this.containerElement.offsetWidth) {
- position.right = 0
+ position.right = 0;
} else {
- position.left = left
+ position.left = left;
}
// guard for mentions suggestions list clipped by bottom edge of window if allowSuggestionsAboveCursor set to true.
// move the list up above the caret if it's getting cut off by the bottom of the window, provided that the list height
// is small enough to NOT cover up the caret
if (
(allowSuggestionsAboveCursor &&
- viewportRelative.top -
- highlighter.scrollTop +
- suggestions.offsetHeight >
- viewportHeight &&
- suggestions.offsetHeight <
- caretOffsetParentRect.top - caretHeight - highlighter.scrollTop) ||
+ viewportRelative.top - highlighter.scrollTop + suggestions.offsetHeight > viewportHeight &&
+ suggestions.offsetHeight < caretOffsetParentRect.top - caretHeight - highlighter.scrollTop) ||
forceSuggestionsAboveCursor
) {
- position.top = top - suggestions.offsetHeight - caretHeight
+ position.top = top - suggestions.offsetHeight - caretHeight;
} else {
- position.top = top
+ position.top = top;
}
}
@@ -811,127 +715,103 @@ class MentionsInput extends React.Component {
position.top === this.state.suggestionsPosition.top &&
position.position === this.state.suggestionsPosition.position
) {
- return
+ return;
}
this.setState({
suggestionsPosition: position,
- })
- }
+ });
+ };
updateHighlighterScroll = () => {
- const input = this.inputElement
- const highlighter = this.highlighterElement
+ const input = this.inputElement;
+ const highlighter = this.highlighterElement;
if (!input || !highlighter) {
// since the invocation of this function is deferred,
// the whole component may have been unmounted in the meanwhile
- return
+ return;
}
- highlighter.scrollLeft = input.scrollLeft
- highlighter.scrollTop = input.scrollTop
- highlighter.height = input.height
- }
+ highlighter.scrollLeft = input.scrollLeft;
+ highlighter.scrollTop = input.scrollTop;
+ highlighter.height = input.height;
+ };
handleCompositionStart = () => {
- isComposing = true
- }
+ isComposing = true;
+ };
handleCompositionEnd = () => {
- isComposing = false
- }
+ isComposing = false;
+ };
setSelection = (selectionStart, selectionEnd) => {
- if (selectionStart === null || selectionEnd === null) return
+ if (selectionStart === null || selectionEnd === null) return;
- const el = this.inputElement
+ const el = this.inputElement;
if (el.setSelectionRange) {
- el.setSelectionRange(selectionStart, selectionEnd)
+ el.setSelectionRange(selectionStart, selectionEnd);
} else if (el.createTextRange) {
- const range = el.createTextRange()
- range.collapse(true)
- range.moveEnd('character', selectionEnd)
- range.moveStart('character', selectionStart)
- range.select()
+ const range = el.createTextRange();
+ range.collapse(true);
+ range.moveEnd('character', selectionEnd);
+ range.moveStart('character', selectionStart);
+ range.select();
}
- }
+ };
updateMentionsQueries = (plainTextValue, caretPosition) => {
// Invalidate previous queries. Async results for previous queries will be neglected.
- this._queryId++
- this.suggestions = {}
+ this._queryId++;
+ this.suggestions = {};
this.setState({
suggestions: {},
- })
+ });
- const value = this.props.value || ''
- const { children } = this.props
- const config = readConfigFromChildren(children)
+ const value = this.props.value || '';
+ const { children } = this.props;
+ const config = readConfigFromChildren(children);
- const positionInValue = mapPlainTextIndex(
- value,
- config,
- caretPosition,
- 'NULL'
- )
+ const positionInValue = mapPlainTextIndex(value, config, caretPosition, 'NULL');
// If caret is inside of mention, do not query
if (positionInValue === null) {
- return
+ return;
}
// Extract substring in between the end of the previous mention and the caret
- const substringStartIndex = getEndOfLastMention(
- value.substring(0, positionInValue),
- config
- )
- const substring = plainTextValue.substring(
- substringStartIndex,
- caretPosition
- )
+ const substringStartIndex = getEndOfLastMention(value.substring(0, positionInValue), config);
+ const substring = plainTextValue.substring(substringStartIndex, caretPosition);
// Check if suggestions have to be shown:
// Match the trigger patterns of all Mention children on the extracted substring
React.Children.forEach(children, (child, childIndex) => {
if (!child) {
- return
+ return;
}
- const regex = makeTriggerRegex(child.props.trigger, this.props)
- const match = substring.match(regex)
+ const regex = makeTriggerRegex(child.props.trigger, this.props);
+ const match = substring.match(regex);
if (match) {
- const querySequenceStart =
- substringStartIndex + substring.indexOf(match[1], match.index)
- this.queryData(
- match[2],
- childIndex,
- querySequenceStart,
- querySequenceStart + match[1].length,
- plainTextValue
- )
+ const querySequenceStart = substringStartIndex + substring.indexOf(match[1], match.index);
+ this.queryData(match[2], childIndex, querySequenceStart, querySequenceStart + match[1].length, plainTextValue);
}
- })
- }
+ });
+ };
clearSuggestions = () => {
// Invalidate previous queries. Async results for previous queries will be neglected.
- this._queryId++
- this.suggestions = {}
+ this._queryId++;
+ this.suggestions = {};
this.setState({
suggestions: {},
focusIndex: 0,
- })
- }
+ });
+ };
- queryData = (
- query,
- childIndex,
- querySequenceStart,
- querySequenceEnd,
- plainTextValue
- ) => {
- const { children, ignoreAccents } = this.props
- const mentionChild = Children.toArray(children)[childIndex]
- const provideData = getDataProvider(mentionChild.props.data, ignoreAccents)
+ queryData = (query, childIndex, querySequenceStart, querySequenceEnd, plainTextValue) => {
+ const { children, ignoreAccents } = this.props;
+ const mentionChild = Children.toArray(children)[childIndex];
+ const provideData = getDataProvider(mentionChild.props.data, ignoreAccents);
const syncResult = provideData(
query,
this.updateSuggestions.bind(
@@ -941,9 +821,9 @@ class MentionsInput extends React.Component {
query,
querySequenceStart,
querySequenceEnd,
- plainTextValue
- )
- )
+ plainTextValue,
+ ),
+ );
if (syncResult instanceof Array) {
this.updateSuggestions(
this._queryId,
@@ -952,22 +832,14 @@ class MentionsInput extends React.Component {
querySequenceStart,
querySequenceEnd,
plainTextValue,
- syncResult
- )
+ syncResult,
+ );
}
- }
+ };
- updateSuggestions = (
- queryId,
- childIndex,
- query,
- querySequenceStart,
- querySequenceEnd,
- plainTextValue,
- results
- ) => {
+ updateSuggestions = (queryId, childIndex, query, querySequenceStart, querySequenceEnd, plainTextValue, results) => {
// neglect async results from previous queries
- if (queryId !== this._queryId) return
+ if (queryId !== this._queryId) return;
// save in property so that multiple sync state updates from different mentions sources
// won't overwrite each other
@@ -983,91 +855,74 @@ class MentionsInput extends React.Component {
},
results,
},
- }
+ };
- const { focusIndex } = this.state
- const suggestionsCount = countSuggestions(this.suggestions)
+ const { focusIndex } = this.state;
+ const suggestionsCount = countSuggestions(this.suggestions);
this.setState({
suggestions: this.suggestions,
- focusIndex:
- focusIndex >= suggestionsCount
- ? Math.max(suggestionsCount - 1, 0)
- : focusIndex,
- })
- }
+ focusIndex: focusIndex >= suggestionsCount ? Math.max(suggestionsCount - 1, 0) : focusIndex,
+ });
+ };
- addMention = (
- { id, display },
- { childIndex, querySequenceStart, querySequenceEnd, plainTextValue }
- ) => {
+ addMention = ({ id, display }, { childIndex, querySequenceStart, querySequenceEnd, plainTextValue }) => {
// Insert mention in the marked up value at the correct position
- const value = this.props.value || ''
- const config = readConfigFromChildren(this.props.children)
- const mentionsChild = Children.toArray(this.props.children)[childIndex]
- const {
- markup,
- displayTransform,
- appendSpaceOnAdd,
- onAdd,
- } = mentionsChild.props
+ const value = this.props.value || '';
+ const config = readConfigFromChildren(this.props.children);
+ const mentionsChild = Children.toArray(this.props.children)[childIndex];
+ const { markup, displayTransform, appendSpaceOnAdd, onAdd } = mentionsChild.props;
- const start = mapPlainTextIndex(value, config, querySequenceStart, 'START')
- const end = start + querySequenceEnd - querySequenceStart
+ const start = mapPlainTextIndex(value, config, querySequenceStart, 'START');
+ const end = start + querySequenceEnd - querySequenceStart;
- let insert = makeMentionsMarkup(markup, id, display)
+ let insert = makeMentionsMarkup(markup, id, display);
if (appendSpaceOnAdd) {
- insert += ' '
+ insert += ' ';
}
- const newValue = spliceString(value, start, end, insert)
+ const newValue = spliceString(value, start, end, insert);
// Refocus input and set caret position to end of mention
- this.inputElement.focus()
+ this.inputElement.focus();
- let displayValue = displayTransform(id, display)
+ let displayValue = displayTransform(id, display);
if (appendSpaceOnAdd) {
- displayValue += ' '
+ displayValue += ' ';
}
- const newCaretPosition = querySequenceStart + displayValue.length
+ const newCaretPosition = querySequenceStart + displayValue.length;
this.setState({
selectionStart: newCaretPosition,
selectionEnd: newCaretPosition,
setSelectionAfterMentionChange: true,
- })
+ });
// Propagate change
- const eventMock = { target: { value: newValue } }
- const mentions = getMentions(newValue, config)
- const newPlainTextValue = spliceString(
- plainTextValue,
- querySequenceStart,
- querySequenceEnd,
- displayValue
- )
+ const eventMock = { target: { value: newValue } };
+ const mentions = getMentions(newValue, config);
+ const newPlainTextValue = spliceString(plainTextValue, querySequenceStart, querySequenceEnd, displayValue);
- this.executeOnChange(eventMock, newValue, newPlainTextValue, mentions)
+ this.executeOnChange(eventMock, newValue, newPlainTextValue, mentions);
if (onAdd) {
- onAdd(id, display, start, end)
+ onAdd(id, display, start, end);
}
// Make sure the suggestions overlay is closed
- this.clearSuggestions()
- }
+ this.clearSuggestions();
+ };
isLoading = () => {
- let isLoading = false
- React.Children.forEach(this.props.children, function(child) {
- isLoading = isLoading || (child && child.props.isLoading)
- })
- return isLoading
- }
+ let isLoading = false;
+ React.Children.forEach(this.props.children, function (child) {
+ isLoading = isLoading || (child && child.props.isLoading);
+ });
+ return isLoading;
+ };
isOpened = () =>
- isNumber(this.state.selectionStart) &&
- (countSuggestions(this.state.suggestions) !== 0 || this.isLoading())
+ isNumber(this.state.selectionStart) && (countSuggestions(this.state.suggestions) !== 0 || this.isLoading());
- _queryId = 0
+ _queryId = 0;
}
/**
@@ -1075,22 +930,18 @@ class MentionsInput extends React.Component {
* Note: According to spec and testing, can count on length values coming back in pixels. See https://developer.mozilla.org/en-US/docs/Web/CSS/used_value#Difference_from_computed_value
*/
const getComputedStyleLengthProp = (forElement, propertyName) => {
- const length = parseFloat(
- window.getComputedStyle(forElement, null).getPropertyValue(propertyName)
- )
- return isFinite(length) ? length : 0
-}
+ const length = parseFloat(window.getComputedStyle(forElement, null).getPropertyValue(propertyName));
+ return isFinite(length) ? length : 0;
+};
-const isMobileSafari =
- typeof navigator !== 'undefined' &&
- /iPhone|iPad|iPod/i.test(navigator.userAgent)
+const isMobileSafari = typeof navigator !== 'undefined' && /iPhone|iPad|iPod/i.test(navigator.userAgent);
const styled = defaultStyle(
{
- position: 'relative',
- overflowY: 'visible',
+ 'position': 'relative',
+ 'overflowY': 'visible',
- input: {
+ 'input': {
display: 'block',
width: '100%',
position: 'absolute',
@@ -1124,7 +975,7 @@ const styled = defaultStyle(
({ singleLine }) => ({
'&singleLine': singleLine,
'&multiLine': !singleLine,
- })
-)
+ }),
+);
-export default styled(MentionsInput)
+export default styled(MentionsInput);
diff --git a/apps/crew/packages/react-mentions/src/MentionsInput.spec.js b/apps/crew/packages/react-mentions/src/MentionsInput.spec.js
index f192f1aaf..47136cf66 100644
--- a/apps/crew/packages/react-mentions/src/MentionsInput.spec.js
+++ b/apps/crew/packages/react-mentions/src/MentionsInput.spec.js
@@ -1,75 +1,72 @@
-import { Mention, MentionsInput } from './index'
+import { Mention, MentionsInput } from './index';
-import React from 'react'
-import { makeTriggerRegex } from './MentionsInput'
-import { mount } from 'enzyme'
+import React from 'react';
+import { makeTriggerRegex } from './MentionsInput';
+import { mount } from 'enzyme';
const data = [
{ id: 'first', value: 'First entry' },
{ id: 'second', value: 'Second entry' },
{ id: 'third', value: 'Third' },
-]
+];
describe('MentionsInput', () => {
- let wrapper, host
+ let wrapper, host;
beforeEach(() => {
// I don't know where enzmye mounts this, but apparently it is somewhere
// where our input cannot have a `scollHeight`/`offsetHeight`. Therefore, some tests would fail.
// By manually creating a wrapper in the DOM, we can work around that
- host = document.createElement('div')
- document.body.appendChild(host)
+ host = document.createElement('div');
+ document.body.appendChild(host);
wrapper = mount(
-
-
-
- )
- })
+
+
+ ,
+ );
+ });
it('should render a textarea by default.', () => {
- expect(wrapper.find('textarea').length).toEqual(1)
- expect(wrapper.find('input').length).toEqual(0)
- })
+ expect(wrapper.find('textarea').length).toEqual(1);
+ expect(wrapper.find('input').length).toEqual(0);
+ });
it('should render a regular input when singleLine is set to true.', () => {
wrapper.setProps({
singleLine: true,
- })
+ });
- expect(wrapper.find('textarea').length).toEqual(0)
- expect(wrapper.find('input').length).toEqual(1)
- })
+ expect(wrapper.find('textarea').length).toEqual(0);
+ expect(wrapper.find('input').length).toEqual(1);
+ });
- it.todo(
- 'should show a list of suggestions once the trigger key has been entered.'
- )
- it.todo(
- 'should be possible to navigate through the suggestions with the up and down arrows.'
- )
- it.todo('should be possible to select a suggestion with enter.')
- it.todo('should be possible to close the suggestions with esc.')
+ it.todo('should show a list of suggestions once the trigger key has been entered.');
+ it.todo('should be possible to navigate through the suggestions with the up and down arrows.');
+ it.todo('should be possible to select a suggestion with enter.');
+ it.todo('should be possible to close the suggestions with esc.');
it('should be able to handle sync responses from multiple mentions sources', () => {
- const extraData = [{ id: 'a', value: 'A' }, { id: 'b', value: 'B' }]
+ const extraData = [
+ { id: 'a', value: 'A' },
+ { id: 'b', value: 'B' },
+ ];
const wrapper = mount(
-
-
-
-
- )
+
+
+
+ ,
+ );
- wrapper.find('textarea').simulate('focus')
+ wrapper.find('textarea').simulate('focus');
wrapper.find('textarea').simulate('select', {
target: { selectionStart: 1, selectionEnd: 1 },
- })
- wrapper.find('textarea').getDOMNode().setSelectionRange(1, 1)
+ });
+ wrapper.find('textarea').getDOMNode().setSelectionRange(1, 1);
- expect(
- wrapper.find('SuggestionsOverlay').find('Suggestion').length
- ).toEqual(data.length + extraData.length)
- })
+ expect(wrapper.find('SuggestionsOverlay').find('Suggestion').length).toEqual(data.length + extraData.length);
+ });
it('should scroll the highlighter in sync with the textarea', () => {
const wrapper = mount(
@@ -80,400 +77,379 @@ describe('MentionsInput', () => {
height: 40,
},
}}
- className="mi"
- value={
- 'multiple lines causing \n1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n the textarea to scroll'
- }
+ className='mi'
+ value={'multiple lines causing \n1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n the textarea to scroll'}
>
-
+
,
{
attachTo: host,
- }
- )
+ },
+ );
- wrapper.find('textarea').getDOMNode().scrollTop = 23
- wrapper.find('textarea').simulate('scroll', { deltaY: 23 })
+ wrapper.find('textarea').getDOMNode().scrollTop = 23;
+ wrapper.find('textarea').simulate('scroll', { deltaY: 23 });
- expect(wrapper.find('.mi__highlighter').getDOMNode().scrollTop).toBe(23)
- })
+ expect(wrapper.find('.mi__highlighter').getDOMNode().scrollTop).toBe(23);
+ });
it('should place suggestions in suggestionsPortalHost', () => {
- let portalNode
+ let portalNode;
const rootWrapper = mount(
-
+
{
- portalNode = el
+ portalNode = el;
}}
>
menu goes here
-
- )
+
,
+ );
const wrapper = mount(
-
-
-
- )
+
+
+ ,
+ );
// focus & select to show suggestions
- wrapper.find('textarea').simulate('focus')
+ wrapper.find('textarea').simulate('focus');
wrapper.find('textarea').simulate('select', {
target: { selectionStart: 1, selectionEnd: 1 },
- })
+ });
- let portalDiv = rootWrapper.find('#portalDiv').getDOMNode()
- const suggestionsNode = portalDiv.querySelector('.testClass__suggestions')
- expect(suggestionsNode).toBeTruthy()
- })
+ let portalDiv = rootWrapper.find('#portalDiv').getDOMNode();
+ const suggestionsNode = portalDiv.querySelector('.testClass__suggestions');
+ expect(suggestionsNode).toBeTruthy();
+ });
it('should accept a custom regex attribute', () => {
- const data = [{ id: 'aaaa', display: '@A' }, { id: 'bbbb', display: '@B' }]
+ const data = [
+ { id: 'aaaa', display: '@A' },
+ { id: 'bbbb', display: '@B' },
+ ];
const wrapper = mount(
-
+
{
- let mention = data.find((item) => item.id === id)
- return mention ? mention.display : `:${id}`
+ let mention = data.find((item) => item.id === id);
+ return mention ? mention.display : `:${id}`;
}}
/>
-
- )
- wrapper.find('textarea').simulate('focus')
- expect(wrapper.find('textarea').getDOMNode().value).toEqual(
- '@A and @B and :invalidId'
- )
- })
+ ,
+ );
+ wrapper.find('textarea').simulate('focus');
+ expect(wrapper.find('textarea').getDOMNode().value).toEqual('@A and @B and :invalidId');
+ });
it('should forward the `inputRef` prop to become the `ref` of the input', () => {
- const inputRef = React.createRef()
+ const inputRef = React.createRef();
const wrapper = mount(
-
-
-
- )
- const el = wrapper.find('textarea').getDOMNode()
- expect(inputRef.current).toBeTruthy()
- expect(inputRef.current).toEqual(el)
- })
+
+
+ ,
+ );
+ const el = wrapper.find('textarea').getDOMNode();
+ expect(inputRef.current).toBeTruthy();
+ expect(inputRef.current).toEqual(el);
+ });
it('should forward the `inputRef` prop to become the `ref` of the input (callback ref)', () => {
- const inputRef = jest.fn()
+ const inputRef = jest.fn();
const wrapper = mount(
-
-
-
- )
- const el = wrapper.find('textarea').getDOMNode()
- expect(inputRef).toHaveBeenCalledWith(el)
- })
+
+
+ ,
+ );
+ const el = wrapper.find('textarea').getDOMNode();
+ expect(inputRef).toHaveBeenCalledWith(el);
+ });
describe('makeTriggerRegex', () => {
it('should return regular expressions', () => {
- const trigger = /abc/
- expect(makeTriggerRegex(trigger)).toEqual(trigger)
- })
+ const trigger = /abc/;
+ expect(makeTriggerRegex(trigger)).toEqual(trigger);
+ });
it('should escape and capture a string trigger', () => {
- const result = makeTriggerRegex('trigger').toString()
- expect(result).toEqual('/(?:^|\\s)(trigger([^\\strigger]*))$/')
- })
+ const result = makeTriggerRegex('trigger').toString();
+ expect(result).toEqual('/(?:^|\\s)(trigger([^\\strigger]*))$/');
+ });
it('should allow spaces in search', () => {
const result = makeTriggerRegex('trigger', {
allowSpaceInQuery: true,
- }).toString()
- expect(result).toEqual('/(?:^|\\s)(trigger([^trigger]*))$/')
- })
- })
+ }).toString();
+ expect(result).toEqual('/(?:^|\\s)(trigger([^trigger]*))$/');
+ });
+ });
describe('custom cut/copy/paste', () => {
- let component
+ let component;
- const plainTextValue = "Hi First, \n\nlet's add Second to the conversation."
- const value =
- "Hi @[First](first), \n\nlet's add @[Second](second) to the conversation."
+ const plainTextValue = "Hi First, \n\nlet's add Second to the conversation.";
+ const value = "Hi @[First](first), \n\nlet's add @[Second](second) to the conversation.";
beforeEach(() => {
component = mount(
-
+
,
{
attachTo: host,
- }
- )
- })
+ },
+ );
+ });
it.each(['cut', 'copy'])(
'should include the whole mention for a "%s" event when the selection starts in one.',
(eventType) => {
- const textarea = component.find('textarea')
+ const textarea = component.find('textarea');
- const selectionStart = plainTextValue.indexOf('First') + 2
- const selectionEnd = plainTextValue.length
+ const selectionStart = plainTextValue.indexOf('First') + 2;
+ const selectionEnd = plainTextValue.length;
textarea.simulate('select', {
target: { selectionStart, selectionEnd },
- })
- textarea.getDOMNode().setSelectionRange(selectionStart, selectionEnd)
+ });
+ textarea.getDOMNode().setSelectionRange(selectionStart, selectionEnd);
- const setData = jest.fn()
+ const setData = jest.fn();
- const event = new Event(eventType, { bubbles: true })
- event.clipboardData = { setData }
+ const event = new Event(eventType, { bubbles: true });
+ event.clipboardData = { setData };
- textarea.getDOMNode().dispatchEvent(event)
+ textarea.getDOMNode().dispatchEvent(event);
- expect(setData).toHaveBeenCalledTimes(2)
+ expect(setData).toHaveBeenCalledTimes(2);
- expect(setData).toHaveBeenNthCalledWith(
- 1,
- 'text/plain',
- plainTextValue.slice(selectionStart, selectionEnd)
- )
+ expect(setData).toHaveBeenNthCalledWith(1, 'text/plain', plainTextValue.slice(selectionStart, selectionEnd));
expect(setData).toHaveBeenNthCalledWith(
2,
'text/react-mentions',
- "@[First](first), \n\nlet's add @[Second](second) to the conversation."
- )
- }
- )
+ "@[First](first), \n\nlet's add @[Second](second) to the conversation.",
+ );
+ },
+ );
it.each(['cut', 'copy'])(
'should include the whole mention for a "%s" event when the selection ends in one.',
(eventType) => {
- const textarea = component.find('textarea')
+ const textarea = component.find('textarea');
- const selectionStart = 0
- const selectionEnd = plainTextValue.indexOf('Second') + 2
+ const selectionStart = 0;
+ const selectionEnd = plainTextValue.indexOf('Second') + 2;
textarea.simulate('select', {
target: { selectionStart, selectionEnd },
- })
- textarea.getDOMNode().setSelectionRange(selectionStart, selectionEnd)
+ });
+ textarea.getDOMNode().setSelectionRange(selectionStart, selectionEnd);
- const setData = jest.fn()
+ const setData = jest.fn();
- const event = new Event(eventType, { bubbles: true })
- event.clipboardData = { setData }
+ const event = new Event(eventType, { bubbles: true });
+ event.clipboardData = { setData };
- textarea.getDOMNode().dispatchEvent(event)
+ textarea.getDOMNode().dispatchEvent(event);
- expect(setData).toHaveBeenCalledTimes(2)
+ expect(setData).toHaveBeenCalledTimes(2);
- expect(setData).toHaveBeenNthCalledWith(
- 1,
- 'text/plain',
- plainTextValue.slice(selectionStart, selectionEnd)
- )
+ expect(setData).toHaveBeenNthCalledWith(1, 'text/plain', plainTextValue.slice(selectionStart, selectionEnd));
expect(setData).toHaveBeenNthCalledWith(
2,
'text/react-mentions',
- "Hi @[First](first), \n\nlet's add @[Second](second)"
- )
- }
- )
+ "Hi @[First](first), \n\nlet's add @[Second](second)",
+ );
+ },
+ );
it.each(['cut', 'copy'])(
'should fallback to the browsers behavior if the "%s" event does not support clipboardData',
(eventType) => {
// IE 11 has no clipboardData attached to the event and only supports mime type "text"
// therefore, the new mechanism should ignore those events and let the browser handle them
- const textarea = component.find('textarea')
+ const textarea = component.find('textarea');
- const selectionStart = plainTextValue.indexOf('First') + 2
- const selectionEnd = plainTextValue.length
+ const selectionStart = plainTextValue.indexOf('First') + 2;
+ const selectionEnd = plainTextValue.length;
textarea.simulate('select', {
target: { selectionStart, selectionEnd },
- })
- textarea.getDOMNode().setSelectionRange(selectionStart, selectionEnd)
+ });
+ textarea.getDOMNode().setSelectionRange(selectionStart, selectionEnd);
- const preventDefault = jest.fn()
- const event = new Event(eventType, { bubbles: true })
- event.preventDefault = preventDefault
+ const preventDefault = jest.fn();
+ const event = new Event(eventType, { bubbles: true });
+ event.preventDefault = preventDefault;
- textarea.getDOMNode().dispatchEvent(event)
+ textarea.getDOMNode().dispatchEvent(event);
- expect(preventDefault).not.toHaveBeenCalled()
- }
- )
+ expect(preventDefault).not.toHaveBeenCalled();
+ },
+ );
it('should remove a leading mention from the value when the text is cut.', () => {
- const onChange = jest.fn()
+ const onChange = jest.fn();
- component.setProps({ onChange })
+ component.setProps({ onChange });
- const textarea = component.find('textarea')
+ const textarea = component.find('textarea');
- const selectionStart = plainTextValue.indexOf('First') + 2
- const selectionEnd = plainTextValue.indexOf('First') + 'First'.length + 5
+ const selectionStart = plainTextValue.indexOf('First') + 2;
+ const selectionEnd = plainTextValue.indexOf('First') + 'First'.length + 5;
textarea.simulate('select', {
target: { selectionStart, selectionEnd },
- })
- textarea.getDOMNode().setSelectionRange(selectionStart, selectionEnd)
+ });
+ textarea.getDOMNode().setSelectionRange(selectionStart, selectionEnd);
- const event = new Event('cut', { bubbles: true })
- event.clipboardData = { setData: jest.fn() }
+ const event = new Event('cut', { bubbles: true });
+ event.clipboardData = { setData: jest.fn() };
- expect(onChange).not.toHaveBeenCalled()
+ expect(onChange).not.toHaveBeenCalled();
- textarea.getDOMNode().dispatchEvent(event)
+ textarea.getDOMNode().dispatchEvent(event);
- expect(onChange).toHaveBeenCalledTimes(1)
+ expect(onChange).toHaveBeenCalledTimes(1);
- const [[, newValue, newPlainTextValue]] = onChange.mock.calls
+ const [[, newValue, newPlainTextValue]] = onChange.mock.calls;
- expect(newValue).toMatchSnapshot()
- expect(newPlainTextValue).toMatchSnapshot()
- })
+ expect(newValue).toMatchSnapshot();
+ expect(newPlainTextValue).toMatchSnapshot();
+ });
it('should remove a trailing mention from the value when the text is cut.', () => {
- const onChange = jest.fn()
+ const onChange = jest.fn();
- component.setProps({ onChange })
+ component.setProps({ onChange });
- const textarea = component.find('textarea')
+ const textarea = component.find('textarea');
- const selectionStart = plainTextValue.indexOf('First') + 'First'.length
- const selectionEnd = plainTextValue.indexOf('Second') + 2
+ const selectionStart = plainTextValue.indexOf('First') + 'First'.length;
+ const selectionEnd = plainTextValue.indexOf('Second') + 2;
textarea.simulate('select', {
target: { selectionStart, selectionEnd },
- })
- textarea.getDOMNode().setSelectionRange(selectionStart, selectionEnd)
+ });
+ textarea.getDOMNode().setSelectionRange(selectionStart, selectionEnd);
- const event = new Event('cut', { bubbles: true })
- event.clipboardData = { setData: jest.fn() }
+ const event = new Event('cut', { bubbles: true });
+ event.clipboardData = { setData: jest.fn() };
- expect(onChange).not.toHaveBeenCalled()
+ expect(onChange).not.toHaveBeenCalled();
- textarea.getDOMNode().dispatchEvent(event)
+ textarea.getDOMNode().dispatchEvent(event);
- expect(onChange).toHaveBeenCalledTimes(1)
+ expect(onChange).toHaveBeenCalledTimes(1);
- const [[, newValue, newPlainTextValue]] = onChange.mock.calls
+ const [[, newValue, newPlainTextValue]] = onChange.mock.calls;
- expect(newValue).toMatchSnapshot()
- expect(newPlainTextValue).toMatchSnapshot()
- })
+ expect(newValue).toMatchSnapshot();
+ expect(newPlainTextValue).toMatchSnapshot();
+ });
it('should read mentions markup from a paste event.', () => {
- const onChange = jest.fn()
+ const onChange = jest.fn();
- component.setProps({ onChange })
+ component.setProps({ onChange });
- const textarea = component.find('textarea')
+ const textarea = component.find('textarea');
- const pastedText = 'Not forget about @[Third](third)!'
+ const pastedText = 'Not forget about @[Third](third)!';
- const event = new Event('paste', { bubbles: true })
+ const event = new Event('paste', { bubbles: true });
event.clipboardData = {
- getData: jest.fn((type) =>
- type === 'text/react-mentions' ? pastedText : ''
- ),
- }
+ getData: jest.fn((type) => (type === 'text/react-mentions' ? pastedText : '')),
+ };
- expect(onChange).not.toHaveBeenCalled()
+ expect(onChange).not.toHaveBeenCalled();
- textarea.getDOMNode().dispatchEvent(event)
+ textarea.getDOMNode().dispatchEvent(event);
- expect(onChange).toHaveBeenCalledTimes(1)
+ expect(onChange).toHaveBeenCalledTimes(1);
- const [[, newValue, newPlainTextValue]] = onChange.mock.calls
+ const [[, newValue, newPlainTextValue]] = onChange.mock.calls;
- expect(newValue).toMatchSnapshot()
- expect(newPlainTextValue).toMatchSnapshot()
- })
+ expect(newValue).toMatchSnapshot();
+ expect(newPlainTextValue).toMatchSnapshot();
+ });
it('should default to the standard pasted text.', () => {
- const onChange = jest.fn()
+ const onChange = jest.fn();
- component.setProps({ onChange })
+ component.setProps({ onChange });
- const textarea = component.find('textarea')
+ const textarea = component.find('textarea');
- const pastedText = 'Not forget about @[Third](third)!'
+ const pastedText = 'Not forget about @[Third](third)!';
- const event = new Event('paste', { bubbles: true })
+ const event = new Event('paste', { bubbles: true });
event.clipboardData = {
getData: jest.fn((type) => (type === 'text/plain' ? pastedText : '')),
- }
+ };
- expect(onChange).not.toHaveBeenCalled()
+ expect(onChange).not.toHaveBeenCalled();
- textarea.getDOMNode().dispatchEvent(event)
+ textarea.getDOMNode().dispatchEvent(event);
- expect(onChange).toHaveBeenCalledTimes(1)
+ expect(onChange).toHaveBeenCalledTimes(1);
- const [[, newValue, newPlainTextValue]] = onChange.mock.calls
+ const [[, newValue, newPlainTextValue]] = onChange.mock.calls;
- expect(newValue).toMatchSnapshot()
- expect(newPlainTextValue).toMatchSnapshot()
- })
+ expect(newValue).toMatchSnapshot();
+ expect(newPlainTextValue).toMatchSnapshot();
+ });
it('should remove carriage returns from pasted values', () => {
- const pastedText =
- "Hi First, \r\n\r\nlet's add Second to the conversation."
+ const pastedText = "Hi First, \r\n\r\nlet's add Second to the conversation.";
- const event = new Event('paste', { bubbles: true })
+ const event = new Event('paste', { bubbles: true });
event.clipboardData = {
getData: jest.fn((type) => (type === 'text/plain' ? pastedText : '')),
- }
+ };
- const onChange = jest.fn()
+ const onChange = jest.fn();
- component.setProps({ onChange, value: '' })
+ component.setProps({ onChange, value: '' });
- expect(onChange).not.toHaveBeenCalled()
+ expect(onChange).not.toHaveBeenCalled();
- const textarea = component.find('textarea')
+ const textarea = component.find('textarea');
- textarea.getDOMNode().dispatchEvent(event)
+ textarea.getDOMNode().dispatchEvent(event);
- const [[, newValue, newPlainTextValue]] = onChange.mock.calls
+ const [[, newValue, newPlainTextValue]] = onChange.mock.calls;
- expect(newValue).toEqual(
- "Hi First, \n\nlet's add Second to the conversation."
- )
+ expect(newValue).toEqual("Hi First, \n\nlet's add Second to the conversation.");
- expect(newPlainTextValue).toEqual(
- "Hi First, \n\nlet's add Second to the conversation."
- )
- })
+ expect(newPlainTextValue).toEqual("Hi First, \n\nlet's add Second to the conversation.");
+ });
it('should fallback to the browsers behaviour if the "paste" event does not support clipboardData', () => {
// IE 11 has no clipboardData attached to the event and only supports mime type "text"
// therefore, the new mechanism should ignore those events and let the browser handle them
- const textarea = component.find('textarea')
+ const textarea = component.find('textarea');
- const selectionStart = plainTextValue.indexOf('First') + 2
- const selectionEnd = plainTextValue.length
+ const selectionStart = plainTextValue.indexOf('First') + 2;
+ const selectionEnd = plainTextValue.length;
textarea.simulate('select', {
target: { selectionStart, selectionEnd },
- })
- textarea.getDOMNode().setSelectionRange(selectionStart, selectionEnd)
+ });
+ textarea.getDOMNode().setSelectionRange(selectionStart, selectionEnd);
- const preventDefault = jest.fn()
- const event = new Event('paste', { bubbles: true })
- event.preventDefault = preventDefault
+ const preventDefault = jest.fn();
+ const event = new Event('paste', { bubbles: true });
+ event.preventDefault = preventDefault;
- textarea.getDOMNode().dispatchEvent(event)
+ textarea.getDOMNode().dispatchEvent(event);
- expect(preventDefault).not.toHaveBeenCalled()
- })
- })
-})
+ expect(preventDefault).not.toHaveBeenCalled();
+ });
+ });
+});
diff --git a/apps/crew/packages/react-mentions/src/Suggestion.js b/apps/crew/packages/react-mentions/src/Suggestion.js
index 81274a17c..a57091faf 100644
--- a/apps/crew/packages/react-mentions/src/Suggestion.js
+++ b/apps/crew/packages/react-mentions/src/Suggestion.js
@@ -1,7 +1,7 @@
-import React from 'react'
-import PropTypes from 'prop-types'
-import { defaultStyle } from './utils'
-import { getSubstringIndex } from './utils'
+import React from 'react';
+import PropTypes from 'prop-types';
+import { defaultStyle } from './utils';
+import { getSubstringIndex } from './utils';
function Suggestion({
id,
@@ -17,44 +17,38 @@ function Suggestion({
className,
classNames,
}) {
- const rest = { onClick, onMouseEnter }
+ const rest = { onClick, onMouseEnter };
const renderContent = () => {
- let display = getDisplay()
- let highlightedDisplay = renderHighlightedDisplay(display, query)
+ let display = getDisplay();
+ let highlightedDisplay = renderHighlightedDisplay(display, query);
if (renderSuggestion) {
- return renderSuggestion(
- suggestion,
- query,
- highlightedDisplay,
- index,
- focused
- )
+ return renderSuggestion(suggestion, query, highlightedDisplay, index, focused);
}
- return highlightedDisplay
- }
+ return highlightedDisplay;
+ };
const getDisplay = () => {
if (typeof suggestion === 'string') {
- return suggestion
+ return suggestion;
}
- let { id, display } = suggestion
+ let { id, display } = suggestion;
if (id === undefined || !display) {
- return id
+ return id;
}
- return display
- }
+ return display;
+ };
const renderHighlightedDisplay = (display) => {
- let i = getSubstringIndex(display, query, ignoreAccents)
+ let i = getSubstringIndex(display, query, ignoreAccents);
if (i === -1) {
- return {display}
+ return {display};
}
return (
@@ -63,14 +57,14 @@ function Suggestion({
{display.substring(i, i + query.length)}
{display.substring(i + query.length)}
- )
- }
+ );
+ };
return (
-
+
{renderContent()}
- )
+ );
}
Suggestion.propTypes = {
@@ -89,13 +83,13 @@ Suggestion.propTypes = {
renderSuggestion: PropTypes.func,
focused: PropTypes.bool,
-}
+};
const styled = defaultStyle(
{
cursor: 'pointer',
},
- (props) => ({ '&focused': props.focused })
-)
+ (props) => ({ '&focused': props.focused }),
+);
-export default styled(Suggestion)
+export default styled(Suggestion);
diff --git a/apps/crew/packages/react-mentions/src/Suggestion.spec.js b/apps/crew/packages/react-mentions/src/Suggestion.spec.js
index 905fdcf8e..06d82490b 100644
--- a/apps/crew/packages/react-mentions/src/Suggestion.spec.js
+++ b/apps/crew/packages/react-mentions/src/Suggestion.spec.js
@@ -1,7 +1,5 @@
describe('Suggestion', () => {
- it.todo('should be possible to pass a focussed style.')
- it.todo('should render the current display of the suggestion.')
- it.todo(
- 'should highlight the part of the display that is matched by the current query.'
- )
-})
+ it.todo('should be possible to pass a focussed style.');
+ it.todo('should render the current display of the suggestion.');
+ it.todo('should highlight the part of the display that is matched by the current query.');
+});
diff --git a/apps/crew/packages/react-mentions/src/SuggestionsOverlay.js b/apps/crew/packages/react-mentions/src/SuggestionsOverlay.js
index 687e709dc..afe153d6f 100644
--- a/apps/crew/packages/react-mentions/src/SuggestionsOverlay.js
+++ b/apps/crew/packages/react-mentions/src/SuggestionsOverlay.js
@@ -1,11 +1,11 @@
-import React, { Children, useState, useEffect } from 'react'
-import PropTypes from 'prop-types'
-import { inline } from 'substyle'
-import { defaultStyle } from './utils'
+import React, { Children, useState, useEffect } from 'react';
+import PropTypes from 'prop-types';
+import { inline } from 'substyle';
+import { defaultStyle } from './utils';
-import { getSuggestionHtmlId } from './utils'
-import Suggestion from './Suggestion'
-import LoadingIndicator from './LoadingIndicator'
+import { getSuggestionHtmlId } from './utils';
+import Suggestion from './Suggestion';
+import LoadingIndicator from './LoadingIndicator';
function SuggestionsOverlay({
id,
@@ -28,61 +28,48 @@ function SuggestionsOverlay({
onMouseDown,
onMouseEnter,
}) {
- const [ulElement, setUlElement] = useState(undefined)
+ const [ulElement, setUlElement] = useState(undefined);
useEffect(() => {
- if (
- !ulElement ||
- ulElement.offsetHeight >= ulElement.scrollHeight ||
- !scrollFocusedIntoView
- ) {
- return
+ if (!ulElement || ulElement.offsetHeight >= ulElement.scrollHeight || !scrollFocusedIntoView) {
+ return;
}
- const scrollTop = ulElement.scrollTop
+ const scrollTop = ulElement.scrollTop;
- let { top, bottom } = ulElement.children[focusIndex].getBoundingClientRect()
- const { top: topContainer } = ulElement.getBoundingClientRect()
- top = top - topContainer + scrollTop
- bottom = bottom - topContainer + scrollTop
+ let { top, bottom } = ulElement.children[focusIndex].getBoundingClientRect();
+ const { top: topContainer } = ulElement.getBoundingClientRect();
+ top = top - topContainer + scrollTop;
+ bottom = bottom - topContainer + scrollTop;
if (top < scrollTop) {
- ulElement.scrollTop = top
+ ulElement.scrollTop = top;
} else if (bottom > ulElement.offsetHeight) {
- ulElement.scrollTop = bottom - ulElement.offsetHeight
+ ulElement.scrollTop = bottom - ulElement.offsetHeight;
}
- }, [focusIndex, scrollFocusedIntoView, ulElement])
+ }, [focusIndex, scrollFocusedIntoView, ulElement]);
const renderSuggestions = () => {
const suggestionsToRender = (
-
+
{Object.values(suggestions).reduce(
(accResults, { results, queryInfo }) => [
...accResults,
- ...results.map((result, index) =>
- renderSuggestion(result, queryInfo, accResults.length + index)
- ),
+ ...results.map((result, index) => renderSuggestion(result, queryInfo, accResults.length + index)),
],
- []
+ [],
)}
- )
+ );
- if (customSuggestionsContainer)
- return customSuggestionsContainer(suggestionsToRender)
- return suggestionsToRender
- }
+ if (customSuggestionsContainer) return customSuggestionsContainer(suggestionsToRender);
+ return suggestionsToRender;
+ };
//여기서 엔터를 눌렀을 때 해당 값 설정되도록 만들수는 없을까?
const renderSuggestion = (result, queryInfo, index) => {
- const isFocused = index === focusIndex
- const { childIndex, query } = queryInfo
- const { renderSuggestion } = Children.toArray(children)[childIndex].props
+ const isFocused = index === focusIndex;
+ const { childIndex, query } = queryInfo;
+ const { renderSuggestion } = Children.toArray(children)[childIndex].props;
return (
select(result, queryInfo)}
onMouseEnter={() => handleMouseEnter(index)}
/>
- )
- }
+ );
+ };
const renderLoadingIndicator = () => {
if (!isLoading) {
- return
+ return;
}
- return
- }
+ return ;
+ };
const handleMouseEnter = (index, ev) => {
if (onMouseEnter) {
- onMouseEnter(index)
+ onMouseEnter(index);
}
- }
+ };
const select = (suggestion, queryInfo) => {
- onSelect(suggestion, queryInfo)
- }
+ onSelect(suggestion, queryInfo);
+ };
const getID = (suggestion) => {
if (typeof suggestion === 'string') {
- return suggestion
+ return suggestion;
}
- return suggestion.id
- }
+ return suggestion.id;
+ };
if (!isOpened) {
- return null
+ return null;
}
return (
@@ -139,7 +126,7 @@ function SuggestionsOverlay({
{renderSuggestions()}
{renderLoadingIndicator()}
- )
+ );
}
SuggestionsOverlay.propTypes = {
@@ -160,13 +147,10 @@ SuggestionsOverlay.propTypes = {
containerRef: PropTypes.oneOfType([
PropTypes.func,
PropTypes.shape({
- current:
- typeof Element === 'undefined'
- ? PropTypes.any
- : PropTypes.instanceOf(Element),
+ current: typeof Element === 'undefined' ? PropTypes.any : PropTypes.instanceOf(Element),
}),
]),
-}
+};
const styled = defaultStyle({
zIndex: 1,
@@ -179,6 +163,6 @@ const styled = defaultStyle({
padding: 0,
listStyleType: 'none',
},
-})
+});
-export default styled(SuggestionsOverlay)
+export default styled(SuggestionsOverlay);
diff --git a/apps/crew/packages/react-mentions/src/SuggestionsOverlay.spec.js b/apps/crew/packages/react-mentions/src/SuggestionsOverlay.spec.js
index 653866a67..c340fbcc7 100644
--- a/apps/crew/packages/react-mentions/src/SuggestionsOverlay.spec.js
+++ b/apps/crew/packages/react-mentions/src/SuggestionsOverlay.spec.js
@@ -1,9 +1,9 @@
describe('SuggestionsOverlay', () => {
- it.todo('should render a list of all passed suggestions.')
- it.todo('should be possible to style the list.')
- it.todo('should be possible to apply styles to the items in the list.')
- it.todo('should notify when the user clicks on a suggestion.')
- it.todo('should be possible to show a loading indicator.')
- it.todo('should be possible to style the loading indicator.')
- it.todo('should notify when the user enters a suggestion with his mouse.')
-})
+ it.todo('should render a list of all passed suggestions.');
+ it.todo('should be possible to style the list.');
+ it.todo('should be possible to apply styles to the items in the list.');
+ it.todo('should notify when the user clicks on a suggestion.');
+ it.todo('should be possible to show a loading indicator.');
+ it.todo('should be possible to style the loading indicator.');
+ it.todo('should notify when the user enters a suggestion with his mouse.');
+});
diff --git a/apps/crew/packages/react-mentions/src/index.js b/apps/crew/packages/react-mentions/src/index.js
index 4ce560f1b..c6d2e3e75 100644
--- a/apps/crew/packages/react-mentions/src/index.js
+++ b/apps/crew/packages/react-mentions/src/index.js
@@ -1,2 +1,2 @@
-export { default as MentionsInput } from './MentionsInput'
-export { default as Mention } from './Mention'
+export { default as MentionsInput } from './MentionsInput';
+export { default as Mention } from './Mention';
diff --git a/apps/crew/packages/react-mentions/src/utils/applyChangeToValue.js b/apps/crew/packages/react-mentions/src/utils/applyChangeToValue.js
index 670283e35..93ed072b0 100644
--- a/apps/crew/packages/react-mentions/src/utils/applyChangeToValue.js
+++ b/apps/crew/packages/react-mentions/src/utils/applyChangeToValue.js
@@ -1,6 +1,6 @@
-import mapPlainTextIndex from './mapPlainTextIndex'
-import getPlainText from './getPlainText'
-import spliceString from './spliceString'
+import mapPlainTextIndex from './mapPlainTextIndex';
+import getPlainText from './getPlainText';
+import spliceString from './spliceString';
// Applies a change from the plain text textarea to the underlying marked up value
// guided by the textarea text selection ranges before and after the change
@@ -8,17 +8,17 @@ const applyChangeToValue = (
value,
plainTextValue,
{ selectionStartBefore, selectionEndBefore, selectionEndAfter },
- config
+ config,
) => {
- let oldPlainTextValue = getPlainText(value, config)
+ let oldPlainTextValue = getPlainText(value, config);
- let lengthDelta = oldPlainTextValue.length - plainTextValue.length
+ let lengthDelta = oldPlainTextValue.length - plainTextValue.length;
if (selectionStartBefore === 'undefined') {
- selectionStartBefore = selectionEndAfter + lengthDelta
+ selectionStartBefore = selectionEndAfter + lengthDelta;
}
if (selectionEndBefore === 'undefined') {
- selectionEndBefore = selectionStartBefore
+ selectionEndBefore = selectionStartBefore;
}
// Fixes an issue with replacing combined characters for complex input. Eg like acented letters on OSX
@@ -27,58 +27,54 @@ const applyChangeToValue = (
selectionEndBefore === selectionEndAfter &&
oldPlainTextValue.length === plainTextValue.length
) {
- selectionStartBefore = selectionStartBefore - 1
+ selectionStartBefore = selectionStartBefore - 1;
}
// extract the insertion from the new plain text value
- let insert = plainTextValue.slice(selectionStartBefore, selectionEndAfter)
+ let insert = plainTextValue.slice(selectionStartBefore, selectionEndAfter);
// handling for Backspace key with no range selection
- let spliceStart = Math.min(selectionStartBefore, selectionEndAfter)
+ let spliceStart = Math.min(selectionStartBefore, selectionEndAfter);
- let spliceEnd = selectionEndBefore
+ let spliceEnd = selectionEndBefore;
if (selectionStartBefore === selectionEndAfter) {
// handling for Delete key with no range selection
- spliceEnd = Math.max(selectionEndBefore, selectionStartBefore + lengthDelta)
+ spliceEnd = Math.max(selectionEndBefore, selectionStartBefore + lengthDelta);
}
- let mappedSpliceStart = mapPlainTextIndex(value, config, spliceStart, 'START')
- let mappedSpliceEnd = mapPlainTextIndex(value, config, spliceEnd, 'END')
+ let mappedSpliceStart = mapPlainTextIndex(value, config, spliceStart, 'START');
+ let mappedSpliceEnd = mapPlainTextIndex(value, config, spliceEnd, 'END');
- let controlSpliceStart = mapPlainTextIndex(value, config, spliceStart, 'NULL')
- let controlSpliceEnd = mapPlainTextIndex(value, config, spliceEnd, 'NULL')
- let willRemoveMention =
- controlSpliceStart === null || controlSpliceEnd === null
+ let controlSpliceStart = mapPlainTextIndex(value, config, spliceStart, 'NULL');
+ let controlSpliceEnd = mapPlainTextIndex(value, config, spliceEnd, 'NULL');
+ let willRemoveMention = controlSpliceStart === null || controlSpliceEnd === null;
- let newValue = spliceString(value, mappedSpliceStart, mappedSpliceEnd, insert)
+ let newValue = spliceString(value, mappedSpliceStart, mappedSpliceEnd, insert);
if (!willRemoveMention) {
// test for auto-completion changes
- let controlPlainTextValue = getPlainText(newValue, config)
+ let controlPlainTextValue = getPlainText(newValue, config);
if (controlPlainTextValue !== plainTextValue) {
// some auto-correction is going on
// find start of diff
- spliceStart = 0
- while (plainTextValue[spliceStart] === controlPlainTextValue[spliceStart])
- spliceStart++
+ spliceStart = 0;
+ while (plainTextValue[spliceStart] === controlPlainTextValue[spliceStart]) spliceStart++;
// extract auto-corrected insertion
- insert = plainTextValue.slice(spliceStart, selectionEndAfter)
+ insert = plainTextValue.slice(spliceStart, selectionEndAfter);
// find index of the unchanged remainder
- spliceEnd = oldPlainTextValue.lastIndexOf(
- plainTextValue.substring(selectionEndAfter)
- )
+ spliceEnd = oldPlainTextValue.lastIndexOf(plainTextValue.substring(selectionEndAfter));
// re-map the corrected indices
- mappedSpliceStart = mapPlainTextIndex(value, config, spliceStart, 'START')
- mappedSpliceEnd = mapPlainTextIndex(value, config, spliceEnd, 'END')
- newValue = spliceString(value, mappedSpliceStart, mappedSpliceEnd, insert)
+ mappedSpliceStart = mapPlainTextIndex(value, config, spliceStart, 'START');
+ mappedSpliceEnd = mapPlainTextIndex(value, config, spliceEnd, 'END');
+ newValue = spliceString(value, mappedSpliceStart, mappedSpliceEnd, insert);
}
}
- return newValue
-}
+ return newValue;
+};
-export default applyChangeToValue
+export default applyChangeToValue;
diff --git a/apps/crew/packages/react-mentions/src/utils/applyChangeToValue.spec.js b/apps/crew/packages/react-mentions/src/utils/applyChangeToValue.spec.js
index 06f6850e5..c6f527b0b 100644
--- a/apps/crew/packages/react-mentions/src/utils/applyChangeToValue.spec.js
+++ b/apps/crew/packages/react-mentions/src/utils/applyChangeToValue.spec.js
@@ -1,10 +1,10 @@
-import applyChangeToValue from './applyChangeToValue'
-import markupToRegex from './markupToRegex'
+import applyChangeToValue from './applyChangeToValue';
+import markupToRegex from './markupToRegex';
describe('#applyChangeToValue', () => {
- const userMarkup = '@[__display__](user:__id__)'
- const emailMarkup = '@[__display__](email:__id__)'
- const defaultDisplayTransform = (id, display) => display
+ const userMarkup = '@[__display__](user:__id__)';
+ const emailMarkup = '@[__display__](email:__id__)';
+ const defaultDisplayTransform = (id, display) => display;
const config = [
{
markup: userMarkup,
@@ -16,19 +16,17 @@ describe('#applyChangeToValue', () => {
regex: markupToRegex(emailMarkup),
displayTransform: defaultDisplayTransform,
},
- ]
+ ];
const value =
- "Hi @[John Doe](user:johndoe), \n\nlet's add @[joe@smoe.com](email:joe@smoe.com) to this conversation..."
- const plainText =
- "Hi John Doe, \n\nlet's add joe@smoe.com to this conversation..."
+ "Hi @[John Doe](user:johndoe), \n\nlet's add @[joe@smoe.com](email:joe@smoe.com) to this conversation...";
+ const plainText = "Hi John Doe, \n\nlet's add joe@smoe.com to this conversation...";
- const displayTransform = id => `<--${id}-->`
- const plainTextDisplayTransform =
- "Hi <--johndoe-->, \n\nlet's add <--joe@smoe.com--> to this conversation..."
+ const displayTransform = (id) => `<--${id}-->`;
+ const plainTextDisplayTransform = "Hi <--johndoe-->, \n\nlet's add <--joe@smoe.com--> to this conversation...";
it('should correctly add a character at the end, beginning, and in the middle of text', () => {
- let changed = 'S' + plainText
+ let changed = 'S' + plainText;
let result = applyChangeToValue(
value,
changed,
@@ -37,11 +35,11 @@ describe('#applyChangeToValue', () => {
selectionEndBefore: 0,
selectionEndAfter: 1,
},
- config
- )
- expect(result).toEqual('S' + value)
+ config,
+ );
+ expect(result).toEqual('S' + value);
- changed = plainText + 'E'
+ changed = plainText + 'E';
result = applyChangeToValue(
value,
changed,
@@ -50,11 +48,11 @@ describe('#applyChangeToValue', () => {
selectionEndBefore: plainText.length,
selectionEndAfter: changed.length,
},
- config
- )
- expect(result).toEqual(value + 'E')
+ config,
+ );
+ expect(result).toEqual(value + 'E');
- changed = "Hi John Doe, \n\nlet's Madd joe@smoe.com to this conversation..."
+ changed = "Hi John Doe, \n\nlet's Madd joe@smoe.com to this conversation...";
result = applyChangeToValue(
value,
changed,
@@ -63,17 +61,16 @@ describe('#applyChangeToValue', () => {
selectionEndBefore: 21,
selectionEndAfter: 22,
},
- config
- )
+ config,
+ );
expect(result).toEqual(
- "Hi @[John Doe](user:johndoe), \n\nlet's Madd @[joe@smoe.com](email:joe@smoe.com) to this conversation..."
- )
- })
+ "Hi @[John Doe](user:johndoe), \n\nlet's Madd @[joe@smoe.com](email:joe@smoe.com) to this conversation...",
+ );
+ });
it('should correctly delete single characters and ranges of selected text', () => {
// delete "i"
- let changed =
- "H John Doe, \n\nlet's add joe@smoe.com to this conversation..."
+ let changed = "H John Doe, \n\nlet's add joe@smoe.com to this conversation...";
let result = applyChangeToValue(
value,
changed,
@@ -82,14 +79,14 @@ describe('#applyChangeToValue', () => {
selectionEndBefore: 2,
selectionEndAfter: 1,
},
- config
- )
+ config,
+ );
expect(result).toEqual(
- "H @[John Doe](user:johndoe), \n\nlet's add @[joe@smoe.com](email:joe@smoe.com) to this conversation..."
- )
+ "H @[John Doe](user:johndoe), \n\nlet's add @[joe@smoe.com](email:joe@smoe.com) to this conversation...",
+ );
// delete "add "
- changed = "Hi John Doe, \n\nlet's joe@smoe.com to this conversation..."
+ changed = "Hi John Doe, \n\nlet's joe@smoe.com to this conversation...";
result = applyChangeToValue(
value,
changed,
@@ -98,16 +95,16 @@ describe('#applyChangeToValue', () => {
selectionEndBefore: plainText.indexOf('add ') + 'add '.length,
selectionEndAfter: plainText.indexOf('add '),
},
- config
- )
+ config,
+ );
expect(result).toEqual(
- "Hi @[John Doe](user:johndoe), \n\nlet's @[joe@smoe.com](email:joe@smoe.com) to this conversation..."
- )
- })
+ "Hi @[John Doe](user:johndoe), \n\nlet's @[joe@smoe.com](email:joe@smoe.com) to this conversation...",
+ );
+ });
it('should correctly add ranges of pasted text and replace the selected range with the new range', () => {
// add range
- let changed = plainText.replace('add', 'add add')
+ let changed = plainText.replace('add', 'add add');
let result = applyChangeToValue(
value,
changed,
@@ -116,12 +113,12 @@ describe('#applyChangeToValue', () => {
selectionEndBefore: plainText.indexOf('add') + 'add'.length,
selectionEndAfter: plainText.indexOf('add') + 'add add'.length,
},
- config
- )
- expect(result).toEqual(value.replace('add', 'add add'))
+ config,
+ );
+ expect(result).toEqual(value.replace('add', 'add add'));
// replace range
- changed = plainText.replace('add', 'remove')
+ changed = plainText.replace('add', 'remove');
result = applyChangeToValue(
value,
changed,
@@ -130,15 +127,14 @@ describe('#applyChangeToValue', () => {
selectionEndBefore: plainText.indexOf('add') + 'add'.length,
selectionEndAfter: plainText.indexOf('add') + 'remove'.length,
},
- config
- )
- expect(result).toEqual(value.replace('add', 'remove'))
- })
+ config,
+ );
+ expect(result).toEqual(value.replace('add', 'remove'));
+ });
it('should remove mentions markup contained in deleted text ranges', () => {
// delete without a range selection
- let changed =
- "Hi John Do, \n\nlet's add joe@smoe.com to this conversation..."
+ let changed = "Hi John Do, \n\nlet's add joe@smoe.com to this conversation...";
let result = applyChangeToValue(
value,
changed,
@@ -147,14 +143,12 @@ describe('#applyChangeToValue', () => {
selectionEndBefore: 11,
selectionEndAfter: 10,
},
- config
- )
- expect(result).toEqual(
- "Hi , \n\nlet's add @[joe@smoe.com](email:joe@smoe.com) to this conversation..."
- )
+ config,
+ );
+ expect(result).toEqual("Hi , \n\nlet's add @[joe@smoe.com](email:joe@smoe.com) to this conversation...");
// delete mention inside the range
- changed = "Hi let's add joe@smoe.com to this conversation..."
+ changed = "Hi let's add joe@smoe.com to this conversation...";
result = applyChangeToValue(
value,
changed,
@@ -163,14 +157,12 @@ describe('#applyChangeToValue', () => {
selectionEndBefore: 15,
selectionEndAfter: 3,
},
- config
- )
- expect(result).toEqual(
- "Hi let's add @[joe@smoe.com](email:joe@smoe.com) to this conversation..."
- )
+ config,
+ );
+ expect(result).toEqual("Hi let's add @[joe@smoe.com](email:joe@smoe.com) to this conversation...");
// delete mention partially inside the range
- changed = "Hi John Doe, \n\nlet's add joe@smoe.com to this conversation..."
+ changed = "Hi John Doe, \n\nlet's add joe@smoe.com to this conversation...";
result = applyChangeToValue(
value,
changed,
@@ -179,16 +171,14 @@ describe('#applyChangeToValue', () => {
selectionEndBefore: plainText.indexOf(' add') + ' add joe@'.length,
selectionEndAfter: plainText.indexOf(' add'),
},
- config
- )
- expect(result).toEqual(
- "Hi @[John Doe](user:johndoe), \n\nlet's to this conversation..."
- )
- })
+ config,
+ );
+ expect(result).toEqual("Hi @[John Doe](user:johndoe), \n\nlet's to this conversation...");
+ });
it('should correctly add a new character after a mention at the end of the string', () => {
- const value = 'Hi @[John Doe](user:johndoe)'
- const changed = 'Hi John Doe,'
+ const value = 'Hi @[John Doe](user:johndoe)';
+ const changed = 'Hi John Doe,';
const result = applyChangeToValue(
value,
@@ -198,13 +188,13 @@ describe('#applyChangeToValue', () => {
selectionEndBefore: 11,
selectionEndAfter: 12,
},
- config
- )
- expect(result).toEqual('Hi @[John Doe](user:johndoe),')
- })
+ config,
+ );
+ expect(result).toEqual('Hi @[John Doe](user:johndoe),');
+ });
it('should support deletion of whole words (Alt + Backspace) and whole lines (Cmd + Backspace)', () => {
- const changed = plainText.replace('add', '')
+ const changed = plainText.replace('add', '');
const result = applyChangeToValue(
value,
@@ -214,15 +204,15 @@ describe('#applyChangeToValue', () => {
selectionEndBefore: 24,
selectionEndAfter: 21,
},
- config
- )
+ config,
+ );
expect(result).toEqual(
- "Hi @[John Doe](user:johndoe), \n\nlet's @[joe@smoe.com](email:joe@smoe.com) to this conversation..."
- )
- })
+ "Hi @[John Doe](user:johndoe), \n\nlet's @[joe@smoe.com](email:joe@smoe.com) to this conversation...",
+ );
+ });
it('should support deletion to the right using Del key', () => {
- const changed = plainText.replace('add', 'dd')
+ const changed = plainText.replace('add', 'dd');
const result = applyChangeToValue(
value,
@@ -232,15 +222,15 @@ describe('#applyChangeToValue', () => {
selectionEndBefore: 21,
selectionEndAfter: 21,
},
- config
- )
+ config,
+ );
expect(result).toEqual(
- "Hi @[John Doe](user:johndoe), \n\nlet's dd @[joe@smoe.com](email:joe@smoe.com) to this conversation..."
- )
- })
+ "Hi @[John Doe](user:johndoe), \n\nlet's dd @[joe@smoe.com](email:joe@smoe.com) to this conversation...",
+ );
+ });
it('should support deletion to the right using Del key when using the displayTransform option', () => {
- const changed = plainTextDisplayTransform.replace('add', 'dd')
+ const changed = plainTextDisplayTransform.replace('add', 'dd');
const result = applyChangeToValue(
value,
changed,
@@ -249,12 +239,12 @@ describe('#applyChangeToValue', () => {
selectionEndBefore: 26,
selectionEndAfter: 26,
},
- config.map(c => ({ ...c, displayTransform }))
- )
+ config.map((c) => ({ ...c, displayTransform })),
+ );
expect(result).toEqual(
- "Hi @[John Doe](user:johndoe), \n\nlet's dd @[joe@smoe.com](email:joe@smoe.com) to this conversation..."
- )
- })
+ "Hi @[John Doe](user:johndoe), \n\nlet's dd @[joe@smoe.com](email:joe@smoe.com) to this conversation...",
+ );
+ });
it('should correctly handle text auto-correction', () => {
const result = applyChangeToValue(
@@ -265,8 +255,8 @@ describe('#applyChangeToValue', () => {
selectionEndBefore: 3,
selectionEndAfter: 4,
},
- config
- )
- expect(result).toEqual("I'll")
- })
-})
+ config,
+ );
+ expect(result).toEqual("I'll");
+ });
+});
diff --git a/apps/crew/packages/react-mentions/src/utils/combineRegExps.js b/apps/crew/packages/react-mentions/src/utils/combineRegExps.js
index 687b0e589..5c4bc2486 100644
--- a/apps/crew/packages/react-mentions/src/utils/combineRegExps.js
+++ b/apps/crew/packages/react-mentions/src/utils/combineRegExps.js
@@ -1,24 +1,22 @@
-import invariant from 'invariant'
+import invariant from 'invariant';
-const combineRegExps = regExps => {
- const serializedRegexParser = /^\/(.+)\/(\w+)?$/
+const combineRegExps = (regExps) => {
+ const serializedRegexParser = /^\/(.+)\/(\w+)?$/;
return new RegExp(
regExps
- .map(regex => {
- const [, regexString, regexFlags] = serializedRegexParser.exec(
- regex.toString()
- )
+ .map((regex) => {
+ const [, regexString, regexFlags] = serializedRegexParser.exec(regex.toString());
invariant(
!regexFlags,
- `RegExp flags are not supported. Change /${regexString}/${regexFlags} into /${regexString}/`
- )
+ `RegExp flags are not supported. Change /${regexString}/${regexFlags} into /${regexString}/`,
+ );
- return `(${regexString})`
+ return `(${regexString})`;
})
.join('|'),
- 'g'
- )
-}
+ 'g',
+ );
+};
-export default combineRegExps
+export default combineRegExps;
diff --git a/apps/crew/packages/react-mentions/src/utils/combineRegExps.spec.js b/apps/crew/packages/react-mentions/src/utils/combineRegExps.spec.js
index 13ee0348c..5def4d336 100644
--- a/apps/crew/packages/react-mentions/src/utils/combineRegExps.spec.js
+++ b/apps/crew/packages/react-mentions/src/utils/combineRegExps.spec.js
@@ -1,8 +1,8 @@
-import combineRegExps from './combineRegExps'
+import combineRegExps from './combineRegExps';
describe('combineRegExps', () => {
it('should concatenate all regexps using | and wrap each one in a capturing group', () => {
- const result = combineRegExps([/a/, /b/])
- expect(result.toString()).toEqual('/(a)|(b)/g')
- })
-})
+ const result = combineRegExps([/a/, /b/]);
+ expect(result.toString()).toEqual('/(a)|(b)/g');
+ });
+});
diff --git a/apps/crew/packages/react-mentions/src/utils/countPlaceholders.js b/apps/crew/packages/react-mentions/src/utils/countPlaceholders.js
index b6054a020..d9d924c53 100644
--- a/apps/crew/packages/react-mentions/src/utils/countPlaceholders.js
+++ b/apps/crew/packages/react-mentions/src/utils/countPlaceholders.js
@@ -1,8 +1,8 @@
-const countPlaceholders = markup => {
- let count = 0
- if (markup.indexOf('__id__') >= 0) count++
- if (markup.indexOf('__display__') >= 0) count++
- return count
-}
+const countPlaceholders = (markup) => {
+ let count = 0;
+ if (markup.indexOf('__id__') >= 0) count++;
+ if (markup.indexOf('__display__') >= 0) count++;
+ return count;
+};
-export default countPlaceholders
+export default countPlaceholders;
diff --git a/apps/crew/packages/react-mentions/src/utils/countSuggestions.js b/apps/crew/packages/react-mentions/src/utils/countSuggestions.js
index c7ee9f198..6c88bb7e8 100644
--- a/apps/crew/packages/react-mentions/src/utils/countSuggestions.js
+++ b/apps/crew/packages/react-mentions/src/utils/countSuggestions.js
@@ -1,7 +1,4 @@
-const countSuggestions = suggestions =>
- Object.values(suggestions).reduce(
- (acc, { results }) => acc + results.length,
- 0
- )
+const countSuggestions = (suggestions) =>
+ Object.values(suggestions).reduce((acc, { results }) => acc + results.length, 0);
-export default countSuggestions
+export default countSuggestions;
diff --git a/apps/crew/packages/react-mentions/src/utils/defaultStyle.js b/apps/crew/packages/react-mentions/src/utils/defaultStyle.js
index ad3e4d02f..8a9b09f28 100644
--- a/apps/crew/packages/react-mentions/src/utils/defaultStyle.js
+++ b/apps/crew/packages/react-mentions/src/utils/defaultStyle.js
@@ -1,34 +1,24 @@
-import React from 'react'
-import useStyles from 'substyle'
+import React from 'react';
+import useStyles from 'substyle';
function createDefaultStyle(defaultStyle, getModifiers) {
const enhance = (ComponentToWrap) => {
- const DefaultStyleEnhancer = ({
- style,
- className,
- classNames,
- ...rest
- }) => {
- const modifiers = getModifiers ? getModifiers(rest) : undefined
- const styles = useStyles(
- defaultStyle,
- { style, className, classNames },
- modifiers
- )
+ const DefaultStyleEnhancer = ({ style, className, classNames, ...rest }) => {
+ const modifiers = getModifiers ? getModifiers(rest) : undefined;
+ const styles = useStyles(defaultStyle, { style, className, classNames }, modifiers);
- return
- }
- const displayName =
- ComponentToWrap.displayName || ComponentToWrap.name || 'Component'
- DefaultStyleEnhancer.displayName = `defaultStyle(${displayName})`
+ return ;
+ };
+ const displayName = ComponentToWrap.displayName || ComponentToWrap.name || 'Component';
+ DefaultStyleEnhancer.displayName = `defaultStyle(${displayName})`;
// return DefaultStyleEnhancer
return React.forwardRef((props, ref) => {
- return DefaultStyleEnhancer({ ...props, ref })
- })
- }
+ return DefaultStyleEnhancer({ ...props, ref });
+ });
+ };
- return enhance
+ return enhance;
}
-export default createDefaultStyle
+export default createDefaultStyle;
diff --git a/apps/crew/packages/react-mentions/src/utils/diacritics.js b/apps/crew/packages/react-mentions/src/utils/diacritics.js
index f454b629d..5abdab4c1 100644
--- a/apps/crew/packages/react-mentions/src/utils/diacritics.js
+++ b/apps/crew/packages/react-mentions/src/utils/diacritics.js
@@ -3,7 +3,8 @@
const lettersDiacritics = [
{
base: 'A',
- letters: /(A|Ⓐ|A|À|Á|Â|Ầ|Ấ|Ẫ|Ẩ|Ã|Ā|Ă|Ằ|Ắ|Ẵ|Ẳ|Ȧ|Ǡ|Ä|Ǟ|Ả|Å|Ǻ|Ǎ|Ȁ|Ȃ|Ạ|Ậ|Ặ|Ḁ|Ą|Ⱥ|Ɐ|[\u0041\u24B6\uFF21\u00C0\u00C1\u00C2\u1EA6\u1EA4\u1EAA\u1EA8\u00C3\u0100\u0102\u1EB0\u1EAE\u1EB4\u1EB2\u0226\u01E0\u00C4\u01DE\u1EA2\u00C5\u01FA\u01CD\u0200\u0202\u1EA0\u1EAC\u1EB6\u1E00\u0104\u023A\u2C6F])/g,
+ letters:
+ /(A|Ⓐ|A|À|Á|Â|Ầ|Ấ|Ẫ|Ẩ|Ã|Ā|Ă|Ằ|Ắ|Ẵ|Ẳ|Ȧ|Ǡ|Ä|Ǟ|Ả|Å|Ǻ|Ǎ|Ȁ|Ȃ|Ạ|Ậ|Ặ|Ḁ|Ą|Ⱥ|Ɐ|[\u0041\u24B6\uFF21\u00C0\u00C1\u00C2\u1EA6\u1EA4\u1EAA\u1EA8\u00C3\u0100\u0102\u1EB0\u1EAE\u1EB4\u1EB2\u0226\u01E0\u00C4\u01DE\u1EA2\u00C5\u01FA\u01CD\u0200\u0202\u1EA0\u1EAC\u1EB6\u1E00\u0104\u023A\u2C6F])/g,
},
{
base: 'AA',
@@ -31,15 +32,18 @@ const lettersDiacritics = [
},
{
base: 'B',
- letters: /(B|Ⓑ|B|Ḃ|Ḅ|Ḇ|Ƀ|Ƃ|Ɓ|[\u0042\u24B7\uFF22\u1E02\u1E04\u1E06\u0243\u0182\u0181])/g,
+ letters:
+ /(B|Ⓑ|B|Ḃ|Ḅ|Ḇ|Ƀ|Ƃ|Ɓ|[\u0042\u24B7\uFF22\u1E02\u1E04\u1E06\u0243\u0182\u0181])/g,
},
{
base: 'C',
- letters: /(C|Ⓒ|C|Ć|Ĉ|Ċ|Č|Ç|Ḉ|Ƈ|Ȼ|Ꜿ|[\u0043\u24B8\uFF23\u0106\u0108\u010A\u010C\u00C7\u1E08\u0187\u023B\uA73E])/g,
+ letters:
+ /(C|Ⓒ|C|Ć|Ĉ|Ċ|Č|Ç|Ḉ|Ƈ|Ȼ|Ꜿ|[\u0043\u24B8\uFF23\u0106\u0108\u010A\u010C\u00C7\u1E08\u0187\u023B\uA73E])/g,
},
{
base: 'D',
- letters: /(D|Ⓓ|D|Ḋ|Ď|Ḍ|Ḑ|Ḓ|Ḏ|Đ|Ƌ|Ɗ|Ɖ|Ꝺ|Ð|[\u0044\u24B9\uFF24\u1E0A\u010E\u1E0C\u1E10\u1E12\u1E0E\u0110\u018B\u018A\u0189\uA779\u00D0])/g,
+ letters:
+ /(D|Ⓓ|D|Ḋ|Ď|Ḍ|Ḑ|Ḓ|Ḏ|Đ|Ƌ|Ɗ|Ɖ|Ꝺ|Ð|[\u0044\u24B9\uFF24\u1E0A\u010E\u1E0C\u1E10\u1E12\u1E0E\u0110\u018B\u018A\u0189\uA779\u00D0])/g,
},
{
base: 'DZ',
@@ -51,7 +55,8 @@ const lettersDiacritics = [
},
{
base: 'E',
- letters: /(E|Ⓔ|E|È|É|Ê|Ề|Ế|Ễ|Ể|Ẽ|Ē|Ḕ|Ḗ|Ĕ|Ė|Ë|Ẻ|Ě|Ȅ|Ȇ|Ẹ|Ệ|Ȩ|Ḝ|Ę|Ḙ|Ḛ|Ɛ|Ǝ|[\u0045\u24BA\uFF25\u00C8\u00C9\u00CA\u1EC0\u1EBE\u1EC4\u1EC2\u1EBC\u0112\u1E14\u1E16\u0114\u0116\u00CB\u1EBA\u011A\u0204\u0206\u1EB8\u1EC6\u0228\u1E1C\u0118\u1E18\u1E1A\u0190\u018E])/g,
+ letters:
+ /(E|Ⓔ|E|È|É|Ê|Ề|Ế|Ễ|Ể|Ẽ|Ē|Ḕ|Ḗ|Ĕ|Ė|Ë|Ẻ|Ě|Ȅ|Ȇ|Ẹ|Ệ|Ȩ|Ḝ|Ę|Ḙ|Ḛ|Ɛ|Ǝ|[\u0045\u24BA\uFF25\u00C8\u00C9\u00CA\u1EC0\u1EBE\u1EC4\u1EC2\u1EBC\u0112\u1E14\u1E16\u0114\u0116\u00CB\u1EBA\u011A\u0204\u0206\u1EB8\u1EC6\u0228\u1E1C\u0118\u1E18\u1E1A\u0190\u018E])/g,
},
{
base: 'F',
@@ -59,15 +64,18 @@ const lettersDiacritics = [
},
{
base: 'G',
- letters: /(G|Ⓖ|G|Ǵ|Ĝ|Ḡ|Ğ|Ġ|Ǧ|Ģ|Ǥ|Ɠ|Ꞡ|Ᵹ|Ꝿ|[\u0047\u24BC\uFF27\u01F4\u011C\u1E20\u011E\u0120\u01E6\u0122\u01E4\u0193\uA7A0\uA77D\uA77E])/g,
+ letters:
+ /(G|Ⓖ|G|Ǵ|Ĝ|Ḡ|Ğ|Ġ|Ǧ|Ģ|Ǥ|Ɠ|Ꞡ|Ᵹ|Ꝿ|[\u0047\u24BC\uFF27\u01F4\u011C\u1E20\u011E\u0120\u01E6\u0122\u01E4\u0193\uA7A0\uA77D\uA77E])/g,
},
{
base: 'H',
- letters: /(H|Ⓗ|H|Ĥ|Ḣ|Ḧ|Ȟ|Ḥ|Ḩ|Ḫ|Ħ|Ⱨ|Ⱶ|Ɥ|[\u0048\u24BD\uFF28\u0124\u1E22\u1E26\u021E\u1E24\u1E28\u1E2A\u0126\u2C67\u2C75\uA78D])/g,
+ letters:
+ /(H|Ⓗ|H|Ĥ|Ḣ|Ḧ|Ȟ|Ḥ|Ḩ|Ḫ|Ħ|Ⱨ|Ⱶ|Ɥ|[\u0048\u24BD\uFF28\u0124\u1E22\u1E26\u021E\u1E24\u1E28\u1E2A\u0126\u2C67\u2C75\uA78D])/g,
},
{
base: 'I',
- letters: /(I|Ⓘ|I|Ì|Í|Î|Ĩ|Ī|Ĭ|İ|Ï|Ḯ|Ỉ|Ǐ|Ȉ|Ȋ|Ị|Į|Ḭ|Ɨ|[\u0049\u24BE\uFF29\u00CC\u00CD\u00CE\u0128\u012A\u012C\u0130\u00CF\u1E2E\u1EC8\u01CF\u0208\u020A\u1ECA\u012E\u1E2C\u0197])/g,
+ letters:
+ /(I|Ⓘ|I|Ì|Í|Î|Ĩ|Ī|Ĭ|İ|Ï|Ḯ|Ỉ|Ǐ|Ȉ|Ȋ|Ị|Į|Ḭ|Ɨ|[\u0049\u24BE\uFF29\u00CC\u00CD\u00CE\u0128\u012A\u012C\u0130\u00CF\u1E2E\u1EC8\u01CF\u0208\u020A\u1ECA\u012E\u1E2C\u0197])/g,
},
{
base: 'J',
@@ -75,11 +83,13 @@ const lettersDiacritics = [
},
{
base: 'K',
- letters: /(K|Ⓚ|K|Ḱ|Ǩ|Ḳ|Ķ|Ḵ|Ƙ|Ⱪ|Ꝁ|Ꝃ|Ꝅ|Ꞣ|[\u004B\u24C0\uFF2B\u1E30\u01E8\u1E32\u0136\u1E34\u0198\u2C69\uA740\uA742\uA744\uA7A2])/g,
+ letters:
+ /(K|Ⓚ|K|Ḱ|Ǩ|Ḳ|Ķ|Ḵ|Ƙ|Ⱪ|Ꝁ|Ꝃ|Ꝅ|Ꞣ|[\u004B\u24C0\uFF2B\u1E30\u01E8\u1E32\u0136\u1E34\u0198\u2C69\uA740\uA742\uA744\uA7A2])/g,
},
{
base: 'L',
- letters: /(L|Ⓛ|L|Ŀ|Ĺ|Ľ|Ḷ|Ḹ|Ļ|Ḽ|Ḻ|Ł|Ƚ|Ɫ|Ⱡ|Ꝉ|Ꝇ|Ꞁ|[\u004C\u24C1\uFF2C\u013F\u0139\u013D\u1E36\u1E38\u013B\u1E3C\u1E3A\u0141\u023D\u2C62\u2C60\uA748\uA746\uA780])/g,
+ letters:
+ /(L|Ⓛ|L|Ŀ|Ĺ|Ľ|Ḷ|Ḹ|Ļ|Ḽ|Ḻ|Ł|Ƚ|Ɫ|Ⱡ|Ꝉ|Ꝇ|Ꞁ|[\u004C\u24C1\uFF2C\u013F\u0139\u013D\u1E36\u1E38\u013B\u1E3C\u1E3A\u0141\u023D\u2C62\u2C60\uA748\uA746\uA780])/g,
},
{
base: 'LJ',
@@ -91,11 +101,13 @@ const lettersDiacritics = [
},
{
base: 'M',
- letters: /(M|Ⓜ|M|Ḿ|Ṁ|Ṃ|Ɱ|Ɯ|[\u004D\u24C2\uFF2D\u1E3E\u1E40\u1E42\u2C6E\u019C])/g,
+ letters:
+ /(M|Ⓜ|M|Ḿ|Ṁ|Ṃ|Ɱ|Ɯ|[\u004D\u24C2\uFF2D\u1E3E\u1E40\u1E42\u2C6E\u019C])/g,
},
{
base: 'N',
- letters: /(N|Ⓝ|N|Ǹ|Ń|Ñ|Ṅ|Ň|Ṇ|Ņ|Ṋ|Ṉ|Ƞ|Ɲ|Ꞑ|Ꞥ|Ŋ|[\u004E\u24C3\uFF2E\u01F8\u0143\u00D1\u1E44\u0147\u1E46\u0145\u1E4A\u1E48\u0220\u019D\uA790\uA7A4\u014A])/g,
+ letters:
+ /(N|Ⓝ|N|Ǹ|Ń|Ñ|Ṅ|Ň|Ṇ|Ņ|Ṋ|Ṉ|Ƞ|Ɲ|Ꞑ|Ꞥ|Ŋ|[\u004E\u24C3\uFF2E\u01F8\u0143\u00D1\u1E44\u0147\u1E46\u0145\u1E4A\u1E48\u0220\u019D\uA790\uA7A4\u014A])/g,
},
{
base: 'NJ',
@@ -107,7 +119,8 @@ const lettersDiacritics = [
},
{
base: 'O',
- letters: /(O|Ⓞ|O|Ò|Ó|Ô|Ồ|Ố|Ỗ|Ổ|Õ|Ṍ|Ȭ|Ṏ|Ō|Ṑ|Ṓ|Ŏ|Ȯ|Ȱ|Ö|Ȫ|Ỏ|Ő|Ǒ|Ȍ|Ȏ|Ơ|Ờ|Ớ|Ỡ|Ở|Ợ|Ọ|Ộ|Ǫ|Ǭ|Ø|Ǿ|Ɔ|Ɵ|Ꝋ|Ꝍ|[\u004F\u24C4\uFF2F\u00D2\u00D3\u00D4\u1ED2\u1ED0\u1ED6\u1ED4\u00D5\u1E4C\u022C\u1E4E\u014C\u1E50\u1E52\u014E\u022E\u0230\u00D6\u022A\u1ECE\u0150\u01D1\u020C\u020E\u01A0\u1EDC\u1EDA\u1EE0\u1EDE\u1EE2\u1ECC\u1ED8\u01EA\u01EC\u00D8\u01FE\u0186\u019F\uA74A\uA74C])/g,
+ letters:
+ /(O|Ⓞ|O|Ò|Ó|Ô|Ồ|Ố|Ỗ|Ổ|Õ|Ṍ|Ȭ|Ṏ|Ō|Ṑ|Ṓ|Ŏ|Ȯ|Ȱ|Ö|Ȫ|Ỏ|Ő|Ǒ|Ȍ|Ȏ|Ơ|Ờ|Ớ|Ỡ|Ở|Ợ|Ọ|Ộ|Ǫ|Ǭ|Ø|Ǿ|Ɔ|Ɵ|Ꝋ|Ꝍ|[\u004F\u24C4\uFF2F\u00D2\u00D3\u00D4\u1ED2\u1ED0\u1ED6\u1ED4\u00D5\u1E4C\u022C\u1E4E\u014C\u1E50\u1E52\u014E\u022E\u0230\u00D6\u022A\u1ECE\u0150\u01D1\u020C\u020E\u01A0\u1EDC\u1EDA\u1EE0\u1EDE\u1EE2\u1ECC\u1ED8\u01EA\u01EC\u00D8\u01FE\u0186\u019F\uA74A\uA74C])/g,
},
{
base: 'OE',
@@ -127,7 +140,8 @@ const lettersDiacritics = [
},
{
base: 'P',
- letters: /(P|Ⓟ|P|Ṕ|Ṗ|Ƥ|Ᵽ|Ꝑ|Ꝓ|Ꝕ|[\u0050\u24C5\uFF30\u1E54\u1E56\u01A4\u2C63\uA750\uA752\uA754])/g,
+ letters:
+ /(P|Ⓟ|P|Ṕ|Ṗ|Ƥ|Ᵽ|Ꝑ|Ꝓ|Ꝕ|[\u0050\u24C5\uFF30\u1E54\u1E56\u01A4\u2C63\uA750\uA752\uA754])/g,
},
{
base: 'Q',
@@ -135,15 +149,18 @@ const lettersDiacritics = [
},
{
base: 'R',
- letters: /(R|Ⓡ|R|Ŕ|Ṙ|Ř|Ȑ|Ȓ|Ṛ|Ṝ|Ŗ|Ṟ|Ɍ|Ɽ|Ꝛ|Ꞧ|Ꞃ|[\u0052\u24C7\uFF32\u0154\u1E58\u0158\u0210\u0212\u1E5A\u1E5C\u0156\u1E5E\u024C\u2C64\uA75A\uA7A6\uA782])/g,
+ letters:
+ /(R|Ⓡ|R|Ŕ|Ṙ|Ř|Ȑ|Ȓ|Ṛ|Ṝ|Ŗ|Ṟ|Ɍ|Ɽ|Ꝛ|Ꞧ|Ꞃ|[\u0052\u24C7\uFF32\u0154\u1E58\u0158\u0210\u0212\u1E5A\u1E5C\u0156\u1E5E\u024C\u2C64\uA75A\uA7A6\uA782])/g,
},
{
base: 'S',
- letters: /(S|Ⓢ|S|ẞ|Ś|Ṥ|Ŝ|Ṡ|Š|Ṧ|Ṣ|Ṩ|Ș|Ş|Ȿ|Ꞩ|Ꞅ|[\u0053\u24C8\uFF33\u1E9E\u015A\u1E64\u015C\u1E60\u0160\u1E66\u1E62\u1E68\u0218\u015E\u2C7E\uA7A8\uA784])/g,
+ letters:
+ /(S|Ⓢ|S|ẞ|Ś|Ṥ|Ŝ|Ṡ|Š|Ṧ|Ṣ|Ṩ|Ș|Ş|Ȿ|Ꞩ|Ꞅ|[\u0053\u24C8\uFF33\u1E9E\u015A\u1E64\u015C\u1E60\u0160\u1E66\u1E62\u1E68\u0218\u015E\u2C7E\uA7A8\uA784])/g,
},
{
base: 'T',
- letters: /(T|Ⓣ|T|Ṫ|Ť|Ṭ|Ț|Ţ|Ṱ|Ṯ|Ŧ|Ƭ|Ʈ|Ⱦ|Ꞇ|[\u0054\u24C9\uFF34\u1E6A\u0164\u1E6C\u021A\u0162\u1E70\u1E6E\u0166\u01AC\u01AE\u023E\uA786])/g,
+ letters:
+ /(T|Ⓣ|T|Ṫ|Ť|Ṭ|Ț|Ţ|Ṱ|Ṯ|Ŧ|Ƭ|Ʈ|Ⱦ|Ꞇ|[\u0054\u24C9\uFF34\u1E6A\u0164\u1E6C\u021A\u0162\u1E70\u1E6E\u0166\u01AC\u01AE\u023E\uA786])/g,
},
{
base: 'TH',
@@ -155,11 +172,13 @@ const lettersDiacritics = [
},
{
base: 'U',
- letters: /(U|Ⓤ|U|Ù|Ú|Û|Ũ|Ṹ|Ū|Ṻ|Ŭ|Ü|Ǜ|Ǘ|Ǖ|Ǚ|Ủ|Ů|Ű|Ǔ|Ȕ|Ȗ|Ư|Ừ|Ứ|Ữ|Ử|Ự|Ụ|Ṳ|Ų|Ṷ|Ṵ|Ʉ|[\u0055\u24CA\uFF35\u00D9\u00DA\u00DB\u0168\u1E78\u016A\u1E7A\u016C\u00DC\u01DB\u01D7\u01D5\u01D9\u1EE6\u016E\u0170\u01D3\u0214\u0216\u01AF\u1EEA\u1EE8\u1EEE\u1EEC\u1EF0\u1EE4\u1E72\u0172\u1E76\u1E74\u0244])/g,
+ letters:
+ /(U|Ⓤ|U|Ù|Ú|Û|Ũ|Ṹ|Ū|Ṻ|Ŭ|Ü|Ǜ|Ǘ|Ǖ|Ǚ|Ủ|Ů|Ű|Ǔ|Ȕ|Ȗ|Ư|Ừ|Ứ|Ữ|Ử|Ự|Ụ|Ṳ|Ų|Ṷ|Ṵ|Ʉ|[\u0055\u24CA\uFF35\u00D9\u00DA\u00DB\u0168\u1E78\u016A\u1E7A\u016C\u00DC\u01DB\u01D7\u01D5\u01D9\u1EE6\u016E\u0170\u01D3\u0214\u0216\u01AF\u1EEA\u1EE8\u1EEE\u1EEC\u1EF0\u1EE4\u1E72\u0172\u1E76\u1E74\u0244])/g,
},
{
base: 'V',
- letters: /(V|Ⓥ|V|Ṽ|Ṿ|Ʋ|Ꝟ|Ʌ|[\u0056\u24CB\uFF36\u1E7C\u1E7E\u01B2\uA75E\u0245])/g,
+ letters:
+ /(V|Ⓥ|V|Ṽ|Ṿ|Ʋ|Ꝟ|Ʌ|[\u0056\u24CB\uFF36\u1E7C\u1E7E\u01B2\uA75E\u0245])/g,
},
{
base: 'VY',
@@ -167,7 +186,8 @@ const lettersDiacritics = [
},
{
base: 'W',
- letters: /(W|Ⓦ|W|Ẁ|Ẃ|Ŵ|Ẇ|Ẅ|Ẉ|Ⱳ|[\u0057\u24CC\uFF37\u1E80\u1E82\u0174\u1E86\u1E84\u1E88\u2C72])/g,
+ letters:
+ /(W|Ⓦ|W|Ẁ|Ẃ|Ŵ|Ẇ|Ẅ|Ẉ|Ⱳ|[\u0057\u24CC\uFF37\u1E80\u1E82\u0174\u1E86\u1E84\u1E88\u2C72])/g,
},
{
base: 'X',
@@ -175,15 +195,18 @@ const lettersDiacritics = [
},
{
base: 'Y',
- letters: /(Y|Ⓨ|Y|Ỳ|Ý|Ŷ|Ỹ|Ȳ|Ẏ|Ÿ|Ỷ|Ỵ|Ƴ|Ɏ|Ỿ|[\u0059\u24CE\uFF39\u1EF2\u00DD\u0176\u1EF8\u0232\u1E8E\u0178\u1EF6\u1EF4\u01B3\u024E\u1EFE])/g,
+ letters:
+ /(Y|Ⓨ|Y|Ỳ|Ý|Ŷ|Ỹ|Ȳ|Ẏ|Ÿ|Ỷ|Ỵ|Ƴ|Ɏ|Ỿ|[\u0059\u24CE\uFF39\u1EF2\u00DD\u0176\u1EF8\u0232\u1E8E\u0178\u1EF6\u1EF4\u01B3\u024E\u1EFE])/g,
},
{
base: 'Z',
- letters: /(Z|Ⓩ|Z|Ź|Ẑ|Ż|Ž|Ẓ|Ẕ|Ƶ|Ȥ|Ɀ|Ⱬ|Ꝣ|[\u005A\u24CF\uFF3A\u0179\u1E90\u017B\u017D\u1E92\u1E94\u01B5\u0224\u2C7F\u2C6B\uA762])/g,
+ letters:
+ /(Z|Ⓩ|Z|Ź|Ẑ|Ż|Ž|Ẓ|Ẕ|Ƶ|Ȥ|Ɀ|Ⱬ|Ꝣ|[\u005A\u24CF\uFF3A\u0179\u1E90\u017B\u017D\u1E92\u1E94\u01B5\u0224\u2C7F\u2C6B\uA762])/g,
},
{
base: 'a',
- letters: /(a|ⓐ|a|ẚ|à|á|â|ầ|ấ|ẫ|ẩ|ã|ā|ă|ằ|ắ|ẵ|ẳ|ȧ|ǡ|ä|ǟ|ả|å|ǻ|ǎ|ȁ|ȃ|ạ|ậ|ặ|ḁ|ą|ⱥ|ɐ|[\u0061\u24D0\uFF41\u1E9A\u00E0\u00E1\u00E2\u1EA7\u1EA5\u1EAB\u1EA9\u00E3\u0101\u0103\u1EB1\u1EAF\u1EB5\u1EB3\u0227\u01E1\u00E4\u01DF\u1EA3\u00E5\u01FB\u01CE\u0201\u0203\u1EA1\u1EAD\u1EB7\u1E01\u0105\u2C65\u0250])/g,
+ letters:
+ /(a|ⓐ|a|ẚ|à|á|â|ầ|ấ|ẫ|ẩ|ã|ā|ă|ằ|ắ|ẵ|ẳ|ȧ|ǡ|ä|ǟ|ả|å|ǻ|ǎ|ȁ|ȃ|ạ|ậ|ặ|ḁ|ą|ⱥ|ɐ|[\u0061\u24D0\uFF41\u1E9A\u00E0\u00E1\u00E2\u1EA7\u1EA5\u1EAB\u1EA9\u00E3\u0101\u0103\u1EB1\u1EAF\u1EB5\u1EB3\u0227\u01E1\u00E4\u01DF\u1EA3\u00E5\u01FB\u01CE\u0201\u0203\u1EA1\u1EAD\u1EB7\u1E01\u0105\u2C65\u0250])/g,
},
{
base: 'aa',
@@ -211,15 +234,18 @@ const lettersDiacritics = [
},
{
base: 'b',
- letters: /(b|ⓑ|b|ḃ|ḅ|ḇ|ƀ|ƃ|ɓ|[\u0062\u24D1\uFF42\u1E03\u1E05\u1E07\u0180\u0183\u0253])/g,
+ letters:
+ /(b|ⓑ|b|ḃ|ḅ|ḇ|ƀ|ƃ|ɓ|[\u0062\u24D1\uFF42\u1E03\u1E05\u1E07\u0180\u0183\u0253])/g,
},
{
base: 'c',
- letters: /(c|ⓒ|c|ć|ĉ|ċ|č|ç|ḉ|ƈ|ȼ|ꜿ|ↄ|[\u0063\u24D2\uFF43\u0107\u0109\u010B\u010D\u00E7\u1E09\u0188\u023C\uA73F\u2184])/g,
+ letters:
+ /(c|ⓒ|c|ć|ĉ|ċ|č|ç|ḉ|ƈ|ȼ|ꜿ|ↄ|[\u0063\u24D2\uFF43\u0107\u0109\u010B\u010D\u00E7\u1E09\u0188\u023C\uA73F\u2184])/g,
},
{
base: 'd',
- letters: /(d|ⓓ|d|ḋ|ď|ḍ|ḑ|ḓ|ḏ|đ|ƌ|ɖ|ɗ|ꝺ|ð|[\u0064\u24D3\uFF44\u1E0B\u010F\u1E0D\u1E11\u1E13\u1E0F\u0111\u018C\u0256\u0257\uA77A\u00F0])/g,
+ letters:
+ /(d|ⓓ|d|ḋ|ď|ḍ|ḑ|ḓ|ḏ|đ|ƌ|ɖ|ɗ|ꝺ|ð|[\u0064\u24D3\uFF44\u1E0B\u010F\u1E0D\u1E11\u1E13\u1E0F\u0111\u018C\u0256\u0257\uA77A\u00F0])/g,
},
{
base: 'dz',
@@ -227,7 +253,8 @@ const lettersDiacritics = [
},
{
base: 'e',
- letters: /(e|ⓔ|e|è|é|ê|ề|ế|ễ|ể|ẽ|ē|ḕ|ḗ|ĕ|ė|ë|ẻ|ě|ȅ|ȇ|ẹ|ệ|ȩ|ḝ|ę|ḙ|ḛ|ɇ|ɛ|ǝ|[\u0065\u24D4\uFF45\u00E8\u00E9\u00EA\u1EC1\u1EBF\u1EC5\u1EC3\u1EBD\u0113\u1E15\u1E17\u0115\u0117\u00EB\u1EBB\u011B\u0205\u0207\u1EB9\u1EC7\u0229\u1E1D\u0119\u1E19\u1E1B\u0247\u025B\u01DD])/g,
+ letters:
+ /(e|ⓔ|e|è|é|ê|ề|ế|ễ|ể|ẽ|ē|ḕ|ḗ|ĕ|ė|ë|ẻ|ě|ȅ|ȇ|ẹ|ệ|ȩ|ḝ|ę|ḙ|ḛ|ɇ|ɛ|ǝ|[\u0065\u24D4\uFF45\u00E8\u00E9\u00EA\u1EC1\u1EBF\u1EC5\u1EC3\u1EBD\u0113\u1E15\u1E17\u0115\u0117\u00EB\u1EBB\u011B\u0205\u0207\u1EB9\u1EC7\u0229\u1E1D\u0119\u1E19\u1E1B\u0247\u025B\u01DD])/g,
},
{
base: 'f',
@@ -235,11 +262,13 @@ const lettersDiacritics = [
},
{
base: 'g',
- letters: /(g|ⓖ|g|ǵ|ĝ|ḡ|ğ|ġ|ǧ|ģ|ǥ|ɠ|ꞡ|ᵹ|ꝿ|[\u0067\u24D6\uFF47\u01F5\u011D\u1E21\u011F\u0121\u01E7\u0123\u01E5\u0260\uA7A1\u1D79\uA77F])/g,
+ letters:
+ /(g|ⓖ|g|ǵ|ĝ|ḡ|ğ|ġ|ǧ|ģ|ǥ|ɠ|ꞡ|ᵹ|ꝿ|[\u0067\u24D6\uFF47\u01F5\u011D\u1E21\u011F\u0121\u01E7\u0123\u01E5\u0260\uA7A1\u1D79\uA77F])/g,
},
{
base: 'h',
- letters: /(h|ⓗ|h|ĥ|ḣ|ḧ|ȟ|ḥ|ḩ|ḫ|ẖ|ħ|ⱨ|ⱶ|ɥ|[\u0068\u24D7\uFF48\u0125\u1E23\u1E27\u021F\u1E25\u1E29\u1E2B\u1E96\u0127\u2C68\u2C76\u0265])/g,
+ letters:
+ /(h|ⓗ|h|ĥ|ḣ|ḧ|ȟ|ḥ|ḩ|ḫ|ẖ|ħ|ⱨ|ⱶ|ɥ|[\u0068\u24D7\uFF48\u0125\u1E23\u1E27\u021F\u1E25\u1E29\u1E2B\u1E96\u0127\u2C68\u2C76\u0265])/g,
},
{
base: 'hv',
@@ -247,7 +276,8 @@ const lettersDiacritics = [
},
{
base: 'i',
- letters: /(i|ⓘ|i|ì|í|î|ĩ|ī|ĭ|ï|ḯ|ỉ|ǐ|ȉ|ȋ|ị|į|ḭ|ɨ|ı|[\u0069\u24D8\uFF49\u00EC\u00ED\u00EE\u0129\u012B\u012D\u00EF\u1E2F\u1EC9\u01D0\u0209\u020B\u1ECB\u012F\u1E2D\u0268\u0131])/g,
+ letters:
+ /(i|ⓘ|i|ì|í|î|ĩ|ī|ĭ|ï|ḯ|ỉ|ǐ|ȉ|ȋ|ị|į|ḭ|ɨ|ı|[\u0069\u24D8\uFF49\u00EC\u00ED\u00EE\u0129\u012B\u012D\u00EF\u1E2F\u1EC9\u01D0\u0209\u020B\u1ECB\u012F\u1E2D\u0268\u0131])/g,
},
{
base: 'ij',
@@ -259,11 +289,13 @@ const lettersDiacritics = [
},
{
base: 'k',
- letters: /(k|ⓚ|k|ḱ|ǩ|ḳ|ķ|ḵ|ƙ|ⱪ|ꝁ|ꝃ|ꝅ|ꞣ|[\u006B\u24DA\uFF4B\u1E31\u01E9\u1E33\u0137\u1E35\u0199\u2C6A\uA741\uA743\uA745\uA7A3])/g,
+ letters:
+ /(k|ⓚ|k|ḱ|ǩ|ḳ|ķ|ḵ|ƙ|ⱪ|ꝁ|ꝃ|ꝅ|ꞣ|[\u006B\u24DA\uFF4B\u1E31\u01E9\u1E33\u0137\u1E35\u0199\u2C6A\uA741\uA743\uA745\uA7A3])/g,
},
{
base: 'l',
- letters: /(l|ⓛ|l|ŀ|ĺ|ľ|ḷ|ḹ|ļ|ḽ|ḻ|ł|ƚ|ɫ|ⱡ|ꝉ|ꞁ|ꝇ|[\u006C\u24DB\uFF4C\u0140\u013A\u013E\u1E37\u1E39\u013C\u1E3D\u1E3B\u0142\u019A\u026B\u2C61\uA749\uA781\uA747])/g,
+ letters:
+ /(l|ⓛ|l|ŀ|ĺ|ľ|ḷ|ḹ|ļ|ḽ|ḻ|ł|ƚ|ɫ|ⱡ|ꝉ|ꞁ|ꝇ|[\u006C\u24DB\uFF4C\u0140\u013A\u013E\u1E37\u1E39\u013C\u1E3D\u1E3B\u0142\u019A\u026B\u2C61\uA749\uA781\uA747])/g,
},
{
base: 'lj',
@@ -271,11 +303,13 @@ const lettersDiacritics = [
},
{
base: 'm',
- letters: /(m|ⓜ|m|ḿ|ṁ|ṃ|ɱ|ɯ|[\u006D\u24DC\uFF4D\u1E3F\u1E41\u1E43\u0271\u026F])/g,
+ letters:
+ /(m|ⓜ|m|ḿ|ṁ|ṃ|ɱ|ɯ|[\u006D\u24DC\uFF4D\u1E3F\u1E41\u1E43\u0271\u026F])/g,
},
{
base: 'n',
- letters: /(n|ⓝ|n|ǹ|ń|ñ|ṅ|ň|ṇ|ņ|ṋ|ṉ|ƞ|ɲ|ʼn|ꞑ|ꞥ|ŋ|[\u006E\u24DD\uFF4E\u01F9\u0144\u00F1\u1E45\u0148\u1E47\u0146\u1E4B\u1E49\u019E\u0272\u0149\uA791\uA7A5\u014B])/g,
+ letters:
+ /(n|ⓝ|n|ǹ|ń|ñ|ṅ|ň|ṇ|ņ|ṋ|ṉ|ƞ|ɲ|ʼn|ꞑ|ꞥ|ŋ|[\u006E\u24DD\uFF4E\u01F9\u0144\u00F1\u1E45\u0148\u1E47\u0146\u1E4B\u1E49\u019E\u0272\u0149\uA791\uA7A5\u014B])/g,
},
{
base: 'nj',
@@ -283,7 +317,8 @@ const lettersDiacritics = [
},
{
base: 'o',
- letters: /(o|ⓞ|o|ò|ó|ô|ồ|ố|ỗ|ổ|õ|ṍ|ȭ|ṏ|ō|ṑ|ṓ|ŏ|ȯ|ȱ|ö|ȫ|ỏ|ő|ǒ|ȍ|ȏ|ơ|ờ|ớ|ỡ|ở|ợ|ọ|ộ|ǫ|ǭ|ø|ǿ|ɔ|ꝋ|ꝍ|ɵ|[\u006F\u24DE\uFF4F\u00F2\u00F3\u00F4\u1ED3\u1ED1\u1ED7\u1ED5\u00F5\u1E4D\u022D\u1E4F\u014D\u1E51\u1E53\u014F\u022F\u0231\u00F6\u022B\u1ECF\u0151\u01D2\u020D\u020F\u01A1\u1EDD\u1EDB\u1EE1\u1EDF\u1EE3\u1ECD\u1ED9\u01EB\u01ED\u00F8\u01FF\u0254\uA74B\uA74D\u0275])/g,
+ letters:
+ /(o|ⓞ|o|ò|ó|ô|ồ|ố|ỗ|ổ|õ|ṍ|ȭ|ṏ|ō|ṑ|ṓ|ŏ|ȯ|ȱ|ö|ȫ|ỏ|ő|ǒ|ȍ|ȏ|ơ|ờ|ớ|ỡ|ở|ợ|ọ|ộ|ǫ|ǭ|ø|ǿ|ɔ|ꝋ|ꝍ|ɵ|[\u006F\u24DE\uFF4F\u00F2\u00F3\u00F4\u1ED3\u1ED1\u1ED7\u1ED5\u00F5\u1E4D\u022D\u1E4F\u014D\u1E51\u1E53\u014F\u022F\u0231\u00F6\u022B\u1ECF\u0151\u01D2\u020D\u020F\u01A1\u1EDD\u1EDB\u1EE1\u1EDF\u1EE3\u1ECD\u1ED9\u01EB\u01ED\u00F8\u01FF\u0254\uA74B\uA74D\u0275])/g,
},
{
base: 'oe',
@@ -303,7 +338,8 @@ const lettersDiacritics = [
},
{
base: 'p',
- letters: /(p|ⓟ|p|ṕ|ṗ|ƥ|ᵽ|ꝑ|ꝓ|ꝕ|[\u0070\u24DF\uFF50\u1E55\u1E57\u01A5\u1D7D\uA751\uA753\uA755])/g,
+ letters:
+ /(p|ⓟ|p|ṕ|ṗ|ƥ|ᵽ|ꝑ|ꝓ|ꝕ|[\u0070\u24DF\uFF50\u1E55\u1E57\u01A5\u1D7D\uA751\uA753\uA755])/g,
},
{
base: 'q',
@@ -311,11 +347,13 @@ const lettersDiacritics = [
},
{
base: 'r',
- letters: /(r|ⓡ|r|ŕ|ṙ|ř|ȑ|ȓ|ṛ|ṝ|ŗ|ṟ|ɍ|ɽ|ꝛ|ꞧ|ꞃ|[\u0072\u24E1\uFF52\u0155\u1E59\u0159\u0211\u0213\u1E5B\u1E5D\u0157\u1E5F\u024D\u027D\uA75B\uA7A7\uA783])/g,
+ letters:
+ /(r|ⓡ|r|ŕ|ṙ|ř|ȑ|ȓ|ṛ|ṝ|ŗ|ṟ|ɍ|ɽ|ꝛ|ꞧ|ꞃ|[\u0072\u24E1\uFF52\u0155\u1E59\u0159\u0211\u0213\u1E5B\u1E5D\u0157\u1E5F\u024D\u027D\uA75B\uA7A7\uA783])/g,
},
{
base: 's',
- letters: /(s|ⓢ|s|ś|ṥ|ŝ|ṡ|š|ṧ|ṣ|ṩ|ș|ş|ȿ|ꞩ|ꞅ|ẛ|ſ|[\u0073\u24E2\uFF53\u015B\u1E65\u015D\u1E61\u0161\u1E67\u1E63\u1E69\u0219\u015F\u023F\uA7A9\uA785\u1E9B\u017F])/g,
+ letters:
+ /(s|ⓢ|s|ś|ṥ|ŝ|ṡ|š|ṧ|ṣ|ṩ|ș|ş|ȿ|ꞩ|ꞅ|ẛ|ſ|[\u0073\u24E2\uFF53\u015B\u1E65\u015D\u1E61\u0161\u1E67\u1E63\u1E69\u0219\u015F\u023F\uA7A9\uA785\u1E9B\u017F])/g,
},
{
base: 'ss',
@@ -323,7 +361,8 @@ const lettersDiacritics = [
},
{
base: 't',
- letters: /(t|ⓣ|t|ṫ|ẗ|ť|ṭ|ț|ţ|ṱ|ṯ|ŧ|ƭ|ʈ|ⱦ|ꞇ|[\u0074\u24E3\uFF54\u1E6B\u1E97\u0165\u1E6D\u021B\u0163\u1E71\u1E6F\u0167\u01AD\u0288\u2C66\uA787])/g,
+ letters:
+ /(t|ⓣ|t|ṫ|ẗ|ť|ṭ|ț|ţ|ṱ|ṯ|ŧ|ƭ|ʈ|ⱦ|ꞇ|[\u0074\u24E3\uFF54\u1E6B\u1E97\u0165\u1E6D\u021B\u0163\u1E71\u1E6F\u0167\u01AD\u0288\u2C66\uA787])/g,
},
{
base: 'th',
@@ -335,11 +374,13 @@ const lettersDiacritics = [
},
{
base: 'u',
- letters: /(u|ⓤ|u|ù|ú|û|ũ|ṹ|ū|ṻ|ŭ|ü|ǜ|ǘ|ǖ|ǚ|ủ|ů|ű|ǔ|ȕ|ȗ|ư|ừ|ứ|ữ|ử|ự|ụ|ṳ|ų|ṷ|ṵ|ʉ|[\u0075\u24E4\uFF55\u00F9\u00FA\u00FB\u0169\u1E79\u016B\u1E7B\u016D\u00FC\u01DC\u01D8\u01D6\u01DA\u1EE7\u016F\u0171\u01D4\u0215\u0217\u01B0\u1EEB\u1EE9\u1EEF\u1EED\u1EF1\u1EE5\u1E73\u0173\u1E77\u1E75\u0289])/g,
+ letters:
+ /(u|ⓤ|u|ù|ú|û|ũ|ṹ|ū|ṻ|ŭ|ü|ǜ|ǘ|ǖ|ǚ|ủ|ů|ű|ǔ|ȕ|ȗ|ư|ừ|ứ|ữ|ử|ự|ụ|ṳ|ų|ṷ|ṵ|ʉ|[\u0075\u24E4\uFF55\u00F9\u00FA\u00FB\u0169\u1E79\u016B\u1E7B\u016D\u00FC\u01DC\u01D8\u01D6\u01DA\u1EE7\u016F\u0171\u01D4\u0215\u0217\u01B0\u1EEB\u1EE9\u1EEF\u1EED\u1EF1\u1EE5\u1E73\u0173\u1E77\u1E75\u0289])/g,
},
{
base: 'v',
- letters: /(v|ⓥ|v|ṽ|ṿ|ʋ|ꝟ|ʌ|[\u0076\u24E5\uFF56\u1E7D\u1E7F\u028B\uA75F\u028C])/g,
+ letters:
+ /(v|ⓥ|v|ṽ|ṿ|ʋ|ꝟ|ʌ|[\u0076\u24E5\uFF56\u1E7D\u1E7F\u028B\uA75F\u028C])/g,
},
{
base: 'vy',
@@ -347,7 +388,8 @@ const lettersDiacritics = [
},
{
base: 'w',
- letters: /(w|ⓦ|w|ẁ|ẃ|ŵ|ẇ|ẅ|ẘ|ẉ|ⱳ|[\u0077\u24E6\uFF57\u1E81\u1E83\u0175\u1E87\u1E85\u1E98\u1E89\u2C73])/g,
+ letters:
+ /(w|ⓦ|w|ẁ|ẃ|ŵ|ẇ|ẅ|ẘ|ẉ|ⱳ|[\u0077\u24E6\uFF57\u1E81\u1E83\u0175\u1E87\u1E85\u1E98\u1E89\u2C73])/g,
},
{
base: 'x',
@@ -355,12 +397,14 @@ const lettersDiacritics = [
},
{
base: 'y',
- letters: /(y|ⓨ|y|ỳ|ý|ŷ|ỹ|ȳ|ẏ|ÿ|ỷ|ẙ|ỵ|ƴ|ɏ|ỿ|[\u0079\u24E8\uFF59\u1EF3\u00FD\u0177\u1EF9\u0233\u1E8F\u00FF\u1EF7\u1E99\u1EF5\u01B4\u024F\u1EFF])/g,
+ letters:
+ /(y|ⓨ|y|ỳ|ý|ŷ|ỹ|ȳ|ẏ|ÿ|ỷ|ẙ|ỵ|ƴ|ɏ|ỿ|[\u0079\u24E8\uFF59\u1EF3\u00FD\u0177\u1EF9\u0233\u1E8F\u00FF\u1EF7\u1E99\u1EF5\u01B4\u024F\u1EFF])/g,
},
{
base: 'z',
- letters: /(z|ⓩ|z|ź|ẑ|ż|ž|ẓ|ẕ|ƶ|ȥ|ɀ|ⱬ|ꝣ|[\u007A\u24E9\uFF5A\u017A\u1E91\u017C\u017E\u1E93\u1E95\u01B6\u0225\u0240\u2C6C\uA763])/g,
+ letters:
+ /(z|ⓩ|z|ź|ẑ|ż|ž|ẓ|ẕ|ƶ|ȥ|ɀ|ⱬ|ꝣ|[\u007A\u24E9\uFF5A\u017A\u1E91\u017C\u017E\u1E93\u1E95\u01B6\u0225\u0240\u2C6C\uA763])/g,
},
-]
+];
-export default lettersDiacritics
+export default lettersDiacritics;
diff --git a/apps/crew/packages/react-mentions/src/utils/escapeRegex.js b/apps/crew/packages/react-mentions/src/utils/escapeRegex.js
index f06982c0c..7327a0421 100644
--- a/apps/crew/packages/react-mentions/src/utils/escapeRegex.js
+++ b/apps/crew/packages/react-mentions/src/utils/escapeRegex.js
@@ -1,4 +1,4 @@
// escape RegExp special characters https://stackoverflow.com/a/9310752/5142490
-const escapeRegex = (str) => str.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&')
+const escapeRegex = (str) => str.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
-export default escapeRegex
+export default escapeRegex;
diff --git a/apps/crew/packages/react-mentions/src/utils/findPositionOfCapturingGroup.js b/apps/crew/packages/react-mentions/src/utils/findPositionOfCapturingGroup.js
index c26f6eddc..851c93615 100644
--- a/apps/crew/packages/react-mentions/src/utils/findPositionOfCapturingGroup.js
+++ b/apps/crew/packages/react-mentions/src/utils/findPositionOfCapturingGroup.js
@@ -1,36 +1,36 @@
-import invariant from 'invariant'
-import PLACEHOLDERS from './placeholders'
+import invariant from 'invariant';
+import PLACEHOLDERS from './placeholders';
const findPositionOfCapturingGroup = (markup, parameterName) => {
invariant(
parameterName === 'id' || parameterName === 'display',
- `Second arg must be either "id" or "display", got: "${parameterName}"`
- )
+ `Second arg must be either "id" or "display", got: "${parameterName}"`,
+ );
// find positions of placeholders in the markup
- let indexDisplay = markup.indexOf(PLACEHOLDERS.display)
- let indexId = markup.indexOf(PLACEHOLDERS.id)
+ let indexDisplay = markup.indexOf(PLACEHOLDERS.display);
+ let indexId = markup.indexOf(PLACEHOLDERS.id);
// set indices to null if not found
- if (indexDisplay < 0) indexDisplay = null
- if (indexId < 0) indexId = null
+ if (indexDisplay < 0) indexDisplay = null;
+ if (indexId < 0) indexId = null;
// markup must contain one of the mandatory placeholders
invariant(
indexDisplay !== null || indexId !== null,
- `The markup '${markup}' does not contain either of the placeholders '__id__' or '__display__'`
- )
+ `The markup '${markup}' does not contain either of the placeholders '__id__' or '__display__'`,
+ );
if (indexDisplay !== null && indexId !== null) {
// both placeholders are used, return 0 or 1 depending on the position of the requested parameter
return (parameterName === 'id' && indexId <= indexDisplay) ||
(parameterName === 'display' && indexDisplay <= indexId)
? 0
- : 1
+ : 1;
}
// just one placeholder is being used, we'll use the captured string for both parameters
- return 0
-}
+ return 0;
+};
-export default findPositionOfCapturingGroup
+export default findPositionOfCapturingGroup;
diff --git a/apps/crew/packages/react-mentions/src/utils/findPositionOfCapturingGroup.spec.js b/apps/crew/packages/react-mentions/src/utils/findPositionOfCapturingGroup.spec.js
index d66f8f4cb..71efacb10 100644
--- a/apps/crew/packages/react-mentions/src/utils/findPositionOfCapturingGroup.spec.js
+++ b/apps/crew/packages/react-mentions/src/utils/findPositionOfCapturingGroup.spec.js
@@ -1,4 +1,4 @@
-import findPositionOfCapturingGroup from './findPositionOfCapturingGroup'
+import findPositionOfCapturingGroup from './findPositionOfCapturingGroup';
describe('#findPositionOfCapturingGroup', () => {
const testData = {
@@ -6,20 +6,18 @@ describe('#findPositionOfCapturingGroup', () => {
'{{__id__#__display__}}': { display: 1, id: 0 },
'{{__id__}}': { display: 0, id: 0 },
'{{__display__}}': { display: 0, id: 0 },
- }
+ };
- Object.keys(testData).forEach(key => {
- const markup = key
- const positions = testData[key]
+ Object.keys(testData).forEach((key) => {
+ const markup = key;
+ const positions = testData[key];
it(`should return ${positions.display} for the 'display' position in markup '${markup}'`, () => {
- expect(findPositionOfCapturingGroup(markup, 'display')).toEqual(
- positions.display
- )
- })
+ expect(findPositionOfCapturingGroup(markup, 'display')).toEqual(positions.display);
+ });
it(`should return ${positions.id} for the 'id' position in markup '${markup}'`, () => {
- expect(findPositionOfCapturingGroup(markup, 'id')).toEqual(positions.id)
- })
- })
-})
+ expect(findPositionOfCapturingGroup(markup, 'id')).toEqual(positions.id);
+ });
+ });
+});
diff --git a/apps/crew/packages/react-mentions/src/utils/findStartOfMentionInPlainText.js b/apps/crew/packages/react-mentions/src/utils/findStartOfMentionInPlainText.js
index 9b717bdc4..1a84b7f66 100644
--- a/apps/crew/packages/react-mentions/src/utils/findStartOfMentionInPlainText.js
+++ b/apps/crew/packages/react-mentions/src/utils/findStartOfMentionInPlainText.js
@@ -1,34 +1,23 @@
-import iterateMentionsMarkup from './iterateMentionsMarkup'
+import iterateMentionsMarkup from './iterateMentionsMarkup';
// For a given indexInPlainText that lies inside a mention,
// returns a the index of of the first char of the mention in the plain text.
// If indexInPlainText does not lie inside a mention, returns indexInPlainText.
const findStartOfMentionInPlainText = (value, config, indexInPlainText) => {
- let result = indexInPlainText
- let foundMention = false
+ let result = indexInPlainText;
+ let foundMention = false;
- let markupIteratee = (
- markup,
- index,
- mentionPlainTextIndex,
- id,
- display,
- childIndex,
- lastMentionEndIndex
- ) => {
- if (
- mentionPlainTextIndex <= indexInPlainText &&
- mentionPlainTextIndex + display.length > indexInPlainText
- ) {
- result = mentionPlainTextIndex
- foundMention = true
+ let markupIteratee = (markup, index, mentionPlainTextIndex, id, display, childIndex, lastMentionEndIndex) => {
+ if (mentionPlainTextIndex <= indexInPlainText && mentionPlainTextIndex + display.length > indexInPlainText) {
+ result = mentionPlainTextIndex;
+ foundMention = true;
}
- }
- iterateMentionsMarkup(value, config, markupIteratee)
+ };
+ iterateMentionsMarkup(value, config, markupIteratee);
if (foundMention) {
- return result
+ return result;
}
-}
+};
-export default findStartOfMentionInPlainText
+export default findStartOfMentionInPlainText;
diff --git a/apps/crew/packages/react-mentions/src/utils/findStartOfMentionInPlainText.spec.js b/apps/crew/packages/react-mentions/src/utils/findStartOfMentionInPlainText.spec.js
index 6c78d4141..92ae8462f 100644
--- a/apps/crew/packages/react-mentions/src/utils/findStartOfMentionInPlainText.spec.js
+++ b/apps/crew/packages/react-mentions/src/utils/findStartOfMentionInPlainText.spec.js
@@ -1,10 +1,10 @@
-import findStartOfMentionInPlainText from './findStartOfMentionInPlainText'
-import markupToRegex from './markupToRegex'
+import findStartOfMentionInPlainText from './findStartOfMentionInPlainText';
+import markupToRegex from './markupToRegex';
describe('#findStartOfMentionInPlainText', () => {
- const userMarkup = '@[__display__](user:__id__)'
- const emailMarkup = '@[__display__](email:__id__)'
- const defaultDisplayTransform = (id, display) => display
+ const userMarkup = '@[__display__](user:__id__)';
+ const emailMarkup = '@[__display__](email:__id__)';
+ const defaultDisplayTransform = (id, display) => display;
const config = [
{
markup: userMarkup,
@@ -16,37 +16,24 @@ describe('#findStartOfMentionInPlainText', () => {
regex: markupToRegex(emailMarkup),
displayTransform: defaultDisplayTransform,
},
- ]
+ ];
const value =
- "Hi @[John Doe](user:johndoe), \n\nlet's add @[joe@smoe.com](email:joe@smoe.com) to this conversation..."
- const plainText =
- "Hi John Doe, \n\nlet's add joe@smoe.com to this conversation..."
+ "Hi @[John Doe](user:johndoe), \n\nlet's add @[joe@smoe.com](email:joe@smoe.com) to this conversation...";
+ const plainText = "Hi John Doe, \n\nlet's add joe@smoe.com to this conversation...";
it("should return the index of the mention's first char in the plain text if the passed index lies inside a mention", () => {
- const result = findStartOfMentionInPlainText(
- value,
- config,
- plainText.indexOf('Doe')
- )
- expect(result).toEqual(plainText.indexOf('John Doe'))
- })
+ const result = findStartOfMentionInPlainText(value, config, plainText.indexOf('Doe'));
+ expect(result).toEqual(plainText.indexOf('John Doe'));
+ });
it('should return `undefined`, if it does not lie inside a mention', () => {
- const result = findStartOfMentionInPlainText(
- value,
- config,
- plainText.indexOf('add')
- )
- expect(result).toEqual(undefined)
- })
+ const result = findStartOfMentionInPlainText(value, config, plainText.indexOf('add'));
+ expect(result).toEqual(undefined);
+ });
it("should return the index of the mention's first char if that one is the probe value", () => {
- const result = findStartOfMentionInPlainText(
- value,
- config,
- plainText.indexOf('John')
- )
- expect(result).toEqual(plainText.indexOf('John'))
- })
-})
+ const result = findStartOfMentionInPlainText(value, config, plainText.indexOf('John'));
+ expect(result).toEqual(plainText.indexOf('John'));
+ });
+});
diff --git a/apps/crew/packages/react-mentions/src/utils/getEndOfLastMention.js b/apps/crew/packages/react-mentions/src/utils/getEndOfLastMention.js
index 66a7c242a..6ee34e63f 100644
--- a/apps/crew/packages/react-mentions/src/utils/getEndOfLastMention.js
+++ b/apps/crew/packages/react-mentions/src/utils/getEndOfLastMention.js
@@ -1,11 +1,9 @@
-import getMentions from './getMentions'
+import getMentions from './getMentions';
const getEndOfLastMention = (value, config) => {
- const mentions = getMentions(value, config)
- const lastMention = mentions[mentions.length - 1]
- return lastMention
- ? lastMention.plainTextIndex + lastMention.display.length
- : 0
-}
+ const mentions = getMentions(value, config);
+ const lastMention = mentions[mentions.length - 1];
+ return lastMention ? lastMention.plainTextIndex + lastMention.display.length : 0;
+};
-export default getEndOfLastMention
+export default getEndOfLastMention;
diff --git a/apps/crew/packages/react-mentions/src/utils/getEndOfLastMention.spec.js b/apps/crew/packages/react-mentions/src/utils/getEndOfLastMention.spec.js
index d65172171..eff5da877 100644
--- a/apps/crew/packages/react-mentions/src/utils/getEndOfLastMention.spec.js
+++ b/apps/crew/packages/react-mentions/src/utils/getEndOfLastMention.spec.js
@@ -1,10 +1,10 @@
-import getEndOfLastMention from './getEndOfLastMention'
-import markupToRegex from './markupToRegex'
+import getEndOfLastMention from './getEndOfLastMention';
+import markupToRegex from './markupToRegex';
describe('#getEndOfLastMention', () => {
- const userMarkup = '@[__display__](user:__id__)'
- const emailMarkup = '@[__display__](email:__id__)'
- const defaultDisplayTransform = (id, display) => display
+ const userMarkup = '@[__display__](user:__id__)';
+ const emailMarkup = '@[__display__](email:__id__)';
+ const defaultDisplayTransform = (id, display) => display;
const config = [
{
markup: userMarkup,
@@ -16,28 +16,28 @@ describe('#getEndOfLastMention', () => {
regex: markupToRegex(emailMarkup),
displayTransform: defaultDisplayTransform,
},
- ]
+ ];
const value =
- "Hi @[John Doe](user:johndoe), \n\nlet's add @[joe@smoe.com](email:joe@smoe.com) to this conversation..."
+ "Hi @[John Doe](user:johndoe), \n\nlet's add @[joe@smoe.com](email:joe@smoe.com) to this conversation...";
- const displayTransform = id => `<--${id}-->`
+ const displayTransform = (id) => `<--${id}-->`;
it('should return the end index of the last mention in the plain text', () => {
- const index = getEndOfLastMention(value, config)
- expect(index).toEqual(37)
- })
+ const index = getEndOfLastMention(value, config);
+ expect(index).toEqual(37);
+ });
it('should take into account the displayTransform', () => {
const index = getEndOfLastMention(
value,
- config.map(c => ({ ...c, displayTransform }))
- )
- expect(index).toEqual(48)
- })
+ config.map((c) => ({ ...c, displayTransform })),
+ );
+ expect(index).toEqual(48);
+ });
it('should return 0 if there is no mention', () => {
- const index = getEndOfLastMention('No mentions to be found here', config)
- expect(index).toEqual(0)
- })
-})
+ const index = getEndOfLastMention('No mentions to be found here', config);
+ expect(index).toEqual(0);
+ });
+});
diff --git a/apps/crew/packages/react-mentions/src/utils/getMentions.js b/apps/crew/packages/react-mentions/src/utils/getMentions.js
index ad931ac8a..165a1981d 100644
--- a/apps/crew/packages/react-mentions/src/utils/getMentions.js
+++ b/apps/crew/packages/react-mentions/src/utils/getMentions.js
@@ -1,21 +1,17 @@
-import iterateMentionsMarkup from './iterateMentionsMarkup'
+import iterateMentionsMarkup from './iterateMentionsMarkup';
const getMentions = (value, config) => {
- const mentions = []
- iterateMentionsMarkup(
- value,
- config,
- (match, index, plainTextIndex, id, display, childIndex, start) => {
- mentions.push({
- id: id,
- display: display,
- childIndex: childIndex,
- index: index,
- plainTextIndex: plainTextIndex,
- })
- }
- )
- return mentions
-}
+ const mentions = [];
+ iterateMentionsMarkup(value, config, (match, index, plainTextIndex, id, display, childIndex, start) => {
+ mentions.push({
+ id: id,
+ display: display,
+ childIndex: childIndex,
+ index: index,
+ plainTextIndex: plainTextIndex,
+ });
+ });
+ return mentions;
+};
-export default getMentions
+export default getMentions;
diff --git a/apps/crew/packages/react-mentions/src/utils/getMentions.spec.js b/apps/crew/packages/react-mentions/src/utils/getMentions.spec.js
index ac733798c..a9a1e95ff 100644
--- a/apps/crew/packages/react-mentions/src/utils/getMentions.spec.js
+++ b/apps/crew/packages/react-mentions/src/utils/getMentions.spec.js
@@ -1,10 +1,10 @@
-import getMentions from './getMentions'
-import markupToRegex from './markupToRegex'
+import getMentions from './getMentions';
+import markupToRegex from './markupToRegex';
describe('#getMentions', () => {
- const userMarkup = '@[__display__](user:__id__)'
- const emailMarkup = '@[__display__](email:__id__)'
- const defaultDisplayTransform = (id, display) => display
+ const userMarkup = '@[__display__](user:__id__)';
+ const emailMarkup = '@[__display__](email:__id__)';
+ const defaultDisplayTransform = (id, display) => display;
const config = [
{
markup: userMarkup,
@@ -16,15 +16,15 @@ describe('#getMentions', () => {
regex: markupToRegex(emailMarkup),
displayTransform: defaultDisplayTransform,
},
- ]
+ ];
const value =
- "Hi @[John Doe](user:johndoe), \n\nlet's add @[joe@smoe.com](email:joe@smoe.com) to this conversation..."
+ "Hi @[John Doe](user:johndoe), \n\nlet's add @[joe@smoe.com](email:joe@smoe.com) to this conversation...";
- const displayTransform = id => `<--${id}-->`
+ const displayTransform = (id) => `<--${id}-->`;
it('should return an array of all mentions in the provided value', () => {
- const mentions = getMentions(value, config)
+ const mentions = getMentions(value, config);
expect(mentions).toEqual([
{
id: 'johndoe',
@@ -40,14 +40,14 @@ describe('#getMentions', () => {
index: 42,
plainTextIndex: 25,
},
- ])
- })
+ ]);
+ });
it('should take into account the displayTransform if passed', () => {
const mentions = getMentions(
value,
- config.map(c => ({ ...c, displayTransform }))
- )
+ config.map((c) => ({ ...c, displayTransform })),
+ );
expect(mentions).toEqual([
{
id: 'johndoe',
@@ -63,6 +63,6 @@ describe('#getMentions', () => {
index: 42,
plainTextIndex: 30,
},
- ])
- })
-})
+ ]);
+ });
+});
diff --git a/apps/crew/packages/react-mentions/src/utils/getPlainText.js b/apps/crew/packages/react-mentions/src/utils/getPlainText.js
index e91e2aeb7..faeb1e5e8 100644
--- a/apps/crew/packages/react-mentions/src/utils/getPlainText.js
+++ b/apps/crew/packages/react-mentions/src/utils/getPlainText.js
@@ -1,18 +1,18 @@
-import iterateMentionsMarkup from './iterateMentionsMarkup'
+import iterateMentionsMarkup from './iterateMentionsMarkup';
const getPlainText = (value, config) => {
- let result = ''
+ let result = '';
iterateMentionsMarkup(
value,
config,
(match, index, plainTextIndex, id, display) => {
- result += display
+ result += display;
},
- plainText => {
- result += plainText
- }
- )
- return result
-}
+ (plainText) => {
+ result += plainText;
+ },
+ );
+ return result;
+};
-export default getPlainText
+export default getPlainText;
diff --git a/apps/crew/packages/react-mentions/src/utils/getPlainText.spec.js b/apps/crew/packages/react-mentions/src/utils/getPlainText.spec.js
index df33535c7..5a33ee7f7 100644
--- a/apps/crew/packages/react-mentions/src/utils/getPlainText.spec.js
+++ b/apps/crew/packages/react-mentions/src/utils/getPlainText.spec.js
@@ -1,10 +1,10 @@
-import getPlainText from './getPlainText'
-import markupToRegex from './markupToRegex'
+import getPlainText from './getPlainText';
+import markupToRegex from './markupToRegex';
describe('#getPlainText', () => {
- const userMarkup = '@[__display__](user:__id__)'
- const emailMarkup = '@[__display__](email:__id__)'
- const defaultDisplayTransform = (id, display) => display
+ const userMarkup = '@[__display__](user:__id__)';
+ const emailMarkup = '@[__display__](email:__id__)';
+ const defaultDisplayTransform = (id, display) => display;
const config = [
{
markup: userMarkup,
@@ -16,25 +16,21 @@ describe('#getPlainText', () => {
regex: markupToRegex(emailMarkup),
displayTransform: defaultDisplayTransform,
},
- ]
+ ];
const value =
- "Hi @[John Doe](user:johndoe), \n\nlet's add @[joe@smoe.com](email:joe@smoe.com) to this conversation..."
+ "Hi @[John Doe](user:johndoe), \n\nlet's add @[joe@smoe.com](email:joe@smoe.com) to this conversation...";
it('should replace markup with the correct display values ', () => {
- expect(getPlainText(value, config)).toEqual(
- "Hi John Doe, \n\nlet's add joe@smoe.com to this conversation..."
- )
- })
+ expect(getPlainText(value, config)).toEqual("Hi John Doe, \n\nlet's add joe@smoe.com to this conversation...");
+ });
it('should take the displayTransform into account', () => {
expect(
getPlainText(
value,
- config.map(c => ({ ...c, displayTransform: id => `<--${id}-->` }))
- )
- ).toEqual(
- "Hi <--johndoe-->, \n\nlet's add <--joe@smoe.com--> to this conversation..."
- )
- })
-})
+ config.map((c) => ({ ...c, displayTransform: (id) => `<--${id}-->` })),
+ ),
+ ).toEqual("Hi <--johndoe-->, \n\nlet's add <--joe@smoe.com--> to this conversation...");
+ });
+});
diff --git a/apps/crew/packages/react-mentions/src/utils/getSubstringIndex.js b/apps/crew/packages/react-mentions/src/utils/getSubstringIndex.js
index 069d7b610..fd0322f06 100644
--- a/apps/crew/packages/react-mentions/src/utils/getSubstringIndex.js
+++ b/apps/crew/packages/react-mentions/src/utils/getSubstringIndex.js
@@ -1,26 +1,23 @@
-import lettersDiacritics from './diacritics'
+import lettersDiacritics from './diacritics';
-const removeAccents = str => {
- let formattedStr = str
+const removeAccents = (str) => {
+ let formattedStr = str;
- lettersDiacritics.forEach(letterDiacritics => {
- formattedStr = formattedStr.replace(
- letterDiacritics.letters,
- letterDiacritics.base
- )
- })
+ lettersDiacritics.forEach((letterDiacritics) => {
+ formattedStr = formattedStr.replace(letterDiacritics.letters, letterDiacritics.base);
+ });
- return formattedStr
-}
+ return formattedStr;
+};
-export const normalizeString = str => removeAccents(str).toLowerCase()
+export const normalizeString = (str) => removeAccents(str).toLowerCase();
const getSubstringIndex = (str, substr, ignoreAccents) => {
if (!ignoreAccents) {
- return str.toLowerCase().indexOf(substr.toLowerCase())
+ return str.toLowerCase().indexOf(substr.toLowerCase());
}
- return normalizeString(str).indexOf(normalizeString(substr))
-}
+ return normalizeString(str).indexOf(normalizeString(substr));
+};
-export default getSubstringIndex
+export default getSubstringIndex;
diff --git a/apps/crew/packages/react-mentions/src/utils/getSubstringIndex.spec.js b/apps/crew/packages/react-mentions/src/utils/getSubstringIndex.spec.js
index ef8535ede..af745f8ac 100644
--- a/apps/crew/packages/react-mentions/src/utils/getSubstringIndex.spec.js
+++ b/apps/crew/packages/react-mentions/src/utils/getSubstringIndex.spec.js
@@ -1,38 +1,19 @@
-import getSubstringIndex, { normalizeString } from './getSubstringIndex'
+import getSubstringIndex, { normalizeString } from './getSubstringIndex';
describe('#normalizeString', () => {
it('Should return the string in lowercase without accents', () => {
- expect(normalizeString('Aurait-Il été ãdOré là-bas ?')).toEqual(
- 'aurait-il ete adore la-bas ?'
- )
- })
-})
+ expect(normalizeString('Aurait-Il été ãdOré là-bas ?')).toEqual('aurait-il ete adore la-bas ?');
+ });
+});
describe('#getSubstringIndex', () => {
it('Should return the index of the substring or -1 ignoring only the case', () => {
- expect(
- getSubstringIndex('Aurait-Il été ãdOré là-bas ?', 'aurait-il')
- ).toEqual(0)
- expect(getSubstringIndex('Aurait-Il été ãdOré là-bas ?', 'adore')).toEqual(
- -1
- )
- expect(
- getSubstringIndex(
- 'Aurait-Il été ãdOré là-bas ?',
- 'not existing substring'
- )
- ).toEqual(-1)
- })
+ expect(getSubstringIndex('Aurait-Il été ãdOré là-bas ?', 'aurait-il')).toEqual(0);
+ expect(getSubstringIndex('Aurait-Il été ãdOré là-bas ?', 'adore')).toEqual(-1);
+ expect(getSubstringIndex('Aurait-Il été ãdOré là-bas ?', 'not existing substring')).toEqual(-1);
+ });
it('Should return the index of the substring or -1 ignoring the accents and the case', () => {
- expect(
- getSubstringIndex('Aurait-Il été ãdOré là-bas ?', 'adore', true)
- ).toEqual(14)
- expect(
- getSubstringIndex(
- 'Aurait-Il été ãdOré là-bas ?',
- 'not existing substring',
- true
- )
- ).toEqual(-1)
- })
-})
+ expect(getSubstringIndex('Aurait-Il été ãdOré là-bas ?', 'adore', true)).toEqual(14);
+ expect(getSubstringIndex('Aurait-Il été ãdOré là-bas ?', 'not existing substring', true)).toEqual(-1);
+ });
+});
diff --git a/apps/crew/packages/react-mentions/src/utils/getSuggestionHtmlId.js b/apps/crew/packages/react-mentions/src/utils/getSuggestionHtmlId.js
index 90ed9071c..76486e669 100644
--- a/apps/crew/packages/react-mentions/src/utils/getSuggestionHtmlId.js
+++ b/apps/crew/packages/react-mentions/src/utils/getSuggestionHtmlId.js
@@ -1,3 +1,3 @@
-const getSuggestionHtmlId = (prefix, id) => `${prefix}-${id}`
+const getSuggestionHtmlId = (prefix, id) => `${prefix}-${id}`;
-export default getSuggestionHtmlId
\ No newline at end of file
+export default getSuggestionHtmlId;
diff --git a/apps/crew/packages/react-mentions/src/utils/getSuggestionHtmlId.spec.js b/apps/crew/packages/react-mentions/src/utils/getSuggestionHtmlId.spec.js
index d7b2a17bc..5d3aa341c 100644
--- a/apps/crew/packages/react-mentions/src/utils/getSuggestionHtmlId.spec.js
+++ b/apps/crew/packages/react-mentions/src/utils/getSuggestionHtmlId.spec.js
@@ -1,10 +1,8 @@
-import getSuggestionHtmlId from './getSuggestionHtmlId'
+import getSuggestionHtmlId from './getSuggestionHtmlId';
describe('#getSuggestionHtmlId', () => {
it('Should build a string from provided prefix and id', () => {
- expect(
- getSuggestionHtmlId('listid1', 'itemid1')
- ).toEqual('listid1-itemid1')
- expect(getSuggestionHtmlId('listid2', 'itemid2')).toEqual('listid2-itemid2')
- })
-})
+ expect(getSuggestionHtmlId('listid1', 'itemid1')).toEqual('listid1-itemid1');
+ expect(getSuggestionHtmlId('listid2', 'itemid2')).toEqual('listid2-itemid2');
+ });
+});
diff --git a/apps/crew/packages/react-mentions/src/utils/index.js b/apps/crew/packages/react-mentions/src/utils/index.js
index eb1193dfd..31212a852 100644
--- a/apps/crew/packages/react-mentions/src/utils/index.js
+++ b/apps/crew/packages/react-mentions/src/utils/index.js
@@ -1,22 +1,20 @@
-export { default as escapeRegex } from './escapeRegex'
-export { default as getPlainText } from './getPlainText'
-export { default as applyChangeToValue } from './applyChangeToValue'
-export {
- default as findStartOfMentionInPlainText,
-} from './findStartOfMentionInPlainText'
-export { default as getMentions } from './getMentions'
-export { default as getSuggestionHtmlId } from './getSuggestionHtmlId'
-export { default as countSuggestions } from './countSuggestions'
-export { default as getEndOfLastMention } from './getEndOfLastMention'
-export { default as mapPlainTextIndex } from './mapPlainTextIndex'
-export { default as readConfigFromChildren } from './readConfigFromChildren'
-export { default as spliceString } from './spliceString'
-export { default as makeMentionsMarkup } from './makeMentionsMarkup'
-export { default as iterateMentionsMarkup } from './iterateMentionsMarkup'
-export { default as getSubstringIndex } from './getSubstringIndex'
-export { default as isIE } from './isIE'
-export { default as isNumber } from './isNumber'
-export { default as merge } from './merge'
-export { default as omit } from './omit'
-export { default as keys } from './keys'
-export { default as defaultStyle } from './defaultStyle'
+export { default as escapeRegex } from './escapeRegex';
+export { default as getPlainText } from './getPlainText';
+export { default as applyChangeToValue } from './applyChangeToValue';
+export { default as findStartOfMentionInPlainText } from './findStartOfMentionInPlainText';
+export { default as getMentions } from './getMentions';
+export { default as getSuggestionHtmlId } from './getSuggestionHtmlId';
+export { default as countSuggestions } from './countSuggestions';
+export { default as getEndOfLastMention } from './getEndOfLastMention';
+export { default as mapPlainTextIndex } from './mapPlainTextIndex';
+export { default as readConfigFromChildren } from './readConfigFromChildren';
+export { default as spliceString } from './spliceString';
+export { default as makeMentionsMarkup } from './makeMentionsMarkup';
+export { default as iterateMentionsMarkup } from './iterateMentionsMarkup';
+export { default as getSubstringIndex } from './getSubstringIndex';
+export { default as isIE } from './isIE';
+export { default as isNumber } from './isNumber';
+export { default as merge } from './merge';
+export { default as omit } from './omit';
+export { default as keys } from './keys';
+export { default as defaultStyle } from './defaultStyle';
diff --git a/apps/crew/packages/react-mentions/src/utils/isIE.js b/apps/crew/packages/react-mentions/src/utils/isIE.js
index 9c34a7312..c8af3e47c 100644
--- a/apps/crew/packages/react-mentions/src/utils/isIE.js
+++ b/apps/crew/packages/react-mentions/src/utils/isIE.js
@@ -1,3 +1,3 @@
-const isIE = () => !!document.documentMode
+const isIE = () => !!document.documentMode;
-export default isIE
+export default isIE;
diff --git a/apps/crew/packages/react-mentions/src/utils/isNumber.js b/apps/crew/packages/react-mentions/src/utils/isNumber.js
index 0cff7030e..693bc2c16 100644
--- a/apps/crew/packages/react-mentions/src/utils/isNumber.js
+++ b/apps/crew/packages/react-mentions/src/utils/isNumber.js
@@ -1,3 +1,3 @@
-const isNumber = val => typeof val === 'number'
+const isNumber = (val) => typeof val === 'number';
-export default isNumber
+export default isNumber;
diff --git a/apps/crew/packages/react-mentions/src/utils/isNumber.spec.js b/apps/crew/packages/react-mentions/src/utils/isNumber.spec.js
index 2de3feafc..d7e2206c0 100644
--- a/apps/crew/packages/react-mentions/src/utils/isNumber.spec.js
+++ b/apps/crew/packages/react-mentions/src/utils/isNumber.spec.js
@@ -1,29 +1,20 @@
-import isNumber from './isNumber'
+import isNumber from './isNumber';
describe('#isNumber', () => {
- const passingValues = [1, 0, NaN]
- const failingValues = [
- [1, 2, 3],
- Object(0),
- true,
- new Date(),
- new Error(),
- { a: 1 },
- /x/,
- 'a',
- ]
+ const passingValues = [1, 0, NaN];
+ const failingValues = [[1, 2, 3], Object(0), true, new Date(), new Error(), { a: 1 }, /x/, 'a'];
- passingValues.forEach(value => {
+ passingValues.forEach((value) => {
it(`should return "true" for numbers: ${value}`, () => {
- const result = isNumber(value)
- expect(result).toBe(true)
- })
- })
+ const result = isNumber(value);
+ expect(result).toBe(true);
+ });
+ });
- failingValues.forEach(value => {
+ failingValues.forEach((value) => {
it(`should return "false" for non-numbers: ${value}`, () => {
- const result = isNumber(value)
- expect(result).toBe(false)
- })
- })
-})
+ const result = isNumber(value);
+ expect(result).toBe(false);
+ });
+ });
+});
diff --git a/apps/crew/packages/react-mentions/src/utils/isPlainObject.js b/apps/crew/packages/react-mentions/src/utils/isPlainObject.js
index 956faa782..ef39b5c68 100644
--- a/apps/crew/packages/react-mentions/src/utils/isPlainObject.js
+++ b/apps/crew/packages/react-mentions/src/utils/isPlainObject.js
@@ -1,4 +1,3 @@
-const isPlainObject = obj =>
- !(obj instanceof Date) && obj === Object(obj) && !Array.isArray(obj)
+const isPlainObject = (obj) => !(obj instanceof Date) && obj === Object(obj) && !Array.isArray(obj);
-export default isPlainObject
+export default isPlainObject;
diff --git a/apps/crew/packages/react-mentions/src/utils/isPlainObject.spec.js b/apps/crew/packages/react-mentions/src/utils/isPlainObject.spec.js
index 5cc10c197..33586fd65 100644
--- a/apps/crew/packages/react-mentions/src/utils/isPlainObject.spec.js
+++ b/apps/crew/packages/react-mentions/src/utils/isPlainObject.spec.js
@@ -1,7 +1,7 @@
-import isPlainObject from './isPlainObject'
+import isPlainObject from './isPlainObject';
describe('isPlainObject', () => {
- ;[
+ [
{ input: {}, expected: true },
{ input: { a: 1 }, expected: true },
{ input: new Object(), expected: true }, // eslint-disable-line no-new-object
@@ -10,9 +10,9 @@ describe('isPlainObject', () => {
{ input: 2, expected: false },
{ input: 'Name', expected: false },
{ input: new Date(), expected: false },
- ].forEach(x => {
+ ].forEach((x) => {
it('should check if input is object', () => {
- expect(isPlainObject(x.input)).toBe(x.expected)
- })
- })
-})
+ expect(isPlainObject(x.input)).toBe(x.expected);
+ });
+ });
+});
diff --git a/apps/crew/packages/react-mentions/src/utils/iterateMentionsMarkup.js b/apps/crew/packages/react-mentions/src/utils/iterateMentionsMarkup.js
index 914e35f2d..3d77b6185 100644
--- a/apps/crew/packages/react-mentions/src/utils/iterateMentionsMarkup.js
+++ b/apps/crew/packages/react-mentions/src/utils/iterateMentionsMarkup.js
@@ -1,62 +1,49 @@
-import findPositionOfCapturingGroup from './findPositionOfCapturingGroup'
-import combineRegExps from './combineRegExps'
-import countPlaceholders from './countPlaceholders'
+import findPositionOfCapturingGroup from './findPositionOfCapturingGroup';
+import combineRegExps from './combineRegExps';
+import countPlaceholders from './countPlaceholders';
-const emptyFn = () => {}
+const emptyFn = () => {};
// Finds all occurrences of the markup in the value and calls the `markupIteratee` callback for each of them.
// The optional `textIteratee` callback is called for each plain text ranges in between these markup occurrences.
-const iterateMentionsMarkup = (
- value,
- config,
- markupIteratee,
- textIteratee = emptyFn
-) => {
- const regex = combineRegExps(config.map(c => c.regex))
-
- let accOffset = 2 // first is whole match, second is the for the capturing group of first regexp component
+const iterateMentionsMarkup = (value, config, markupIteratee, textIteratee = emptyFn) => {
+ const regex = combineRegExps(config.map((c) => c.regex));
+
+ let accOffset = 2; // first is whole match, second is the for the capturing group of first regexp component
const captureGroupOffsets = config.map(({ markup }) => {
- const result = accOffset
+ const result = accOffset;
// + 1 is for the capturing group we add around each regexp component in combineRegExps
- accOffset += countPlaceholders(markup) + 1
- return result
- })
+ accOffset += countPlaceholders(markup) + 1;
+ return result;
+ });
- let match
- let start = 0
- let currentPlainTextIndex = 0
+ let match;
+ let start = 0;
+ let currentPlainTextIndex = 0;
// detect all mention markup occurrences in the value and iterate the matches
while ((match = regex.exec(value)) !== null) {
- const offset = captureGroupOffsets.find(o => !!match[o]) // eslint-disable-line no-loop-func
- const mentionChildIndex = captureGroupOffsets.indexOf(offset)
- const { markup, displayTransform } = config[mentionChildIndex]
- const idPos = offset + findPositionOfCapturingGroup(markup, 'id')
- const displayPos = offset + findPositionOfCapturingGroup(markup, 'display')
-
- const id = match[idPos]
- const display = displayTransform(id, match[displayPos])
-
- let substr = value.substring(start, match.index)
- textIteratee(substr, start, currentPlainTextIndex)
- currentPlainTextIndex += substr.length
-
- markupIteratee(
- match[0],
- match.index,
- currentPlainTextIndex,
- id,
- display,
- mentionChildIndex,
- start
- )
- currentPlainTextIndex += display.length
- start = regex.lastIndex
+ const offset = captureGroupOffsets.find((o) => !!match[o]); // eslint-disable-line no-loop-func
+ const mentionChildIndex = captureGroupOffsets.indexOf(offset);
+ const { markup, displayTransform } = config[mentionChildIndex];
+ const idPos = offset + findPositionOfCapturingGroup(markup, 'id');
+ const displayPos = offset + findPositionOfCapturingGroup(markup, 'display');
+
+ const id = match[idPos];
+ const display = displayTransform(id, match[displayPos]);
+
+ let substr = value.substring(start, match.index);
+ textIteratee(substr, start, currentPlainTextIndex);
+ currentPlainTextIndex += substr.length;
+
+ markupIteratee(match[0], match.index, currentPlainTextIndex, id, display, mentionChildIndex, start);
+ currentPlainTextIndex += display.length;
+ start = regex.lastIndex;
}
if (start < value.length) {
- textIteratee(value.substring(start), start, currentPlainTextIndex)
+ textIteratee(value.substring(start), start, currentPlainTextIndex);
}
-}
+};
-export default iterateMentionsMarkup
+export default iterateMentionsMarkup;
diff --git a/apps/crew/packages/react-mentions/src/utils/iterateMentionsMarkup.spec.js b/apps/crew/packages/react-mentions/src/utils/iterateMentionsMarkup.spec.js
index 92681462f..ac2121932 100644
--- a/apps/crew/packages/react-mentions/src/utils/iterateMentionsMarkup.spec.js
+++ b/apps/crew/packages/react-mentions/src/utils/iterateMentionsMarkup.spec.js
@@ -1,10 +1,10 @@
-import iterateMentionsMarkup from './iterateMentionsMarkup'
-import markupToRegex from './markupToRegex'
+import iterateMentionsMarkup from './iterateMentionsMarkup';
+import markupToRegex from './markupToRegex';
describe('#iterateMentionsMarkup', () => {
- const userMarkup = '@[__display__](user:__id__)'
- const emailMarkup = '@[__display__](email:__id__)'
- const defaultDisplayTransform = (id, display) => display
+ const userMarkup = '@[__display__](user:__id__)';
+ const emailMarkup = '@[__display__](email:__id__)';
+ const defaultDisplayTransform = (id, display) => display;
const config = [
{
markup: userMarkup,
@@ -16,22 +16,20 @@ describe('#iterateMentionsMarkup', () => {
regex: markupToRegex(emailMarkup),
displayTransform: defaultDisplayTransform,
},
- ]
+ ];
const value =
- "Hi @[John Doe](user:johndoe), \n\nlet's add @[joe@smoe.com](email:joe@smoe.com) to this conversation..."
- const plainText =
- "Hi John Doe, \n\nlet's add joe@smoe.com to this conversation..."
+ "Hi @[John Doe](user:johndoe), \n\nlet's add @[joe@smoe.com](email:joe@smoe.com) to this conversation...";
+ const plainText = "Hi John Doe, \n\nlet's add joe@smoe.com to this conversation...";
- const displayTransform = id => `<--${id}-->`
- const plainTextDisplayTransform =
- "Hi <--johndoe-->, \n\nlet's add <--joe@smoe.com--> to this conversation..."
+ const displayTransform = (id) => `<--${id}-->`;
+ const plainTextDisplayTransform = "Hi <--johndoe-->, \n\nlet's add <--joe@smoe.com--> to this conversation...";
it('should call the `markupIteratee` for every markup occurrence', () => {
- const markupIteratee = jest.fn()
- iterateMentionsMarkup(value, config, markupIteratee)
+ const markupIteratee = jest.fn();
+ iterateMentionsMarkup(value, config, markupIteratee);
- expect(markupIteratee.mock.calls.length).toEqual(2)
+ expect(markupIteratee.mock.calls.length).toEqual(2);
expect(markupIteratee).toHaveBeenCalledWith(
'@[John Doe](user:johndoe)',
value.indexOf('@[John Doe](user:johndoe)'),
@@ -39,8 +37,8 @@ describe('#iterateMentionsMarkup', () => {
'johndoe',
'John Doe',
0,
- 0
- )
+ 0,
+ );
expect(markupIteratee).toHaveBeenCalledWith(
'@[joe@smoe.com](email:joe@smoe.com)',
value.indexOf('@[joe@smoe.com](email:joe@smoe.com)'),
@@ -48,23 +46,21 @@ describe('#iterateMentionsMarkup', () => {
'joe@smoe.com',
'joe@smoe.com',
1,
- value.indexOf('@[John Doe](user:johndoe)') +
- '@[John Doe](user:johndoe)'.length
- )
- })
+ value.indexOf('@[John Doe](user:johndoe)') + '@[John Doe](user:johndoe)'.length,
+ );
+ });
it('should call the `markupIteratee` with the correct plain text indices when a display transform is used', () => {
- const markupIteratee = jest.fn()
- const displayTransform = (id, display) => `[${display}]`
+ const markupIteratee = jest.fn();
+ const displayTransform = (id, display) => `[${display}]`;
iterateMentionsMarkup(
value,
- config.map(c => ({ ...c, displayTransform })),
- markupIteratee
- )
- const plainTextWithDisplayTransform =
- "Hi [John Doe], \n\nlet's add [joe@smoe.com] to this conversation..."
+ config.map((c) => ({ ...c, displayTransform })),
+ markupIteratee,
+ );
+ const plainTextWithDisplayTransform = "Hi [John Doe], \n\nlet's add [joe@smoe.com] to this conversation...";
- expect(markupIteratee.mock.calls.length).toEqual(2)
+ expect(markupIteratee.mock.calls.length).toEqual(2);
expect(markupIteratee).toHaveBeenCalledWith(
'@[John Doe](user:johndoe)',
value.indexOf('@[John Doe](user:johndoe)'),
@@ -72,8 +68,8 @@ describe('#iterateMentionsMarkup', () => {
'johndoe',
'[John Doe]',
0,
- 0
- )
+ 0,
+ );
expect(markupIteratee).toHaveBeenCalledWith(
'@[joe@smoe.com](email:joe@smoe.com)',
value.indexOf('@[joe@smoe.com](email:joe@smoe.com)'),
@@ -81,38 +77,37 @@ describe('#iterateMentionsMarkup', () => {
'joe@smoe.com',
'[joe@smoe.com]',
1,
- value.indexOf('@[John Doe](user:johndoe)') +
- '@[John Doe](user:johndoe)'.length
- )
- })
+ value.indexOf('@[John Doe](user:johndoe)') + '@[John Doe](user:johndoe)'.length,
+ );
+ });
it('should call the `textIteratee` for all plain text sub string between markups', () => {
- const textIteratee = jest.fn()
- iterateMentionsMarkup(value, config, () => {}, textIteratee)
+ const textIteratee = jest.fn();
+ iterateMentionsMarkup(value, config, () => {}, textIteratee);
- expect(textIteratee.mock.calls.length).toEqual(3)
- expect(textIteratee).toHaveBeenCalledWith('Hi ', 0, 0)
+ expect(textIteratee.mock.calls.length).toEqual(3);
+ expect(textIteratee).toHaveBeenCalledWith('Hi ', 0, 0);
expect(textIteratee).toHaveBeenCalledWith(
", \n\nlet's add ",
value.indexOf(", \n\nlet's add "),
- plainText.indexOf(", \n\nlet's add ")
- )
+ plainText.indexOf(", \n\nlet's add "),
+ );
expect(textIteratee).toHaveBeenCalledWith(
' to this conversation...',
value.indexOf(' to this conversation...'),
- plainText.indexOf(' to this conversation...')
- )
- })
+ plainText.indexOf(' to this conversation...'),
+ );
+ });
it('should call the `markupIteratee` for every markup occurrence with display transform', () => {
- const markupIteratee = jest.fn()
+ const markupIteratee = jest.fn();
iterateMentionsMarkup(
value,
- config.map(c => ({ ...c, displayTransform })),
- markupIteratee
- )
+ config.map((c) => ({ ...c, displayTransform })),
+ markupIteratee,
+ );
- expect(markupIteratee.mock.calls.length).toEqual(2)
+ expect(markupIteratee.mock.calls.length).toEqual(2);
expect(markupIteratee).toHaveBeenCalledWith(
'@[John Doe](user:johndoe)',
value.indexOf('@[John Doe](user:johndoe)'),
@@ -120,8 +115,8 @@ describe('#iterateMentionsMarkup', () => {
'johndoe',
'<--johndoe-->',
0,
- 0
- )
+ 0,
+ );
expect(markupIteratee).toHaveBeenCalledWith(
'@[joe@smoe.com](email:joe@smoe.com)',
value.indexOf('@[joe@smoe.com](email:joe@smoe.com)'),
@@ -129,31 +124,30 @@ describe('#iterateMentionsMarkup', () => {
'joe@smoe.com',
'<--joe@smoe.com-->',
1,
- value.indexOf('@[John Doe](user:johndoe)') +
- '@[John Doe](user:johndoe)'.length
- )
- })
+ value.indexOf('@[John Doe](user:johndoe)') + '@[John Doe](user:johndoe)'.length,
+ );
+ });
it('should call the `textIteratee` for all plain text sub string between markups with display transform', () => {
- const textIteratee = jest.fn()
+ const textIteratee = jest.fn();
iterateMentionsMarkup(
value,
- config.map(c => ({ ...c, displayTransform })),
+ config.map((c) => ({ ...c, displayTransform })),
() => {},
- textIteratee
- )
+ textIteratee,
+ );
- expect(textIteratee.mock.calls.length).toEqual(3)
- expect(textIteratee).toHaveBeenCalledWith('Hi ', 0, 0)
+ expect(textIteratee.mock.calls.length).toEqual(3);
+ expect(textIteratee).toHaveBeenCalledWith('Hi ', 0, 0);
expect(textIteratee).toHaveBeenCalledWith(
", \n\nlet's add ",
value.indexOf(", \n\nlet's add "),
- plainTextDisplayTransform.indexOf(", \n\nlet's add ")
- )
+ plainTextDisplayTransform.indexOf(", \n\nlet's add "),
+ );
expect(textIteratee).toHaveBeenCalledWith(
' to this conversation...',
value.indexOf(' to this conversation...'),
- plainTextDisplayTransform.indexOf(' to this conversation...')
- )
- })
-})
+ plainTextDisplayTransform.indexOf(' to this conversation...'),
+ );
+ });
+});
diff --git a/apps/crew/packages/react-mentions/src/utils/keys.js b/apps/crew/packages/react-mentions/src/utils/keys.js
index 62bbe37a1..772cefeb1 100644
--- a/apps/crew/packages/react-mentions/src/utils/keys.js
+++ b/apps/crew/packages/react-mentions/src/utils/keys.js
@@ -1,5 +1,5 @@
-const keys = obj => {
- return obj === Object(obj) ? Object.keys(obj) : []
-}
+const keys = (obj) => {
+ return obj === Object(obj) ? Object.keys(obj) : [];
+};
-export default keys
+export default keys;
diff --git a/apps/crew/packages/react-mentions/src/utils/keys.spec.js b/apps/crew/packages/react-mentions/src/utils/keys.spec.js
index a3dcb73b7..1d2831054 100644
--- a/apps/crew/packages/react-mentions/src/utils/keys.spec.js
+++ b/apps/crew/packages/react-mentions/src/utils/keys.spec.js
@@ -1,14 +1,14 @@
-import keys from './keys'
+import keys from './keys';
describe('#keys', () => {
const inputValues = [
{ input: { a: 1, b: 1 }, expected: ['a', 'b'] },
{ input: {}, expected: [] },
- ]
+ ];
- inputValues.forEach(value => {
+ inputValues.forEach((value) => {
it(`should return the string keyed property names of 'object'`, () => {
- expect(keys(value.input)).toEqual(value.expected)
- })
- })
-})
+ expect(keys(value.input)).toEqual(value.expected);
+ });
+ });
+});
diff --git a/apps/crew/packages/react-mentions/src/utils/makeMentionsMarkup.js b/apps/crew/packages/react-mentions/src/utils/makeMentionsMarkup.js
index a7caa8937..b4000484d 100644
--- a/apps/crew/packages/react-mentions/src/utils/makeMentionsMarkup.js
+++ b/apps/crew/packages/react-mentions/src/utils/makeMentionsMarkup.js
@@ -1,9 +1,7 @@
-import PLACEHOLDERS from './placeholders'
+import PLACEHOLDERS from './placeholders';
const makeMentionsMarkup = (markup, id, display) => {
- return markup
- .replace(PLACEHOLDERS.id, id)
- .replace(PLACEHOLDERS.display, display)
-}
+ return markup.replace(PLACEHOLDERS.id, id).replace(PLACEHOLDERS.display, display);
+};
-export default makeMentionsMarkup
+export default makeMentionsMarkup;
diff --git a/apps/crew/packages/react-mentions/src/utils/mapPlainTextIndex.js b/apps/crew/packages/react-mentions/src/utils/mapPlainTextIndex.js
index e6a0b82c8..f3f548407 100644
--- a/apps/crew/packages/react-mentions/src/utils/mapPlainTextIndex.js
+++ b/apps/crew/packages/react-mentions/src/utils/mapPlainTextIndex.js
@@ -1,4 +1,4 @@
-import iterateMentionsMarkup from './iterateMentionsMarkup'
+import iterateMentionsMarkup from './iterateMentionsMarkup';
// For the passed character index in the plain text string, returns the corresponding index
// in the marked up value string.
@@ -7,53 +7,40 @@ import iterateMentionsMarkup from './iterateMentionsMarkup'
// - 'START' to return the index of the mention markup's first char (default)
// - 'END' to return the index after its last char
// - 'NULL' to return null
-const mapPlainTextIndex = (
- value,
- config,
- indexInPlainText,
- inMarkupCorrection = 'START'
-) => {
+const mapPlainTextIndex = (value, config, indexInPlainText, inMarkupCorrection = 'START') => {
if (typeof indexInPlainText !== 'number') {
- return indexInPlainText
+ return indexInPlainText;
}
- let result
+ let result;
let textIteratee = (substr, index, substrPlainTextIndex) => {
- if (result !== undefined) return
+ if (result !== undefined) return;
if (substrPlainTextIndex + substr.length >= indexInPlainText) {
// found the corresponding position in the current plain text range
- result = index + indexInPlainText - substrPlainTextIndex
+ result = index + indexInPlainText - substrPlainTextIndex;
}
- }
- let markupIteratee = (
- markup,
- index,
- mentionPlainTextIndex,
- id,
- display,
- childIndex,
- lastMentionEndIndex
- ) => {
- if (result !== undefined) return
+ };
+ let markupIteratee = (markup, index, mentionPlainTextIndex, id, display, childIndex, lastMentionEndIndex) => {
+ if (result !== undefined) return;
if (mentionPlainTextIndex + display.length > indexInPlainText) {
// found the corresponding position inside current match,
// return the index of the first or after the last char of the matching markup
// depending on whether the `inMarkupCorrection`
if (inMarkupCorrection === 'NULL') {
- result = null
+ result = null;
} else {
- result = index + (inMarkupCorrection === 'END' ? markup.length : 0)
+ result = index + (inMarkupCorrection === 'END' ? markup.length : 0);
}
}
- }
+ };
- iterateMentionsMarkup(value, config, markupIteratee, textIteratee)
+ iterateMentionsMarkup(value, config, markupIteratee, textIteratee);
// when a mention is at the end of the value and we want to get the caret position
// at the end of the string, result is undefined
- return result === undefined ? value.length : result
-}
+ return result === undefined ? value.length : result;
+};
-export default mapPlainTextIndex
+export default mapPlainTextIndex;
diff --git a/apps/crew/packages/react-mentions/src/utils/mapPlainTextIndex.spec.js b/apps/crew/packages/react-mentions/src/utils/mapPlainTextIndex.spec.js
index 9b2b79cef..ede8af039 100644
--- a/apps/crew/packages/react-mentions/src/utils/mapPlainTextIndex.spec.js
+++ b/apps/crew/packages/react-mentions/src/utils/mapPlainTextIndex.spec.js
@@ -1,10 +1,10 @@
-import mapPlainTextIndex from './mapPlainTextIndex'
-import markupToRegex from './markupToRegex'
+import mapPlainTextIndex from './mapPlainTextIndex';
+import markupToRegex from './markupToRegex';
describe('#mapPlainTextIndex', () => {
- const userMarkup = '@[__display__](user:__id__)'
- const emailMarkup = '@[__display__](email:__id__)'
- const defaultDisplayTransform = (id, display) => display
+ const userMarkup = '@[__display__](user:__id__)';
+ const emailMarkup = '@[__display__](email:__id__)';
+ const defaultDisplayTransform = (id, display) => display;
const config = [
{
markup: userMarkup,
@@ -16,111 +16,107 @@ describe('#mapPlainTextIndex', () => {
regex: markupToRegex(emailMarkup),
displayTransform: defaultDisplayTransform,
},
- ]
+ ];
const value =
- "Hi @[John Doe](user:johndoe), \n\nlet's add @[joe@smoe.com](email:joe@smoe.com) to this conversation..."
- const plainText =
- "Hi John Doe, \n\nlet's add joe@smoe.com to this conversation..."
- const plainTextDisplayTransform =
- "Hi <--johndoe-->, \n\nlet's add <--joe@smoe.com--> to this conversation..."
+ "Hi @[John Doe](user:johndoe), \n\nlet's add @[joe@smoe.com](email:joe@smoe.com) to this conversation...";
+ const plainText = "Hi John Doe, \n\nlet's add joe@smoe.com to this conversation...";
+ const plainTextDisplayTransform = "Hi <--johndoe-->, \n\nlet's add <--joe@smoe.com--> to this conversation...";
it('should correctly calculate the index of a character in the plain text between mentions', () => {
- const plainTextIndex = plainText.indexOf("let's add")
- const result = mapPlainTextIndex(value, config, plainTextIndex)
- expect(result).toEqual(value.indexOf("let's add"))
- })
+ const plainTextIndex = plainText.indexOf("let's add");
+ const result = mapPlainTextIndex(value, config, plainTextIndex);
+ expect(result).toEqual(value.indexOf("let's add"));
+ });
it('should correctly calculate the index of a character in the plain text between mentions with display tranform', () => {
- const plainTextIndex = plainTextDisplayTransform.indexOf("let's add")
+ const plainTextIndex = plainTextDisplayTransform.indexOf("let's add");
const result = mapPlainTextIndex(
value,
- config.map(c => ({ ...c, displayTransform: id => `<--${id}-->` })),
+ config.map((c) => ({ ...c, displayTransform: (id) => `<--${id}-->` })),
plainTextIndex,
- 'START'
- )
- expect(result).toEqual(value.indexOf("let's add"))
- })
+ 'START',
+ );
+ expect(result).toEqual(value.indexOf("let's add"));
+ });
it('should correctly calculate the indices of the character in the plain text before the first mention', () => {
- const result = mapPlainTextIndex(value, config, 2)
- expect(result).toEqual(2)
- })
+ const result = mapPlainTextIndex(value, config, 2);
+ expect(result).toEqual(2);
+ });
it('should correctly calculate the index of a character in the plain text after the last mention', () => {
- const plainTextIndex = plainText.indexOf('...')
- const result = mapPlainTextIndex(value, config, plainTextIndex)
- expect(result).toEqual(value.indexOf('...'))
- })
+ const plainTextIndex = plainText.indexOf('...');
+ const result = mapPlainTextIndex(value, config, plainTextIndex);
+ expect(result).toEqual(value.indexOf('...'));
+ });
it('should correctly calculate the index of the first plain text character after a mention', () => {
- const plainTextIndex = plainText.indexOf(',') // first char after John Doe mention
- const result = mapPlainTextIndex(value, config, plainTextIndex)
- expect(result).toEqual(value.indexOf(','))
- })
+ const plainTextIndex = plainText.indexOf(','); // first char after John Doe mention
+ const result = mapPlainTextIndex(value, config, plainTextIndex);
+ expect(result).toEqual(value.indexOf(','));
+ });
it('should return the input index if there are no mentions', () => {
- const result = mapPlainTextIndex(plainText, config, 10)
- expect(result).toEqual(10)
- })
+ const result = mapPlainTextIndex(plainText, config, 10);
+ expect(result).toEqual(10);
+ });
it("should return the index of the corresponding markup's first character if the plain text index lies inside a mention", () => {
// index for first char of markup
- let plainTextIndex = plainText.indexOf('John Doe')
- let result = mapPlainTextIndex(value, config, plainTextIndex)
- expect(result).toEqual(value.indexOf('@[John Doe](user:johndoe)'))
+ let plainTextIndex = plainText.indexOf('John Doe');
+ let result = mapPlainTextIndex(value, config, plainTextIndex);
+ expect(result).toEqual(value.indexOf('@[John Doe](user:johndoe)'));
// index of char inside the markup
- const joeMarkup = '@[joe@smoe.com](email:joe@smoe.com)'
- plainTextIndex = plainText.indexOf('joe@smoe.com') + 3
- result = mapPlainTextIndex(value, config, plainTextIndex)
- expect(result).toEqual(value.indexOf(joeMarkup))
+ const joeMarkup = '@[joe@smoe.com](email:joe@smoe.com)';
+ plainTextIndex = plainText.indexOf('joe@smoe.com') + 3;
+ result = mapPlainTextIndex(value, config, plainTextIndex);
+ expect(result).toEqual(value.indexOf(joeMarkup));
// index of markup's last char
- plainTextIndex =
- plainText.indexOf('joe@smoe.com') + 'joe@smoe.com'.length - 1
- result = mapPlainTextIndex(value, config, plainTextIndex)
- expect(result).toEqual(value.indexOf(joeMarkup))
- })
+ plainTextIndex = plainText.indexOf('joe@smoe.com') + 'joe@smoe.com'.length - 1;
+ result = mapPlainTextIndex(value, config, plainTextIndex);
+ expect(result).toEqual(value.indexOf(joeMarkup));
+ });
it("should return the index of the corresponding markup's last character if the plain text index lies inside a mention and the `inMarkupCorrection` is set to 'END'", () => {
// index for first char of markup
- let plainTextIndex = plainText.indexOf('John Doe')
- let result = mapPlainTextIndex(value, config, plainTextIndex, 'END')
- expect(result).toEqual(value.indexOf('@[John Doe](user:johndoe)'))
+ let plainTextIndex = plainText.indexOf('John Doe');
+ let result = mapPlainTextIndex(value, config, plainTextIndex, 'END');
+ expect(result).toEqual(value.indexOf('@[John Doe](user:johndoe)'));
// index of char inside the markup
- const joeMarkup = '@[joe@smoe.com](email:joe@smoe.com)'
- plainTextIndex = plainText.indexOf('joe@smoe.com') + 3
- result = mapPlainTextIndex(value, config, plainTextIndex, 'END')
- expect(result).toEqual(value.indexOf(joeMarkup) + joeMarkup.length)
+ const joeMarkup = '@[joe@smoe.com](email:joe@smoe.com)';
+ plainTextIndex = plainText.indexOf('joe@smoe.com') + 3;
+ result = mapPlainTextIndex(value, config, plainTextIndex, 'END');
+ expect(result).toEqual(value.indexOf(joeMarkup) + joeMarkup.length);
// index of markup's last char
- plainTextIndex =
- plainText.indexOf('joe@smoe.com') + 'joe@smoe.com'.length - 1
- result = mapPlainTextIndex(value, config, plainTextIndex, 'END')
- expect(result).toEqual(value.indexOf(joeMarkup) + joeMarkup.length)
- })
+ plainTextIndex = plainText.indexOf('joe@smoe.com') + 'joe@smoe.com'.length - 1;
+ result = mapPlainTextIndex(value, config, plainTextIndex, 'END');
+ expect(result).toEqual(value.indexOf(joeMarkup) + joeMarkup.length);
+ });
it("should return `null` if `inMarkupCorrection` is set to 'NULL'", () => {
// index of char inside the markup
- const plainTextIndex = plainText.indexOf('joe@smoe.com') + 3
- const result = mapPlainTextIndex(value, config, plainTextIndex, 'NULL')
- expect(result).toEqual(null)
- })
+ const plainTextIndex = plainText.indexOf('joe@smoe.com') + 3;
+ const result = mapPlainTextIndex(value, config, plainTextIndex, 'NULL');
+ expect(result).toEqual(null);
+ });
it("should return the index of the corresponding markup's first character if the plain text index lies inside a mention with display transform", () => {
// index of char inside the markup
- const joeMarkup = '@[joe@smoe.com](email:joe@smoe.com)'
- const plainTextIndex = plainTextDisplayTransform.indexOf('joe@smoe.com') + 3
- const result = mapPlainTextIndex(value, config, plainTextIndex)
- expect(result).toEqual(value.indexOf(joeMarkup))
- })
+ const joeMarkup = '@[joe@smoe.com](email:joe@smoe.com)';
+ const plainTextIndex = plainTextDisplayTransform.indexOf('joe@smoe.com') + 3;
+ const result = mapPlainTextIndex(value, config, plainTextIndex);
+ expect(result).toEqual(value.indexOf(joeMarkup));
+ });
it('should return the correctly mapped caret position at the end of the string after a mention', () => {
- const value = 'Hi @[John Doe](user:johndoe)'
- const plainText = 'Hi John Doe'
- const result = mapPlainTextIndex(value, config, plainText.length, 'END')
- expect(result).toEqual(value.length)
- })
-})
+ const value = 'Hi @[John Doe](user:johndoe)';
+ const plainText = 'Hi John Doe';
+ const result = mapPlainTextIndex(value, config, plainText.length, 'END');
+ expect(result).toEqual(value.length);
+ });
+});
diff --git a/apps/crew/packages/react-mentions/src/utils/markupToRegex.js b/apps/crew/packages/react-mentions/src/utils/markupToRegex.js
index c2ca234ed..d71e433a7 100644
--- a/apps/crew/packages/react-mentions/src/utils/markupToRegex.js
+++ b/apps/crew/packages/react-mentions/src/utils/markupToRegex.js
@@ -1,28 +1,18 @@
-import PLACEHOLDERS from './placeholders'
-import escapeRegex from './escapeRegex'
+import PLACEHOLDERS from './placeholders';
+import escapeRegex from './escapeRegex';
const markupToRegex = (markup) => {
- const escapedMarkup = escapeRegex(markup)
+ const escapedMarkup = escapeRegex(markup);
- const charAfterDisplay =
- markup[
- markup.indexOf(PLACEHOLDERS.display) + PLACEHOLDERS.display.length
- ]
+ const charAfterDisplay = markup[markup.indexOf(PLACEHOLDERS.display) + PLACEHOLDERS.display.length];
- const charAfterId =
- markup[markup.indexOf(PLACEHOLDERS.id) + PLACEHOLDERS.id.length]
+ const charAfterId = markup[markup.indexOf(PLACEHOLDERS.id) + PLACEHOLDERS.id.length];
- return new RegExp(
- escapedMarkup
- .replace(
- PLACEHOLDERS.display,
- `([^${escapeRegex(charAfterDisplay || '')}]+?)`
- )
- .replace(
- PLACEHOLDERS.id,
- `([^${escapeRegex(charAfterId || '')}]+?)`
- )
- )
-}
+ return new RegExp(
+ escapedMarkup
+ .replace(PLACEHOLDERS.display, `([^${escapeRegex(charAfterDisplay || '')}]+?)`)
+ .replace(PLACEHOLDERS.id, `([^${escapeRegex(charAfterId || '')}]+?)`),
+ );
+};
-export default markupToRegex
+export default markupToRegex;
diff --git a/apps/crew/packages/react-mentions/src/utils/markupToRegex.spec.js b/apps/crew/packages/react-mentions/src/utils/markupToRegex.spec.js
index 5f5ecbbb3..4c2f07d0d 100644
--- a/apps/crew/packages/react-mentions/src/utils/markupToRegex.spec.js
+++ b/apps/crew/packages/react-mentions/src/utils/markupToRegex.spec.js
@@ -1,35 +1,33 @@
-import markupToRegex from './markupToRegex'
+import markupToRegex from './markupToRegex';
describe('#markupToRegex', () => {
it('it should generate a regex that matches the markup for the given pattern', () => {
- const regex = markupToRegex('@[__display__](foo:__id__)')
+ const regex = markupToRegex('@[__display__](foo:__id__)');
- const [mention, display, id] = regex.exec('Hi @[Foo](foo:1), how are you?')
+ const [mention, display, id] = regex.exec('Hi @[Foo](foo:1), how are you?');
- expect(mention).toEqual('@[Foo](foo:1)')
- expect(display).toEqual('Foo')
- expect(id).toEqual('1')
- })
+ expect(mention).toEqual('@[Foo](foo:1)');
+ expect(display).toEqual('Foo');
+ expect(id).toEqual('1');
+ });
it('it should match lazily', () => {
- const regex = markupToRegex('@[__display__](foo:__id__)')
+ const regex = markupToRegex('@[__display__](foo:__id__)');
- const [mention, display, id] = regex.exec(
- 'Hi @[Foo](foo:1)](bar:2), how are you?'
- )
+ const [mention, display, id] = regex.exec('Hi @[Foo](foo:1)](bar:2), how are you?');
- expect(mention).toEqual('@[Foo](foo:1)')
- expect(display).toEqual('Foo')
- expect(id).toEqual('1')
- })
+ expect(mention).toEqual('@[Foo](foo:1)');
+ expect(display).toEqual('Foo');
+ expect(id).toEqual('1');
+ });
it('should only should stop matching the placeholder group once we hit the char after the placeholder in the markup', () => {
- const regex = markupToRegex('@[__display__](foo:__id__)')
- expect(regex.exec('Hi @[Foo], how are you ](foo:1)')).toEqual(null)
- })
-
+ const regex = markupToRegex('@[__display__](foo:__id__)');
+ expect(regex.exec('Hi @[Foo], how are you ](foo:1)')).toEqual(null);
+ });
+
it('should parse regex that doesn\'t use "display"', () => {
- const regex = markupToRegex('[tag id=__id__ /]')
- expect(regex.exec('[tag id=italy /]')[1]).toEqual('italy')
- })
-})
+ const regex = markupToRegex('[tag id=__id__ /]');
+ expect(regex.exec('[tag id=italy /]')[1]).toEqual('italy');
+ });
+});
diff --git a/apps/crew/packages/react-mentions/src/utils/merge.js b/apps/crew/packages/react-mentions/src/utils/merge.js
index 9ac475021..c4206f078 100644
--- a/apps/crew/packages/react-mentions/src/utils/merge.js
+++ b/apps/crew/packages/react-mentions/src/utils/merge.js
@@ -1,9 +1,9 @@
-import mergeDeep from './mergeDeep'
+import mergeDeep from './mergeDeep';
const merge = (target, ...sources) => {
return sources.reduce((t, s) => {
- return mergeDeep(t, s)
- }, target)
-}
+ return mergeDeep(t, s);
+ }, target);
+};
-export default merge
+export default merge;
diff --git a/apps/crew/packages/react-mentions/src/utils/merge.spec.js b/apps/crew/packages/react-mentions/src/utils/merge.spec.js
index 885a579df..1576fe897 100644
--- a/apps/crew/packages/react-mentions/src/utils/merge.spec.js
+++ b/apps/crew/packages/react-mentions/src/utils/merge.spec.js
@@ -1,15 +1,15 @@
-import merge from './merge'
+import merge from './merge';
describe('#merge', () => {
- ;[
+ [
{ input1: { a: 2 }, input2: {}, expected: { a: 2 } },
{ input1: { a: 2 }, input2: { b: 3 }, expected: { a: 2, b: 3 } },
{ input1: {}, input2: { b: 3 }, expected: { b: 3 } },
{ input1: {}, input2: {}, expected: {} },
{ input1: undefined, input2: undefined, expected: {} },
- ].forEach(x => {
+ ].forEach((x) => {
it('should merge values from input1 + input2', () => {
- expect(merge(x.input1, x.input2)).toEqual(x.expected)
- })
- })
-})
+ expect(merge(x.input1, x.input2)).toEqual(x.expected);
+ });
+ });
+});
diff --git a/apps/crew/packages/react-mentions/src/utils/mergeDeep.js b/apps/crew/packages/react-mentions/src/utils/mergeDeep.js
index 907c33442..5345bdd45 100644
--- a/apps/crew/packages/react-mentions/src/utils/mergeDeep.js
+++ b/apps/crew/packages/react-mentions/src/utils/mergeDeep.js
@@ -1,19 +1,19 @@
-import isPlainObject from './isPlainObject'
-import keys from './keys'
+import isPlainObject from './isPlainObject';
+import keys from './keys';
const mergeDeep = (target, source) => {
- let output = Object.assign({}, target)
+ let output = Object.assign({}, target);
if (isPlainObject(target) && isPlainObject(source)) {
- keys(source).forEach(key => {
+ keys(source).forEach((key) => {
if (isPlainObject(source[key])) {
- if (!(key in target)) Object.assign(output, { [key]: source[key] })
- else output[key] = mergeDeep(target[key], source[key])
+ if (!(key in target)) Object.assign(output, { [key]: source[key] });
+ else output[key] = mergeDeep(target[key], source[key]);
} else {
- Object.assign(output, { [key]: source[key] })
+ Object.assign(output, { [key]: source[key] });
}
- })
+ });
}
- return output
-}
+ return output;
+};
-export default mergeDeep
+export default mergeDeep;
diff --git a/apps/crew/packages/react-mentions/src/utils/omit.js b/apps/crew/packages/react-mentions/src/utils/omit.js
index 29dc37887..33e45bc94 100644
--- a/apps/crew/packages/react-mentions/src/utils/omit.js
+++ b/apps/crew/packages/react-mentions/src/utils/omit.js
@@ -1,11 +1,11 @@
const omit = (obj, ...rest) => {
- const keys = [].concat(...rest)
+ const keys = [].concat(...rest);
return Object.keys(obj).reduce((acc, k) => {
if (obj.hasOwnProperty(k) && !keys.includes(k) && obj[k] !== undefined) {
- acc[k] = obj[k]
+ acc[k] = obj[k];
}
- return acc
- }, {})
-}
+ return acc;
+ }, {});
+};
-export default omit
+export default omit;
diff --git a/apps/crew/packages/react-mentions/src/utils/omit.spec.js b/apps/crew/packages/react-mentions/src/utils/omit.spec.js
index c3c906cd9..01cd0fe67 100644
--- a/apps/crew/packages/react-mentions/src/utils/omit.spec.js
+++ b/apps/crew/packages/react-mentions/src/utils/omit.spec.js
@@ -1,4 +1,4 @@
-import omit from './omit'
+import omit from './omit';
describe('#omit', () => {
const values = [
@@ -7,17 +7,15 @@ describe('#omit', () => {
{ input: { a: 2 }, keys: ['b'], expected: { a: 2 } },
{ input: { a: 2, c: 3 }, keys: 'b', expected: { a: 2, c: 3 } },
{ input: { a: 2, b: 3, c: 4 }, keys: ['a', 'c'], expected: { b: 3 } },
- ]
+ ];
- values.forEach(value => {
+ values.forEach((value) => {
it(`should omit values from input with given key `, () => {
- expect(omit(value.input, value.keys, value.other)).toEqual(value.expected)
- })
- })
+ expect(omit(value.input, value.keys, value.other)).toEqual(value.expected);
+ });
+ });
it(`should omit values from input with given mutliples arguments `, () => {
- expect(omit({ a: 2, b: 3 }, 'style', ['someKey', 'otherKey', 'b'])).toEqual(
- { a: 2 }
- )
- })
-})
+ expect(omit({ a: 2, b: 3 }, 'style', ['someKey', 'otherKey', 'b'])).toEqual({ a: 2 });
+ });
+});
diff --git a/apps/crew/packages/react-mentions/src/utils/placeholders.js b/apps/crew/packages/react-mentions/src/utils/placeholders.js
index 57fefe1be..de557b382 100644
--- a/apps/crew/packages/react-mentions/src/utils/placeholders.js
+++ b/apps/crew/packages/react-mentions/src/utils/placeholders.js
@@ -1,4 +1,4 @@
export default {
id: '__id__',
display: '__display__',
-}
+};
diff --git a/apps/crew/packages/react-mentions/src/utils/readConfigFromChildren.js b/apps/crew/packages/react-mentions/src/utils/readConfigFromChildren.js
index 67f3d313e..3000471d2 100644
--- a/apps/crew/packages/react-mentions/src/utils/readConfigFromChildren.js
+++ b/apps/crew/packages/react-mentions/src/utils/readConfigFromChildren.js
@@ -1,30 +1,26 @@
-import { Children } from 'react'
-import invariant from 'invariant'
-import markupToRegex from './markupToRegex'
-import countPlaceholders from './countPlaceholders'
+import { Children } from 'react';
+import invariant from 'invariant';
+import markupToRegex from './markupToRegex';
+import countPlaceholders from './countPlaceholders';
-const readConfigFromChildren = children =>
- Children.toArray(children).map(
- ({ props: { markup, regex, displayTransform } }) => ({
- markup,
- regex: regex
- ? coerceCapturingGroups(regex, markup)
- : markupToRegex(markup),
- displayTransform: displayTransform || ((id, display) => display || id),
- })
- )
+const readConfigFromChildren = (children) =>
+ Children.toArray(children).map(({ props: { markup, regex, displayTransform } }) => ({
+ markup,
+ regex: regex ? coerceCapturingGroups(regex, markup) : markupToRegex(markup),
+ displayTransform: displayTransform || ((id, display) => display || id),
+ }));
// make sure that the custom regex defines the correct number of capturing groups
const coerceCapturingGroups = (regex, markup) => {
- const numberOfGroups = new RegExp(regex.toString() + '|').exec('').length - 1
- const numberOfPlaceholders = countPlaceholders(markup)
+ const numberOfGroups = new RegExp(regex.toString() + '|').exec('').length - 1;
+ const numberOfPlaceholders = countPlaceholders(markup);
invariant(
numberOfGroups === numberOfPlaceholders,
- `Number of capturing groups in RegExp ${regex.toString()} (${numberOfGroups}) does not match the number of placeholders in the markup '${markup}' (${numberOfPlaceholders})`
- )
+ `Number of capturing groups in RegExp ${regex.toString()} (${numberOfGroups}) does not match the number of placeholders in the markup '${markup}' (${numberOfPlaceholders})`,
+ );
- return regex
-}
+ return regex;
+};
-export default readConfigFromChildren
+export default readConfigFromChildren;
diff --git a/apps/crew/packages/react-mentions/src/utils/spliceString.js b/apps/crew/packages/react-mentions/src/utils/spliceString.js
index c86c500a6..5c60bfb9f 100644
--- a/apps/crew/packages/react-mentions/src/utils/spliceString.js
+++ b/apps/crew/packages/react-mentions/src/utils/spliceString.js
@@ -1,4 +1,3 @@
-const spliceString = (str, start, end, insert) =>
- str.substring(0, start) + insert + str.substring(end)
+const spliceString = (str, start, end, insert) => str.substring(0, start) + insert + str.substring(end);
-export default spliceString
+export default spliceString;
diff --git a/apps/crew/packages/react-mentions/src/utils/spliceString.spec.js b/apps/crew/packages/react-mentions/src/utils/spliceString.spec.js
index 2aad23ff0..ffc023999 100644
--- a/apps/crew/packages/react-mentions/src/utils/spliceString.spec.js
+++ b/apps/crew/packages/react-mentions/src/utils/spliceString.spec.js
@@ -1,7 +1,7 @@
-import spliceString from './spliceString'
+import spliceString from './spliceString';
describe('#spliceString', () => {
it('should replace the substring between start and end with the provided insertion', () => {
- expect(spliceString('012345678', 1, 4, 'xx')).toEqual('0xx45678')
- })
-})
+ expect(spliceString('012345678', 1, 4, 'xx')).toEqual('0xx45678');
+ });
+});
diff --git a/apps/crew/pages/_app.tsx b/apps/crew/pages/_app.tsx
index 10aaa78b3..a27286f10 100644
--- a/apps/crew/pages/_app.tsx
+++ b/apps/crew/pages/_app.tsx
@@ -1,4 +1,6 @@
-import { authToken } from '@/store/tokenStore';
+import '@sopt-makers/ui/dist/index.css';
+import '../styles/globals.css';
+
import { getUserProfile } from '@api/user';
import Loader from '@common/loader/Loader';
import { OverlayProvider } from '@hook/useOverlay/OverlayProvider';
@@ -10,7 +12,6 @@ import Header from '@shared/header/Header';
import SEO from '@shared/seo/SEO';
import { setAccessTokens } from '@shared/util/auth';
import { DialogProvider, ToastProvider } from '@sopt-makers/ui';
-import '@sopt-makers/ui/dist/index.css';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { ReactQueryDevtools } from '@tanstack/react-query-devtools';
import { GTM_ID, pageview } from '@util/gtm';
@@ -20,8 +21,10 @@ import Script from 'next/script';
import React, { useEffect, useState } from 'react';
import { styled, theme } from 'stitches.config';
import { globalStyles } from 'styles/globals';
+
+import { authToken } from '@/store/tokenStore';
+
import { ampli } from '../src/ampli';
-import '../styles/globals.css';
function MyApp({ Component, pageProps }: AppProps) {
globalStyles();
@@ -35,7 +38,7 @@ function MyApp({ Component, pageProps }: AppProps) {
staleTime: Infinity,
},
},
- })
+ }),
);
const router = useRouter();
const _authToken = useStore(authToken);
@@ -105,8 +108,8 @@ function MyApp({ Component, pageProps }: AppProps) {