New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@react-ui-org/react-ui

Package Overview
Dependencies
Maintainers
0
Versions
53
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@react-ui-org/react-ui - npm Package Compare versions

Comparing version 0.57.0 to 0.58.0

src/components/Popover/_helpers/cleanPlacementStyle.js

13

package.json
{
"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",

9

src/components/_helpers/resolveContextOrProp.js
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&apos;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&apos;m success variant of card.
{' '}
<TextLink href="/" label="This is a link" />
</CardBody>

@@ -166,2 +168,4 @@ <CardFooter>

Hello! I&apos;m warning variant of card.
{' '}
<TextLink href="/" label="This is a link" />
</CardBody>

@@ -175,2 +179,4 @@ <CardFooter>

Hello! I&apos;m danger variant of card.
{' '}
<TextLink href="/" label="This is a link" />
</CardBody>

@@ -184,2 +190,4 @@ <CardFooter>

Hello! I&apos;m help variant of card.
{' '}
<TextLink href="/" label="This is a link" />
</CardBody>

@@ -193,2 +201,4 @@ <CardFooter>

Hello! I&apos;m info variant of card.
{' '}
<TextLink href="/" label="This is a link" />
</CardBody>

@@ -202,2 +212,4 @@ <CardFooter>

Hello! I&apos;m note variant of card.
{' '}
<TextLink href="/" label="This is a link" />
</CardBody>

@@ -211,2 +223,4 @@ <CardFooter>

Hello! I&apos;m light (default) variant of card.
{' '}
<TextLink href="/" label="This is a link" />
</CardBody>

@@ -220,2 +234,4 @@ <CardFooter>

Hello! I&apos;m dark variant of card.
{' '}
<TextLink href="/" label="This is a link" />
</CardBody>

@@ -239,2 +255,4 @@ <CardFooter>

Hello! I&apos;m a disabled card.
{' '}
<TextLink href="/" label="This is a link" />
</CardBody>

@@ -248,2 +266,4 @@ <CardFooter>

Hello! I&apos;m a disabled raised card.
{' '}
<TextLink href="/" label="This is a link" />
</CardBody>

@@ -257,2 +277,4 @@ <CardFooter>

Hello! I&apos;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

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc