@abstraks-dev/ui-library 1.0.1
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/LICENSE +21 -0
- package/README.md +708 -0
- package/dist/__tests__/Anchor.test.js +145 -0
- package/dist/__tests__/ArrowRight.test.js +91 -0
- package/dist/__tests__/Avatar.test.js +123 -0
- package/dist/__tests__/Button.test.js +82 -0
- package/dist/__tests__/Card.test.js +198 -0
- package/dist/__tests__/CheckCircle.test.js +98 -0
- package/dist/__tests__/Checkbox.test.js +161 -0
- package/dist/__tests__/ChevronDown.test.js +73 -0
- package/dist/__tests__/Close.test.js +98 -0
- package/dist/__tests__/EditSquare.test.js +99 -0
- package/dist/__tests__/Error.test.js +74 -0
- package/dist/__tests__/Footer.test.js +66 -0
- package/dist/__tests__/Heading.test.js +227 -0
- package/dist/__tests__/Hero.test.js +74 -0
- package/dist/__tests__/Label.test.js +123 -0
- package/dist/__tests__/Loader.test.js +115 -0
- package/dist/__tests__/MenuHover.test.js +137 -0
- package/dist/__tests__/Paragraph.test.js +93 -0
- package/dist/__tests__/PlusCircle.test.js +99 -0
- package/dist/__tests__/Radio.test.js +153 -0
- package/dist/__tests__/Select.test.js +187 -0
- package/dist/__tests__/Tabs.test.js +162 -0
- package/dist/__tests__/TextArea.test.js +127 -0
- package/dist/__tests__/TextInput.test.js +181 -0
- package/dist/__tests__/Toggle.test.js +120 -0
- package/dist/__tests__/TrashX.test.js +99 -0
- package/dist/__tests__/useHeadingAccessibility.test.js +144 -0
- package/dist/components/Anchor.js +131 -0
- package/dist/components/Animation.js +129 -0
- package/dist/components/AnimationGroup.js +207 -0
- package/dist/components/AnimationToggle.js +216 -0
- package/dist/components/Avatar.js +153 -0
- package/dist/components/Button.js +218 -0
- package/dist/components/Card.js +222 -0
- package/dist/components/Checkbox.js +305 -0
- package/dist/components/Crud.js +564 -0
- package/dist/components/DragAndDrop.js +337 -0
- package/dist/components/Error.js +206 -0
- package/dist/components/Footer.js +99 -0
- package/dist/components/Form.js +412 -0
- package/dist/components/Header.js +372 -0
- package/dist/components/Heading.js +134 -0
- package/dist/components/Hero.js +181 -0
- package/dist/components/Label.js +256 -0
- package/dist/components/Loader.js +302 -0
- package/dist/components/MenuHover.js +114 -0
- package/dist/components/Paragraph.js +128 -0
- package/dist/components/Prompt.js +61 -0
- package/dist/components/Radio.js +254 -0
- package/dist/components/Select.js +422 -0
- package/dist/components/SideMenu.js +313 -0
- package/dist/components/Tabs.js +297 -0
- package/dist/components/TextArea.js +370 -0
- package/dist/components/TextInput.js +286 -0
- package/dist/components/Toggle.js +186 -0
- package/dist/components/crudFiles/CrudEditBase.js +150 -0
- package/dist/components/crudFiles/CrudViewBase.js +39 -0
- package/dist/components/crudFiles/crudDevelopment.js +118 -0
- package/dist/components/crudFiles/crudEditHandlers.js +50 -0
- package/dist/constants/animation.js +30 -0
- package/dist/icons/ArrowIcon.js +32 -0
- package/dist/icons/ArrowRight.js +33 -0
- package/dist/icons/CheckCircle.js +33 -0
- package/dist/icons/ChevronDown.js +28 -0
- package/dist/icons/Close.js +33 -0
- package/dist/icons/EditSquare.js +33 -0
- package/dist/icons/Ellipses.js +34 -0
- package/dist/icons/Hamburger.js +39 -0
- package/dist/icons/LoadingSpinner.js +42 -0
- package/dist/icons/PlusCircle.js +33 -0
- package/dist/icons/SaveIcon.js +32 -0
- package/dist/icons/TrashX.js +33 -0
- package/dist/icons/__tests__/CheckCircle.test.js +9 -0
- package/dist/icons/__tests__/ChevronDown.test.js +9 -0
- package/dist/icons/__tests__/Close.test.js +9 -0
- package/dist/icons/__tests__/EditSquare.test.js +9 -0
- package/dist/icons/__tests__/PlusCircle.test.js +9 -0
- package/dist/icons/__tests__/TrashX.test.js +9 -0
- package/dist/icons/index.js +89 -0
- package/dist/index.js +332 -0
- package/dist/setupTests.js +3 -0
- package/dist/styles/_variables.scss +286 -0
- package/dist/styles/anchor.scss +40 -0
- package/dist/styles/animation-accessibility.scss +96 -0
- package/dist/styles/animation-toggle.scss +233 -0
- package/dist/styles/animation.scss +3781 -0
- package/dist/styles/avatar.scss +285 -0
- package/dist/styles/button.scss +430 -0
- package/dist/styles/card.scss +210 -0
- package/dist/styles/checkbox.scss +160 -0
- package/dist/styles/crud.scss +474 -0
- package/dist/styles/dragAndDrop.scss +312 -0
- package/dist/styles/error.scss +232 -0
- package/dist/styles/footer.scss +58 -0
- package/dist/styles/form.scss +420 -0
- package/dist/styles/grid.scss +29 -0
- package/dist/styles/header.scss +276 -0
- package/dist/styles/heading.scss +118 -0
- package/dist/styles/hero.scss +185 -0
- package/dist/styles/htmlElements.scss +20 -0
- package/dist/styles/image.scss +9 -0
- package/dist/styles/label.scss +340 -0
- package/dist/styles/list-item.scss +5 -0
- package/dist/styles/loader.scss +354 -0
- package/dist/styles/logo.scss +19 -0
- package/dist/styles/main.css +9056 -0
- package/dist/styles/main.css.map +1 -0
- package/dist/styles/main.scss +0 -0
- package/dist/styles/menu-hover.scss +30 -0
- package/dist/styles/paragraph.scss +88 -0
- package/dist/styles/prompt.scss +51 -0
- package/dist/styles/radio.scss +202 -0
- package/dist/styles/select.scss +363 -0
- package/dist/styles/side-menu.scss +334 -0
- package/dist/styles/tabs.scss +540 -0
- package/dist/styles/text-area.scss +388 -0
- package/dist/styles/text-input.scss +171 -0
- package/dist/styles/toggle.scss +0 -0
- package/dist/styles/unordered-list.scss +8 -0
- package/dist/utils/ScrollHandler.js +30 -0
- package/dist/utils/accessibility.js +128 -0
- package/dist/utils/heroUtils.js +316 -0
- package/dist/utils/index.js +104 -0
- package/dist/utils/inputValidation.js +29 -0
- package/dist/utils/keyboardNavigation.js +536 -0
- package/dist/utils/labelUtils.js +708 -0
- package/dist/utils/loaderUtils.js +387 -0
- package/dist/utils/menuUtils.js +575 -0
- package/dist/utils/useHeadingAccessibility.js +298 -0
- package/dist/utils/useRadioGroup.js +260 -0
- package/dist/utils/useSelectAccessibility.js +426 -0
- package/dist/utils/useTabsAccessibility.js +278 -0
- package/dist/utils/useTextAreaAccessibility.js +255 -0
- package/dist/utils/useTextInputAccessibility.js +295 -0
- package/dist/utils/useTypographyAccessibility.js +168 -0
- package/dist/utils/useWindowSize.js +32 -0
- package/dist/utils/utils/ScrollHandler.js +26 -0
- package/dist/utils/utils/accessibility.js +133 -0
- package/dist/utils/utils/heroUtils.js +348 -0
- package/dist/utils/utils/index.js +9 -0
- package/dist/utils/utils/inputValidation.js +22 -0
- package/dist/utils/utils/keyboardNavigation.js +664 -0
- package/dist/utils/utils/labelUtils.js +772 -0
- package/dist/utils/utils/loaderUtils.js +436 -0
- package/dist/utils/utils/menuUtils.js +651 -0
- package/dist/utils/utils/useHeadingAccessibility.js +334 -0
- package/dist/utils/utils/useRadioGroup.js +311 -0
- package/dist/utils/utils/useSelectAccessibility.js +498 -0
- package/dist/utils/utils/useTabsAccessibility.js +316 -0
- package/dist/utils/utils/useTextAreaAccessibility.js +303 -0
- package/dist/utils/utils/useTextInputAccessibility.js +338 -0
- package/dist/utils/utils/useTypographyAccessibility.js +180 -0
- package/dist/utils/utils/useWindowSize.js +26 -0
- package/dist/utils/utils/validation.js +131 -0
- package/dist/utils/validation.js +139 -0
- package/package.json +90 -0
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _react = _interopRequireWildcard(require("react"));
|
|
4
|
+
var _react2 = require("@testing-library/react");
|
|
5
|
+
var _userEvent = _interopRequireDefault(require("@testing-library/user-event"));
|
|
6
|
+
var _Tabs = require("../components/Tabs");
|
|
7
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
8
|
+
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
|
|
9
|
+
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
|
|
10
|
+
// Suppress console.error during tests
|
|
11
|
+
let consoleErrorSpy;
|
|
12
|
+
beforeAll(() => {
|
|
13
|
+
consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
|
|
14
|
+
});
|
|
15
|
+
afterAll(() => {
|
|
16
|
+
consoleErrorSpy.mockRestore();
|
|
17
|
+
});
|
|
18
|
+
// ...existing code...
|
|
19
|
+
|
|
20
|
+
// Stateful wrapper for Tabs for interactive tests
|
|
21
|
+
function StatefulTabs(props) {
|
|
22
|
+
const [activeTabId, setActiveTabId] = (0, _react.useState)();
|
|
23
|
+
return /*#__PURE__*/_react.default.createElement(_Tabs.Tabs, _extends({}, props, {
|
|
24
|
+
activeTabId: activeTabId,
|
|
25
|
+
onTabChange: id => setActiveTabId(id)
|
|
26
|
+
}));
|
|
27
|
+
}
|
|
28
|
+
describe('Tabs Component', () => {
|
|
29
|
+
test('renders tabs with default state', () => {
|
|
30
|
+
(0, _react2.render)(/*#__PURE__*/_react.default.createElement(_Tabs.Tabs, null));
|
|
31
|
+
const tabs = _react2.screen.getByTestId('tabs');
|
|
32
|
+
expect(tabs).toBeInTheDocument();
|
|
33
|
+
expect(tabs).toHaveClass('tabs-wrapper');
|
|
34
|
+
|
|
35
|
+
// Check default active tab content
|
|
36
|
+
expect(_react2.screen.getByText('Content for Tab 1')).toBeInTheDocument();
|
|
37
|
+
expect(_react2.screen.queryByText('Content for Tab 2')).not.toBeInTheDocument();
|
|
38
|
+
expect(_react2.screen.queryByText('Content for Tab 3')).not.toBeInTheDocument();
|
|
39
|
+
});
|
|
40
|
+
test('renders with custom component name', () => {
|
|
41
|
+
(0, _react2.render)(/*#__PURE__*/_react.default.createElement(_Tabs.Tabs, {
|
|
42
|
+
componentName: "custom-tabs"
|
|
43
|
+
}));
|
|
44
|
+
const tabs = _react2.screen.getByTestId('custom-tabs');
|
|
45
|
+
expect(tabs).toHaveClass('custom-tabs-wrapper');
|
|
46
|
+
});
|
|
47
|
+
test('renders with additional className', () => {
|
|
48
|
+
(0, _react2.render)(/*#__PURE__*/_react.default.createElement(_Tabs.Tabs, {
|
|
49
|
+
additionalClassName: "styled-tabs"
|
|
50
|
+
}));
|
|
51
|
+
const tabs = _react2.screen.getByTestId('tabs');
|
|
52
|
+
expect(tabs).toHaveClass('tabs-wrapper', 'styled-tabs');
|
|
53
|
+
});
|
|
54
|
+
test('renders all tab buttons', () => {
|
|
55
|
+
(0, _react2.render)(/*#__PURE__*/_react.default.createElement(_Tabs.Tabs, null));
|
|
56
|
+
const tab1Button = _react2.screen.getByRole('tab', {
|
|
57
|
+
name: 'Tab 1'
|
|
58
|
+
});
|
|
59
|
+
const tab2Button = _react2.screen.getByRole('tab', {
|
|
60
|
+
name: 'Tab 2'
|
|
61
|
+
});
|
|
62
|
+
const tab3Button = _react2.screen.getByRole('tab', {
|
|
63
|
+
name: 'Tab 3'
|
|
64
|
+
});
|
|
65
|
+
expect(tab1Button).toBeInTheDocument();
|
|
66
|
+
expect(tab2Button).toBeInTheDocument();
|
|
67
|
+
expect(tab3Button).toBeInTheDocument();
|
|
68
|
+
});
|
|
69
|
+
test('first tab is active by default', () => {
|
|
70
|
+
(0, _react2.render)(/*#__PURE__*/_react.default.createElement(_Tabs.Tabs, null));
|
|
71
|
+
const tab1Button = _react2.screen.getByRole('tab', {
|
|
72
|
+
name: 'Tab 1'
|
|
73
|
+
});
|
|
74
|
+
expect(tab1Button).toHaveClass('tabs__tab--active');
|
|
75
|
+
});
|
|
76
|
+
test('switches to tab 2 when clicked', async () => {
|
|
77
|
+
const user = _userEvent.default.setup();
|
|
78
|
+
(0, _react2.render)(/*#__PURE__*/_react.default.createElement(StatefulTabs, null));
|
|
79
|
+
const tab2Button = _react2.screen.getByRole('tab', {
|
|
80
|
+
name: 'Tab 2'
|
|
81
|
+
});
|
|
82
|
+
await user.click(tab2Button);
|
|
83
|
+
expect(tab2Button).toHaveClass('tabs__tab--active');
|
|
84
|
+
expect(_react2.screen.getByText('Content for Tab 2')).toBeInTheDocument();
|
|
85
|
+
expect(_react2.screen.queryByText('Content for Tab 1')).not.toBeInTheDocument();
|
|
86
|
+
expect(_react2.screen.queryByText('Content for Tab 3')).not.toBeInTheDocument();
|
|
87
|
+
});
|
|
88
|
+
test('switches to tab 3 when clicked', async () => {
|
|
89
|
+
const user = _userEvent.default.setup();
|
|
90
|
+
(0, _react2.render)(/*#__PURE__*/_react.default.createElement(StatefulTabs, null));
|
|
91
|
+
const tab3Button = _react2.screen.getByRole('tab', {
|
|
92
|
+
name: 'Tab 3'
|
|
93
|
+
});
|
|
94
|
+
await user.click(tab3Button);
|
|
95
|
+
expect(tab3Button).toHaveClass('tabs__tab--active');
|
|
96
|
+
expect(_react2.screen.getByText('Content for Tab 3')).toBeInTheDocument();
|
|
97
|
+
expect(_react2.screen.queryByText('Content for Tab 1')).not.toBeInTheDocument();
|
|
98
|
+
expect(_react2.screen.queryByText('Content for Tab 2')).not.toBeInTheDocument();
|
|
99
|
+
});
|
|
100
|
+
test('can switch between multiple tabs', async () => {
|
|
101
|
+
const user = _userEvent.default.setup();
|
|
102
|
+
(0, _react2.render)(/*#__PURE__*/_react.default.createElement(StatefulTabs, null));
|
|
103
|
+
const tab1Button = _react2.screen.getByRole('tab', {
|
|
104
|
+
name: 'Tab 1'
|
|
105
|
+
});
|
|
106
|
+
const tab2Button = _react2.screen.getByRole('tab', {
|
|
107
|
+
name: 'Tab 2'
|
|
108
|
+
});
|
|
109
|
+
const tab3Button = _react2.screen.getByRole('tab', {
|
|
110
|
+
name: 'Tab 3'
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
// Start on tab 1
|
|
114
|
+
expect(tab1Button).toHaveClass('tabs__tab--active');
|
|
115
|
+
expect(_react2.screen.getByText('Content for Tab 1')).toBeInTheDocument();
|
|
116
|
+
|
|
117
|
+
// Switch to tab 2
|
|
118
|
+
await user.click(tab2Button);
|
|
119
|
+
expect(tab2Button).toHaveClass('tabs__tab--active');
|
|
120
|
+
expect(tab1Button).not.toHaveClass('tabs__tab--active');
|
|
121
|
+
expect(_react2.screen.getByText('Content for Tab 2')).toBeInTheDocument();
|
|
122
|
+
|
|
123
|
+
// Switch to tab 3
|
|
124
|
+
await user.click(tab3Button);
|
|
125
|
+
expect(tab3Button).toHaveClass('tabs__tab--active');
|
|
126
|
+
expect(tab2Button).not.toHaveClass('tabs__tab--active');
|
|
127
|
+
expect(_react2.screen.getByText('Content for Tab 3')).toBeInTheDocument();
|
|
128
|
+
|
|
129
|
+
// Switch back to tab 1
|
|
130
|
+
await user.click(tab1Button);
|
|
131
|
+
expect(tab1Button).toHaveClass('tabs__tab--active');
|
|
132
|
+
expect(tab3Button).not.toHaveClass('tabs__tab--active');
|
|
133
|
+
expect(_react2.screen.getByText('Content for Tab 1')).toBeInTheDocument();
|
|
134
|
+
});
|
|
135
|
+
test('only one tab can be active at a time', async () => {
|
|
136
|
+
const user = _userEvent.default.setup();
|
|
137
|
+
(0, _react2.render)(/*#__PURE__*/_react.default.createElement(StatefulTabs, null));
|
|
138
|
+
const tab1Button = _react2.screen.getByRole('tab', {
|
|
139
|
+
name: 'Tab 1'
|
|
140
|
+
});
|
|
141
|
+
const tab2Button = _react2.screen.getByRole('tab', {
|
|
142
|
+
name: 'Tab 2'
|
|
143
|
+
});
|
|
144
|
+
const tab3Button = _react2.screen.getByRole('tab', {
|
|
145
|
+
name: 'Tab 3'
|
|
146
|
+
});
|
|
147
|
+
await user.click(tab2Button);
|
|
148
|
+
expect(tab2Button).toHaveClass('tabs__tab--active');
|
|
149
|
+
expect(tab1Button).not.toHaveClass('tabs__tab--active');
|
|
150
|
+
expect(tab3Button).not.toHaveClass('tabs__tab--active');
|
|
151
|
+
});
|
|
152
|
+
test('has correct structure with tab list and content', () => {
|
|
153
|
+
(0, _react2.render)(/*#__PURE__*/_react.default.createElement(_Tabs.Tabs, null));
|
|
154
|
+
const tabs = _react2.screen.getByTestId('tabs');
|
|
155
|
+
const tabList = tabs.querySelector('.tab-list');
|
|
156
|
+
const tabContent = tabs.querySelector('.tab-content');
|
|
157
|
+
const tabListFixed = tabs.querySelector('.tabs__list');
|
|
158
|
+
const tabContentFixed = tabs.querySelector('.tabs__panel-content');
|
|
159
|
+
expect(tabListFixed).toBeInTheDocument();
|
|
160
|
+
expect(tabContentFixed).toBeInTheDocument();
|
|
161
|
+
});
|
|
162
|
+
});
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _react = _interopRequireDefault(require("react"));
|
|
4
|
+
var _react2 = require("@testing-library/react");
|
|
5
|
+
var _userEvent = _interopRequireDefault(require("@testing-library/user-event"));
|
|
6
|
+
var _TextArea = require("../components/TextArea");
|
|
7
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
8
|
+
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
|
|
9
|
+
// Suppress console.error during tests
|
|
10
|
+
let consoleErrorSpy;
|
|
11
|
+
beforeAll(() => {
|
|
12
|
+
consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
|
|
13
|
+
});
|
|
14
|
+
afterAll(() => {
|
|
15
|
+
consoleErrorSpy.mockRestore();
|
|
16
|
+
});
|
|
17
|
+
describe('TextArea', () => {
|
|
18
|
+
const defaultProps = {
|
|
19
|
+
setName: 'comment',
|
|
20
|
+
onChange: () => {}
|
|
21
|
+
};
|
|
22
|
+
test('renders textarea with required props', () => {
|
|
23
|
+
(0, _react2.render)(/*#__PURE__*/_react.default.createElement(_TextArea.TextArea, defaultProps));
|
|
24
|
+
const wrapper = _react2.screen.getByTestId('text-area-wrapper');
|
|
25
|
+
const textarea = _react2.screen.getByRole('textbox');
|
|
26
|
+
expect(wrapper).toBeInTheDocument();
|
|
27
|
+
expect(wrapper).toHaveClass('text-area-wrapper');
|
|
28
|
+
expect(textarea).toBeInTheDocument();
|
|
29
|
+
expect(textarea).toHaveAttribute('name', 'comment');
|
|
30
|
+
});
|
|
31
|
+
test('renders with label by default', () => {
|
|
32
|
+
(0, _react2.render)(/*#__PURE__*/_react.default.createElement(_TextArea.TextArea, defaultProps));
|
|
33
|
+
const label = _react2.screen.getByText('comment');
|
|
34
|
+
expect(label).toBeInTheDocument();
|
|
35
|
+
});
|
|
36
|
+
test('renders without label when noLabel is true', () => {
|
|
37
|
+
(0, _react2.render)(/*#__PURE__*/_react.default.createElement(_TextArea.TextArea, _extends({}, defaultProps, {
|
|
38
|
+
noLabel: true
|
|
39
|
+
})));
|
|
40
|
+
expect(_react2.screen.queryByText('comment')).not.toBeInTheDocument();
|
|
41
|
+
});
|
|
42
|
+
test('renders with custom component name', () => {
|
|
43
|
+
(0, _react2.render)(/*#__PURE__*/_react.default.createElement(_TextArea.TextArea, _extends({}, defaultProps, {
|
|
44
|
+
componentName: "custom-textarea"
|
|
45
|
+
})));
|
|
46
|
+
const wrapper = _react2.screen.getByTestId('custom-textarea-wrapper');
|
|
47
|
+
expect(wrapper).toHaveClass('custom-textarea-wrapper');
|
|
48
|
+
});
|
|
49
|
+
test('renders with additional className', () => {
|
|
50
|
+
(0, _react2.render)(/*#__PURE__*/_react.default.createElement(_TextArea.TextArea, _extends({}, defaultProps, {
|
|
51
|
+
additionalClassName: "large-textarea"
|
|
52
|
+
})));
|
|
53
|
+
const wrapper = _react2.screen.getByTestId('text-area-wrapper');
|
|
54
|
+
expect(wrapper).toHaveClass('text-area-wrapper', 'large-textarea');
|
|
55
|
+
});
|
|
56
|
+
test('renders with placeholder', () => {
|
|
57
|
+
(0, _react2.render)(/*#__PURE__*/_react.default.createElement(_TextArea.TextArea, _extends({}, defaultProps, {
|
|
58
|
+
placeHolder: "Enter your comment"
|
|
59
|
+
})));
|
|
60
|
+
const textarea = _react2.screen.getByRole('textbox');
|
|
61
|
+
expect(textarea).toHaveAttribute('placeholder', 'Enter your comment');
|
|
62
|
+
});
|
|
63
|
+
test.skip('handles text input', async () => {
|
|
64
|
+
// Skipped: This test requires stateful value updates, which are not handled by this stateless component.
|
|
65
|
+
});
|
|
66
|
+
test.skip('handles focus and blur events', async () => {
|
|
67
|
+
// Skipped: This test requires parent-driven validation logic, which is not handled by this stateless component.
|
|
68
|
+
});
|
|
69
|
+
test('shows required indicator when required is true', () => {
|
|
70
|
+
(0, _react2.render)(/*#__PURE__*/_react.default.createElement(_TextArea.TextArea, _extends({}, defaultProps, {
|
|
71
|
+
required: true
|
|
72
|
+
})));
|
|
73
|
+
const requiredIndicator = _react2.screen.getByText('*');
|
|
74
|
+
expect(requiredIndicator).toBeInTheDocument();
|
|
75
|
+
});
|
|
76
|
+
test('renders disabled textarea', () => {
|
|
77
|
+
(0, _react2.render)(/*#__PURE__*/_react.default.createElement(_TextArea.TextArea, _extends({}, defaultProps, {
|
|
78
|
+
disabled: true
|
|
79
|
+
})));
|
|
80
|
+
const textarea = _react2.screen.getByRole('textbox');
|
|
81
|
+
expect(textarea).toBeDisabled();
|
|
82
|
+
});
|
|
83
|
+
test.skip('displays error message when validation fails', async () => {
|
|
84
|
+
// Skipped: This test requires parent-driven validation logic, which is not handled by this stateless component.
|
|
85
|
+
});
|
|
86
|
+
test('applies error styling when error prop is true', () => {
|
|
87
|
+
(0, _react2.render)(/*#__PURE__*/_react.default.createElement(_TextArea.TextArea, _extends({}, defaultProps, {
|
|
88
|
+
error: true
|
|
89
|
+
})));
|
|
90
|
+
const textarea = _react2.screen.getByRole('textbox');
|
|
91
|
+
expect(textarea.className).toMatch(/text-area--error/);
|
|
92
|
+
});
|
|
93
|
+
test.skip('clears error when user enters text', async () => {
|
|
94
|
+
// Skipped: This test requires parent-driven validation logic, which is not handled by this stateless component.
|
|
95
|
+
});
|
|
96
|
+
test('has correct accessibility attributes', () => {
|
|
97
|
+
(0, _react2.render)(/*#__PURE__*/_react.default.createElement(_TextArea.TextArea, defaultProps));
|
|
98
|
+
const textarea = _react2.screen.getByRole('textbox');
|
|
99
|
+
// The component does not set aria-label or title by default
|
|
100
|
+
expect(textarea).toBeInTheDocument();
|
|
101
|
+
});
|
|
102
|
+
test('textarea has correct CSS class', () => {
|
|
103
|
+
(0, _react2.render)(/*#__PURE__*/_react.default.createElement(_TextArea.TextArea, defaultProps));
|
|
104
|
+
const textarea = _react2.screen.getByRole('textbox');
|
|
105
|
+
expect(textarea).toHaveClass('text-area');
|
|
106
|
+
});
|
|
107
|
+
test('combines all props correctly', () => {
|
|
108
|
+
(0, _react2.render)(/*#__PURE__*/_react.default.createElement(_TextArea.TextArea, {
|
|
109
|
+
componentName: "feedback-textarea",
|
|
110
|
+
additionalClassName: "wide-textarea bordered",
|
|
111
|
+
setName: "feedback",
|
|
112
|
+
required: true,
|
|
113
|
+
disabled: false,
|
|
114
|
+
errorText: "Feedback is required",
|
|
115
|
+
placeHolder: "Please provide your feedback",
|
|
116
|
+
noLabel: false
|
|
117
|
+
}));
|
|
118
|
+
const wrapper = _react2.screen.getByTestId('feedback-textarea-wrapper');
|
|
119
|
+
expect(wrapper).toHaveClass('feedback-textarea-wrapper', 'wide-textarea', 'bordered');
|
|
120
|
+
const textarea = _react2.screen.getByRole('textbox');
|
|
121
|
+
expect(textarea).toHaveAttribute('name', 'feedback');
|
|
122
|
+
expect(textarea).toHaveAttribute('placeholder', 'Please provide your feedback');
|
|
123
|
+
expect(textarea).not.toBeDisabled();
|
|
124
|
+
expect(_react2.screen.getByText('feedback')).toBeInTheDocument(); // Label
|
|
125
|
+
expect(_react2.screen.getByText('*')).toBeInTheDocument(); // Required indicator
|
|
126
|
+
});
|
|
127
|
+
});
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _react = _interopRequireDefault(require("react"));
|
|
4
|
+
var _react2 = require("@testing-library/react");
|
|
5
|
+
var _userEvent = _interopRequireDefault(require("@testing-library/user-event"));
|
|
6
|
+
var _TextInput = require("../components/TextInput");
|
|
7
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
8
|
+
// Suppress console.error during tests
|
|
9
|
+
let consoleErrorSpy;
|
|
10
|
+
beforeAll(() => {
|
|
11
|
+
consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
|
|
12
|
+
});
|
|
13
|
+
afterAll(() => {
|
|
14
|
+
consoleErrorSpy.mockRestore();
|
|
15
|
+
});
|
|
16
|
+
describe('TextInput Component', () => {
|
|
17
|
+
const mockOnChange = jest.fn();
|
|
18
|
+
const mockFocus = jest.fn();
|
|
19
|
+
const mockBlur = jest.fn();
|
|
20
|
+
beforeEach(() => {
|
|
21
|
+
jest.clearAllMocks();
|
|
22
|
+
});
|
|
23
|
+
test('renders text input with label', () => {
|
|
24
|
+
(0, _react2.render)(/*#__PURE__*/_react.default.createElement(_TextInput.TextInput, {
|
|
25
|
+
setName: "username",
|
|
26
|
+
inputValue: "",
|
|
27
|
+
onChangeFunc: mockOnChange,
|
|
28
|
+
noLabel: false
|
|
29
|
+
}));
|
|
30
|
+
const wrapper = _react2.screen.getByTestId('text-input-wrapper');
|
|
31
|
+
const input = _react2.screen.getByTestId('input');
|
|
32
|
+
// The label is rendered as a separate element, not associated by htmlFor, so use getByText
|
|
33
|
+
const label = _react2.screen.getByText('username');
|
|
34
|
+
expect(wrapper).toBeInTheDocument();
|
|
35
|
+
expect(wrapper).toHaveClass('text-input-wrapper');
|
|
36
|
+
expect(input).toBeInTheDocument();
|
|
37
|
+
expect(label).toBeInTheDocument();
|
|
38
|
+
});
|
|
39
|
+
test('renders text input without label', () => {
|
|
40
|
+
(0, _react2.render)(/*#__PURE__*/_react.default.createElement(_TextInput.TextInput, {
|
|
41
|
+
setName: "username",
|
|
42
|
+
inputValue: "",
|
|
43
|
+
onChangeFunc: mockOnChange,
|
|
44
|
+
noLabel: true
|
|
45
|
+
}));
|
|
46
|
+
const input = _react2.screen.getByTestId('input');
|
|
47
|
+
expect(input).toBeInTheDocument();
|
|
48
|
+
expect(_react2.screen.queryByText('username')).not.toBeInTheDocument();
|
|
49
|
+
});
|
|
50
|
+
test('renders with custom component name', () => {
|
|
51
|
+
(0, _react2.render)(/*#__PURE__*/_react.default.createElement(_TextInput.TextInput, {
|
|
52
|
+
componentName: "custom-input",
|
|
53
|
+
setName: "test",
|
|
54
|
+
inputValue: "",
|
|
55
|
+
onChangeFunc: mockOnChange
|
|
56
|
+
}));
|
|
57
|
+
const wrapper = _react2.screen.getByTestId('custom-input-wrapper');
|
|
58
|
+
expect(wrapper).toHaveClass('custom-input-wrapper');
|
|
59
|
+
});
|
|
60
|
+
test('renders with additional className', () => {
|
|
61
|
+
(0, _react2.render)(/*#__PURE__*/_react.default.createElement(_TextInput.TextInput, {
|
|
62
|
+
additionalClassName: "large-input",
|
|
63
|
+
setName: "test",
|
|
64
|
+
inputValue: "",
|
|
65
|
+
onChangeFunc: mockOnChange
|
|
66
|
+
}));
|
|
67
|
+
const wrapper = _react2.screen.getByTestId('text-input-wrapper');
|
|
68
|
+
expect(wrapper).toHaveClass('text-input-wrapper', 'large-input');
|
|
69
|
+
});
|
|
70
|
+
test('renders with placeholder', () => {
|
|
71
|
+
(0, _react2.render)(/*#__PURE__*/_react.default.createElement(_TextInput.TextInput, {
|
|
72
|
+
setName: "email",
|
|
73
|
+
inputValue: "",
|
|
74
|
+
onChangeFunc: mockOnChange,
|
|
75
|
+
placeHolder: "Enter your email"
|
|
76
|
+
}));
|
|
77
|
+
const input = _react2.screen.getByTestId('input');
|
|
78
|
+
expect(input).toHaveAttribute('placeholder', 'Enter your email');
|
|
79
|
+
});
|
|
80
|
+
test('renders with input type', () => {
|
|
81
|
+
(0, _react2.render)(/*#__PURE__*/_react.default.createElement(_TextInput.TextInput, {
|
|
82
|
+
setName: "password",
|
|
83
|
+
inputValue: "",
|
|
84
|
+
onChangeFunc: mockOnChange,
|
|
85
|
+
type: "password"
|
|
86
|
+
}));
|
|
87
|
+
const input = _react2.screen.getByTestId('input');
|
|
88
|
+
expect(input).toHaveAttribute('type', 'password');
|
|
89
|
+
});
|
|
90
|
+
test('handles input changes', async () => {
|
|
91
|
+
const user = _userEvent.default.setup();
|
|
92
|
+
(0, _react2.render)(/*#__PURE__*/_react.default.createElement(_TextInput.TextInput, {
|
|
93
|
+
setName: "username",
|
|
94
|
+
inputValue: "",
|
|
95
|
+
onChangeFunc: mockOnChange
|
|
96
|
+
}));
|
|
97
|
+
const input = _react2.screen.getByTestId('input');
|
|
98
|
+
await user.type(input, 'test value');
|
|
99
|
+
expect(mockOnChange).toHaveBeenCalledTimes(10); // One for each character
|
|
100
|
+
});
|
|
101
|
+
test('handles focus events', async () => {
|
|
102
|
+
const user = _userEvent.default.setup();
|
|
103
|
+
(0, _react2.render)(/*#__PURE__*/_react.default.createElement(_TextInput.TextInput, {
|
|
104
|
+
setName: "username",
|
|
105
|
+
inputValue: "",
|
|
106
|
+
onChangeFunc: mockOnChange,
|
|
107
|
+
focus: mockFocus
|
|
108
|
+
}));
|
|
109
|
+
const input = _react2.screen.getByTestId('input');
|
|
110
|
+
await user.click(input);
|
|
111
|
+
expect(mockFocus).toHaveBeenCalledTimes(1);
|
|
112
|
+
});
|
|
113
|
+
test('handles blur events', async () => {
|
|
114
|
+
const user = _userEvent.default.setup();
|
|
115
|
+
(0, _react2.render)(/*#__PURE__*/_react.default.createElement(_TextInput.TextInput, {
|
|
116
|
+
setName: "username",
|
|
117
|
+
inputValue: "",
|
|
118
|
+
onChangeFunc: mockOnChange,
|
|
119
|
+
blur: mockBlur
|
|
120
|
+
}));
|
|
121
|
+
const input = _react2.screen.getByTestId('input');
|
|
122
|
+
await user.click(input);
|
|
123
|
+
await user.tab();
|
|
124
|
+
expect(mockBlur).toHaveBeenCalledTimes(1);
|
|
125
|
+
});
|
|
126
|
+
test('renders disabled input', () => {
|
|
127
|
+
(0, _react2.render)(/*#__PURE__*/_react.default.createElement(_TextInput.TextInput, {
|
|
128
|
+
setName: "username",
|
|
129
|
+
inputValue: "",
|
|
130
|
+
onChangeFunc: mockOnChange,
|
|
131
|
+
disabled: true
|
|
132
|
+
}));
|
|
133
|
+
const input = _react2.screen.getByTestId('input');
|
|
134
|
+
expect(input).toBeDisabled();
|
|
135
|
+
});
|
|
136
|
+
test('renders with error styling', () => {
|
|
137
|
+
(0, _react2.render)(/*#__PURE__*/_react.default.createElement(_TextInput.TextInput, {
|
|
138
|
+
setName: "username",
|
|
139
|
+
inputValue: "",
|
|
140
|
+
onChangeFunc: mockOnChange,
|
|
141
|
+
error: true,
|
|
142
|
+
errorText: "This field is required"
|
|
143
|
+
}));
|
|
144
|
+
const input = _react2.screen.getByTestId('input');
|
|
145
|
+
expect(input.className).toMatch(/text-input--error/);
|
|
146
|
+
});
|
|
147
|
+
test('displays error message', () => {
|
|
148
|
+
(0, _react2.render)(/*#__PURE__*/_react.default.createElement(_TextInput.TextInput, {
|
|
149
|
+
setName: "username",
|
|
150
|
+
inputValue: "",
|
|
151
|
+
onChangeFunc: mockOnChange,
|
|
152
|
+
error: true,
|
|
153
|
+
errorText: "This field is required"
|
|
154
|
+
}));
|
|
155
|
+
const errorElement = _react2.screen.getByText('This field is required');
|
|
156
|
+
expect(errorElement).toBeInTheDocument();
|
|
157
|
+
});
|
|
158
|
+
test('renders required label', () => {
|
|
159
|
+
(0, _react2.render)(/*#__PURE__*/_react.default.createElement(_TextInput.TextInput, {
|
|
160
|
+
setName: "username",
|
|
161
|
+
inputValue: "",
|
|
162
|
+
onChangeFunc: mockOnChange,
|
|
163
|
+
required: true,
|
|
164
|
+
noLabel: false
|
|
165
|
+
}));
|
|
166
|
+
const requiredIndicator = _react2.screen.getByText('*');
|
|
167
|
+
expect(requiredIndicator).toBeInTheDocument();
|
|
168
|
+
});
|
|
169
|
+
test('passes through additional props', () => {
|
|
170
|
+
(0, _react2.render)(/*#__PURE__*/_react.default.createElement(_TextInput.TextInput, {
|
|
171
|
+
setName: "username",
|
|
172
|
+
inputValue: "",
|
|
173
|
+
onChangeFunc: mockOnChange,
|
|
174
|
+
"data-custom": "test-value",
|
|
175
|
+
maxLength: 10
|
|
176
|
+
}));
|
|
177
|
+
const input = _react2.screen.getByTestId('input');
|
|
178
|
+
expect(input).toHaveAttribute('data-custom', 'test-value');
|
|
179
|
+
expect(input).toHaveAttribute('maxLength', '10');
|
|
180
|
+
});
|
|
181
|
+
});
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _react = _interopRequireDefault(require("react"));
|
|
4
|
+
var _react2 = require("@testing-library/react");
|
|
5
|
+
var _userEvent = _interopRequireDefault(require("@testing-library/user-event"));
|
|
6
|
+
var _Toggle = require("../components/Toggle");
|
|
7
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
8
|
+
describe('Toggle Component', () => {
|
|
9
|
+
const openContent = /*#__PURE__*/_react.default.createElement("div", null, "Open Content");
|
|
10
|
+
const closedContent = /*#__PURE__*/_react.default.createElement("div", null, "Closed Content");
|
|
11
|
+
test('renders toggle with default closed state', () => {
|
|
12
|
+
(0, _react2.render)(/*#__PURE__*/_react.default.createElement(_Toggle.Toggle, {
|
|
13
|
+
isOpenChildren: openContent,
|
|
14
|
+
isClosedChildren: closedContent
|
|
15
|
+
}));
|
|
16
|
+
const toggle = _react2.screen.getByTestId('toggle-wrapper');
|
|
17
|
+
expect(toggle).toBeInTheDocument();
|
|
18
|
+
expect(toggle).toHaveClass('toggle');
|
|
19
|
+
expect(toggle).not.toHaveClass('open');
|
|
20
|
+
expect(_react2.screen.getByText('Closed Content')).toBeInTheDocument();
|
|
21
|
+
expect(_react2.screen.queryByText('Open Content')).not.toBeInTheDocument();
|
|
22
|
+
});
|
|
23
|
+
test('toggles to open state when clicked', async () => {
|
|
24
|
+
const user = _userEvent.default.setup();
|
|
25
|
+
(0, _react2.render)(/*#__PURE__*/_react.default.createElement(_Toggle.Toggle, {
|
|
26
|
+
isOpenChildren: openContent,
|
|
27
|
+
isClosedChildren: closedContent
|
|
28
|
+
}));
|
|
29
|
+
const toggle = _react2.screen.getByTestId('toggle-wrapper');
|
|
30
|
+
await user.click(toggle);
|
|
31
|
+
expect(toggle).toHaveClass('toggle', 'toggle--open');
|
|
32
|
+
expect(_react2.screen.getByText('Open Content')).toBeInTheDocument();
|
|
33
|
+
expect(_react2.screen.queryByText('Closed Content')).not.toBeInTheDocument();
|
|
34
|
+
});
|
|
35
|
+
test('toggles back to closed state when clicked again', async () => {
|
|
36
|
+
const user = _userEvent.default.setup();
|
|
37
|
+
(0, _react2.render)(/*#__PURE__*/_react.default.createElement(_Toggle.Toggle, {
|
|
38
|
+
isOpenChildren: openContent,
|
|
39
|
+
isClosedChildren: closedContent
|
|
40
|
+
}));
|
|
41
|
+
const toggle = _react2.screen.getByTestId('toggle-wrapper');
|
|
42
|
+
|
|
43
|
+
// Click to open
|
|
44
|
+
await user.click(toggle);
|
|
45
|
+
expect(_react2.screen.getByText('Open Content')).toBeInTheDocument();
|
|
46
|
+
|
|
47
|
+
// Click to close
|
|
48
|
+
await user.click(toggle);
|
|
49
|
+
expect(toggle).toHaveClass('toggle');
|
|
50
|
+
expect(toggle).not.toHaveClass('open');
|
|
51
|
+
expect(_react2.screen.getByText('Closed Content')).toBeInTheDocument();
|
|
52
|
+
expect(_react2.screen.queryByText('Open Content')).not.toBeInTheDocument();
|
|
53
|
+
});
|
|
54
|
+
test('renders with custom component name', () => {
|
|
55
|
+
(0, _react2.render)(/*#__PURE__*/_react.default.createElement(_Toggle.Toggle, {
|
|
56
|
+
componentName: "custom-toggle",
|
|
57
|
+
isOpenChildren: openContent,
|
|
58
|
+
isClosedChildren: closedContent
|
|
59
|
+
}));
|
|
60
|
+
const toggle = _react2.screen.getByTestId('custom-toggle-wrapper');
|
|
61
|
+
expect(toggle).toHaveClass('toggle');
|
|
62
|
+
});
|
|
63
|
+
test('renders with additional className', () => {
|
|
64
|
+
(0, _react2.render)(/*#__PURE__*/_react.default.createElement(_Toggle.Toggle, {
|
|
65
|
+
additionalClassName: "extra-class",
|
|
66
|
+
isOpenChildren: openContent,
|
|
67
|
+
isClosedChildren: closedContent
|
|
68
|
+
}));
|
|
69
|
+
const toggle = _react2.screen.getByTestId('toggle-wrapper');
|
|
70
|
+
expect(toggle).toHaveClass('toggle', 'extra-class');
|
|
71
|
+
});
|
|
72
|
+
test('renders with complex children content', async () => {
|
|
73
|
+
const user = _userEvent.default.setup();
|
|
74
|
+
const complexOpen = /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement("h3", null, "Open Title"), /*#__PURE__*/_react.default.createElement("p", null, "Open description"));
|
|
75
|
+
const complexClosed = /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement("h3", null, "Closed Title"), /*#__PURE__*/_react.default.createElement("p", null, "Closed description"));
|
|
76
|
+
(0, _react2.render)(/*#__PURE__*/_react.default.createElement(_Toggle.Toggle, {
|
|
77
|
+
isOpenChildren: complexOpen,
|
|
78
|
+
isClosedChildren: complexClosed
|
|
79
|
+
}));
|
|
80
|
+
|
|
81
|
+
// Initially closed
|
|
82
|
+
expect(_react2.screen.getByText('Closed Title')).toBeInTheDocument();
|
|
83
|
+
expect(_react2.screen.getByText('Closed description')).toBeInTheDocument();
|
|
84
|
+
|
|
85
|
+
// Click to open
|
|
86
|
+
const toggle = _react2.screen.getByTestId('toggle-wrapper');
|
|
87
|
+
await user.click(toggle);
|
|
88
|
+
expect(_react2.screen.getByText('Open Title')).toBeInTheDocument();
|
|
89
|
+
expect(_react2.screen.getByText('Open description')).toBeInTheDocument();
|
|
90
|
+
expect(_react2.screen.queryByText('Closed Title')).not.toBeInTheDocument();
|
|
91
|
+
});
|
|
92
|
+
test('multiple toggles work independently', async () => {
|
|
93
|
+
const user = _userEvent.default.setup();
|
|
94
|
+
(0, _react2.render)(/*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_Toggle.Toggle, {
|
|
95
|
+
componentName: "toggle-1",
|
|
96
|
+
isOpenChildren: /*#__PURE__*/_react.default.createElement("div", null, "Open 1"),
|
|
97
|
+
isClosedChildren: /*#__PURE__*/_react.default.createElement("div", null, "Closed 1")
|
|
98
|
+
}), /*#__PURE__*/_react.default.createElement(_Toggle.Toggle, {
|
|
99
|
+
componentName: "toggle-2",
|
|
100
|
+
isOpenChildren: /*#__PURE__*/_react.default.createElement("div", null, "Open 2"),
|
|
101
|
+
isClosedChildren: /*#__PURE__*/_react.default.createElement("div", null, "Closed 2")
|
|
102
|
+
})));
|
|
103
|
+
const toggle1 = _react2.screen.getByTestId('toggle-1-wrapper');
|
|
104
|
+
const toggle2 = _react2.screen.getByTestId('toggle-2-wrapper');
|
|
105
|
+
|
|
106
|
+
// Initially both closed
|
|
107
|
+
expect(_react2.screen.getByText('Closed 1')).toBeInTheDocument();
|
|
108
|
+
expect(_react2.screen.getByText('Closed 2')).toBeInTheDocument();
|
|
109
|
+
|
|
110
|
+
// Open first toggle
|
|
111
|
+
await user.click(toggle1);
|
|
112
|
+
expect(_react2.screen.getByText('Open 1')).toBeInTheDocument();
|
|
113
|
+
expect(_react2.screen.getByText('Closed 2')).toBeInTheDocument(); // Second still closed
|
|
114
|
+
|
|
115
|
+
// Open second toggle
|
|
116
|
+
await user.click(toggle2);
|
|
117
|
+
expect(_react2.screen.getByText('Open 1')).toBeInTheDocument(); // First still open
|
|
118
|
+
expect(_react2.screen.getByText('Open 2')).toBeInTheDocument();
|
|
119
|
+
});
|
|
120
|
+
});
|