@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.
Files changed (158) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +708 -0
  3. package/dist/__tests__/Anchor.test.js +145 -0
  4. package/dist/__tests__/ArrowRight.test.js +91 -0
  5. package/dist/__tests__/Avatar.test.js +123 -0
  6. package/dist/__tests__/Button.test.js +82 -0
  7. package/dist/__tests__/Card.test.js +198 -0
  8. package/dist/__tests__/CheckCircle.test.js +98 -0
  9. package/dist/__tests__/Checkbox.test.js +161 -0
  10. package/dist/__tests__/ChevronDown.test.js +73 -0
  11. package/dist/__tests__/Close.test.js +98 -0
  12. package/dist/__tests__/EditSquare.test.js +99 -0
  13. package/dist/__tests__/Error.test.js +74 -0
  14. package/dist/__tests__/Footer.test.js +66 -0
  15. package/dist/__tests__/Heading.test.js +227 -0
  16. package/dist/__tests__/Hero.test.js +74 -0
  17. package/dist/__tests__/Label.test.js +123 -0
  18. package/dist/__tests__/Loader.test.js +115 -0
  19. package/dist/__tests__/MenuHover.test.js +137 -0
  20. package/dist/__tests__/Paragraph.test.js +93 -0
  21. package/dist/__tests__/PlusCircle.test.js +99 -0
  22. package/dist/__tests__/Radio.test.js +153 -0
  23. package/dist/__tests__/Select.test.js +187 -0
  24. package/dist/__tests__/Tabs.test.js +162 -0
  25. package/dist/__tests__/TextArea.test.js +127 -0
  26. package/dist/__tests__/TextInput.test.js +181 -0
  27. package/dist/__tests__/Toggle.test.js +120 -0
  28. package/dist/__tests__/TrashX.test.js +99 -0
  29. package/dist/__tests__/useHeadingAccessibility.test.js +144 -0
  30. package/dist/components/Anchor.js +131 -0
  31. package/dist/components/Animation.js +129 -0
  32. package/dist/components/AnimationGroup.js +207 -0
  33. package/dist/components/AnimationToggle.js +216 -0
  34. package/dist/components/Avatar.js +153 -0
  35. package/dist/components/Button.js +218 -0
  36. package/dist/components/Card.js +222 -0
  37. package/dist/components/Checkbox.js +305 -0
  38. package/dist/components/Crud.js +564 -0
  39. package/dist/components/DragAndDrop.js +337 -0
  40. package/dist/components/Error.js +206 -0
  41. package/dist/components/Footer.js +99 -0
  42. package/dist/components/Form.js +412 -0
  43. package/dist/components/Header.js +372 -0
  44. package/dist/components/Heading.js +134 -0
  45. package/dist/components/Hero.js +181 -0
  46. package/dist/components/Label.js +256 -0
  47. package/dist/components/Loader.js +302 -0
  48. package/dist/components/MenuHover.js +114 -0
  49. package/dist/components/Paragraph.js +128 -0
  50. package/dist/components/Prompt.js +61 -0
  51. package/dist/components/Radio.js +254 -0
  52. package/dist/components/Select.js +422 -0
  53. package/dist/components/SideMenu.js +313 -0
  54. package/dist/components/Tabs.js +297 -0
  55. package/dist/components/TextArea.js +370 -0
  56. package/dist/components/TextInput.js +286 -0
  57. package/dist/components/Toggle.js +186 -0
  58. package/dist/components/crudFiles/CrudEditBase.js +150 -0
  59. package/dist/components/crudFiles/CrudViewBase.js +39 -0
  60. package/dist/components/crudFiles/crudDevelopment.js +118 -0
  61. package/dist/components/crudFiles/crudEditHandlers.js +50 -0
  62. package/dist/constants/animation.js +30 -0
  63. package/dist/icons/ArrowIcon.js +32 -0
  64. package/dist/icons/ArrowRight.js +33 -0
  65. package/dist/icons/CheckCircle.js +33 -0
  66. package/dist/icons/ChevronDown.js +28 -0
  67. package/dist/icons/Close.js +33 -0
  68. package/dist/icons/EditSquare.js +33 -0
  69. package/dist/icons/Ellipses.js +34 -0
  70. package/dist/icons/Hamburger.js +39 -0
  71. package/dist/icons/LoadingSpinner.js +42 -0
  72. package/dist/icons/PlusCircle.js +33 -0
  73. package/dist/icons/SaveIcon.js +32 -0
  74. package/dist/icons/TrashX.js +33 -0
  75. package/dist/icons/__tests__/CheckCircle.test.js +9 -0
  76. package/dist/icons/__tests__/ChevronDown.test.js +9 -0
  77. package/dist/icons/__tests__/Close.test.js +9 -0
  78. package/dist/icons/__tests__/EditSquare.test.js +9 -0
  79. package/dist/icons/__tests__/PlusCircle.test.js +9 -0
  80. package/dist/icons/__tests__/TrashX.test.js +9 -0
  81. package/dist/icons/index.js +89 -0
  82. package/dist/index.js +332 -0
  83. package/dist/setupTests.js +3 -0
  84. package/dist/styles/_variables.scss +286 -0
  85. package/dist/styles/anchor.scss +40 -0
  86. package/dist/styles/animation-accessibility.scss +96 -0
  87. package/dist/styles/animation-toggle.scss +233 -0
  88. package/dist/styles/animation.scss +3781 -0
  89. package/dist/styles/avatar.scss +285 -0
  90. package/dist/styles/button.scss +430 -0
  91. package/dist/styles/card.scss +210 -0
  92. package/dist/styles/checkbox.scss +160 -0
  93. package/dist/styles/crud.scss +474 -0
  94. package/dist/styles/dragAndDrop.scss +312 -0
  95. package/dist/styles/error.scss +232 -0
  96. package/dist/styles/footer.scss +58 -0
  97. package/dist/styles/form.scss +420 -0
  98. package/dist/styles/grid.scss +29 -0
  99. package/dist/styles/header.scss +276 -0
  100. package/dist/styles/heading.scss +118 -0
  101. package/dist/styles/hero.scss +185 -0
  102. package/dist/styles/htmlElements.scss +20 -0
  103. package/dist/styles/image.scss +9 -0
  104. package/dist/styles/label.scss +340 -0
  105. package/dist/styles/list-item.scss +5 -0
  106. package/dist/styles/loader.scss +354 -0
  107. package/dist/styles/logo.scss +19 -0
  108. package/dist/styles/main.css +9056 -0
  109. package/dist/styles/main.css.map +1 -0
  110. package/dist/styles/main.scss +0 -0
  111. package/dist/styles/menu-hover.scss +30 -0
  112. package/dist/styles/paragraph.scss +88 -0
  113. package/dist/styles/prompt.scss +51 -0
  114. package/dist/styles/radio.scss +202 -0
  115. package/dist/styles/select.scss +363 -0
  116. package/dist/styles/side-menu.scss +334 -0
  117. package/dist/styles/tabs.scss +540 -0
  118. package/dist/styles/text-area.scss +388 -0
  119. package/dist/styles/text-input.scss +171 -0
  120. package/dist/styles/toggle.scss +0 -0
  121. package/dist/styles/unordered-list.scss +8 -0
  122. package/dist/utils/ScrollHandler.js +30 -0
  123. package/dist/utils/accessibility.js +128 -0
  124. package/dist/utils/heroUtils.js +316 -0
  125. package/dist/utils/index.js +104 -0
  126. package/dist/utils/inputValidation.js +29 -0
  127. package/dist/utils/keyboardNavigation.js +536 -0
  128. package/dist/utils/labelUtils.js +708 -0
  129. package/dist/utils/loaderUtils.js +387 -0
  130. package/dist/utils/menuUtils.js +575 -0
  131. package/dist/utils/useHeadingAccessibility.js +298 -0
  132. package/dist/utils/useRadioGroup.js +260 -0
  133. package/dist/utils/useSelectAccessibility.js +426 -0
  134. package/dist/utils/useTabsAccessibility.js +278 -0
  135. package/dist/utils/useTextAreaAccessibility.js +255 -0
  136. package/dist/utils/useTextInputAccessibility.js +295 -0
  137. package/dist/utils/useTypographyAccessibility.js +168 -0
  138. package/dist/utils/useWindowSize.js +32 -0
  139. package/dist/utils/utils/ScrollHandler.js +26 -0
  140. package/dist/utils/utils/accessibility.js +133 -0
  141. package/dist/utils/utils/heroUtils.js +348 -0
  142. package/dist/utils/utils/index.js +9 -0
  143. package/dist/utils/utils/inputValidation.js +22 -0
  144. package/dist/utils/utils/keyboardNavigation.js +664 -0
  145. package/dist/utils/utils/labelUtils.js +772 -0
  146. package/dist/utils/utils/loaderUtils.js +436 -0
  147. package/dist/utils/utils/menuUtils.js +651 -0
  148. package/dist/utils/utils/useHeadingAccessibility.js +334 -0
  149. package/dist/utils/utils/useRadioGroup.js +311 -0
  150. package/dist/utils/utils/useSelectAccessibility.js +498 -0
  151. package/dist/utils/utils/useTabsAccessibility.js +316 -0
  152. package/dist/utils/utils/useTextAreaAccessibility.js +303 -0
  153. package/dist/utils/utils/useTextInputAccessibility.js +338 -0
  154. package/dist/utils/utils/useTypographyAccessibility.js +180 -0
  155. package/dist/utils/utils/useWindowSize.js +26 -0
  156. package/dist/utils/utils/validation.js +131 -0
  157. package/dist/utils/validation.js +139 -0
  158. package/package.json +90 -0
