@pingux/astro 2.210.6-alpha.0 → 2.212.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/cjs/components/ComboBoxField/ComboBoxField.js +2 -1
- package/lib/cjs/components/LabelValuePairs/LabelValuePairs.d.ts +14 -0
- package/lib/cjs/components/LabelValuePairs/LabelValuePairs.js +70 -0
- package/lib/cjs/components/LabelValuePairs/LabelValuePairs.mdx +69 -0
- package/lib/cjs/components/LabelValuePairs/LabelValuePairs.stories.js +109 -0
- package/lib/cjs/components/LabelValuePairs/LabelValuePairs.styles.d.ts +18 -0
- package/lib/cjs/components/LabelValuePairs/LabelValuePairs.styles.js +28 -0
- package/lib/cjs/components/LabelValuePairs/LabelValuePairs.test.js +315 -0
- package/lib/cjs/components/LabelValuePairs/LabelValuePairsLabel.d.ts +4 -0
- package/lib/cjs/components/LabelValuePairs/LabelValuePairsLabel.js +47 -0
- package/lib/cjs/components/LabelValuePairs/LabelValuePairsRow.d.ts +3 -0
- package/lib/cjs/components/LabelValuePairs/LabelValuePairsRow.js +40 -0
- package/lib/cjs/components/LabelValuePairs/LabelValuePairsSubvalue.d.ts +4 -0
- package/lib/cjs/components/LabelValuePairs/LabelValuePairsSubvalue.js +29 -0
- package/lib/cjs/components/LabelValuePairs/LabelValuePairsValue.d.ts +4 -0
- package/lib/cjs/components/LabelValuePairs/LabelValuePairsValue.js +120 -0
- package/lib/cjs/components/LabelValuePairs/constants.d.ts +5 -0
- package/lib/cjs/components/LabelValuePairs/constants.js +12 -0
- package/lib/cjs/components/LabelValuePairs/index.d.ts +2 -0
- package/lib/cjs/components/LabelValuePairs/index.js +62 -0
- package/lib/cjs/components/LabelValuePairs/labelValuePairsAttributes.d.ts +74 -0
- package/lib/cjs/components/LabelValuePairs/labelValuePairsAttributes.js +20 -0
- package/lib/cjs/components/Popover/Popover.js +3 -2
- package/lib/cjs/components/Popover/Popover.test.js +8 -0
- package/lib/cjs/components/PopoverMenu/PopoverMenu.js +2 -1
- package/lib/cjs/components/SearchField/SearchAutoComplete.js +2 -1
- package/lib/cjs/hooks/useSelectField/useSelectField.js +1 -1
- package/lib/cjs/index.d.ts +3 -0
- package/lib/cjs/index.js +79 -52
- package/lib/cjs/recipes/ListAndPanel.stories.js +1 -16
- package/lib/cjs/recipes/PanelContent.stories.js +11 -47
- package/lib/cjs/recipes/items.js +38 -30
- package/lib/cjs/styles/themes/next-gen/convertedComponentList.js +1 -1
- package/lib/cjs/styles/themes/next-gen/next-gen.d.ts +17 -0
- package/lib/cjs/styles/themes/next-gen/variants/variants.d.ts +17 -0
- package/lib/cjs/styles/themes/next-gen/variants/variants.js +2 -0
- package/lib/cjs/styles/variants/variants.js +2 -0
- package/lib/cjs/types/index.d.ts +1 -0
- package/lib/cjs/types/index.js +46 -35
- package/lib/cjs/types/labelValuePairs.d.ts +35 -0
- package/lib/cjs/types/labelValuePairs.js +6 -0
- package/lib/cjs/utils/designUtils/figmaLinks.d.ts +3 -0
- package/lib/cjs/utils/designUtils/figmaLinks.js +3 -0
- package/lib/components/ComboBoxField/ComboBoxField.js +2 -1
- package/lib/components/LabelValuePairs/LabelValuePairs.js +35 -0
- package/lib/components/LabelValuePairs/LabelValuePairs.mdx +69 -0
- package/lib/components/LabelValuePairs/LabelValuePairs.stories.js +102 -0
- package/lib/components/LabelValuePairs/LabelValuePairs.styles.js +21 -0
- package/lib/components/LabelValuePairs/LabelValuePairs.test.js +309 -0
- package/lib/components/LabelValuePairs/LabelValuePairsLabel.js +35 -0
- package/lib/components/LabelValuePairs/LabelValuePairsRow.js +28 -0
- package/lib/components/LabelValuePairs/LabelValuePairsSubvalue.js +17 -0
- package/lib/components/LabelValuePairs/LabelValuePairsValue.js +108 -0
- package/lib/components/LabelValuePairs/constants.js +5 -0
- package/lib/components/LabelValuePairs/index.js +2 -0
- package/lib/components/LabelValuePairs/labelValuePairsAttributes.js +13 -0
- package/lib/components/Popover/Popover.js +3 -2
- package/lib/components/Popover/Popover.test.js +8 -0
- package/lib/components/PopoverMenu/PopoverMenu.js +2 -1
- package/lib/components/SearchField/SearchAutoComplete.js +2 -1
- package/lib/hooks/useSelectField/useSelectField.js +1 -1
- package/lib/index.js +3 -0
- package/lib/recipes/ListAndPanel.stories.js +3 -18
- package/lib/recipes/PanelContent.stories.js +11 -47
- package/lib/recipes/items.js +39 -31
- package/lib/styles/themes/next-gen/convertedComponentList.js +1 -1
- package/lib/styles/themes/next-gen/variants/variants.js +2 -0
- package/lib/styles/variants/variants.js +2 -0
- package/lib/types/index.js +1 -0
- package/lib/types/labelValuePairs.js +1 -0
- package/lib/utils/designUtils/figmaLinks.js +3 -0
- package/package.json +1 -1
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { TestingAttributes } from './shared/test';
|
|
3
|
+
import { BoxProps } from './box';
|
|
4
|
+
import { HelpHintProps } from './helpHint';
|
|
5
|
+
import { IconProps } from './icon';
|
|
6
|
+
import { IconButtonProps } from './iconButton';
|
|
7
|
+
import { SkeletonProps } from './skeleton';
|
|
8
|
+
import { TextProps } from './text';
|
|
9
|
+
export type ValueType = 'COPYABLE' | 'MASKED' | 'ELEMENT';
|
|
10
|
+
interface LabelValuePairsSubComponentProps {
|
|
11
|
+
containerProps?: BoxProps & TestingAttributes;
|
|
12
|
+
textProps?: TextProps & TestingAttributes;
|
|
13
|
+
iconProps?: IconProps;
|
|
14
|
+
}
|
|
15
|
+
export interface LabelValuePairsContainerProps extends BoxProps, TestingAttributes {
|
|
16
|
+
children?: ReactNode;
|
|
17
|
+
}
|
|
18
|
+
export type LabelValuePairsProps = LabelValuePairsContainerProps;
|
|
19
|
+
export type LabelValuePairsRowProps = LabelValuePairsContainerProps;
|
|
20
|
+
export interface LabelValuePairsLabelProps extends TestingAttributes, Omit<LabelValuePairsSubComponentProps, 'iconProps'> {
|
|
21
|
+
children?: ReactNode;
|
|
22
|
+
helpHint?: ReactNode;
|
|
23
|
+
helpHintProps?: HelpHintProps;
|
|
24
|
+
}
|
|
25
|
+
export interface LabelValuePairsValueProps extends TestingAttributes, LabelValuePairsSubComponentProps {
|
|
26
|
+
children?: ReactNode;
|
|
27
|
+
valueType?: ValueType;
|
|
28
|
+
isLoading?: boolean;
|
|
29
|
+
iconButtonProps?: IconButtonProps;
|
|
30
|
+
skeletonProps?: SkeletonProps;
|
|
31
|
+
}
|
|
32
|
+
export interface LabelValuePairsSubvalueProps extends TestingAttributes, TextProps {
|
|
33
|
+
children?: ReactNode;
|
|
34
|
+
}
|
|
35
|
+
export {};
|
|
@@ -123,6 +123,9 @@ var FIGMA_LINKS = exports.FIGMA_LINKS = {
|
|
|
123
123
|
inlineEditing: {
|
|
124
124
|
"default": 'https://www.figma.com/file/bpbEw54gTTcdIiZs4PKK1p/Astro-Specs?type=design&node-id=5244-14864&mode=design&t=1pPbrQvGkdMYBNqk-0'
|
|
125
125
|
},
|
|
126
|
+
labelValuePairs: {
|
|
127
|
+
"default": 'https://www.figma.com/file/bpbEw54gTTcdIiZs4PKK1p/Astro-Specs?node-id=43431%3A4249&mode=dev'
|
|
128
|
+
},
|
|
126
129
|
link: {
|
|
127
130
|
"default": 'https://www.figma.com/file/bpbEw54gTTcdIiZs4PKK1p/Astro-Specs?type=design&node-id=8708-29543&t=8Wwd3tIBh3GEjCJB-0'
|
|
128
131
|
},
|
|
@@ -194,7 +194,8 @@ var ComboBoxField = /*#__PURE__*/forwardRef(function (props, ref) {
|
|
|
194
194
|
style: style,
|
|
195
195
|
state: state,
|
|
196
196
|
triggerRef: inputRef,
|
|
197
|
-
popoverRef: popoverRef
|
|
197
|
+
popoverRef: popoverRef,
|
|
198
|
+
offset: 5
|
|
198
199
|
}, ___EmotionJSX(FocusScope, null, ___EmotionJSX(DismissButton, {
|
|
199
200
|
onDismiss: state.close
|
|
200
201
|
}), ___EmotionJSX(ScrollBox, scrollBoxProps, ___EmotionJSX(ListBox, _extends({
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import _extends from "@babel/runtime-corejs3/helpers/esm/extends";
|
|
2
|
+
import _objectWithoutProperties from "@babel/runtime-corejs3/helpers/esm/objectWithoutProperties";
|
|
3
|
+
var _excluded = ["children"];
|
|
4
|
+
import React, { forwardRef } from 'react';
|
|
5
|
+
import { Box } from '../../index';
|
|
6
|
+
import PairLabel from './LabelValuePairsLabel';
|
|
7
|
+
import Pair from './LabelValuePairsRow';
|
|
8
|
+
import PairSubvalue from './LabelValuePairsSubvalue';
|
|
9
|
+
import PairValue from './LabelValuePairsValue';
|
|
10
|
+
import { jsx as ___EmotionJSX } from "@emotion/react";
|
|
11
|
+
var displayName = 'LabelValuePairs';
|
|
12
|
+
var LabelValuePairs = /*#__PURE__*/forwardRef(function (props, ref) {
|
|
13
|
+
var children = props.children,
|
|
14
|
+
others = _objectWithoutProperties(props, _excluded);
|
|
15
|
+
return ___EmotionJSX(Box, _extends({
|
|
16
|
+
ref: ref,
|
|
17
|
+
variant: "labelValuePairs.container"
|
|
18
|
+
}, others), children);
|
|
19
|
+
});
|
|
20
|
+
LabelValuePairs.displayName = displayName;
|
|
21
|
+
|
|
22
|
+
// The subcomponents are exported bare under a `Pair*` naming family (`Pair`, `PairLabel`,
|
|
23
|
+
// `PairValue`, `PairSubvalue`) as the primary, terser usage — the short `Row`/`Label` names
|
|
24
|
+
// can't be exported bare from the top-level barrel (`libs/astro/src/index.ts`) because they
|
|
25
|
+
// already resolve to unrelated exports there: `Label` (a form-label component) and `Row`
|
|
26
|
+
// (from react-stately). Prefixing sidesteps that collision. Static properties are also
|
|
27
|
+
// attached so the namespaced `<LabelValuePairs.Row>` / `.Label` / `.Value` / `.Subvalue`
|
|
28
|
+
// access keeps working; inside the namespace the short names are unambiguous.
|
|
29
|
+
var LabelValuePairsWithSubcomponents = LabelValuePairs;
|
|
30
|
+
LabelValuePairsWithSubcomponents.Row = Pair;
|
|
31
|
+
LabelValuePairsWithSubcomponents.Label = PairLabel;
|
|
32
|
+
LabelValuePairsWithSubcomponents.Value = PairValue;
|
|
33
|
+
LabelValuePairsWithSubcomponents.Subvalue = PairSubvalue;
|
|
34
|
+
export default LabelValuePairsWithSubcomponents;
|
|
35
|
+
export { Pair, PairLabel, PairSubvalue, PairValue };
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { Meta } from '@storybook/addon-docs/blocks';
|
|
2
|
+
import * as LabelValuePairsStories from './LabelValuePairs.stories';
|
|
3
|
+
|
|
4
|
+
<Meta of={LabelValuePairsStories} isTemplate />
|
|
5
|
+
|
|
6
|
+
# LabelValuePairs
|
|
7
|
+
|
|
8
|
+
LabelValuePairs renders a vertical list of labelled key/value rows. It is intended for read-only detail views such as slide-over panels, summary tabs, and profile pages.
|
|
9
|
+
|
|
10
|
+
Pairs are composed from child components. Each pair supports four value display modes, an optional help hint tooltip, a secondary sub-label, and an optional inline label icon or action element. Pairs with a falsy value are suppressed unless the pair is in a loading state.
|
|
11
|
+
|
|
12
|
+
```jsx
|
|
13
|
+
import { Icon, LabelValuePairs, Pair, PairLabel, PairValue, PairSubvalue } from '@pingux/astro';
|
|
14
|
+
|
|
15
|
+
<LabelValuePairs>
|
|
16
|
+
<Pair>
|
|
17
|
+
<PairLabel helpHint="...">
|
|
18
|
+
Username
|
|
19
|
+
<Icon aria-hidden="true" title={{ name: '' }} icon={InformationIcon} />
|
|
20
|
+
</PairLabel>
|
|
21
|
+
<PairSubvalue>Optional secondary text</PairSubvalue>
|
|
22
|
+
<PairValue valueType={ValueTypes.COPYABLE}>jsmith</PairValue>
|
|
23
|
+
</Pair>
|
|
24
|
+
</LabelValuePairs>
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### Required Components
|
|
28
|
+
|
|
29
|
+
`LabelValuePairs` is a public composition API, not a standalone data-driven component. Each pair must be composed from these building blocks, available both as named exports (`Pair`, `PairLabel`, `PairValue`, `PairSubvalue`) and, equivalently, as static properties on the parent (`LabelValuePairs.Row`, `.Label`, `.Value`, `.Subvalue`):
|
|
30
|
+
|
|
31
|
+
- **`Pair`** — wraps one labelled entry. Expects a `PairLabel`, optionally a `PairSubvalue`, and a `PairValue` as children. Suppresses itself (renders nothing) when its `PairValue` child's content is falsy and not loading.
|
|
32
|
+
- **`PairLabel`** — the pair's heading text, rendered as an `<h5>`. Accepts an optional `helpHint` prop. Its first child is the label text; an optional second child renders alongside it as an icon or action element (e.g. an `Icon` or `IconButton`).
|
|
33
|
+
- **`PairValue`** — the pair's value content. Accepts `valueType` (see Value Types below) and `isLoading`.
|
|
34
|
+
- **`PairSubvalue`** — optional secondary text rendered beneath the label.
|
|
35
|
+
|
|
36
|
+
### Value Types
|
|
37
|
+
|
|
38
|
+
Use the exported `ValueTypes` constant to select the display mode for a `PairValue`'s content.
|
|
39
|
+
|
|
40
|
+
| `valueType` | Behavior |
|
|
41
|
+
| ---- | --------- |
|
|
42
|
+
| _(omitted)_ | Renders the value as plain `Text`. |
|
|
43
|
+
| `ValueTypes.COPYABLE` | Wraps the value in `CopyText`, adding a copy-to-clipboard button. |
|
|
44
|
+
| `ValueTypes.MASKED` | Displays bullet characters by default. An eye toggle reveals or hides the real value. |
|
|
45
|
+
| `ValueTypes.ELEMENT` | Renders `Value`'s children directly as a React node — use for custom content. |
|
|
46
|
+
|
|
47
|
+
### Loading State
|
|
48
|
+
|
|
49
|
+
Set `isLoading` on `PairValue` to replace the value area with a skeleton placeholder. The pair still renders its label normally, and it renders even when `PairValue` has no children — useful when data is being fetched.
|
|
50
|
+
|
|
51
|
+
### Accessibility
|
|
52
|
+
|
|
53
|
+
This component adheres to standard heading and landmark semantics.
|
|
54
|
+
|
|
55
|
+
#### Keyboard Navigation
|
|
56
|
+
|
|
57
|
+
| Keys | Functions |
|
|
58
|
+
| ---- | --------- |
|
|
59
|
+
| Tab | Moves focus through interactive elements: copy buttons, masked value toggles, and help hint triggers. |
|
|
60
|
+
| Space or Enter | Activates the focused button (copy, show/hide, or help hint). |
|
|
61
|
+
| Escape | Closes an open help hint popover. |
|
|
62
|
+
|
|
63
|
+
#### Screen Readers
|
|
64
|
+
|
|
65
|
+
This component uses the following attributes to assist screen readers:
|
|
66
|
+
- Each label heading is rendered as an **`<h5>`** element, preserving document outline semantics.
|
|
67
|
+
- The `helpHint` trigger button uses **`aria-label`** derived from the row label (e.g. `"Client ID help hint"`).
|
|
68
|
+
- The masked value toggle uses **`aria-label="Show content"`** or **`"Hide content"`** to reflect the current state.
|
|
69
|
+
- Loading rows use **`role="alert"`** and **`aria-live="assertive"`** on the skeleton container so screen readers announce when content becomes available.
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import _Object$keys from "@babel/runtime-corejs3/core-js-stable/object/keys";
|
|
2
|
+
import _Object$getOwnPropertySymbols from "@babel/runtime-corejs3/core-js-stable/object/get-own-property-symbols";
|
|
3
|
+
import _filterInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/filter";
|
|
4
|
+
import _Object$getOwnPropertyDescriptor from "@babel/runtime-corejs3/core-js-stable/object/get-own-property-descriptor";
|
|
5
|
+
import _forEachInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/for-each";
|
|
6
|
+
import _Object$getOwnPropertyDescriptors from "@babel/runtime-corejs3/core-js-stable/object/get-own-property-descriptors";
|
|
7
|
+
import _Object$defineProperties from "@babel/runtime-corejs3/core-js-stable/object/define-properties";
|
|
8
|
+
import _Object$defineProperty from "@babel/runtime-corejs3/core-js-stable/object/define-property";
|
|
9
|
+
import _defineProperty from "@babel/runtime-corejs3/helpers/esm/defineProperty";
|
|
10
|
+
function ownKeys(e, r) { var t = _Object$keys(e); if (_Object$getOwnPropertySymbols) { var o = _Object$getOwnPropertySymbols(e); r && (o = _filterInstanceProperty(o).call(o, function (r) { return _Object$getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
11
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var _context, _context2; var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? _forEachInstanceProperty(_context = ownKeys(Object(t), !0)).call(_context, function (r) { _defineProperty(e, r, t[r]); }) : _Object$getOwnPropertyDescriptors ? _Object$defineProperties(e, _Object$getOwnPropertyDescriptors(t)) : _forEachInstanceProperty(_context2 = ownKeys(Object(t))).call(_context2, function (r) { _Object$defineProperty(e, r, _Object$getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
12
|
+
import React from 'react';
|
|
13
|
+
import CheckIcon from '@pingux/mdi-react/CheckIcon';
|
|
14
|
+
import DocsLayout from '../../../.storybook/storybookDocsLayout';
|
|
15
|
+
import { Box, IconWrapper, LabelValuePairs, NoticeIcon, Pair, PairLabel, PairSubvalue, PairValue, Text, ValueTypes } from '../..';
|
|
16
|
+
import { useGetTheme } from '../../hooks';
|
|
17
|
+
import { FIGMA_LINKS } from '../../utils/designUtils/figmaLinks';
|
|
18
|
+
import statuses from '../../utils/devUtils/constants/statuses';
|
|
19
|
+
import LabelValuePairsReadme from './LabelValuePairs.mdx';
|
|
20
|
+
import { labelValuePairsArgTypes } from './labelValuePairsAttributes';
|
|
21
|
+
import { jsx as ___EmotionJSX } from "@emotion/react";
|
|
22
|
+
export default {
|
|
23
|
+
title: 'Components/LabelValuePairs',
|
|
24
|
+
component: LabelValuePairs,
|
|
25
|
+
parameters: {
|
|
26
|
+
docs: {
|
|
27
|
+
page: function page() {
|
|
28
|
+
return ___EmotionJSX(React.Fragment, null, ___EmotionJSX(LabelValuePairsReadme, null), ___EmotionJSX(DocsLayout, null));
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
argTypes: _objectSpread({}, labelValuePairsArgTypes)
|
|
33
|
+
};
|
|
34
|
+
export var Default = function Default(args) {
|
|
35
|
+
return ___EmotionJSX(LabelValuePairs, args, ___EmotionJSX(Pair, null, ___EmotionJSX(PairLabel, null, "Username"), ___EmotionJSX(PairValue, null, "jsmith")), ___EmotionJSX(Pair, null, ___EmotionJSX(PairLabel, null, "Email"), ___EmotionJSX(PairValue, null, "jsmith@example.com")), ___EmotionJSX(Pair, null, ___EmotionJSX(PairLabel, null, "Role"), ___EmotionJSX(PairValue, null, "Administrator")));
|
|
36
|
+
};
|
|
37
|
+
Default.parameters = {
|
|
38
|
+
design: {
|
|
39
|
+
type: 'figma',
|
|
40
|
+
url: FIGMA_LINKS.labelValuePairs["default"]
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
export var WithCopyableValues = function WithCopyableValues(args) {
|
|
44
|
+
return ___EmotionJSX(LabelValuePairs, args, ___EmotionJSX(Pair, null, ___EmotionJSX(PairLabel, null, "API Key"), ___EmotionJSX(PairValue, {
|
|
45
|
+
valueType: ValueTypes.COPYABLE
|
|
46
|
+
}, "abc123def456ghi789")), ___EmotionJSX(Pair, null, ___EmotionJSX(PairLabel, null, "Client Secret"), ___EmotionJSX(PairValue, {
|
|
47
|
+
valueType: ValueTypes.COPYABLE
|
|
48
|
+
}, "supersecretvalue")));
|
|
49
|
+
};
|
|
50
|
+
export var WithMaskedValue = function WithMaskedValue(args) {
|
|
51
|
+
return ___EmotionJSX(LabelValuePairs, args, ___EmotionJSX(Pair, null, ___EmotionJSX(PairLabel, null, "Password"), ___EmotionJSX(PairValue, {
|
|
52
|
+
valueType: ValueTypes.MASKED
|
|
53
|
+
}, "mypassword123")));
|
|
54
|
+
};
|
|
55
|
+
export var WithHelpHint = function WithHelpHint(args) {
|
|
56
|
+
return ___EmotionJSX(LabelValuePairs, args, ___EmotionJSX(Pair, null, ___EmotionJSX(PairLabel, {
|
|
57
|
+
helpHint: "This is the unique identifier for your OAuth application."
|
|
58
|
+
}, "Client ID"), ___EmotionJSX(PairValue, null, "client-abc-123")));
|
|
59
|
+
};
|
|
60
|
+
export var WithSubLabel = function WithSubLabel(args) {
|
|
61
|
+
return ___EmotionJSX(LabelValuePairs, args, ___EmotionJSX(Pair, null, ___EmotionJSX(PairLabel, null, "Domain"), ___EmotionJSX(PairSubvalue, null, "The primary domain for your environment."), ___EmotionJSX(PairValue, null, "example.com")));
|
|
62
|
+
};
|
|
63
|
+
export var WithLabelIcon = function WithLabelIcon(args) {
|
|
64
|
+
var _useGetTheme = useGetTheme(),
|
|
65
|
+
isOnyx = _useGetTheme.themeState.isOnyx;
|
|
66
|
+
var icon = isOnyx ? ___EmotionJSX(IconWrapper, {
|
|
67
|
+
icon: CheckIcon,
|
|
68
|
+
color: "green",
|
|
69
|
+
size: "xs",
|
|
70
|
+
isCircle: true,
|
|
71
|
+
title: {
|
|
72
|
+
name: 'Verified'
|
|
73
|
+
},
|
|
74
|
+
iconProps: {
|
|
75
|
+
size: 'sm'
|
|
76
|
+
}
|
|
77
|
+
}) : ___EmotionJSX(NoticeIcon, {
|
|
78
|
+
color: "green",
|
|
79
|
+
status: statuses.SUCCESS,
|
|
80
|
+
"aria-label": "".concat(statuses.SUCCESS, "-icon"),
|
|
81
|
+
size: "xs"
|
|
82
|
+
});
|
|
83
|
+
return ___EmotionJSX(LabelValuePairs, args, ___EmotionJSX(Pair, null, ___EmotionJSX(PairLabel, null, "Status", ___EmotionJSX(Box, {
|
|
84
|
+
isRow: true,
|
|
85
|
+
gap: "xs",
|
|
86
|
+
alignItems: "center"
|
|
87
|
+
}, icon, ___EmotionJSX(Text, {
|
|
88
|
+
variant: "listSubtitle",
|
|
89
|
+
color: isOnyx ? 'darkgreen' : 'green'
|
|
90
|
+
}, "Verified"))), ___EmotionJSX(PairValue, null, "Active")));
|
|
91
|
+
};
|
|
92
|
+
export var WithLoadingState = function WithLoadingState(args) {
|
|
93
|
+
return ___EmotionJSX(Box, {
|
|
94
|
+
width: "200px"
|
|
95
|
+
}, ___EmotionJSX(LabelValuePairs, args, ___EmotionJSX(Pair, null, ___EmotionJSX(PairLabel, null, "Username"), ___EmotionJSX(PairValue, {
|
|
96
|
+
isLoading: true
|
|
97
|
+
})), ___EmotionJSX(Pair, null, ___EmotionJSX(PairLabel, null, "Email"), ___EmotionJSX(PairValue, {
|
|
98
|
+
isLoading: true
|
|
99
|
+
})), ___EmotionJSX(Pair, null, ___EmotionJSX(PairLabel, null, "Role"), ___EmotionJSX(PairValue, {
|
|
100
|
+
isLoading: true
|
|
101
|
+
}))));
|
|
102
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
var container = {
|
|
2
|
+
gap: 'md'
|
|
3
|
+
};
|
|
4
|
+
var fieldItem = {
|
|
5
|
+
gap: 'xs'
|
|
6
|
+
};
|
|
7
|
+
var value = {
|
|
8
|
+
fontWeight: 0,
|
|
9
|
+
color: 'secondary'
|
|
10
|
+
};
|
|
11
|
+
var subLabel = {
|
|
12
|
+
fontSize: 'sm',
|
|
13
|
+
fontWeight: 0,
|
|
14
|
+
color: 'secondary'
|
|
15
|
+
};
|
|
16
|
+
export default {
|
|
17
|
+
container: container,
|
|
18
|
+
fieldItem: fieldItem,
|
|
19
|
+
value: value,
|
|
20
|
+
subLabel: subLabel
|
|
21
|
+
};
|
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
import _Object$keys from "@babel/runtime-corejs3/core-js-stable/object/keys";
|
|
2
|
+
import _Object$getOwnPropertySymbols from "@babel/runtime-corejs3/core-js-stable/object/get-own-property-symbols";
|
|
3
|
+
import _filterInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/filter";
|
|
4
|
+
import _Object$getOwnPropertyDescriptor from "@babel/runtime-corejs3/core-js-stable/object/get-own-property-descriptor";
|
|
5
|
+
import _forEachInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/for-each";
|
|
6
|
+
import _Object$getOwnPropertyDescriptors from "@babel/runtime-corejs3/core-js-stable/object/get-own-property-descriptors";
|
|
7
|
+
import _Object$defineProperties from "@babel/runtime-corejs3/core-js-stable/object/define-properties";
|
|
8
|
+
import _Symbol from "@babel/runtime-corejs3/core-js-stable/symbol";
|
|
9
|
+
import _Object$create from "@babel/runtime-corejs3/core-js-stable/object/create";
|
|
10
|
+
import _bindInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/bind";
|
|
11
|
+
import _Object$getPrototypeOf from "@babel/runtime-corejs3/core-js-stable/object/get-prototype-of";
|
|
12
|
+
import _Object$setPrototypeOf from "@babel/runtime-corejs3/core-js-stable/object/set-prototype-of";
|
|
13
|
+
import _Symbol$asyncIterator from "@babel/runtime-corejs3/core-js-stable/symbol/async-iterator";
|
|
14
|
+
import _Promise from "@babel/runtime-corejs3/core-js-stable/promise";
|
|
15
|
+
import _Symbol$iterator from "@babel/runtime-corejs3/core-js-stable/symbol/iterator";
|
|
16
|
+
import _reverseInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/reverse";
|
|
17
|
+
import _typeof from "@babel/runtime-corejs3/helpers/esm/typeof";
|
|
18
|
+
import _asyncToGenerator from "@babel/runtime-corejs3/helpers/esm/asyncToGenerator";
|
|
19
|
+
import _defineProperty from "@babel/runtime-corejs3/helpers/esm/defineProperty";
|
|
20
|
+
function _regeneratorRuntime() { "use strict"; var r = _regenerator(), e = r.m(_regeneratorRuntime), t = (_Object$getPrototypeOf ? _Object$getPrototypeOf(e) : e.__proto__).constructor; function n(r) { var e = "function" == typeof r && r.constructor; return !!e && (e === t || "GeneratorFunction" === (e.displayName || e.name)); } var o = { "throw": 1, "return": 2, "break": 3, "continue": 3 }; function a(r) { var e, t; return function (n) { e || (e = { stop: function stop() { return t(n.a, 2); }, "catch": function _catch() { return n.v; }, abrupt: function abrupt(r, e) { return t(n.a, o[r], e); }, delegateYield: function delegateYield(r, o, a) { return e.resultName = o, t(n.d, _regeneratorValues(r), a); }, finish: function finish(r) { return t(n.f, r); } }, t = function t(r, _t, o) { n.p = e.prev, n.n = e.next; try { return r(_t, o); } finally { e.next = n.n; } }), e.resultName && (e[e.resultName] = n.v, e.resultName = void 0), e.sent = n.v, e.next = n.n; try { return r.call(this, e); } finally { n.p = e.prev, n.n = e.next; } }; } return (_regeneratorRuntime = function _regeneratorRuntime() { return { wrap: function wrap(e, t, n, o) { return r.w(a(e), t, n, o && _reverseInstanceProperty(o).call(o)); }, isGeneratorFunction: n, mark: r.m, awrap: function awrap(r, e) { return new _OverloadYield(r, e); }, AsyncIterator: _regeneratorAsyncIterator, async: function async(r, e, t, o, u) { return (n(e) ? _regeneratorAsyncGen : _regeneratorAsync)(a(r), e, t, o, u); }, keys: _regeneratorKeys, values: _regeneratorValues }; })(); }
|
|
21
|
+
function _regeneratorValues(e) { if (null != e) { var t = e["function" == typeof _Symbol && _Symbol$iterator || "@@iterator"], r = 0; if (t) return t.call(e); if ("function" == typeof e.next) return e; if (!isNaN(e.length)) return { next: function next() { return e && r >= e.length && (e = void 0), { value: e && e[r++], done: !e }; } }; } throw new TypeError(_typeof(e) + " is not iterable"); }
|
|
22
|
+
function _regeneratorKeys(e) { var n = Object(e), r = []; for (var t in n) r.unshift(t); return function e() { for (; r.length;) if ((t = r.pop()) in n) return e.value = t, e.done = !1, e; return e.done = !0, e; }; }
|
|
23
|
+
function _regeneratorAsync(n, e, r, t, o) { var a = _regeneratorAsyncGen(n, e, r, t, o); return a.next().then(function (n) { return n.done ? n.value : a.next(); }); }
|
|
24
|
+
function _regeneratorAsyncGen(r, e, t, o, n) { return new _regeneratorAsyncIterator(_regenerator().w(r, e, t, o), n || _Promise); }
|
|
25
|
+
function _regeneratorAsyncIterator(t, e) { function n(r, o, i, f) { try { var c = t[r](o), u = c.value; return u instanceof _OverloadYield ? e.resolve(u.v).then(function (t) { n("next", t, i, f); }, function (t) { n("throw", t, i, f); }) : e.resolve(u).then(function (t) { c.value = t, i(c); }, function (t) { return n("throw", t, i, f); }); } catch (t) { f(t); } } var r; this.next || (_regeneratorDefine2(_regeneratorAsyncIterator.prototype), _regeneratorDefine2(_regeneratorAsyncIterator.prototype, "function" == typeof _Symbol && _Symbol$asyncIterator || "@asyncIterator", function () { return this; })), _regeneratorDefine2(this, "_invoke", function (t, o, i) { function f() { return new e(function (e, r) { n(t, i, e, r); }); } return r = r ? r.then(f, f) : f(); }, !0); }
|
|
26
|
+
function _regenerator() { /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/babel/babel/blob/main/packages/babel-helpers/LICENSE */ var e, t, r = "function" == typeof _Symbol ? _Symbol : {}, n = r.iterator || "@@iterator", o = r.toStringTag || "@@toStringTag"; function i(r, n, o, i) { var c = n && n.prototype instanceof Generator ? n : Generator, u = _Object$create(c.prototype); return _regeneratorDefine2(u, "_invoke", function (r, n, o) { var i, c, u, f = 0, p = o || [], y = !1, G = { p: 0, n: 0, v: e, a: d, f: _bindInstanceProperty(d).call(d, e, 4), d: function d(t, r) { return i = t, c = 0, u = e, G.n = r, a; } }; function d(r, n) { for (c = r, u = n, t = 0; !y && f && !o && t < p.length; t++) { var o, i = p[t], d = G.p, l = i[2]; r > 3 ? (o = l === n) && (u = i[(c = i[4]) ? 5 : (c = 3, 3)], i[4] = i[5] = e) : i[0] <= d && ((o = r < 2 && d < i[1]) ? (c = 0, G.v = n, G.n = i[1]) : d < l && (o = r < 3 || i[0] > n || n > l) && (i[4] = r, i[5] = n, G.n = l, c = 0)); } if (o || r > 1) return a; throw y = !0, n; } return function (o, p, l) { if (f > 1) throw TypeError("Generator is already running"); for (y && 1 === p && d(p, l), c = p, u = l; (t = c < 2 ? e : u) || !y;) { i || (c ? c < 3 ? (c > 1 && (G.n = -1), d(c, u)) : G.n = u : G.v = u); try { if (f = 2, i) { if (c || (o = "next"), t = i[o]) { if (!(t = t.call(i, u))) throw TypeError("iterator result is not an object"); if (!t.done) return t; u = t.value, c < 2 && (c = 0); } else 1 === c && (t = i["return"]) && t.call(i), c < 2 && (u = TypeError("The iterator does not provide a '" + o + "' method"), c = 1); i = e; } else if ((t = (y = G.n < 0) ? u : r.call(n, G)) !== a) break; } catch (t) { i = e, c = 1, u = t; } finally { f = 1; } } return { value: t, done: y }; }; }(r, o, i), !0), u; } var a = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} t = _Object$getPrototypeOf; var c = [][n] ? t(t([][n]())) : (_regeneratorDefine2(t = {}, n, function () { return this; }), t), u = GeneratorFunctionPrototype.prototype = Generator.prototype = _Object$create(c); function f(e) { return _Object$setPrototypeOf ? _Object$setPrototypeOf(e, GeneratorFunctionPrototype) : (e.__proto__ = GeneratorFunctionPrototype, _regeneratorDefine2(e, o, "GeneratorFunction")), e.prototype = _Object$create(u), e; } return GeneratorFunction.prototype = GeneratorFunctionPrototype, _regeneratorDefine2(u, "constructor", GeneratorFunctionPrototype), _regeneratorDefine2(GeneratorFunctionPrototype, "constructor", GeneratorFunction), GeneratorFunction.displayName = "GeneratorFunction", _regeneratorDefine2(GeneratorFunctionPrototype, o, "GeneratorFunction"), _regeneratorDefine2(u), _regeneratorDefine2(u, o, "Generator"), _regeneratorDefine2(u, n, function () { return this; }), _regeneratorDefine2(u, "toString", function () { return "[object Generator]"; }), (_regenerator = function _regenerator() { return { w: i, m: f }; })(); }
|
|
27
|
+
function _regeneratorDefine2(e, r, n, t) { var i = _Object$defineProperty; try { i({}, "", {}); } catch (e) { i = 0; } _regeneratorDefine2 = function _regeneratorDefine(e, r, n, t) { function o(r, n) { _regeneratorDefine2(e, r, function (e) { return this._invoke(r, n, e); }); } r ? i ? i(e, r, { value: n, enumerable: !t, configurable: !t, writable: !t }) : e[r] = n : (o("next", 0), o("throw", 1), o("return", 2)); }, _regeneratorDefine2(e, r, n, t); }
|
|
28
|
+
function _OverloadYield(e, d) { this.v = e, this.k = d; }
|
|
29
|
+
import _Object$defineProperty from "@babel/runtime-corejs3/core-js-stable/object/define-property";
|
|
30
|
+
import _repeatInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/repeat";
|
|
31
|
+
function ownKeys(e, r) { var t = _Object$keys(e); if (_Object$getOwnPropertySymbols) { var o = _Object$getOwnPropertySymbols(e); r && (o = _filterInstanceProperty(o).call(o, function (r) { return _Object$getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
32
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var _context5, _context6; var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? _forEachInstanceProperty(_context5 = ownKeys(Object(t), !0)).call(_context5, function (r) { _defineProperty(e, r, t[r]); }) : _Object$getOwnPropertyDescriptors ? _Object$defineProperties(e, _Object$getOwnPropertyDescriptors(t)) : _forEachInstanceProperty(_context6 = ownKeys(Object(t))).call(_context6, function (r) { _Object$defineProperty(e, r, _Object$getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
33
|
+
import React from 'react';
|
|
34
|
+
import InformationIcon from '@pingux/mdi-react/InformationIcon';
|
|
35
|
+
import userEvent from '@testing-library/user-event';
|
|
36
|
+
import { Icon } from '../../index';
|
|
37
|
+
import { act, render, screen } from '../../utils/testUtils/testWrapper';
|
|
38
|
+
import { universalComponentTests } from '../../utils/testUtils/universalComponentTest';
|
|
39
|
+
import LabelValuePairs, { Pair, PairLabel, PairSubvalue, PairValue, ValueTypes } from '.';
|
|
40
|
+
import { jsx as ___EmotionJSX } from "@emotion/react";
|
|
41
|
+
var originalClipboard = _objectSpread({}, global.navigator.clipboard);
|
|
42
|
+
var getComponent = function getComponent(children) {
|
|
43
|
+
return render(___EmotionJSX(LabelValuePairs, null, children));
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
// Needs to be added to each components test file
|
|
47
|
+
universalComponentTests({
|
|
48
|
+
renderComponent: function renderComponent(props) {
|
|
49
|
+
return ___EmotionJSX(LabelValuePairs, props, ___EmotionJSX(Pair, null, ___EmotionJSX(PairLabel, null, "Username"), ___EmotionJSX(PairValue, null, "jsmith")));
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
test('renders a row for each field with a value', function () {
|
|
53
|
+
getComponent(___EmotionJSX(Pair, null, ___EmotionJSX(PairLabel, null, "Username"), ___EmotionJSX(PairValue, null, "jsmith")));
|
|
54
|
+
expect(screen.getByText('Username')).toBeInTheDocument();
|
|
55
|
+
expect(screen.getByText('jsmith')).toBeInTheDocument();
|
|
56
|
+
});
|
|
57
|
+
test('rows with falsy value are not rendered unless isLoading is true', function () {
|
|
58
|
+
getComponent(___EmotionJSX(React.Fragment, null, ___EmotionJSX(Pair, null, ___EmotionJSX(PairLabel, null, "Empty Field"), ___EmotionJSX(PairValue, null)), ___EmotionJSX(Pair, null, ___EmotionJSX(PairLabel, null, "Null Field"), ___EmotionJSX(PairValue, null, null)), ___EmotionJSX(Pair, null, ___EmotionJSX(PairLabel, null, "Visible Field"), ___EmotionJSX(PairValue, null, "some value"))));
|
|
59
|
+
expect(screen.queryByText('Empty Field')).not.toBeInTheDocument();
|
|
60
|
+
expect(screen.queryByText('Null Field')).not.toBeInTheDocument();
|
|
61
|
+
expect(screen.getByText('Visible Field')).toBeInTheDocument();
|
|
62
|
+
});
|
|
63
|
+
test('rows with falsy value are rendered when isLoading is true', function () {
|
|
64
|
+
getComponent(___EmotionJSX(Pair, null, ___EmotionJSX(PairLabel, null, "Loading Field"), ___EmotionJSX(PairValue, {
|
|
65
|
+
isLoading: true
|
|
66
|
+
})));
|
|
67
|
+
expect(screen.getByText('Loading Field')).toBeInTheDocument();
|
|
68
|
+
});
|
|
69
|
+
describe('valueType COPYABLE', function () {
|
|
70
|
+
beforeEach(function () {
|
|
71
|
+
var mockClipboard = {
|
|
72
|
+
writeText: jest.fn()
|
|
73
|
+
};
|
|
74
|
+
_Object$defineProperty(window, 'navigator', {
|
|
75
|
+
value: {
|
|
76
|
+
clipboard: mockClipboard
|
|
77
|
+
},
|
|
78
|
+
configurable: true
|
|
79
|
+
});
|
|
80
|
+
global.document.execCommand = jest.fn();
|
|
81
|
+
jest.spyOn(document, 'execCommand').mockReturnValue(true);
|
|
82
|
+
});
|
|
83
|
+
afterEach(function () {
|
|
84
|
+
jest.resetAllMocks();
|
|
85
|
+
_Object$defineProperty(window, 'navigator', {
|
|
86
|
+
value: {
|
|
87
|
+
clipboard: originalClipboard
|
|
88
|
+
},
|
|
89
|
+
configurable: true
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
test('renders a copy-to-clipboard button', function () {
|
|
93
|
+
getComponent(___EmotionJSX(Pair, null, ___EmotionJSX(PairLabel, null, "API Key"), ___EmotionJSX(PairValue, {
|
|
94
|
+
valueType: ValueTypes.COPYABLE
|
|
95
|
+
}, "abc123")));
|
|
96
|
+
expect(screen.getByLabelText('copy to clipboard')).toBeInTheDocument();
|
|
97
|
+
});
|
|
98
|
+
test('clicking the copy button writes the field value to the clipboard', /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee2() {
|
|
99
|
+
var fieldValue, button;
|
|
100
|
+
return _regeneratorRuntime().wrap(function _callee2$(_context2) {
|
|
101
|
+
while (1) switch (_context2.prev = _context2.next) {
|
|
102
|
+
case 0:
|
|
103
|
+
fieldValue = 'abc123';
|
|
104
|
+
getComponent(___EmotionJSX(Pair, null, ___EmotionJSX(PairLabel, null, "API Key"), ___EmotionJSX(PairValue, {
|
|
105
|
+
valueType: ValueTypes.COPYABLE
|
|
106
|
+
}, fieldValue)));
|
|
107
|
+
button = screen.getByLabelText('copy to clipboard');
|
|
108
|
+
_context2.next = 5;
|
|
109
|
+
return act(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee() {
|
|
110
|
+
return _regeneratorRuntime().wrap(function _callee$(_context) {
|
|
111
|
+
while (1) switch (_context.prev = _context.next) {
|
|
112
|
+
case 0:
|
|
113
|
+
return _context.abrupt("return", userEvent.click(button));
|
|
114
|
+
case 1:
|
|
115
|
+
case "end":
|
|
116
|
+
return _context.stop();
|
|
117
|
+
}
|
|
118
|
+
}, _callee);
|
|
119
|
+
})));
|
|
120
|
+
case 5:
|
|
121
|
+
expect(navigator.clipboard.writeText).toHaveBeenCalledTimes(1);
|
|
122
|
+
expect(navigator.clipboard.writeText).toHaveBeenCalledWith(fieldValue);
|
|
123
|
+
case 7:
|
|
124
|
+
case "end":
|
|
125
|
+
return _context2.stop();
|
|
126
|
+
}
|
|
127
|
+
}, _callee2);
|
|
128
|
+
})));
|
|
129
|
+
});
|
|
130
|
+
test('valueType ELEMENT renders the provided node directly', function () {
|
|
131
|
+
var customNode = ___EmotionJSX("span", {
|
|
132
|
+
"data-testid": "custom-element"
|
|
133
|
+
}, "Custom Element");
|
|
134
|
+
getComponent(___EmotionJSX(Pair, null, ___EmotionJSX(PairLabel, null, "Custom"), ___EmotionJSX(PairValue, {
|
|
135
|
+
valueType: ValueTypes.ELEMENT
|
|
136
|
+
}, customNode)));
|
|
137
|
+
expect(screen.getByTestId('custom-element')).toBeInTheDocument();
|
|
138
|
+
expect(screen.getByText('Custom Element')).toBeInTheDocument();
|
|
139
|
+
});
|
|
140
|
+
test('valueType MASKED renders bullet characters by default', function () {
|
|
141
|
+
var _context3;
|
|
142
|
+
var secretValue = 'secret';
|
|
143
|
+
getComponent(___EmotionJSX(Pair, null, ___EmotionJSX(PairLabel, null, "Password"), ___EmotionJSX(PairValue, {
|
|
144
|
+
valueType: ValueTypes.MASKED
|
|
145
|
+
}, secretValue)));
|
|
146
|
+
var bullets = _repeatInstanceProperty(_context3 = '•').call(_context3, secretValue.length);
|
|
147
|
+
expect(screen.getByText(bullets)).toBeInTheDocument();
|
|
148
|
+
});
|
|
149
|
+
test('masked toggle has aria-label "Show content" initially, clicking reveals value and changes label to "Hide content"', /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee3() {
|
|
150
|
+
var secretValue, showButton;
|
|
151
|
+
return _regeneratorRuntime().wrap(function _callee3$(_context4) {
|
|
152
|
+
while (1) switch (_context4.prev = _context4.next) {
|
|
153
|
+
case 0:
|
|
154
|
+
secretValue = 'mypassword';
|
|
155
|
+
getComponent(___EmotionJSX(Pair, null, ___EmotionJSX(PairLabel, null, "Secret"), ___EmotionJSX(PairValue, {
|
|
156
|
+
valueType: ValueTypes.MASKED
|
|
157
|
+
}, secretValue)));
|
|
158
|
+
showButton = screen.getByLabelText('Show content');
|
|
159
|
+
expect(showButton).toBeInTheDocument();
|
|
160
|
+
|
|
161
|
+
// The actual value should not be visible yet
|
|
162
|
+
expect(screen.queryByText(secretValue)).not.toBeInTheDocument();
|
|
163
|
+
_context4.next = 7;
|
|
164
|
+
return userEvent.click(showButton);
|
|
165
|
+
case 7:
|
|
166
|
+
// After click: value is revealed and button label changes
|
|
167
|
+
expect(screen.getByText(secretValue)).toBeInTheDocument();
|
|
168
|
+
expect(screen.getByLabelText('Hide content')).toBeInTheDocument();
|
|
169
|
+
case 9:
|
|
170
|
+
case "end":
|
|
171
|
+
return _context4.stop();
|
|
172
|
+
}
|
|
173
|
+
}, _callee3);
|
|
174
|
+
})));
|
|
175
|
+
test('isLoading renders the skeleton and has role="alert" in the DOM', function () {
|
|
176
|
+
getComponent(___EmotionJSX(Pair, null, ___EmotionJSX(PairLabel, null, "Loading Row"), ___EmotionJSX(PairValue, {
|
|
177
|
+
isLoading: true
|
|
178
|
+
}, "will be replaced")));
|
|
179
|
+
expect(screen.getByRole('alert')).toBeInTheDocument();
|
|
180
|
+
});
|
|
181
|
+
test('isLoading renders even when value is falsy', function () {
|
|
182
|
+
getComponent(___EmotionJSX(Pair, null, ___EmotionJSX(PairLabel, null, "Empty Loading Row"), ___EmotionJSX(PairValue, {
|
|
183
|
+
isLoading: true
|
|
184
|
+
}, undefined)));
|
|
185
|
+
expect(screen.getByText('Empty Loading Row')).toBeInTheDocument();
|
|
186
|
+
expect(screen.getByRole('alert')).toBeInTheDocument();
|
|
187
|
+
});
|
|
188
|
+
test('helpHint content appears and trigger button has expected aria-label', function () {
|
|
189
|
+
var helpText = 'This is some help content';
|
|
190
|
+
var fieldLabel = 'Help Field';
|
|
191
|
+
getComponent(___EmotionJSX(Pair, null, ___EmotionJSX(PairLabel, {
|
|
192
|
+
helpHint: helpText
|
|
193
|
+
}, fieldLabel), ___EmotionJSX(PairValue, null, "value here")));
|
|
194
|
+
var expectedAriaLabel = "".concat(fieldLabel, " help hint");
|
|
195
|
+
expect(screen.getByLabelText(expectedAriaLabel)).toBeInTheDocument();
|
|
196
|
+
});
|
|
197
|
+
test('Subvalue renders when provided', function () {
|
|
198
|
+
getComponent(___EmotionJSX(Pair, null, ___EmotionJSX(PairLabel, null, "Main Label"), ___EmotionJSX(PairSubvalue, null, "Secondary label text"), ___EmotionJSX(PairValue, null, "some value")));
|
|
199
|
+
expect(screen.getByText('Secondary label text')).toBeInTheDocument();
|
|
200
|
+
});
|
|
201
|
+
test('second child renders as an icon element when provided', function () {
|
|
202
|
+
getComponent(___EmotionJSX(Pair, null, ___EmotionJSX(PairLabel, null, "Icon Field", ___EmotionJSX(Icon, {
|
|
203
|
+
"aria-hidden": "true",
|
|
204
|
+
title: {
|
|
205
|
+
name: ''
|
|
206
|
+
},
|
|
207
|
+
icon: InformationIcon
|
|
208
|
+
})), ___EmotionJSX(PairValue, null, "icon value")));
|
|
209
|
+
// the icon is aria-hidden so must query with hidden: true
|
|
210
|
+
var icons = screen.getAllByRole('img', {
|
|
211
|
+
hidden: true
|
|
212
|
+
});
|
|
213
|
+
expect(icons.length).toBeGreaterThan(0);
|
|
214
|
+
});
|
|
215
|
+
describe('sub-component prop passthrough', function () {
|
|
216
|
+
test('PairLabel forwards containerProps and textProps, and renders a second child as an icon', function () {
|
|
217
|
+
getComponent(___EmotionJSX(Pair, null, ___EmotionJSX(PairLabel, {
|
|
218
|
+
containerProps: {
|
|
219
|
+
'data-testid': 'label-container'
|
|
220
|
+
},
|
|
221
|
+
textProps: {
|
|
222
|
+
'data-testid': 'label-text'
|
|
223
|
+
}
|
|
224
|
+
}, "Field", ___EmotionJSX(Icon, {
|
|
225
|
+
"data-testid": "label-icon",
|
|
226
|
+
"aria-hidden": "true",
|
|
227
|
+
title: {
|
|
228
|
+
name: ''
|
|
229
|
+
},
|
|
230
|
+
icon: InformationIcon
|
|
231
|
+
})), ___EmotionJSX(PairValue, null, "value")));
|
|
232
|
+
expect(screen.getByTestId('label-container')).toBeInTheDocument();
|
|
233
|
+
expect(screen.getByTestId('label-text')).toBeInTheDocument();
|
|
234
|
+
expect(screen.getByTestId('label-icon')).toBeInTheDocument();
|
|
235
|
+
});
|
|
236
|
+
test('PairLabel forwards helpHintProps to the HelpHint popover trigger', function () {
|
|
237
|
+
getComponent(___EmotionJSX(Pair, null, ___EmotionJSX(PairLabel, {
|
|
238
|
+
helpHint: "Help content",
|
|
239
|
+
helpHintProps: {
|
|
240
|
+
'data-testid': 'label-help-hint'
|
|
241
|
+
}
|
|
242
|
+
}, "Field"), ___EmotionJSX(PairValue, null, "value")));
|
|
243
|
+
expect(screen.getByTestId('label-help-hint')).toBeInTheDocument();
|
|
244
|
+
});
|
|
245
|
+
test('PairValue forwards containerProps and textProps for the default text display', function () {
|
|
246
|
+
getComponent(___EmotionJSX(Pair, null, ___EmotionJSX(PairLabel, null, "Field"), ___EmotionJSX(PairValue, {
|
|
247
|
+
containerProps: {
|
|
248
|
+
'data-testid': 'value-container'
|
|
249
|
+
},
|
|
250
|
+
textProps: {
|
|
251
|
+
'data-testid': 'value-text'
|
|
252
|
+
}
|
|
253
|
+
}, "value")));
|
|
254
|
+
expect(screen.getByTestId('value-text')).toBeInTheDocument();
|
|
255
|
+
});
|
|
256
|
+
test('PairValue forwards containerProps and textProps for COPYABLE values', function () {
|
|
257
|
+
getComponent(___EmotionJSX(Pair, null, ___EmotionJSX(PairLabel, null, "Field"), ___EmotionJSX(PairValue, {
|
|
258
|
+
valueType: ValueTypes.COPYABLE,
|
|
259
|
+
containerProps: {
|
|
260
|
+
'data-testid': 'copy-container'
|
|
261
|
+
},
|
|
262
|
+
textProps: {
|
|
263
|
+
'data-testid': 'copy-text'
|
|
264
|
+
}
|
|
265
|
+
}, "abc123")));
|
|
266
|
+
expect(screen.getByTestId('copy-container')).toBeInTheDocument();
|
|
267
|
+
expect(screen.getByTestId('copy-text')).toBeInTheDocument();
|
|
268
|
+
});
|
|
269
|
+
test('PairValue forwards containerProps, textProps, iconProps, and iconButtonProps for MASKED values', function () {
|
|
270
|
+
getComponent(___EmotionJSX(Pair, null, ___EmotionJSX(PairLabel, null, "Field"), ___EmotionJSX(PairValue, {
|
|
271
|
+
valueType: ValueTypes.MASKED,
|
|
272
|
+
containerProps: {
|
|
273
|
+
'data-testid': 'masked-container'
|
|
274
|
+
},
|
|
275
|
+
textProps: {
|
|
276
|
+
'data-testid': 'masked-text'
|
|
277
|
+
},
|
|
278
|
+
iconProps: {
|
|
279
|
+
'data-testid': 'masked-icon'
|
|
280
|
+
},
|
|
281
|
+
iconButtonProps: {
|
|
282
|
+
'data-testid': 'masked-icon-button'
|
|
283
|
+
}
|
|
284
|
+
}, "secret")));
|
|
285
|
+
expect(screen.getByTestId('masked-container')).toBeInTheDocument();
|
|
286
|
+
expect(screen.getByTestId('masked-text')).toBeInTheDocument();
|
|
287
|
+
expect(screen.getByTestId('masked-icon')).toBeInTheDocument();
|
|
288
|
+
expect(screen.getByTestId('masked-icon-button')).toBeInTheDocument();
|
|
289
|
+
});
|
|
290
|
+
test('PairValue forwards skeletonProps and containerProps when isLoading', function () {
|
|
291
|
+
getComponent(___EmotionJSX(Pair, null, ___EmotionJSX(PairLabel, null, "Field"), ___EmotionJSX(PairValue, {
|
|
292
|
+
isLoading: true,
|
|
293
|
+
containerProps: {
|
|
294
|
+
'data-testid': 'loading-container'
|
|
295
|
+
},
|
|
296
|
+
skeletonProps: {
|
|
297
|
+
'data-testid': 'loading-skeleton'
|
|
298
|
+
}
|
|
299
|
+
})));
|
|
300
|
+
expect(screen.getByTestId('loading-container')).toBeInTheDocument();
|
|
301
|
+
expect(screen.getByTestId('loading-skeleton')).toBeInTheDocument();
|
|
302
|
+
});
|
|
303
|
+
test('PairSubvalue forwards TextProps directly', function () {
|
|
304
|
+
getComponent(___EmotionJSX(Pair, null, ___EmotionJSX(PairLabel, null, "Field"), ___EmotionJSX(PairSubvalue, {
|
|
305
|
+
"data-testid": "subvalue-text"
|
|
306
|
+
}, "Secondary text"), ___EmotionJSX(PairValue, null, "value")));
|
|
307
|
+
expect(screen.getByTestId('subvalue-text')).toBeInTheDocument();
|
|
308
|
+
});
|
|
309
|
+
});
|