@react-ui-org/react-ui
Advanced tools
Comparing version 0.57.0 to 0.58.0
{ | ||
"name": "@react-ui-org/react-ui", | ||
"description": "React UI is a themeable UI library for React apps.", | ||
"version": "0.57.0", | ||
"version": "0.58.0", | ||
"keywords": [ | ||
@@ -34,2 +34,13 @@ "react", | ||
}, | ||
"devEngines": { | ||
"runtime": { | ||
"name": "node", | ||
"version": "22.x", | ||
"onFail": "error" | ||
}, | ||
"packageManager": { | ||
"name": "npm", | ||
"onFail": "error" | ||
} | ||
}, | ||
"scripts": { | ||
@@ -36,0 +47,0 @@ "build": "webpack --mode=production && webpack --mode=development", |
export const resolveContextOrProp = (contextValue, propValue) => { | ||
if (contextValue != null) { | ||
return contextValue; | ||
// We need to test: | ||
// * `false` - for when the `contextValue` is boolean | ||
// * `null` - for when the `contextValue` is non-boolean | ||
if (contextValue === false || contextValue === null) { | ||
return propValue; | ||
} | ||
return propValue; | ||
return contextValue; | ||
}; |
import PropTypes from 'prop-types'; | ||
import React, { useContext } from 'react'; | ||
import { | ||
RUIContext, | ||
withGlobalProps, | ||
} from '../../provider'; | ||
import { withGlobalProps } from '../../providers/globalProps'; | ||
import { TranslationsContext } from '../../providers/translations'; | ||
import { classNames } from '../../utils/classNames'; | ||
@@ -20,3 +18,3 @@ import { transferProps } from '../../utils/transferProps'; | ||
}) => { | ||
const { translations } = useContext(RUIContext); | ||
const translations = useContext(TranslationsContext); | ||
@@ -23,0 +21,0 @@ return ( |
@@ -44,2 +44,4 @@ # Alert | ||
<strong>Success:</strong> Settings have been successfully saved. | ||
{' '} | ||
<TextLink href="/" label="Undo" /> | ||
</Alert> | ||
@@ -57,3 +59,3 @@ ``` | ||
{' '} | ||
<a href="/">Update my payment options</a> | ||
<TextLink href="/" label="Update my payment options" /> | ||
</Alert> | ||
@@ -73,3 +75,3 @@ ``` | ||
{' '} | ||
<a href="/">Try again</a> | ||
<TextLink href="/" label="Try again" /> | ||
</Alert> | ||
@@ -86,2 +88,4 @@ ``` | ||
anywhere else. | ||
{' '} | ||
<TextLink href="/" label="Help me choose" /> | ||
</Alert> | ||
@@ -97,2 +101,4 @@ ``` | ||
<strong>Info:</strong> This feature depends on user's OS preferences. | ||
{' '} | ||
<TextLink href="/" label="Open preferences" /> | ||
</Alert> | ||
@@ -108,2 +114,4 @@ ``` | ||
<strong>Note:</strong> This feature may not be available in all regions. | ||
{' '} | ||
<TextLink href="/" label="Show list of regions" /> | ||
</Alert> | ||
@@ -120,2 +128,4 @@ ``` | ||
<strong>Light alert:</strong> Stands out on dark backgrounds. | ||
{' '} | ||
<TextLink href="/" label="This is a link" /> | ||
</Alert> | ||
@@ -132,2 +142,4 @@ </docoff-placeholder> | ||
<strong>Dark alert:</strong> Stands out on light backgrounds. | ||
{' '} | ||
<TextLink href="/" label="This is a link" /> | ||
</Alert> | ||
@@ -201,10 +213,10 @@ ``` | ||
| Custom Property | Description | | ||
|------------------------------------------------------|--------------------------------------------------------------| | ||
| `--rui-Alert__padding` | Padding between border and message | | ||
| `--rui-Alert__font-weight` | Message font weight | | ||
| `--rui-Alert__border-width` | Border width | | ||
| `--rui-Alert__border-radius` | Corner radius | | ||
| `--rui-Alert__emphasis__font-weight` | Font weight of text emphasised with `<strong>` | | ||
| `--rui-Alert__stripe__width` | Width of the border at the start of the Alert | | ||
| Custom Property | Description | | ||
|--------------------------------------|------------------------------------------------| | ||
| `--rui-Alert__padding` | Padding between border and message | | ||
| `--rui-Alert__font-weight` | Message font weight | | ||
| `--rui-Alert__border-width` | Border width | | ||
| `--rui-Alert__border-radius` | Corner radius | | ||
| `--rui-Alert__emphasis__font-weight` | Font weight of text emphasised with `<strong>` | | ||
| `--rui-Alert__stripe__width` | Width of the border at the start of the Alert | | ||
@@ -211,0 +223,0 @@ ### Theming Variants |
import PropTypes from 'prop-types'; | ||
import React from 'react'; | ||
import { withGlobalProps } from '../../provider'; | ||
import { withGlobalProps } from '../../providers/globalProps'; | ||
import { classNames } from '../../utils/classNames'; | ||
@@ -5,0 +5,0 @@ import { transferProps } from '../../utils/transferProps'; |
import PropTypes from 'prop-types'; | ||
import React, { useContext } from 'react'; | ||
import { withGlobalProps } from '../../provider'; | ||
import { withGlobalProps } from '../../providers/globalProps'; | ||
import { classNames } from '../../utils/classNames'; | ||
@@ -5,0 +5,0 @@ import { transferProps } from '../../utils/transferProps'; |
@@ -5,3 +5,3 @@ import PropTypes from 'prop-types'; | ||
} from 'react'; | ||
import { withGlobalProps } from '../../provider'; | ||
import { withGlobalProps } from '../../providers/globalProps'; | ||
import { classNames } from '../../utils/classNames'; | ||
@@ -8,0 +8,0 @@ import { transferProps } from '../../utils/transferProps'; |
import PropTypes from 'prop-types'; | ||
import React from 'react'; | ||
import { withGlobalProps } from '../../provider'; | ||
import { withGlobalProps } from '../../providers/globalProps'; | ||
import { classNames } from '../../utils/classNames'; | ||
@@ -5,0 +5,0 @@ import { transferProps } from '../../utils/transferProps'; |
import PropTypes from 'prop-types'; | ||
import React from 'react'; | ||
import { withGlobalProps } from '../../provider'; | ||
import { withGlobalProps } from '../../providers/globalProps'; | ||
import { transferProps } from '../../utils/transferProps'; | ||
@@ -5,0 +5,0 @@ import styles from './Card.module.scss'; |
import PropTypes from 'prop-types'; | ||
import React from 'react'; | ||
import { withGlobalProps } from '../../provider'; | ||
import { transferProps } from '../../utils/transferProps'; | ||
import { withGlobalProps } from '../../providers/globalProps'; | ||
import { isChildrenEmpty } from '../_helpers/isChildrenEmpty'; | ||
@@ -6,0 +6,0 @@ import styles from './Card.module.scss'; |
@@ -157,2 +157,4 @@ # Card | ||
Hello! I'm success variant of card. | ||
{' '} | ||
<TextLink href="/" label="This is a link" /> | ||
</CardBody> | ||
@@ -166,2 +168,4 @@ <CardFooter> | ||
Hello! I'm warning variant of card. | ||
{' '} | ||
<TextLink href="/" label="This is a link" /> | ||
</CardBody> | ||
@@ -175,2 +179,4 @@ <CardFooter> | ||
Hello! I'm danger variant of card. | ||
{' '} | ||
<TextLink href="/" label="This is a link" /> | ||
</CardBody> | ||
@@ -184,2 +190,4 @@ <CardFooter> | ||
Hello! I'm help variant of card. | ||
{' '} | ||
<TextLink href="/" label="This is a link" /> | ||
</CardBody> | ||
@@ -193,2 +201,4 @@ <CardFooter> | ||
Hello! I'm info variant of card. | ||
{' '} | ||
<TextLink href="/" label="This is a link" /> | ||
</CardBody> | ||
@@ -202,2 +212,4 @@ <CardFooter> | ||
Hello! I'm note variant of card. | ||
{' '} | ||
<TextLink href="/" label="This is a link" /> | ||
</CardBody> | ||
@@ -211,2 +223,4 @@ <CardFooter> | ||
Hello! I'm light (default) variant of card. | ||
{' '} | ||
<TextLink href="/" label="This is a link" /> | ||
</CardBody> | ||
@@ -220,2 +234,4 @@ <CardFooter> | ||
Hello! I'm dark variant of card. | ||
{' '} | ||
<TextLink href="/" label="This is a link" /> | ||
</CardBody> | ||
@@ -239,2 +255,4 @@ <CardFooter> | ||
Hello! I'm a disabled card. | ||
{' '} | ||
<TextLink href="/" label="This is a link" /> | ||
</CardBody> | ||
@@ -248,2 +266,4 @@ <CardFooter> | ||
Hello! I'm a disabled raised card. | ||
{' '} | ||
<TextLink href="/" label="This is a link" /> | ||
</CardBody> | ||
@@ -257,2 +277,4 @@ <CardFooter> | ||
Hello! I'm a disabled success variant of card. | ||
{' '} | ||
<TextLink href="/" label="This is a link" /> | ||
</CardBody> | ||
@@ -259,0 +281,0 @@ <CardFooter> |
import PropTypes from 'prop-types'; | ||
import React, { useContext } from 'react'; | ||
import { withGlobalProps } from '../../provider'; | ||
import { withGlobalProps } from '../../providers/globalProps'; | ||
import { classNames } from '../../utils/classNames'; | ||
@@ -18,2 +18,3 @@ import { transferProps } from '../../utils/transferProps'; | ||
labelPosition, | ||
renderAsRequired, | ||
required, | ||
@@ -34,3 +35,3 @@ validationState, | ||
disabled && styles.isRootDisabled, | ||
required && styles.isRootRequired, | ||
(renderAsRequired || required) && styles.isRootRequired, | ||
getRootValidationStateClassName(validationState, styles), | ||
@@ -87,2 +88,3 @@ )} | ||
labelPosition: 'after', | ||
renderAsRequired: false, | ||
required: false, | ||
@@ -126,4 +128,8 @@ validationState: null, | ||
/** | ||
* If `true`, the input will be required. | ||
* If `true`, the input will be rendered as if it was required. | ||
*/ | ||
renderAsRequired: PropTypes.bool, | ||
/** | ||
* If `true`, the input will be made and rendered as required, regardless of the `renderAsRequired` prop. | ||
*/ | ||
required: PropTypes.bool, | ||
@@ -130,0 +136,0 @@ /** |
@@ -21,3 +21,9 @@ # CheckboxField | ||
checked={agree} | ||
label="I agree" | ||
label={( | ||
<> | ||
I have read and agree with | ||
{' '} | ||
<TextLink href="#" label="terms and conditions" /> | ||
</> | ||
)} | ||
onChange={() => setAgree(!agree)} | ||
@@ -136,3 +142,9 @@ /> | ||
checked={agree} | ||
label="I have read and agree with terms and conditions" | ||
label={( | ||
<> | ||
I have read and agree with | ||
{' '} | ||
<TextLink href="#" label="terms and conditions" /> | ||
</> | ||
)} | ||
onChange={() => setAgree(!agree)} | ||
@@ -143,10 +155,28 @@ validationState="valid" | ||
checked={agree} | ||
label="I have read and agree with terms and conditions" | ||
label={( | ||
<> | ||
I have read and agree with | ||
{' '} | ||
<TextLink href="#" label="terms and conditions" /> | ||
</> | ||
)} | ||
onChange={() => setAgree(!agree)} | ||
validationState="warning" | ||
validationText="Please wait 10 minutes until we verify your data." | ||
validationText={( | ||
<> | ||
Please wait 10 minutes until we verify your data. | ||
{' '} | ||
<TextLink href="#" label="Cancel" /> | ||
</> | ||
)} | ||
/> | ||
<CheckboxField | ||
checked={agree} | ||
label="I have read and agree with terms and conditions" | ||
label={( | ||
<> | ||
I have read and agree with | ||
{' '} | ||
<TextLink href="#" label="terms and conditions" /> | ||
</> | ||
)} | ||
onChange={() => setAgree(!agree)} | ||
@@ -162,2 +192,77 @@ required | ||
### Required State | ||
The required state indicates that the input is mandatory. Required fields | ||
display an asterisk `*` after the label by default. | ||
```docoff-react-preview | ||
React.createElement(() => { | ||
const [agree, setAgree] = React.useState(true); | ||
return ( | ||
<CheckboxField | ||
checked={agree} | ||
label="I agree" | ||
onChange={() => setAgree(!agree)} | ||
required | ||
/> | ||
); | ||
}); | ||
``` | ||
#### Styling the Required State | ||
All form fields in React UI can be | ||
[styled](/docs/customize/theming/forms/#required-state) | ||
to indicate the required state. | ||
However, you may find yourself in a situation where a form field is valid in | ||
both checked and unchecked states, for example to turn on or off a feature. | ||
If your project uses the label color as the primary means to indicate the | ||
required state of input fields and the usual asterisk `*` is omitted, you may | ||
want to keep the label color consistent for both states to avoid confusion. | ||
For this edge case, there is the `renderAsRequired` prop: | ||
```docoff-react-preview | ||
React.createElement(() => { | ||
const [optional, setOptional] = React.useState(false); | ||
const [renderAsRequired, setRenderAsRequired] = React.useState(false); | ||
return ( | ||
<React.Fragment> | ||
<style> | ||
{` | ||
.example { | ||
display: flex; | ||
flex-wrap: wrap; | ||
gap: 1rem 0.5rem; | ||
} | ||
.example--themed-form-fields { | ||
--rui-FormField__label__color: var(--rui-color-text-secondary); | ||
--rui-FormField--required__label__color: var(--rui-color-text-primary); | ||
--rui-FormField--required__sign: ''; | ||
} | ||
`} | ||
</style> | ||
<div class="example example--themed-form-fields"> | ||
<CheckboxField | ||
checked={optional} | ||
label="This field is optional" | ||
onChange={() => setOptional(!optional)} | ||
/> | ||
<CheckboxField | ||
checked={renderAsRequired} | ||
label="This field is optional but looks like required" | ||
onChange={() => setRenderAsRequired(!renderAsRequired)} | ||
renderAsRequired | ||
/> | ||
</div> | ||
</React.Fragment> | ||
); | ||
}); | ||
``` | ||
It renders the field as if it was required, but doesn't add the `required` | ||
attribute to the actual input. | ||
### Disabled State | ||
@@ -164,0 +269,0 @@ |
import PropTypes from 'prop-types'; | ||
import React, { useContext } from 'react'; | ||
import { withGlobalProps } from '../../provider'; | ||
import { withGlobalProps } from '../../providers/globalProps'; | ||
import { classNames } from '../../utils/classNames'; | ||
@@ -5,0 +5,0 @@ import { transferProps } from '../../utils/transferProps'; |
import PropTypes from 'prop-types'; | ||
import React, { useMemo } from 'react'; | ||
import { withGlobalProps } from '../../provider'; | ||
import { withGlobalProps } from '../../providers/globalProps'; | ||
import { classNames } from '../../utils/classNames'; | ||
@@ -5,0 +5,0 @@ import { transferProps } from '../../utils/transferProps'; |
import PropTypes from 'prop-types'; | ||
import React, { useContext } from 'react'; | ||
import { withGlobalProps } from '../../provider'; | ||
import { withGlobalProps } from '../../providers/globalProps'; | ||
import { classNames } from '../../utils/classNames'; | ||
@@ -5,0 +5,0 @@ import { transferProps } from '../../utils/transferProps'; |
import PropTypes from 'prop-types'; | ||
import React from 'react'; | ||
import { withGlobalProps } from '../../provider'; | ||
import { withGlobalProps } from '../../providers/globalProps'; | ||
import { transferProps } from '../../utils/transferProps'; | ||
@@ -5,0 +5,0 @@ import { isChildrenEmpty } from '../_helpers/isChildrenEmpty'; |
import PropTypes from 'prop-types'; | ||
import React from 'react'; | ||
import { withGlobalProps } from '../../provider'; | ||
import { withGlobalProps } from '../../providers/globalProps'; | ||
import { transferProps } from '../../utils/transferProps'; | ||
@@ -5,0 +5,0 @@ import { isChildrenEmpty } from '../_helpers/isChildrenEmpty'; |
@@ -6,4 +6,3 @@ import PropTypes from 'prop-types'; | ||
} from 'react'; | ||
import { Text } from '../Text'; | ||
import { withGlobalProps } from '../../provider'; | ||
import { withGlobalProps } from '../../providers/globalProps'; | ||
import { classNames } from '../../utils/classNames'; | ||
@@ -16,2 +15,3 @@ import { transferProps } from '../../utils/transferProps'; | ||
import { FormLayoutContext } from '../FormLayout'; | ||
import { Text } from '../Text'; | ||
import { InputGroupContext } from './InputGroupContext'; | ||
@@ -18,0 +18,0 @@ import styles from './InputGroup.module.scss'; |
import PropTypes from 'prop-types'; | ||
import React, { useRef } from 'react'; | ||
import { createPortal } from 'react-dom'; | ||
import { withGlobalProps } from '../../provider'; | ||
import { withGlobalProps } from '../../providers/globalProps'; | ||
import { classNames } from '../../utils/classNames'; | ||
@@ -6,0 +6,0 @@ import { transferProps } from '../../utils/transferProps'; |
import PropTypes from 'prop-types'; | ||
import React from 'react'; | ||
import { withGlobalProps } from '../../provider'; | ||
import { withGlobalProps } from '../../providers/globalProps'; | ||
import { classNames } from '../../utils/classNames'; | ||
@@ -5,0 +5,0 @@ import { transferProps } from '../../utils/transferProps'; |
import PropTypes from 'prop-types'; | ||
import React, { useContext } from 'react'; | ||
import { | ||
RUIContext, | ||
withGlobalProps, | ||
} from '../../provider'; | ||
import { TranslationsContext } from '../../providers/translations'; | ||
import { withGlobalProps } from '../../providers/globalProps'; | ||
import { transferProps } from '../../utils/transferProps'; | ||
@@ -16,3 +14,3 @@ import styles from './ModalCloseButton.module.scss'; | ||
const { translations } = useContext(RUIContext); | ||
const translations = useContext(TranslationsContext); | ||
@@ -19,0 +17,0 @@ return ( |
import PropTypes from 'prop-types'; | ||
import React from 'react'; | ||
import { withGlobalProps } from '../../provider'; | ||
import { withGlobalProps } from '../../providers/globalProps'; | ||
import { transferProps } from '../../utils/transferProps'; | ||
@@ -5,0 +5,0 @@ import { isChildrenEmpty } from '../_helpers/isChildrenEmpty'; |
import PropTypes from 'prop-types'; | ||
import React from 'react'; | ||
import { withGlobalProps } from '../../provider'; | ||
import { withGlobalProps } from '../../providers/globalProps'; | ||
import { classNames } from '../../utils/classNames'; | ||
@@ -5,0 +5,0 @@ import { transferProps } from '../../utils/transferProps'; |
import PropTypes from 'prop-types'; | ||
import React from 'react'; | ||
import { withGlobalProps } from '../../provider'; | ||
import { withGlobalProps } from '../../providers/globalProps'; | ||
import { classNames } from '../../utils/classNames'; | ||
@@ -5,0 +5,0 @@ import { transferProps } from '../../utils/transferProps'; |
import PropTypes from 'prop-types'; | ||
import React from 'react'; | ||
import { withGlobalProps } from '../../provider'; | ||
import { withGlobalProps } from '../../providers/globalProps'; | ||
import { transferProps } from '../../utils/transferProps'; | ||
@@ -5,0 +5,0 @@ import styles from './ModalTitle.module.scss'; |
@@ -33,3 +33,3 @@ # Modal | ||
return ( | ||
<RUIProvider globalProps={{ | ||
<GlobalPropsProvider globalProps={{ | ||
Modal: { preventScrollUnderneath: window.document.documentElement } | ||
@@ -76,3 +76,3 @@ }}> | ||
</div> | ||
</RUIProvider> | ||
</GlobalPropsProvider> | ||
); | ||
@@ -131,3 +131,3 @@ }); | ||
return ( | ||
<RUIProvider globalProps={{ | ||
<GlobalPropsProvider globalProps={{ | ||
Modal: { preventScrollUnderneath: window.document.documentElement } | ||
@@ -253,3 +253,3 @@ }}> | ||
</div> | ||
</RUIProvider> | ||
</GlobalPropsProvider> | ||
); | ||
@@ -288,3 +288,3 @@ }); | ||
return ( | ||
<RUIProvider globalProps={{ | ||
<GlobalPropsProvider globalProps={{ | ||
Modal: { preventScrollUnderneath: window.document.documentElement } | ||
@@ -382,3 +382,3 @@ }}> | ||
</div> | ||
</RUIProvider> | ||
</GlobalPropsProvider> | ||
); | ||
@@ -424,3 +424,3 @@ }); | ||
return ( | ||
<RUIProvider globalProps={{ | ||
<GlobalPropsProvider globalProps={{ | ||
Modal: { preventScrollUnderneath: window.document.documentElement } | ||
@@ -527,3 +527,3 @@ }}> | ||
</div> | ||
</RUIProvider> | ||
</GlobalPropsProvider> | ||
); | ||
@@ -549,3 +549,3 @@ }); | ||
return ( | ||
<RUIProvider globalProps={{ | ||
<GlobalPropsProvider globalProps={{ | ||
Modal: { preventScrollUnderneath: window.document.documentElement } | ||
@@ -617,3 +617,3 @@ }}> | ||
</div> | ||
</RUIProvider> | ||
</GlobalPropsProvider> | ||
); | ||
@@ -635,3 +635,3 @@ }); | ||
return ( | ||
<RUIProvider globalProps={{ | ||
<GlobalPropsProvider globalProps={{ | ||
Modal: { preventScrollUnderneath: window.document.documentElement } | ||
@@ -679,3 +679,3 @@ }}> | ||
</div> | ||
</RUIProvider> | ||
</GlobalPropsProvider> | ||
); | ||
@@ -705,3 +705,3 @@ }); | ||
return ( | ||
<RUIProvider globalProps={{ | ||
<GlobalPropsProvider globalProps={{ | ||
Modal: { preventScrollUnderneath: window.document.documentElement } | ||
@@ -750,3 +750,3 @@ }}> | ||
</div> | ||
</RUIProvider> | ||
</GlobalPropsProvider> | ||
); | ||
@@ -771,3 +771,3 @@ }); | ||
return ( | ||
<RUIProvider globalProps={{ | ||
<GlobalPropsProvider globalProps={{ | ||
Modal: { preventScrollUnderneath: window.document.documentElement } | ||
@@ -825,3 +825,3 @@ }}> | ||
</div> | ||
</RUIProvider> | ||
</GlobalPropsProvider> | ||
); | ||
@@ -955,3 +955,3 @@ }); | ||
return ( | ||
<RUIProvider globalProps={{ | ||
<GlobalPropsProvider globalProps={{ | ||
Modal: { preventScrollUnderneath: window.document.documentElement } | ||
@@ -1019,3 +1019,3 @@ }}> | ||
</div> | ||
</RUIProvider> | ||
</GlobalPropsProvider> | ||
); | ||
@@ -1022,0 +1022,0 @@ }); |
import PropTypes from 'prop-types'; | ||
import React from 'react'; | ||
import { withGlobalProps } from '../../provider'; | ||
import { withGlobalProps } from '../../providers/globalProps'; | ||
import { classNames } from '../../utils/classNames'; | ||
@@ -5,0 +5,0 @@ import { transferProps } from '../../utils/transferProps'; |
import PropTypes from 'prop-types'; | ||
import React from 'react'; | ||
import { createPortal } from 'react-dom'; | ||
import { withGlobalProps } from '../../provider'; | ||
import { withGlobalProps } from '../../providers/globalProps'; | ||
import { classNames } from '../../utils/classNames'; | ||
import { transferProps } from '../../utils/transferProps'; | ||
import cleanPlacementStyle from './_helpers/cleanPlacementStyle'; | ||
import getRootSideClassName from './_helpers/getRootSideClassName'; | ||
@@ -15,2 +16,4 @@ import getRootAlignmentClassName from './_helpers/getRootAlignmentClassName'; | ||
children, | ||
placementStyle, | ||
popoverTargetId, | ||
portalId, | ||
@@ -21,15 +24,31 @@ ...restProps | ||
const PopoverEl = ( | ||
<div | ||
{...transferProps(restProps)} | ||
className={classNames( | ||
styles.root, | ||
ref && styles.isRootControlled, | ||
getRootSideClassName(placement, styles), | ||
getRootAlignmentClassName(placement, styles), | ||
<> | ||
{/** | ||
* This hack is needed because the default behavior of the Popover API is to place the popover into a | ||
* top-layer. It is currently not possible to position an element in the top-layer relative to a normal element. | ||
* This will create a hidden browser popover, then with CSS it will open and close the RUI popover. | ||
*/} | ||
{!!popoverTargetId && ( | ||
<div | ||
className={styles.helper} | ||
id={popoverTargetId} | ||
popover="auto" | ||
/> | ||
)} | ||
ref={ref} | ||
> | ||
{children} | ||
<span className={styles.arrow} /> | ||
</div> | ||
<div | ||
{...transferProps(restProps)} | ||
className={classNames( | ||
styles.root, | ||
ref && styles.isRootControlled, | ||
popoverTargetId && styles.controlledPopover, | ||
getRootSideClassName(placement, styles), | ||
getRootAlignmentClassName(placement, styles), | ||
)} | ||
ref={ref} | ||
style={placementStyle ? cleanPlacementStyle(placementStyle) : null} | ||
> | ||
{children} | ||
<span className={styles.arrow} /> | ||
</div> | ||
</> | ||
); | ||
@@ -46,2 +65,4 @@ | ||
placement: 'bottom', | ||
placementStyle: null, | ||
popoverTargetId: null, | ||
portalId: null, | ||
@@ -74,2 +95,26 @@ }; | ||
/** | ||
* Used for positioning the popover with a library like Floating UI. It is filtered, | ||
* then passed to the popover as the `style` prop. | ||
*/ | ||
placementStyle: PropTypes.shape({ | ||
bottom: PropTypes.string, | ||
inset: PropTypes.string, | ||
'inset-block-end': PropTypes.string, | ||
'inset-block-start': PropTypes.string, | ||
'inset-inline-end': PropTypes.string, | ||
'inset-inline-start': PropTypes.string, | ||
left: PropTypes.string, | ||
position: PropTypes.string, | ||
right: PropTypes.string, | ||
top: PropTypes.string, | ||
'transform-origin': PropTypes.string, | ||
translate: PropTypes.string, | ||
}), | ||
/** | ||
* If set, the popover will become controlled, meaning it will be hidden by default and will need a trigger to open. | ||
* This sets the ID of the internal helper element for the popover. | ||
* Assign the same ID to `popovertarget` of a trigger to make it open and close. | ||
*/ | ||
popoverTargetId: PropTypes.string, | ||
/** | ||
* If set, popover is rendered in the React Portal with that ID. | ||
@@ -76,0 +121,0 @@ */ |
import PropTypes from 'prop-types'; | ||
import React from 'react'; | ||
import { withGlobalProps } from '../../provider'; | ||
import { withGlobalProps } from '../../providers/globalProps'; | ||
import { transferProps } from '../../utils/transferProps'; | ||
@@ -5,0 +5,0 @@ import styles from './PopoverWrapper.module.scss'; |
@@ -165,2 +165,25 @@ # Popover | ||
To position the popover, you need to provide the `placementStyle` prop with the | ||
style you want to apply to the popover. This prop should only be used to | ||
position the popover. The allowed props are: | ||
- `position` | ||
- `inset` | ||
- `inset-inline-start` | ||
- `inset-inline-end` | ||
- `inset-block-start` | ||
- `inset-block-end` | ||
- `top` | ||
- `right` | ||
- `bottom` | ||
- `left` | ||
- `translate` | ||
- `transform-origin` | ||
⚠️ [`inset`][mdn-inset] is a shorthand for `top right bottom left`, not for | ||
`inset-*` properties. | ||
As opposed to `top right bottom left` and the `inset` shorthand, `inset-*` | ||
properties are writing-direction aware. | ||
ℹ️ The following example is using external library [Floating UI]. To use | ||
@@ -271,6 +294,6 @@ Floating UI, install it first: | ||
placement={finalPlacement} | ||
style={{ | ||
placementStyle={{ | ||
position: strategy, | ||
top: y ? y : '', | ||
left: x ? x : '', | ||
top: `${y}px`, | ||
left: `${x}px`, | ||
}} | ||
@@ -289,2 +312,35 @@ ref={floating} | ||
## Controlled Popover | ||
Popover API can be used to control visibility of Popover component. You need to | ||
set `id` on the trigger element and matching `popoverTargetId` attribute on the | ||
Popover component. This leverages the browser's Popover API to control the | ||
popover, automatically closing it when the trigger or the backdrop is pressed. | ||
```docoff-react-preview | ||
React.createElement(() => { | ||
// All inline styles in this example are for demonstration purposes only. | ||
return ( | ||
<div | ||
style={{ | ||
display: 'grid', | ||
placeContent: 'center', | ||
minWidth: '20rem', | ||
minHeight: '10rem', | ||
}} | ||
> | ||
<PopoverWrapper> | ||
<Button | ||
label="Want to see a popover? Click me!" | ||
popovertarget="my-popover-helper" | ||
/> | ||
<Popover id="my-popover" popoverTargetId="my-popover-helper"> | ||
Hello there! | ||
</Popover> | ||
</PopoverWrapper> | ||
</div> | ||
); | ||
}); | ||
``` | ||
## Forwarding HTML Attributes | ||
@@ -332,3 +388,4 @@ | ||
[Floating UI]: https://floating-ui.com/docs/react-dom | ||
[mdn-inset]: https://developer.mozilla.org/en-US/docs/Web/CSS/inset | ||
[React common props]: https://react.dev/reference/react-dom/components/common#common-props | ||
[ref]: https://reactjs.org/docs/refs-and-the-dom.html |
import PropTypes from 'prop-types'; | ||
import React, { useContext } from 'react'; | ||
import { withGlobalProps } from '../../provider'; | ||
import { withGlobalProps } from '../../providers/globalProps'; | ||
import { classNames } from '../../utils/classNames'; | ||
@@ -19,2 +19,3 @@ import { transferProps } from '../../utils/transferProps'; | ||
options, | ||
renderAsRequired, | ||
required, | ||
@@ -37,3 +38,3 @@ validationState, | ||
disabled && styles.isRootDisabled, | ||
required && styles.isRootRequired, | ||
(renderAsRequired || required) && styles.isRootRequired, | ||
getRootValidationStateClassName(validationState, styles), | ||
@@ -121,2 +122,3 @@ )} | ||
layout: 'vertical', | ||
renderAsRequired: false, | ||
required: false, | ||
@@ -187,4 +189,8 @@ validationState: null, | ||
/** | ||
* If `true`, the input will be required. | ||
* If `true`, the input will be rendered as if it was required. | ||
*/ | ||
renderAsRequired: PropTypes.bool, | ||
/** | ||
* If `true`, the input will be made and rendered as required, regardless of the `renderAsRequired` prop. | ||
*/ | ||
required: PropTypes.bool, | ||
@@ -191,0 +197,0 @@ /** |
@@ -240,2 +240,105 @@ # Radio | ||
### Required State | ||
The required state indicates that the input is mandatory. | ||
```docoff-react-preview | ||
React.createElement(() => { | ||
const [fruit, setFruit] = React.useState('apple'); | ||
return ( | ||
<Radio | ||
label="Your favourite fruit" | ||
onChange={(e) => setFruit(e.target.value)} | ||
options={[ | ||
{ | ||
label: 'Apple', | ||
value: 'apple', | ||
}, | ||
{ | ||
label: 'Banana', | ||
value: 'banana', | ||
}, | ||
{ | ||
label: 'Grapefruit', | ||
value: 'grapefruit', | ||
}, | ||
]} | ||
value={fruit} | ||
required | ||
/> | ||
); | ||
}) | ||
``` | ||
#### Styling the Required State | ||
All form fields in React UI can be | ||
[styled](/docs/customize/theming/forms/#required-state) | ||
to indicate the required state. | ||
However, you may find yourself in a situation where a form field is valid in | ||
both selected and unselected states, for example to turn on or off a feature. | ||
If your project uses the label color as the primary means to indicate the | ||
required state of input fields and the usual asterisk `*` is omitted, you may | ||
want to keep the label color consistent for both states to avoid confusion. | ||
For this edge case, there is the `renderAsRequired` prop: | ||
```docoff-react-preview | ||
React.createElement(() => { | ||
const [fruit, setFruit] = React.useState('apple'); | ||
const options = [ | ||
{ | ||
label: 'Apple', | ||
value: 'apple', | ||
}, | ||
{ | ||
label: 'Banana', | ||
value: 'banana', | ||
}, | ||
{ | ||
label: 'Grapefruit', | ||
value: 'grapefruit', | ||
}, | ||
]; | ||
return ( | ||
<React.Fragment> | ||
<style> | ||
{` | ||
.example { | ||
display: flex; | ||
flex-wrap: wrap; | ||
gap: 1rem 0.5rem; | ||
} | ||
.example--themed-form-fields { | ||
--rui-FormField__label__color: var(--rui-color-text-secondary); | ||
--rui-FormField--required__label__color: var(--rui-color-text-primary); | ||
--rui-FormField--required__sign: ''; | ||
} | ||
`} | ||
</style> | ||
<div class="example example--themed-form-fields"> | ||
<Radio | ||
label="This field is optional" | ||
onChange={(e) => setFruit(e.target.value)} | ||
options={options} | ||
value={fruit} | ||
/> | ||
<Radio | ||
label="This field is optional but looks like required" | ||
onChange={(e) => setFruit(e.target.value)} | ||
options={options} | ||
value={fruit} | ||
renderAsRequired | ||
/> | ||
</div> | ||
</React.Fragment> | ||
); | ||
}) | ||
``` | ||
It renders the field as if it was required, but doesn't add the `required` | ||
attribute to the actual input. | ||
### Disabled State | ||
@@ -242,0 +345,0 @@ |
@@ -9,6 +9,4 @@ import PropTypes from 'prop-types'; | ||
} from 'react'; | ||
import { | ||
RUIContext, | ||
withGlobalProps, | ||
} from '../../provider'; | ||
import { TranslationsContext } from '../../providers/translations'; | ||
import { withGlobalProps } from '../../providers/globalProps'; | ||
import { classNames } from '../../utils/classNames'; | ||
@@ -52,3 +50,3 @@ import { transferProps } from '../../utils/transferProps'; | ||
const { translations } = useContext(RUIContext); | ||
const translations = useContext(TranslationsContext); | ||
@@ -55,0 +53,0 @@ const [isAutoScrollInProgress, setIsAutoScrollInProgress] = useState(false); |
@@ -595,2 +595,105 @@ # SelectField | ||
### Required State | ||
The required state indicates that the input is mandatory. | ||
```docoff-react-preview | ||
React.createElement(() => { | ||
const [fruit, setFruit] = React.useState('apple'); | ||
return ( | ||
<SelectField | ||
label="Your favourite fruit" | ||
onChange={(e) => setFruit(e.target.value)} | ||
options={[ | ||
{ | ||
label: 'Apple', | ||
value: 'apple', | ||
}, | ||
{ | ||
label: 'Banana', | ||
value: 'banana', | ||
}, | ||
{ | ||
label: 'Grapefruit', | ||
value: 'grapefruit', | ||
}, | ||
]} | ||
value={fruit} | ||
required | ||
/> | ||
); | ||
}); | ||
``` | ||
#### Styling the Required State | ||
All form fields in React UI can be | ||
[styled](/docs/customize/theming/forms/#required-state) | ||
to indicate the required state. | ||
However, you may find yourself in a situation where a form field is valid in | ||
both selected and unselected states, for example to turn on or off a feature. | ||
If your project uses the label color as the primary means to indicate the | ||
required state of input fields and the usual asterisk `*` is omitted, you may | ||
want to keep the label color consistent for both states to avoid confusion. | ||
For this edge case, there is the `renderAsRequired` prop: | ||
```docoff-react-preview | ||
React.createElement(() => { | ||
const [fruit, setFruit] = React.useState('apple'); | ||
const options = [ | ||
{ | ||
label: 'Apple', | ||
value: 'apple', | ||
}, | ||
{ | ||
label: 'Banana', | ||
value: 'banana', | ||
}, | ||
{ | ||
label: 'Grapefruit', | ||
value: 'grapefruit', | ||
}, | ||
]; | ||
return ( | ||
<React.Fragment> | ||
<style> | ||
{` | ||
.example { | ||
display: flex; | ||
flex-wrap: wrap; | ||
gap: 1rem 0.5rem; | ||
} | ||
.example--themed-form-fields { | ||
--rui-FormField__label__color: var(--rui-color-text-secondary); | ||
--rui-FormField--required__label__color: var(--rui-color-text-primary); | ||
--rui-FormField--required__sign: ''; | ||
} | ||
`} | ||
</style> | ||
<div class="example example--themed-form-fields"> | ||
<SelectField | ||
label="This field is optional" | ||
onChange={(e) => setFruit(e.target.value)} | ||
options={options} | ||
value={fruit} | ||
/> | ||
<SelectField | ||
label="This field is optional but looks like required" | ||
onChange={(e) => setFruit(e.target.value)} | ||
options={options} | ||
value={fruit} | ||
renderAsRequired | ||
/> | ||
</div> | ||
</React.Fragment> | ||
); | ||
}); | ||
``` | ||
It renders the field as if it was required, but doesn't add the `required` | ||
attribute to the actual input. | ||
### Disabled State | ||
@@ -597,0 +700,0 @@ |
import PropTypes from 'prop-types'; | ||
import React, { useContext } from 'react'; | ||
import { withGlobalProps } from '../../provider'; | ||
import { withGlobalProps } from '../../providers/globalProps'; | ||
import { classNames } from '../../utils/classNames'; | ||
@@ -24,2 +24,3 @@ import { transferProps } from '../../utils/transferProps'; | ||
options, | ||
renderAsRequired, | ||
required, | ||
@@ -47,3 +48,3 @@ size, | ||
inputGroupContext && styles.isRootGrouped, | ||
required && styles.isRootRequired, | ||
(renderAsRequired || required) && styles.isRootRequired, | ||
getRootSizeClassName( | ||
@@ -141,2 +142,3 @@ resolveContextOrProp(inputGroupContext && inputGroupContext.size, size), | ||
layout: 'vertical', | ||
renderAsRequired: false, | ||
required: false, | ||
@@ -233,4 +235,8 @@ size: 'medium', | ||
/** | ||
* If `true`, the input will be required. | ||
* If `true`, the input will be rendered as if it was required. | ||
*/ | ||
renderAsRequired: PropTypes.bool, | ||
/** | ||
* If `true`, the input will be made and rendered as required, regardless of the `renderAsRequired` prop. | ||
*/ | ||
required: PropTypes.bool, | ||
@@ -237,0 +243,0 @@ /** |
import PropTypes from 'prop-types'; | ||
import React from 'react'; | ||
import { withGlobalProps } from '../../provider'; | ||
import { withGlobalProps } from '../../providers/globalProps'; | ||
import { transferProps } from '../../utils/transferProps'; | ||
@@ -5,0 +5,0 @@ import { TableHeaderCell } from './_components/TableHeaderCell'; |
import PropTypes from 'prop-types'; | ||
import React from 'react'; | ||
import { withGlobalProps } from '../../provider'; | ||
import { withGlobalProps } from '../../providers/globalProps'; | ||
import { transferProps } from '../../utils/transferProps'; | ||
@@ -5,0 +5,0 @@ import styles from './Tabs.module.scss'; |
import PropTypes from 'prop-types'; | ||
import React from 'react'; | ||
import { withGlobalProps } from '../../provider'; | ||
import { withGlobalProps } from '../../providers/globalProps'; | ||
import { classNames } from '../../utils/classNames'; | ||
@@ -5,0 +5,0 @@ import { transferProps } from '../../utils/transferProps'; |
import PropTypes from 'prop-types'; | ||
import React from 'react'; | ||
import { withGlobalProps } from '../../provider'; | ||
import { withGlobalProps } from '../../providers/globalProps'; | ||
import { classNames } from '../../utils/classNames'; | ||
@@ -5,0 +5,0 @@ import { transferProps } from '../../utils/transferProps'; |
import PropTypes from 'prop-types'; | ||
import React, { useContext } from 'react'; | ||
import { withGlobalProps } from '../../provider'; | ||
import { withGlobalProps } from '../../providers/globalProps'; | ||
import { classNames } from '../../utils/classNames'; | ||
@@ -5,0 +5,0 @@ import { transferProps } from '../../utils/transferProps'; |
@@ -391,3 +391,9 @@ # TextField | ||
validationState="warning" | ||
validationText="Account with this name already exists, pick a different one." | ||
validationText={( | ||
<> | ||
Account with this name already exists, pick a different one. | ||
{' '} | ||
<TextLink href="#" label="Forgot your password?" /> | ||
</> | ||
)} | ||
value="joe" | ||
@@ -415,3 +421,9 @@ required | ||
validationState="warning" | ||
validationText="Account with this name already exists, pick a different one." | ||
validationText={( | ||
<> | ||
Account with this name already exists, pick a different one. | ||
{' '} | ||
<TextLink href="#" label="Forgot your password?" /> | ||
</> | ||
)} | ||
variant="filled" | ||
@@ -418,0 +430,0 @@ value="joe" |
import PropTypes from 'prop-types'; | ||
import React, { useContext } from 'react'; | ||
import { withGlobalProps } from '../../provider'; | ||
import { withGlobalProps } from '../../providers/globalProps'; | ||
import { classNames } from '../../utils/classNames'; | ||
@@ -5,0 +5,0 @@ import { transferProps } from '../../utils/transferProps'; |
@@ -67,9 +67,16 @@ # TextLink | ||
ℹ️ The TextLink component is context-aware and can inherit text color from its | ||
parent component. This applies for components using | ||
[Feedback color collection](/docs/foundation/collections#colors) and for | ||
components in any of the supported | ||
[validation states](/docs/foundation/colors#validation-states). | ||
In such cases, the custom properties marked with an asterisk (\*) are ignored. | ||
| Custom Property | Description | | ||
|-------------------------------------------|-------------------------------------| | ||
| `--rui-TextLink__color` | Text color | | ||
| `--rui-TextLink__color` \* | Text color | | ||
| `--rui-TextLink__text-decoration` | Text decoration, e.g. underline | | ||
| `--rui-TextLink--hover__color` | Text color on hover | | ||
| `--rui-TextLink--hover__color` \* | Text color on hover | | ||
| `--rui-TextLink--hover__text-decoration` | Text decoration on hover | | ||
| `--rui-TextLink--active__color` | Text color in the active state | | ||
| `--rui-TextLink--active__color` \* | Text color in the active state | | ||
| `--rui-TextLink--active__text-decoration` | Text decoration in the active state | | ||
@@ -76,0 +83,0 @@ |
import PropTypes from 'prop-types'; | ||
import React from 'react'; | ||
import { withGlobalProps } from '../../provider'; | ||
import { withGlobalProps } from '../../providers/globalProps'; | ||
import { transferProps } from '../../utils/transferProps'; | ||
@@ -5,0 +5,0 @@ import styles from './TextLink.module.scss'; |
@@ -151,3 +151,11 @@ # Toggle | ||
validationState="invalid" | ||
validationText="Please upgrade your plan to make this option available." | ||
validationText={( | ||
<> | ||
Please | ||
{' '} | ||
<TextLink href="#" label="upgrade your plan" /> | ||
{' '} | ||
to make this option available. | ||
</> | ||
)} | ||
/> | ||
@@ -159,2 +167,76 @@ </> | ||
### Required State | ||
The required state indicates that the input is mandatory. | ||
```docoff-react-preview | ||
React.createElement(() => { | ||
const [studioQuality, setStudioQuality] = React.useState(true); | ||
return ( | ||
<Toggle | ||
checked={studioQuality} | ||
label="Listen in studio quality" | ||
onChange={() => setStudioQuality(!studioQuality)} | ||
required | ||
/> | ||
); | ||
}); | ||
``` | ||
#### Styling the Required State | ||
All form fields in React UI can be | ||
[styled](/docs/customize/theming/forms/#required-state) | ||
to indicate the required state. | ||
However, you may find yourself in a situation where a form field is valid in | ||
both checked and unchecked states, for example to turn on or off a feature. | ||
If your project uses the label color as the primary means to indicate the | ||
required state of input fields and the usual asterisk `*` is omitted, you may | ||
want to keep the label color consistent for both states to avoid confusion. | ||
For this edge case, there is the `renderAsRequired` prop: | ||
```docoff-react-preview | ||
React.createElement(() => { | ||
const [optional, setOptional] = React.useState(false); | ||
const [renderAsRequired, setRenderAsRequired] = React.useState(false); | ||
return ( | ||
<React.Fragment> | ||
<style> | ||
{` | ||
.example { | ||
display: flex; | ||
flex-wrap: wrap; | ||
gap: 1rem 0.5rem; | ||
} | ||
.example--themed-form-fields { | ||
--rui-FormField__label__color: var(--rui-color-text-secondary); | ||
--rui-FormField--required__label__color: var(--rui-color-text-primary); | ||
--rui-FormField--required__sign: ''; | ||
} | ||
`} | ||
</style> | ||
<div class="example example--themed-form-fields"> | ||
<Toggle | ||
checked={optional} | ||
label="This field is optional" | ||
onChange={() => setOptional(!optional)} | ||
/> | ||
<Toggle | ||
checked={renderAsRequired} | ||
label="This field is optional but looks like required" | ||
onChange={() => setRenderAsRequired(!renderAsRequired)} | ||
renderAsRequired | ||
/> | ||
</div> | ||
</React.Fragment> | ||
); | ||
}); | ||
``` | ||
It renders the field as if it was required, but doesn't add the `required` | ||
attribute to the actual input. | ||
### Disabled State | ||
@@ -161,0 +243,0 @@ |
import PropTypes from 'prop-types'; | ||
import React, { useContext } from 'react'; | ||
import { withGlobalProps } from '../../provider'; | ||
import { withGlobalProps } from '../../providers/globalProps'; | ||
import { classNames } from '../../utils/classNames'; | ||
@@ -18,2 +18,3 @@ import { transferProps } from '../../utils/transferProps'; | ||
labelPosition, | ||
renderAsRequired, | ||
required, | ||
@@ -35,3 +36,3 @@ validationState, | ||
disabled && styles.isRootDisabled, | ||
required && styles.isRootRequired, | ||
(required || renderAsRequired) && styles.isRootRequired, | ||
getRootValidationStateClassName(validationState, styles), | ||
@@ -89,2 +90,3 @@ )} | ||
labelPosition: 'after', | ||
renderAsRequired: false, | ||
required: false, | ||
@@ -126,4 +128,8 @@ validationState: null, | ||
/** | ||
* If `true`, the input will be required. | ||
* If `true`, the input will be rendered as if it was required. | ||
*/ | ||
renderAsRequired: PropTypes.bool, | ||
/** | ||
* If `true`, the input will be made and rendered as required, regardless of the `renderAsRequired` prop. | ||
*/ | ||
required: PropTypes.bool, | ||
@@ -130,0 +136,0 @@ /** |
import PropTypes from 'prop-types'; | ||
import React from 'react'; | ||
import { withGlobalProps } from '../../provider'; | ||
import { withGlobalProps } from '../../providers/globalProps'; | ||
import { classNames } from '../../utils/classNames'; | ||
@@ -5,0 +5,0 @@ import { transferProps } from '../../utils/transferProps'; |
import PropTypes from 'prop-types'; | ||
import React from 'react'; | ||
import { withGlobalProps } from '../../provider'; | ||
import { withGlobalProps } from '../../providers/globalProps'; | ||
import { classNames } from '../../utils/classNames'; | ||
@@ -5,0 +5,0 @@ import { transferProps } from '../../utils/transferProps'; |
@@ -5,3 +5,3 @@ import PropTypes from 'prop-types'; | ||
import { transferProps } from '../../utils/transferProps'; | ||
import { withGlobalProps } from '../../provider'; | ||
import { withGlobalProps } from '../../providers/globalProps'; | ||
import { isChildrenEmpty } from '../_helpers/isChildrenEmpty'; | ||
@@ -8,0 +8,0 @@ import styles from './Toolbar.module.scss'; |
@@ -60,4 +60,5 @@ // Global definitions | ||
// Provider | ||
export { RUIProvider } from './provider'; | ||
// Providers | ||
export { GlobalPropsProvider } from './providers/globalProps'; | ||
export { TranslationsProvider } from './providers/translations'; | ||
@@ -64,0 +65,0 @@ // Utils |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
2333460
254
21956
121
151