@@ -0,0 +1,372 @@
1
+ "use strict";
2
+ 'use client';
3
+
4
+ /**
5
+ * Header Component
6
+ *
7
+ * A responsive navigation header component that adapts between desktop and mobile layouts.
8
+ * Features keyboard navigation, screen reader support, and ARIA compliance.
9
+ *
10
+ * @component
11
+ * @example
12
+ * ```jsx
13
+ * <Header
14
+ * logo={<Logo />}
15
+ * navigation={navigationItems}
16
+ * mapMenuItems={mobileMenuItems}
17
+ * hasAuth={true}
18
+ * isMenuOpen={false}
19
+ * isEllipsesOpen={false}
20
+ * onMenuToggle={(isOpen) => setMenuOpen(isOpen)}
21
+ * onEllipsesToggle={(isOpen) => setEllipsesOpen(isOpen)}
22
+ * ariaLabel="Main navigation"
23
+ * menuAriaLabel="Navigation menu"
24
+ * userMenuAriaLabel="User menu"
25
+ * avatarSrc="path/to/avatar.jpg"
26
+ * />
27
+ * ```
28
+ *
29
+ * @param {object} props - Component props
30
+ * @param {string} [props.componentName='header'] - Base component CSS class name
31
+ * @param {string} [props.additionalClassName=''] - Additional CSS classes to apply
32
+ * @param {React.ReactNode} props.logo - Logo element to display in header (required for branding)
33
+ * @param {React.ReactNode} props.navigation - Desktop navigation items (required for navigation)
34
+ * @param {React.ReactNode} props.mapMenuItems - Mobile navigation menu items (required for mobile UX)
35
+ * @param {boolean} [props.hasAuth=false] - Whether user is authenticated (affects UI layout)
36
+ * @param {React.ReactNode} [props.signInLink] - Sign in link component for unauthenticated users
37
+ * @param {React.ReactNode} [props.signUpLink] - Sign up link component for unauthenticated users
38
+ * @param {string} [props.avatarSrc] - User avatar image source for authenticated users
39
+ * @param {React.ReactNode[]} [props.ellipsesList=[]] - List of user menu items for dropdown
40
+ * @param {React.ReactNode} [props.search] - Search component for header search functionality
41
+ * @param {boolean} props.isMenuOpen - Whether mobile menu is currently open (controlled state, required)
42
+ * @param {boolean} props.isEllipsesOpen - Whether user dropdown menu is currently open (controlled state, required)
43
+ * @param {function} props.onMenuToggle - Callback when mobile menu toggle is triggered (required for state management)
44
+ * @param {function} props.onEllipsesToggle - Callback when user dropdown toggle is triggered (required for state management)
45
+ * @param {function} [props.onKeyDown] - Additional callback for custom keyboard event handling
46
+ * @param {string} props.ariaLabel - ARIA label for the header element (required for accessibility)
47
+ * @param {string} props.menuAriaLabel - ARIA label for the navigation menu (required for screen readers)
48
+ * @param {string} props.userMenuAriaLabel - ARIA label for the user menu (required for screen readers)
49
+ */
50
+ 'react';
51
+
52
+ Object.defineProperty(exports, "__esModule", {
53
+ value: true
54
+ });
55
+ exports.Header = void 0;
56
+ var _react = _interopRequireWildcard(require("react"));
57
+ var _propTypes = require("prop-types");
58
+ var _Avatar = require("./Avatar");
59
+ var _SideMenu = require("./SideMenu");
60
+ var _Close = require("../icons/Close");
61
+ var _Hamburger = require("../icons/Hamburger");
62
+ var _useWindowSize = require("../utils/useWindowSize");
63
+ var _accessibility = require("../utils/accessibility");
64
+ 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); }
65
+ 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); } // components
66
+ // utils
67
+ /**
68
+ * Header Component
69
+ *
70
+ * A responsive navigation header component that adapts between desktop and mobile layouts.
71
+ * Features keyboard navigation, screen reader support, and ARIA compliance.
72
+ *
73
+ * @component
74
+ * @example
75
+ * ```jsx
76
+ * <Header
77
+ * logo={<Logo />}
78
+ * navigation={navigationItems}
79
+ * hasAuth={true}
80
+ * isMenuOpen={false}
81
+ * onMenuToggle={(isOpen) => setMenuOpen(isOpen)}
82
+ * onEllipsesToggle={(isOpen) => setEllipsesOpen(isOpen)}
83
+ * avatarSrc="path/to/avatar.jpg"
84
+ * />
85
+ * ```
86
+ */
87
+ const Header = exports.Header = /*#__PURE__*/(0, _react.forwardRef)(({
88
+ // Core props
89
+ id,
90
+ className = '',
91
+ // Content props
92
+ logo = null,
93
+ navigation = null,
94
+ mapMenuItems = null,
95
+ signInLink = null,
96
+ signUpLink = null,
97
+ avatarSrc = null,
98
+ ellipsesList = [],
99
+ search = null,
100
+ // Behavior props
101
+ hasAuth = false,
102
+ isMenuOpen = false,
103
+ isEllipsesOpen = false,
104
+ // Event props
105
+ onMenuToggle = null,
106
+ onEllipsesToggle = null,
107
+ onKeyDown = null,
108
+ // Accessibility props
109
+ ariaLabel = 'Main navigation',
110
+ menuAriaLabel = 'Navigation menu',
111
+ userMenuAriaLabel = 'User menu',
112
+ // Legacy props (for backward compatibility - internal use only)
113
+ componentName = 'header',
114
+ additionalClassName = '',
115
+ ...restProps
116
+ }, ref) => {
117
+ // Handle legacy prop mapping
118
+ const finalId = id || `header-${Math.random().toString(36).substr(2, 9)}`;
119
+ const finalClassName = className || additionalClassName;
120
+ const size = (0, _useWindowSize.useWindowSize)();
121
+ const isMobile = size.width < 768;
122
+
123
+ // Handle keyboard navigation
124
+ const handleKeyDown = event => {
125
+ const {
126
+ key,
127
+ target
128
+ } = event;
129
+
130
+ // Escape key closes any open menus
131
+ if (key === 'Escape') {
132
+ if (isMenuOpen && onMenuToggle) {
133
+ onMenuToggle(false);
134
+ (0, _accessibility.announceToScreenReader)('Menu closed');
135
+ }
136
+ if (isEllipsesOpen && onEllipsesToggle) {
137
+ onEllipsesToggle(false);
138
+ (0, _accessibility.announceToScreenReader)('User menu closed');
139
+ }
140
+ }
141
+
142
+ // Tab key management for focus trapping in mobile menu
143
+ if (key === 'Tab' && isMenuOpen && isMobile) {
144
+ const focusableElements = target.closest('.side-menu')?.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])');
145
+ if (focusableElements && focusableElements.length > 0) {
146
+ const firstElement = focusableElements[0];
147
+ const lastElement = focusableElements[focusableElements.length - 1];
148
+ if (event.shiftKey && target === firstElement) {
149
+ event.preventDefault();
150
+ (0, _accessibility.safeFocus)(lastElement);
151
+ } else if (!event.shiftKey && target === lastElement) {
152
+ event.preventDefault();
153
+ (0, _accessibility.safeFocus)(firstElement);
154
+ }
155
+ }
156
+ }
157
+ if (onKeyDown) onKeyDown(event);
158
+ };
159
+
160
+ // Hamburger and Close icons
161
+ const hamburgerIcon = /*#__PURE__*/_react.default.createElement(_Hamburger.Hamburger, null);
162
+ const closeIcon = /*#__PURE__*/_react.default.createElement(_Close.Close, null);
163
+
164
+ // Handlers for menu and ellipses
165
+ const handleMenuToggle = () => {
166
+ if (onMenuToggle) onMenuToggle(!isMenuOpen);
167
+ };
168
+ const handleEllipsesToggle = () => {
169
+ if (onEllipsesToggle) onEllipsesToggle(!isEllipsesOpen);
170
+ };
171
+ return /*#__PURE__*/_react.default.createElement("header", _extends({
172
+ ref: ref,
173
+ id: finalId,
174
+ className: `${componentName} ${finalClassName}`,
175
+ "data-testid": componentName,
176
+ role: "banner",
177
+ "aria-label": ariaLabel,
178
+ onKeyDown: handleKeyDown
179
+ }, restProps), /*#__PURE__*/_react.default.createElement("div", {
180
+ className: isMobile ? 'container-mobile' : 'container-large'
181
+ }, logo, search, isMobile ? /*#__PURE__*/_react.default.createElement(_SideMenu.SideMenu, {
182
+ direction: "vertical",
183
+ position: "top",
184
+ isOpen: isMenuOpen,
185
+ onToggle: handleMenuToggle,
186
+ onOpen: () => (0, _accessibility.announceToScreenReader)('Menu opened'),
187
+ onClose: () => (0, _accessibility.announceToScreenReader)('Menu closed'),
188
+ closeOnBackdrop: true,
189
+ closeOnEscape: true,
190
+ ariaLabel: menuAriaLabel,
191
+ trigger: /*#__PURE__*/_react.default.createElement("button", {
192
+ type: "button",
193
+ "aria-label": `${isMenuOpen ? 'Close' : 'Open'} ${menuAriaLabel.toLowerCase()}`,
194
+ "aria-expanded": isMenuOpen,
195
+ "aria-controls": "mobile-navigation",
196
+ onClick: handleMenuToggle,
197
+ className: "mobile-menu-trigger"
198
+ }, hamburgerIcon),
199
+ rightIconClose: /*#__PURE__*/_react.default.createElement("button", {
200
+ type: "button",
201
+ "aria-label": "Close menu",
202
+ onClick: handleMenuToggle,
203
+ className: "mobile-menu-close"
204
+ }, closeIcon),
205
+ menuItems: mapMenuItems,
206
+ navigation: navigation,
207
+ signInLink: signInLink,
208
+ signUpLink: signUpLink,
209
+ avatarSrc: avatarSrc,
210
+ ellipsesList: ellipsesList,
211
+ userMenuAriaLabel: userMenuAriaLabel,
212
+ isEllipsesOpen: isEllipsesOpen,
213
+ onEllipsesToggle: handleEllipsesToggle
214
+ }) : /*#__PURE__*/_react.default.createElement("nav", {
215
+ className: "navigation",
216
+ "data-testid": "navigation",
217
+ role: "navigation",
218
+ "aria-label": menuAriaLabel
219
+ }, /*#__PURE__*/_react.default.createElement("ul", {
220
+ className: "unordered-list",
221
+ role: "menubar",
222
+ "aria-orientation": "horizontal"
223
+ }, navigation), /*#__PURE__*/_react.default.createElement("ul", {
224
+ className: "unordered-list auth-menu",
225
+ role: "menubar",
226
+ "aria-label": "Authentication"
227
+ }, hasAuth ? /*#__PURE__*/_react.default.createElement("li", {
228
+ className: "list-item",
229
+ role: "none"
230
+ }, /*#__PURE__*/_react.default.createElement("div", {
231
+ className: "head"
232
+ }, /*#__PURE__*/_react.default.createElement("button", {
233
+ type: "button",
234
+ className: "ellipses",
235
+ onClick: handleEllipsesToggle,
236
+ "aria-label": `${isEllipsesOpen ? 'Close' : 'Open'} ${userMenuAriaLabel.toLowerCase()}`,
237
+ "aria-expanded": isEllipsesOpen,
238
+ "aria-haspopup": "menu",
239
+ "aria-controls": "user-menu-dropdown",
240
+ id: "user-menu-button"
241
+ }, /*#__PURE__*/_react.default.createElement(_Avatar.Avatar, {
242
+ dimensions: "50px",
243
+ source: avatarSrc,
244
+ alt: "User avatar"
245
+ }), isEllipsesOpen && /*#__PURE__*/_react.default.createElement("div", {
246
+ className: "ellipses-content",
247
+ role: "menu",
248
+ "aria-labelledby": "user-menu-button",
249
+ id: "user-menu-dropdown"
250
+ }, /*#__PURE__*/_react.default.createElement("ul", {
251
+ className: "unordered-list",
252
+ role: "none"
253
+ }, ellipsesList))))) : /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("li", {
254
+ className: "list-item",
255
+ role: "none"
256
+ }, /*#__PURE__*/_react.default.createElement("div", {
257
+ role: "menuitem",
258
+ tabIndex: 0
259
+ }, signInLink)), /*#__PURE__*/_react.default.createElement("li", {
260
+ className: "list-item",
261
+ role: "none"
262
+ }, /*#__PURE__*/_react.default.createElement("div", {
263
+ role: "menuitem",
264
+ tabIndex: 0
265
+ }, signUpLink)))))));
266
+ });
267
+
268
+ // Set display name for debugging
269
+ Header.displayName = 'Header';
270
+ Header.propTypes = {
271
+ // ===========================================
272
+ // Core Props
273
+ // ===========================================
274
+ /**
275
+ * Unique identifier for the component
276
+ */
277
+ id: _propTypes.string,
278
+ /**
279
+ * Additional CSS classes to apply
280
+ */
281
+ className: _propTypes.string,
282
+ // ===========================================
283
+ // Content Props
284
+ // ===========================================
285
+ /**
286
+ * Logo element to display in header (required for branding)
287
+ */
288
+ logo: _propTypes.node.isRequired,
289
+ /**
290
+ * Desktop navigation items (required for navigation)
291
+ */
292
+ navigation: _propTypes.node.isRequired,
293
+ /**
294
+ * Mobile navigation menu items (required for mobile UX)
295
+ */
296
+ mapMenuItems: _propTypes.node.isRequired,
297
+ /**
298
+ * Sign in link component for unauthenticated users
299
+ */
300
+ signInLink: _propTypes.node,
301
+ /**
302
+ * Sign up link component for unauthenticated users
303
+ */
304
+ signUpLink: _propTypes.node,
305
+ /**
306
+ * User avatar image source for authenticated users
307
+ */
308
+ avatarSrc: _propTypes.string,
309
+ /**
310
+ * List of user menu items for dropdown
311
+ */
312
+ ellipsesList: (0, _propTypes.arrayOf)(_propTypes.node),
313
+ /**
314
+ * Search component for header search functionality
315
+ */
316
+ search: _propTypes.node,
317
+ // ===========================================
318
+ // Behavior Props
319
+ // ===========================================
320
+ /**
321
+ * Whether user is authenticated (affects UI layout)
322
+ */
323
+ hasAuth: _propTypes.bool,
324
+ /**
325
+ * Whether mobile menu is currently open (controlled state, required)
326
+ */
327
+ isMenuOpen: _propTypes.bool.isRequired,
328
+ /**
329
+ * Whether user dropdown menu is currently open (controlled state, required)
330
+ */
331
+ isEllipsesOpen: _propTypes.bool.isRequired,
332
+ // ===========================================
333
+ // Event Props
334
+ // ===========================================
335
+ /**
336
+ * Callback when mobile menu toggle is triggered (required for state management)
337
+ */
338
+ onMenuToggle: _propTypes.func.isRequired,
339
+ /**
340
+ * Callback when user dropdown toggle is triggered (required for state management)
341
+ */
342
+ onEllipsesToggle: _propTypes.func.isRequired,
343
+ /**
344
+ * Additional callback for custom keyboard event handling
345
+ */
346
+ onKeyDown: _propTypes.func,
347
+ // ===========================================
348
+ // Accessibility Props
349
+ // ===========================================
350
+ /**
351
+ * ARIA label for the header element (required for accessibility)
352
+ */
353
+ ariaLabel: _propTypes.string.isRequired,
354
+ /**
355
+ * ARIA label for the navigation menu (required for screen readers)
356
+ */
357
+ menuAriaLabel: _propTypes.string.isRequired,
358
+ /**
359
+ * ARIA label for the user menu (required for screen readers)
360
+ */
361
+ userMenuAriaLabel: _propTypes.string.isRequired,
362
+ /**
363
+ * Use id for identification
364
+ * Base component CSS class name
365
+ */
366
+ componentName: _propTypes.string,
367
+ /**
368
+ * Use className instead
369
+ * Additional CSS classes to apply
370
+ */
371
+ additionalClassName: _propTypes.string
372
+ };
@@ -0,0 +1,134 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = exports.Heading = void 0;
7
+ var _react = _interopRequireWildcard(require("react"));
8
+ var _propTypes = require("prop-types");
9
+ 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); }
10
+ 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); }
11
+ /**
12
+ * Heading Component
13
+ *
14
+ * A semantic heading component that renders appropriate HTML heading elements (h1-h6)
15
+ * with proper accessibility and styling support.
16
+ *
17
+ * This component ensures proper document structure and hierarchy for screen readers
18
+ * and SEO while providing flexible styling options.
19
+ *
20
+ * @component
21
+ * @example
22
+ * // Basic usage
23
+ * <Heading level={1}>Main Page Title</Heading>
24
+ *
25
+ * @example
26
+ * // With custom styling and accessibility
27
+ * <Heading
28
+ * level={2}
29
+ * className="section-title"
30
+ * id="about-section"
31
+ * aria-describedby="about-description"
32
+ * >
33
+ * About Us
34
+ * </Heading>
35
+ *
36
+ * @example
37
+ * // With different variants and sizes
38
+ * <Heading level={3} variant="primary" size="large">
39
+ * Feature Highlight
40
+ * </Heading>
41
+ */
42
+ const Heading = exports.Heading = /*#__PURE__*/(0, _react.forwardRef)(({
43
+ // Core props
44
+ level = 1,
45
+ children = null,
46
+ // Layout props
47
+ className = '',
48
+ variant = 'default',
49
+ size = 'default',
50
+ // Accessibility props
51
+ id,
52
+ 'aria-level': ariaLevel,
53
+ 'aria-labelledby': ariaLabelledby,
54
+ 'aria-describedby': ariaDescribedby,
55
+ // Legacy props (for backward compatibility - internal use only)
56
+ additionalClassName = '',
57
+ componentName = 'heading',
58
+ ...restProps
59
+ }, ref) => {
60
+ // Handle legacy prop mapping
61
+ // For backward compatibility, if variant is a number, treat it as level
62
+ const isLegacyVariant = typeof variant === 'number';
63
+ const finalLevel = isLegacyVariant ? variant : level;
64
+ const finalClassName = className || additionalClassName;
65
+
66
+ // Build CSS classes - keep it simple to match tests
67
+ const HeadingTag = `h${finalLevel}`;
68
+ const headingClasses = [HeadingTag, componentName, finalClassName].filter(Boolean).join(' ').trim();
69
+ return /*#__PURE__*/_react.default.createElement(HeadingTag, _extends({
70
+ ref: ref,
71
+ id: id,
72
+ className: headingClasses,
73
+ "data-testid": componentName
74
+ // Accessibility attributes
75
+ ,
76
+ "aria-level": ariaLevel || finalLevel,
77
+ "aria-labelledby": ariaLabelledby,
78
+ "aria-describedby": ariaDescribedby
79
+ }, restProps), children);
80
+ });
81
+ var _default = exports.default = Heading; // Set display name for debugging
82
+ Heading.displayName = 'Heading';
83
+ Heading.propTypes = {
84
+ // ===========================================
85
+ // Core Props
86
+ // ===========================================
87
+ /**
88
+ * Heading level (1-6) that determines semantic importance and HTML element.
89
+ * Required for proper document structure and accessibility.
90
+ */
91
+ level: (0, _propTypes.oneOf)([1, 2, 3, 4, 5, 6]),
92
+ /**
93
+ * Unique identifier for the heading
94
+ */
95
+ id: _propTypes.string,
96
+ // ===========================================
97
+ // Content Props
98
+ // ===========================================
99
+ /**
100
+ * The content to be displayed in the heading.
101
+ * Can be text, React elements, or other nodes.
102
+ */
103
+ children: _propTypes.node,
104
+ // ===========================================
105
+ // Appearance Props
106
+ // ===========================================
107
+ /**
108
+ * Additional CSS classes to apply to the heading element
109
+ */
110
+ className: _propTypes.string,
111
+ /**
112
+ * Visual style variant
113
+ */
114
+ variant: _propTypes.string,
115
+ /**
116
+ * Size variant for the heading
117
+ */
118
+ size: _propTypes.string,
119
+ // ===========================================
120
+ // Accessibility Props
121
+ // ===========================================
122
+ /**
123
+ * ARIA level override (if different from semantic level)
124
+ */
125
+ 'aria-level': (0, _propTypes.oneOf)([1, 2, 3, 4, 5, 6]),
126
+ /**
127
+ * ID of element that labels this heading
128
+ */
129
+ 'aria-labelledby': _propTypes.string,
130
+ /**
131
+ * ID(s) of elements that describe this heading
132
+ */
133
+ 'aria-describedby': _propTypes.string
134
+ };
@@ -0,0 +1,181 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = exports.Hero = void 0;
7
+ var _react = _interopRequireWildcard(require("react"));
8
+ var _Animation = require("./Animation");
9
+ var _propTypes = require("prop-types");
10
+ 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); }
11
+ 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); }
12
+ /**
13
+ * Hero - Accessible hero section component for prominent content display
14
+ *
15
+ * Features:
16
+ * - Semantic HTML structure using section element
17
+ * - Background image support with accessibility features
18
+ * - Customizable overlay with opacity controls
19
+ * - Full ARIA support for screen readers
20
+ * - Responsive design with flexible content area
21
+ * - High contrast mode support
22
+ *
23
+ * Accessibility:
24
+ * - Uses semantic <section> element with proper ARIA roles
25
+ * - Background images include proper alt text descriptions
26
+ * - Screen reader accessible overlay elements
27
+ * - Proper landmark navigation with role="banner"
28
+ * - Focus management and keyboard navigation support
29
+ *
30
+ * @component
31
+ * @example
32
+ * // Basic hero with background
33
+ * <Hero background="/hero-image.jpg" backgroundAlt="City skyline">
34
+ * <h1>Welcome to Our Platform</h1>
35
+ * <p>Discover amazing features and capabilities.</p>
36
+ * </Hero>
37
+ *
38
+ * @example
39
+ * // Hero with overlay for better text readability
40
+ * <Hero
41
+ * background="/hero.jpg"
42
+ * backgroundAlt="Team collaboration"
43
+ * hasOverlay={true}
44
+ * overlayOpacity="dark"
45
+ * >
46
+ * <h1>Build Something Amazing</h1>
47
+ * </Hero>
48
+ *
49
+ * @example
50
+ * // Custom styling and accessibility
51
+ * <Hero
52
+ * className="landing-hero"
53
+ * role="banner"
54
+ * aria-label="Main hero section"
55
+ * >
56
+ * <h1>No Background Hero</h1>
57
+ * </Hero>
58
+ */
59
+ const Hero = exports.Hero = /*#__PURE__*/(0, _react.forwardRef)(({
60
+ // Core props
61
+ children = null,
62
+ background = null,
63
+ backgroundAlt = '',
64
+ // Layout props
65
+ className = '',
66
+ hasOverlay = false,
67
+ overlayOpacity = 'medium',
68
+ // Accessibility props
69
+ role = 'banner',
70
+ ariaLabel = null,
71
+ ariaLabelledBy = null,
72
+ // Legacy props (for backward compatibility - internal use only)
73
+ additionalClassName = '',
74
+ componentName = 'hero',
75
+ testId = 'hero',
76
+ ...restProps
77
+ }, ref) => {
78
+ // Handle legacy prop mapping
79
+ const finalClassName = className || additionalClassName;
80
+
81
+ // Build CSS classes
82
+
83
+ const finalComponentName = componentName || 'hero';
84
+ const overlayClass = hasOverlay ? `${finalComponentName}--overlay-${overlayOpacity}` : '';
85
+ const heroClasses = [`${finalComponentName}-wrapper`, overlayClass, finalClassName].filter(Boolean).join(' ').trim();
86
+
87
+ // Accessibility attributes
88
+ const accessibilityProps = {
89
+ role,
90
+ ...(ariaLabel && {
91
+ 'aria-label': ariaLabel
92
+ }),
93
+ ...(ariaLabelledBy && {
94
+ 'aria-labelledby': ariaLabelledBy
95
+ }),
96
+ ...(background && backgroundAlt && {
97
+ 'aria-describedby': `${testId}-bg-description`
98
+ })
99
+ };
100
+ return /*#__PURE__*/_react.default.createElement(_Animation.AnimatedDiv, {
101
+ fadingEntrances: "fadeIn",
102
+ duration: "faster"
103
+ }, /*#__PURE__*/_react.default.createElement("section", _extends({
104
+ ref: ref,
105
+ className: heroClasses,
106
+ "data-testid": testId || finalComponentName,
107
+ style: background ? {
108
+ backgroundImage: `url(${background})`
109
+ } : {}
110
+ }, accessibilityProps, restProps), background && backgroundAlt && /*#__PURE__*/_react.default.createElement("div", {
111
+ id: `${testId}-bg-description`,
112
+ className: "sr-only"
113
+ }, "Background image: ", backgroundAlt), hasOverlay && /*#__PURE__*/_react.default.createElement("div", {
114
+ className: `${finalComponentName}__overlay`,
115
+ "aria-hidden": "true"
116
+ }), /*#__PURE__*/_react.default.createElement("div", {
117
+ className: finalComponentName
118
+ }, children)));
119
+ });
120
+ Hero.propTypes = {
121
+ // ===========================================
122
+ // Content Props
123
+ // ===========================================
124
+ /**
125
+ * Content to display within the hero section
126
+ */
127
+ children: _propTypes.node,
128
+ // ===========================================
129
+ // Appearance Props
130
+ // ===========================================
131
+ /**
132
+ * Background image URL
133
+ */
134
+ background: _propTypes.string,
135
+ /**
136
+ * Alt text description for background image (required when background is provided)
137
+ */
138
+ backgroundAlt: _propTypes.string,
139
+ /**
140
+ * Additional CSS classes to apply to the hero wrapper
141
+ */
142
+ className: _propTypes.string,
143
+ /**
144
+ * Whether to show a semi-transparent overlay over the background
145
+ */
146
+ hasOverlay: _propTypes.bool,
147
+ /**
148
+ * Opacity level of the overlay
149
+ */
150
+ overlayOpacity: (0, _propTypes.oneOf)(['light', 'medium', 'dark']),
151
+ // ===========================================
152
+ // Accessibility Props
153
+ // ===========================================
154
+ /**
155
+ * ARIA role for semantic meaning
156
+ */
157
+ role: (0, _propTypes.oneOf)(['banner', 'region', 'main']),
158
+ /**
159
+ * ARIA label for accessibility
160
+ */
161
+ // aria-label is used as a prop, not ariaLabel
162
+ /**
163
+ * ID of element that labels this hero section
164
+ */
165
+ ariaLabelledBy: _propTypes.string,
166
+ /**
167
+ * Use className instead
168
+ */
169
+ additionalClassName: _propTypes.string,
170
+ /**
171
+ * Use className/id for identification
172
+ * Base CSS class name for the component
173
+ */
174
+ componentName: _propTypes.string,
175
+ /**
176
+ * Test ID for testing and automation
177
+ */
178
+ testId: _propTypes.string
179
+ };
180
+ Hero.displayName = 'Hero';
181
+ var _default = exports.default = Hero;