taro-uno-ui 0.9.0-beta
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 +100 -0
- package/README.md +273 -0
- package/dist/js/index-6NJ3A1Dn.js +26535 -0
- package/dist/js/index-6NJ3A1Dn.js.map +1 -0
- package/dist/js/index-DFdcksbe.js +1165 -0
- package/dist/js/index-DFdcksbe.js.map +1 -0
- package/dist/js/index-DXRIkWX1.js +1148 -0
- package/dist/js/index-DXRIkWX1.js.map +1 -0
- package/dist/js/index-DffLRSro.js +26519 -0
- package/dist/js/index-DffLRSro.js.map +1 -0
- package/package.json +119 -0
- package/src/app.config.ts +55 -0
- package/src/app.scss +508 -0
- package/src/app.tsx +44 -0
- package/src/components/basic/Button/Button.styles.ts +130 -0
- package/src/components/basic/Button/Button.test.tsx +154 -0
- package/src/components/basic/Button/Button.tsx +93 -0
- package/src/components/basic/Button/Button.types.ts +45 -0
- package/src/components/basic/Button/index.tsx +6 -0
- package/src/components/basic/Divider/Divider.styles.ts +488 -0
- package/src/components/basic/Divider/Divider.test.tsx +551 -0
- package/src/components/basic/Divider/Divider.tsx +361 -0
- package/src/components/basic/Divider/Divider.types.ts +261 -0
- package/src/components/basic/Divider/index.tsx +25 -0
- package/src/components/basic/Icon/Icon.styles.ts +359 -0
- package/src/components/basic/Icon/Icon.test.tsx +357 -0
- package/src/components/basic/Icon/Icon.tsx +154 -0
- package/src/components/basic/Icon/Icon.types.ts +210 -0
- package/src/components/basic/Icon/index.tsx +22 -0
- package/src/components/basic/Text/Text.styles.ts +500 -0
- package/src/components/basic/Text/Text.test.tsx +299 -0
- package/src/components/basic/Text/Text.tsx +340 -0
- package/src/components/basic/Text/Text.types.ts +319 -0
- package/src/components/basic/Text/index.tsx +27 -0
- package/src/components/basic/Typography/Typography.styles.ts +346 -0
- package/src/components/basic/Typography/Typography.tsx +205 -0
- package/src/components/basic/Typography/Typography.types.ts +296 -0
- package/src/components/basic/Typography/index.tsx +14 -0
- package/src/components/basic/index.tsx +302 -0
- package/src/components/common/ErrorBoundary.tsx +87 -0
- package/src/components/common/LazyComponent.tsx +246 -0
- package/src/components/common/ResponsiveContainer.tsx +93 -0
- package/src/components/common/ResponsiveGrid.tsx +183 -0
- package/src/components/common/SecurityProvider.tsx +110 -0
- package/src/components/common/ThemeProvider.tsx +128 -0
- package/src/components/common/VirtualList.tsx +368 -0
- package/src/components/common/__tests__/ErrorBoundary.test.tsx +249 -0
- package/src/components/common/index.tsx +7 -0
- package/src/components/display/Avatar/Avatar.styles.ts +62 -0
- package/src/components/display/Avatar/Avatar.test.tsx +390 -0
- package/src/components/display/Avatar/Avatar.tsx +79 -0
- package/src/components/display/Avatar/Avatar.types.ts +40 -0
- package/src/components/display/Avatar/index.ts +3 -0
- package/src/components/display/Badge/Badge.tsx +42 -0
- package/src/components/display/Badge/Badge.types.ts +29 -0
- package/src/components/display/Badge/index.ts +2 -0
- package/src/components/display/Calendar/Calendar.styles.ts +255 -0
- package/src/components/display/Calendar/Calendar.test.tsx +30 -0
- package/src/components/display/Calendar/Calendar.tsx +337 -0
- package/src/components/display/Calendar/Calendar.types.ts +91 -0
- package/src/components/display/Calendar/index.ts +3 -0
- package/src/components/display/Card/Card.styles.ts +89 -0
- package/src/components/display/Card/Card.test.tsx +180 -0
- package/src/components/display/Card/Card.tsx +135 -0
- package/src/components/display/Card/Card.types.ts +55 -0
- package/src/components/display/Card/index.ts +3 -0
- package/src/components/display/Carousel/Carousel.styles.ts +206 -0
- package/src/components/display/Carousel/Carousel.tsx +295 -0
- package/src/components/display/Carousel/Carousel.types.ts +57 -0
- package/src/components/display/Carousel/index.ts +3 -0
- package/src/components/display/List/List.styles.ts +79 -0
- package/src/components/display/List/List.tsx +115 -0
- package/src/components/display/List/List.types.ts +68 -0
- package/src/components/display/List/index.ts +3 -0
- package/src/components/display/Rate/Rate.styles.ts +266 -0
- package/src/components/display/Rate/Rate.tsx +332 -0
- package/src/components/display/Rate/Rate.types.ts +111 -0
- package/src/components/display/Rate/index.ts +28 -0
- package/src/components/display/Table/Table.styles.ts +269 -0
- package/src/components/display/Table/Table.test.tsx +343 -0
- package/src/components/display/Table/Table.tsx +430 -0
- package/src/components/display/Table/Table.types.ts +255 -0
- package/src/components/display/Table/index.tsx +16 -0
- package/src/components/display/Tag/Tag.styles.ts +197 -0
- package/src/components/display/Tag/Tag.test.tsx +541 -0
- package/src/components/display/Tag/Tag.tsx +156 -0
- package/src/components/display/Tag/Tag.types.ts +49 -0
- package/src/components/display/Tag/index.ts +3 -0
- package/src/components/display/Timeline/Timeline.styles.ts +211 -0
- package/src/components/display/Timeline/Timeline.tsx +239 -0
- package/src/components/display/Timeline/Timeline.types.ts +56 -0
- package/src/components/display/Timeline/index.ts +3 -0
- package/src/components/display/index.tsx +143 -0
- package/src/components/feedback/Loading/Loading.styles.ts +117 -0
- package/src/components/feedback/Loading/Loading.test.tsx +534 -0
- package/src/components/feedback/Loading/Loading.tsx +127 -0
- package/src/components/feedback/Loading/Loading.types.ts +33 -0
- package/src/components/feedback/Loading/index.ts +9 -0
- package/src/components/feedback/Message/Message.styles.ts +41 -0
- package/src/components/feedback/Message/Message.test.tsx +234 -0
- package/src/components/feedback/Message/Message.tsx +96 -0
- package/src/components/feedback/Message/Message.types.ts +37 -0
- package/src/components/feedback/Message/index.ts +9 -0
- package/src/components/feedback/Modal/Modal.styles.ts +21 -0
- package/src/components/feedback/Modal/Modal.test.tsx +11 -0
- package/src/components/feedback/Modal/Modal.tsx +291 -0
- package/src/components/feedback/Modal/Modal.types.ts +141 -0
- package/src/components/feedback/Modal/index.tsx +11 -0
- package/src/components/feedback/Notification/Notification.styles.ts +443 -0
- package/src/components/feedback/Notification/Notification.test.tsx +401 -0
- package/src/components/feedback/Notification/Notification.tsx +370 -0
- package/src/components/feedback/Notification/Notification.types.ts +336 -0
- package/src/components/feedback/Notification/NotificationManager.tsx +376 -0
- package/src/components/feedback/Notification/index.ts +33 -0
- package/src/components/feedback/Notification/index.tsx +164 -0
- package/src/components/feedback/Progress/Progress.styles.ts +460 -0
- package/src/components/feedback/Progress/Progress.test.simple.tsx +14 -0
- package/src/components/feedback/Progress/Progress.test.tsx +312 -0
- package/src/components/feedback/Progress/Progress.tsx +508 -0
- package/src/components/feedback/Progress/Progress.types.ts +163 -0
- package/src/components/feedback/Progress/index.ts +3 -0
- package/src/components/feedback/Progress/index.tsx +38 -0
- package/src/components/feedback/Progress/utils/animation.ts +204 -0
- package/src/components/feedback/Progress/utils/index.ts +26 -0
- package/src/components/feedback/Progress/utils/progress-calculator.ts +217 -0
- package/src/components/feedback/Result/Result.styles.ts +139 -0
- package/src/components/feedback/Result/Result.tsx +233 -0
- package/src/components/feedback/Result/Result.types.ts +128 -0
- package/src/components/feedback/Result/index.tsx +3 -0
- package/src/components/feedback/Toast/Toast.styles.ts +17 -0
- package/src/components/feedback/Toast/Toast.test.tsx +10 -0
- package/src/components/feedback/Toast/Toast.tsx +372 -0
- package/src/components/feedback/Toast/Toast.types.ts +86 -0
- package/src/components/feedback/Toast/index.tsx +3 -0
- package/src/components/feedback/Tooltip/Tooltip.examples.tsx +458 -0
- package/src/components/feedback/Tooltip/Tooltip.styles.ts +346 -0
- package/src/components/feedback/Tooltip/Tooltip.test.tsx +446 -0
- package/src/components/feedback/Tooltip/Tooltip.tsx +283 -0
- package/src/components/feedback/Tooltip/Tooltip.types.ts +172 -0
- package/src/components/feedback/Tooltip/index.ts +3 -0
- package/src/components/feedback/Tooltip/index.tsx +258 -0
- package/src/components/feedback/index.tsx +164 -0
- package/src/components/form/Cascader/Cascader.styles.ts +526 -0
- package/src/components/form/Cascader/Cascader.test.tsx +77 -0
- package/src/components/form/Cascader/Cascader.tsx +585 -0
- package/src/components/form/Cascader/Cascader.types.ts +582 -0
- package/src/components/form/Cascader/hooks/index.ts +3 -0
- package/src/components/form/Cascader/hooks/useCascaderFieldNames.ts +16 -0
- package/src/components/form/Cascader/hooks/useCascaderOptions.ts +109 -0
- package/src/components/form/Cascader/hooks/useCascaderState.ts +133 -0
- package/src/components/form/Cascader/index.ts +25 -0
- package/src/components/form/Cascader/utils/formatDisplayValue.ts +19 -0
- package/src/components/form/Cascader/utils/index.ts +1 -0
- package/src/components/form/Checkbox/Checkbox.styles.ts +608 -0
- package/src/components/form/Checkbox/Checkbox.test.tsx +1140 -0
- package/src/components/form/Checkbox/Checkbox.tsx +496 -0
- package/src/components/form/Checkbox/Checkbox.types.ts +472 -0
- package/src/components/form/Checkbox/CheckboxGroup.tsx +444 -0
- package/src/components/form/Checkbox/index.tsx +27 -0
- package/src/components/form/DatePicker/DatePicker.styles.ts +393 -0
- package/src/components/form/DatePicker/DatePicker.test.tsx +407 -0
- package/src/components/form/DatePicker/DatePicker.tsx +360 -0
- package/src/components/form/DatePicker/DatePicker.types.ts +247 -0
- package/src/components/form/DatePicker/index.tsx +15 -0
- package/src/components/form/Form/Form.styles.ts +357 -0
- package/src/components/form/Form/Form.test.tsx +122 -0
- package/src/components/form/Form/Form.tsx +695 -0
- package/src/components/form/Form/Form.types.ts +407 -0
- package/src/components/form/Form/index.tsx +31 -0
- package/src/components/form/Input/Input.enhanced.tsx +732 -0
- package/src/components/form/Input/Input.styles.ts +438 -0
- package/src/components/form/Input/Input.test.tsx +494 -0
- package/src/components/form/Input/Input.tsx +541 -0
- package/src/components/form/Input/Input.types.ts +285 -0
- package/src/components/form/Input/index.tsx +26 -0
- package/src/components/form/InputNumber/InputNumber.styles.ts +665 -0
- package/src/components/form/InputNumber/InputNumber.tsx +370 -0
- package/src/components/form/InputNumber/InputNumber.types.ts +318 -0
- package/src/components/form/InputNumber/components/InputNumberClearButton.tsx +32 -0
- package/src/components/form/InputNumber/components/InputNumberControls.tsx +42 -0
- package/src/components/form/InputNumber/components/index.ts +2 -0
- package/src/components/form/InputNumber/hooks/index.ts +4 -0
- package/src/components/form/InputNumber/hooks/useInputNumberState.ts +315 -0
- package/src/components/form/InputNumber/hooks/useInputNumberValidation.ts +147 -0
- package/src/components/form/InputNumber/index.ts +25 -0
- package/src/components/form/Radio/Radio.styles.ts +458 -0
- package/src/components/form/Radio/Radio.test.tsx +547 -0
- package/src/components/form/Radio/Radio.tsx +283 -0
- package/src/components/form/Radio/Radio.types.ts +410 -0
- package/src/components/form/Radio/index.tsx +21 -0
- package/src/components/form/Select/Select.styles.ts +514 -0
- package/src/components/form/Select/Select.test.tsx +648 -0
- package/src/components/form/Select/Select.tsx +474 -0
- package/src/components/form/Select/Select.types.ts +428 -0
- package/src/components/form/Select/index.tsx +30 -0
- package/src/components/form/Slider/Slider.styles.ts +139 -0
- package/src/components/form/Slider/Slider.test.tsx +553 -0
- package/src/components/form/Slider/Slider.tsx +326 -0
- package/src/components/form/Slider/Slider.types.ts +108 -0
- package/src/components/form/Slider/index.tsx +10 -0
- package/src/components/form/Switch/Switch.styles.ts +540 -0
- package/src/components/form/Switch/Switch.test.tsx +345 -0
- package/src/components/form/Switch/Switch.tsx +464 -0
- package/src/components/form/Switch/Switch.types.ts +386 -0
- package/src/components/form/Switch/index.tsx +26 -0
- package/src/components/form/Textarea/Textarea.styles.ts +592 -0
- package/src/components/form/Textarea/Textarea.test.tsx +1075 -0
- package/src/components/form/Textarea/Textarea.tsx +602 -0
- package/src/components/form/Textarea/Textarea.types.ts +371 -0
- package/src/components/form/Textarea/index.tsx +26 -0
- package/src/components/form/TimePicker/TimePicker.styles.ts +438 -0
- package/src/components/form/TimePicker/TimePicker.test.tsx +306 -0
- package/src/components/form/TimePicker/TimePicker.tsx +228 -0
- package/src/components/form/TimePicker/TimePicker.types.ts +385 -0
- package/src/components/form/TimePicker/index.ts +21 -0
- package/src/components/form/Transfer/Transfer.styles.ts +502 -0
- package/src/components/form/Transfer/Transfer.test.tsx +316 -0
- package/src/components/form/Transfer/Transfer.tsx +402 -0
- package/src/components/form/Transfer/Transfer.types.ts +557 -0
- package/src/components/form/Transfer/components/TransferItem.tsx +101 -0
- package/src/components/form/Transfer/components/TransferList.tsx +285 -0
- package/src/components/form/Transfer/components/TransferOperations.tsx +84 -0
- package/src/components/form/Transfer/components/TransferPagination.tsx +135 -0
- package/src/components/form/Transfer/components/TransferSearch.tsx +88 -0
- package/src/components/form/Transfer/components/index.ts +6 -0
- package/src/components/form/Transfer/hooks/index.ts +3 -0
- package/src/components/form/Transfer/hooks/useTransferData.ts +192 -0
- package/src/components/form/Transfer/hooks/useTransferState.ts +114 -0
- package/src/components/form/Transfer/index.ts +33 -0
- package/src/components/form/Upload/Upload.styles.ts +145 -0
- package/src/components/form/Upload/Upload.test.tsx +10 -0
- package/src/components/form/Upload/Upload.tsx +451 -0
- package/src/components/form/Upload/Upload.types.ts +200 -0
- package/src/components/form/Upload/index.tsx +12 -0
- package/src/components/form/index.tsx +121 -0
- package/src/components/index.tsx +146 -0
- package/src/components/layout/Affix/Affix.styles.ts +37 -0
- package/src/components/layout/Affix/Affix.test.tsx +10 -0
- package/src/components/layout/Affix/Affix.tsx +91 -0
- package/src/components/layout/Affix/Affix.types.ts +29 -0
- package/src/components/layout/Affix/index.tsx +3 -0
- package/src/components/layout/Col/Col.styles.ts +185 -0
- package/src/components/layout/Col/Col.test.tsx +535 -0
- package/src/components/layout/Col/Col.tsx +115 -0
- package/src/components/layout/Col/Col.types.ts +59 -0
- package/src/components/layout/Col/index.tsx +3 -0
- package/src/components/layout/Container/Container.styles.ts +161 -0
- package/src/components/layout/Container/Container.test.tsx +380 -0
- package/src/components/layout/Container/Container.tsx +132 -0
- package/src/components/layout/Container/Container.types.ts +63 -0
- package/src/components/layout/Container/index.tsx +3 -0
- package/src/components/layout/Grid/Grid.styles.ts +183 -0
- package/src/components/layout/Grid/Grid.test.tsx +637 -0
- package/src/components/layout/Grid/Grid.tsx +173 -0
- package/src/components/layout/Grid/Grid.types.ts +78 -0
- package/src/components/layout/Grid/index.tsx +3 -0
- package/src/components/layout/Layout/Content.tsx +38 -0
- package/src/components/layout/Layout/Footer.tsx +38 -0
- package/src/components/layout/Layout/Header.tsx +38 -0
- package/src/components/layout/Layout/Layout.styles.ts +84 -0
- package/src/components/layout/Layout/Layout.test.tsx +10 -0
- package/src/components/layout/Layout/Layout.tsx +39 -0
- package/src/components/layout/Layout/Layout.types.ts +58 -0
- package/src/components/layout/Layout/Sider.tsx +56 -0
- package/src/components/layout/Layout/index.tsx +8 -0
- package/src/components/layout/Row/Row.styles.ts +159 -0
- package/src/components/layout/Row/Row.test.tsx +467 -0
- package/src/components/layout/Row/Row.tsx +139 -0
- package/src/components/layout/Row/Row.types.ts +60 -0
- package/src/components/layout/Row/index.tsx +3 -0
- package/src/components/layout/Space/Space.styles.ts +255 -0
- package/src/components/layout/Space/Space.test.tsx +682 -0
- package/src/components/layout/Space/Space.tsx +211 -0
- package/src/components/layout/Space/Space.types.ts +92 -0
- package/src/components/layout/Space/index.tsx +12 -0
- package/src/components/layout/index.tsx +68 -0
- package/src/components/navigation/Menu/Menu.styles.ts +779 -0
- package/src/components/navigation/Menu/Menu.tsx +355 -0
- package/src/components/navigation/Menu/Menu.types.ts +231 -0
- package/src/components/navigation/Menu/Menu.utils.ts +187 -0
- package/src/components/navigation/Menu/MenuItem.tsx +126 -0
- package/src/components/navigation/Menu/SubMenu.tsx +148 -0
- package/src/components/navigation/Menu/__tests__/Menu.test.tsx +687 -0
- package/src/components/navigation/Menu/index.tsx +124 -0
- package/src/components/navigation/NavBar/NavBar.styles.ts +129 -0
- package/src/components/navigation/NavBar/NavBar.test.tsx +287 -0
- package/src/components/navigation/NavBar/NavBar.tsx +231 -0
- package/src/components/navigation/NavBar/NavBar.types.ts +54 -0
- package/src/components/navigation/NavBar/index.tsx +3 -0
- package/src/components/navigation/Pagination/Pagination.styles.ts +187 -0
- package/src/components/navigation/Pagination/Pagination.test.tsx +673 -0
- package/src/components/navigation/Pagination/Pagination.tsx +395 -0
- package/src/components/navigation/Pagination/Pagination.types.ts +86 -0
- package/src/components/navigation/Pagination/index.ts +18 -0
- package/src/components/navigation/Pagination/index.tsx +9 -0
- package/src/components/navigation/Steps/Step.tsx +56 -0
- package/src/components/navigation/Steps/Steps.styles.ts +154 -0
- package/src/components/navigation/Steps/Steps.test.tsx +12 -0
- package/src/components/navigation/Steps/Steps.tsx +113 -0
- package/src/components/navigation/Steps/Steps.types.ts +47 -0
- package/src/components/navigation/Steps/index.tsx +3 -0
- package/src/components/navigation/Tabs/Tabs.styles.ts +199 -0
- package/src/components/navigation/Tabs/Tabs.test.tsx +661 -0
- package/src/components/navigation/Tabs/Tabs.tsx +253 -0
- package/src/components/navigation/Tabs/Tabs.types.ts +114 -0
- package/src/components/navigation/Tabs/index.tsx +3 -0
- package/src/components/navigation/Tree/Tree.styles.ts +553 -0
- package/src/components/navigation/Tree/Tree.test.basic.tsx +7 -0
- package/src/components/navigation/Tree/Tree.test.functional.tsx +496 -0
- package/src/components/navigation/Tree/Tree.test.import.check.tsx +6 -0
- package/src/components/navigation/Tree/Tree.test.import.tsx +6 -0
- package/src/components/navigation/Tree/Tree.test.minimal.tsx +5 -0
- package/src/components/navigation/Tree/Tree.test.simple.tsx +30 -0
- package/src/components/navigation/Tree/Tree.test.tsx +908 -0
- package/src/components/navigation/Tree/Tree.test.working.tsx +673 -0
- package/src/components/navigation/Tree/Tree.tsx +600 -0
- package/src/components/navigation/Tree/Tree.types.ts +909 -0
- package/src/components/navigation/Tree/Tree.utils.ts +452 -0
- package/src/components/navigation/Tree/index.ts +33 -0
- package/src/components/navigation/Tree/index.tsx +23 -0
- package/src/components/navigation/index.tsx +83 -0
- package/src/constants/index.ts +785 -0
- package/src/hooks/index.ts +110 -0
- package/src/hooks/types.ts +10 -0
- package/src/hooks/useAsync.ts +65 -0
- package/src/hooks/useEventHandling.ts +444 -0
- package/src/hooks/useLifecycle.ts +399 -0
- package/src/hooks/usePerformance.ts +441 -0
- package/src/hooks/usePerformanceMonitor.ts +348 -0
- package/src/hooks/usePlatform.ts +62 -0
- package/src/hooks/useRequest.test.ts +11 -0
- package/src/hooks/useRequest.ts +135 -0
- package/src/hooks/useStateManagement.ts +300 -0
- package/src/hooks/useStyle.ts +537 -0
- package/src/hooks/useTheme.ts +347 -0
- package/src/hooks/useVirtualScroll.ts +331 -0
- package/src/index.ts +298 -0
- package/src/platform/index.ts +1188 -0
- package/src/providers/AppProvider.test.tsx +63 -0
- package/src/providers/AppProvider.tsx +155 -0
- package/src/providers/index.ts +1 -0
- package/src/theme/ThemeProvider.tsx +283 -0
- package/src/theme/ThemeProvider.types.ts +26 -0
- package/src/theme/animations.tsx +660 -0
- package/src/theme/defaults.ts +188 -0
- package/src/theme/design-system.ts +562 -0
- package/src/theme/design-tokens.ts +1136 -0
- package/src/theme/generated/dark-theme.scss +120 -0
- package/src/theme/generated/tokens.css +441 -0
- package/src/theme/generated/tokens.scss +320 -0
- package/src/theme/index.ts +120 -0
- package/src/theme/responsive.tsx +193 -0
- package/src/theme/styles/mixins.scss +612 -0
- package/src/theme/styles/variables.scss +295 -0
- package/src/theme/styles.ts +403 -0
- package/src/theme/tokens/colors.ts +256 -0
- package/src/theme/tokens/effects.ts +260 -0
- package/src/theme/tokens/index.ts +217 -0
- package/src/theme/tokens/spacing.ts +137 -0
- package/src/theme/tokens/typography.ts +186 -0
- package/src/theme/types.ts +188 -0
- package/src/theme/useThemeUtils.ts +313 -0
- package/src/theme/utils.ts +501 -0
- package/src/theme/variables.ts +583 -0
- package/src/types/accessibility.ts +51 -0
- package/src/types/button.ts +562 -0
- package/src/types/component-props.ts +317 -0
- package/src/types/env.d.ts +20 -0
- package/src/types/index.ts +427 -0
- package/src/types/modules.d.ts +40 -0
- package/src/types/standardized-components.ts +544 -0
- package/src/types/taro-adapter.d.ts +174 -0
- package/src/types/taro-components.d.ts +73 -0
- package/src/types/utils.ts +410 -0
- package/src/utils/__tests__/inputValidator.test.ts +338 -0
- package/src/utils/__tests__/responsiveUtils.test.ts +310 -0
- package/src/utils/__tests__/xssProtection.test.ts +268 -0
- package/src/utils/cache.ts +83 -0
- package/src/utils/createNamespace.ts +24 -0
- package/src/utils/environment.ts +95 -0
- package/src/utils/error-handler.ts +88 -0
- package/src/utils/errorLogger.ts +197 -0
- package/src/utils/formatUtils.ts +444 -0
- package/src/utils/index.ts +115 -0
- package/src/utils/inputValidator.ts +261 -0
- package/src/utils/network/http-client.test.ts +18 -0
- package/src/utils/network/http-client.ts +151 -0
- package/src/utils/performance/performance.ts +850 -0
- package/src/utils/responsiveUtils.ts +357 -0
- package/src/utils/rtl-support.ts +344 -0
- package/src/utils/security/api-security.ts +386 -0
- package/src/utils/security/xss-protection.ts +69 -0
- package/src/utils/securityHeaders.ts +314 -0
- package/src/utils/typeHelpers.ts +16 -0
- package/src/utils/types/dataProcessing.ts +543 -0
- package/src/utils/types/typeHelpers.ts +187 -0
- package/src/utils/xssProtection.ts +420 -0
|
@@ -0,0 +1,637 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { vi } from 'vitest'
|
|
3
|
+
import { render, screen, fireEvent } from '@testing-library/react'
|
|
4
|
+
import { Grid } from '../Grid'
|
|
5
|
+
import type { GridProps, GridRef } from './Grid.types'
|
|
6
|
+
|
|
7
|
+
// Mock Taro components
|
|
8
|
+
vi.mock('@tarojs/components', () => ({
|
|
9
|
+
View: 'div'
|
|
10
|
+
}))
|
|
11
|
+
|
|
12
|
+
// Mock styles
|
|
13
|
+
vi.mock('../Grid.styles', () => ({
|
|
14
|
+
gridStyles: {
|
|
15
|
+
ALIGN_MAP: {
|
|
16
|
+
start: 'flex-start',
|
|
17
|
+
center: 'center',
|
|
18
|
+
end: 'flex-end',
|
|
19
|
+
stretch: 'stretch'
|
|
20
|
+
},
|
|
21
|
+
JUSTIFY_MAP: {
|
|
22
|
+
start: 'flex-start',
|
|
23
|
+
end: 'flex-end',
|
|
24
|
+
center: 'center',
|
|
25
|
+
'space-around': 'space-around',
|
|
26
|
+
'space-between': 'space-between',
|
|
27
|
+
'space-evenly': 'space-evenly'
|
|
28
|
+
},
|
|
29
|
+
getBaseStyle: (props: any) => ({
|
|
30
|
+
display: 'grid',
|
|
31
|
+
gridTemplateColumns: typeof props.cols === 'number' ? `repeat(${props.cols}, 1fr)` : props.cols,
|
|
32
|
+
gridTemplateRows: props.rows ? (typeof props.rows === 'number' ? `repeat(${props.rows}, 1fr)` : props.rows) : undefined,
|
|
33
|
+
gap: typeof props.gap === 'number' ? `${props.gap}px` : props.gap || '8px',
|
|
34
|
+
rowGap: props.rowGap ? (typeof props.rowGap === 'number' ? `${props.rowGap}px` : props.rowGap) : undefined,
|
|
35
|
+
columnGap: props.columnGap ? (typeof props.columnGap === 'number' ? `${props.columnGap}px` : props.columnGap) : undefined,
|
|
36
|
+
alignItems: props.align,
|
|
37
|
+
justifyContent: props.justify
|
|
38
|
+
}),
|
|
39
|
+
getItemStyle: (index: number, total: number, cols: any) => ({
|
|
40
|
+
gridColumn: `span ${Math.ceil(24 / (typeof cols === 'number' ? cols : parseInt(cols)))}`,
|
|
41
|
+
padding: '8px',
|
|
42
|
+
border: '1px solid #eee'
|
|
43
|
+
}),
|
|
44
|
+
getResponsiveStyle: (responsive: any) => responsive ? { '@media (max-width: 768px)': { gridTemplateColumns: '1fr' } } : {},
|
|
45
|
+
getClassName: (props: any) => `taro-uno-grid taro-uno-grid--${props.cols} taro-uno-grid--${props.align} taro-uno-grid--${props.justify} ${props.className || ''}`
|
|
46
|
+
}
|
|
47
|
+
}))
|
|
48
|
+
|
|
49
|
+
describe('Grid Component', () => {
|
|
50
|
+
const mockRef = React.createRef<GridRef>()
|
|
51
|
+
|
|
52
|
+
beforeEach(() => {
|
|
53
|
+
vi.clearAllMocks()
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
describe('Rendering', () => {
|
|
57
|
+
it('renders grid with default props', () => {
|
|
58
|
+
render(<Grid data-testid="grid">Test Grid</Grid>)
|
|
59
|
+
const grid = screen.getByTestId('grid')
|
|
60
|
+
expect(grid).toBeInTheDocument()
|
|
61
|
+
expect(grid).toHaveTextContent('Test Grid')
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
it('renders grid with custom cols', () => {
|
|
65
|
+
render(<Grid cols={3} data-testid="grid">3 Columns</Grid>)
|
|
66
|
+
const grid = screen.getByTestId('grid')
|
|
67
|
+
expect(grid).toBeInTheDocument()
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
it('renders grid with custom rows', () => {
|
|
71
|
+
render(<Grid rows={2} data-testid="grid">2 Rows</Grid>)
|
|
72
|
+
const grid = screen.getByTestId('grid')
|
|
73
|
+
expect(grid).toBeInTheDocument()
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
it('renders grid with custom gap', () => {
|
|
77
|
+
render(<Grid gap={16} data-testid="grid">Custom Gap</Grid>)
|
|
78
|
+
const grid = screen.getByTestId('grid')
|
|
79
|
+
expect(grid).toBeInTheDocument()
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
it('renders grid with custom rowGap', () => {
|
|
83
|
+
render(<Grid rowGap={12} data-testid="grid">Custom Row Gap</Grid>)
|
|
84
|
+
const grid = screen.getByTestId('grid')
|
|
85
|
+
expect(grid).toBeInTheDocument()
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
it('renders grid with custom columnGap', () => {
|
|
89
|
+
render(<Grid columnGap={12} data-testid="grid">Custom Column Gap</Grid>)
|
|
90
|
+
const grid = screen.getByTestId('grid')
|
|
91
|
+
expect(grid).toBeInTheDocument()
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
it('renders grid with custom align', () => {
|
|
95
|
+
render(<Grid align="center" data-testid="grid">Centered Grid</Grid>)
|
|
96
|
+
const grid = screen.getByTestId('grid')
|
|
97
|
+
expect(grid).toBeInTheDocument()
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
it('renders grid with custom justify', () => {
|
|
101
|
+
render(<Grid justify="center" data-testid="grid">Centered Grid</Grid>)
|
|
102
|
+
const grid = screen.getByTestId('grid')
|
|
103
|
+
expect(grid).toBeInTheDocument()
|
|
104
|
+
})
|
|
105
|
+
|
|
106
|
+
it('renders grid with custom className', () => {
|
|
107
|
+
render(<Grid className="custom-grid" data-testid="grid">Custom Class</Grid>)
|
|
108
|
+
const grid = screen.getByTestId('grid')
|
|
109
|
+
expect(grid).toBeInTheDocument()
|
|
110
|
+
expect(grid).toHaveClass('custom-grid')
|
|
111
|
+
})
|
|
112
|
+
|
|
113
|
+
it('renders empty grid', () => {
|
|
114
|
+
render(<Grid data-testid="grid" />)
|
|
115
|
+
const grid = screen.getByTestId('grid')
|
|
116
|
+
expect(grid).toBeInTheDocument()
|
|
117
|
+
expect(grid).toBeEmptyDOMElement()
|
|
118
|
+
})
|
|
119
|
+
|
|
120
|
+
it('renders grid with multiple children', () => {
|
|
121
|
+
render(
|
|
122
|
+
<Grid data-testid="grid">
|
|
123
|
+
<div>Item 1</div>
|
|
124
|
+
<div>Item 2</div>
|
|
125
|
+
<div>Item 3</div>
|
|
126
|
+
</Grid>
|
|
127
|
+
)
|
|
128
|
+
const grid = screen.getByTestId('grid')
|
|
129
|
+
expect(grid).toBeInTheDocument()
|
|
130
|
+
expect(grid.children).toHaveLength(3)
|
|
131
|
+
})
|
|
132
|
+
|
|
133
|
+
it('renders grid with responsive props', () => {
|
|
134
|
+
render(<Grid responsive={{ xs: { cols: 1 } }} data-testid="grid">Responsive</Grid>)
|
|
135
|
+
const grid = screen.getByTestId('grid')
|
|
136
|
+
expect(grid).toBeInTheDocument()
|
|
137
|
+
})
|
|
138
|
+
|
|
139
|
+
it('renders grid with string cols', () => {
|
|
140
|
+
render(<Grid cols="repeat(auto-fit, minmax(200px, 1fr))" data-testid="grid">Auto Grid</Grid>)
|
|
141
|
+
const grid = screen.getByTestId('grid')
|
|
142
|
+
expect(grid).toBeInTheDocument()
|
|
143
|
+
})
|
|
144
|
+
|
|
145
|
+
it('renders grid with maximum cols', () => {
|
|
146
|
+
render(<Grid cols={12} data-testid="grid">Max Columns</Grid>)
|
|
147
|
+
const grid = screen.getByTestId('grid')
|
|
148
|
+
expect(grid).toBeInTheDocument()
|
|
149
|
+
})
|
|
150
|
+
|
|
151
|
+
it('renders grid with minimum cols', () => {
|
|
152
|
+
render(<Grid cols={1} data-testid="grid">Min Columns</Grid>)
|
|
153
|
+
const grid = screen.getByTestId('grid')
|
|
154
|
+
expect(grid).toBeInTheDocument()
|
|
155
|
+
})
|
|
156
|
+
})
|
|
157
|
+
|
|
158
|
+
describe('Grid Items', () => {
|
|
159
|
+
it('renders grid items with proper styling', () => {
|
|
160
|
+
render(
|
|
161
|
+
<Grid cols={3} data-testid="grid">
|
|
162
|
+
<div>Item 1</div>
|
|
163
|
+
<div>Item 2</div>
|
|
164
|
+
<div>Item 3</div>
|
|
165
|
+
</Grid>
|
|
166
|
+
)
|
|
167
|
+
const grid = screen.getByTestId('grid')
|
|
168
|
+
expect(grid).toBeInTheDocument()
|
|
169
|
+
expect(grid.children).toHaveLength(3)
|
|
170
|
+
expect(screen.getByText('Item 1')).toBeInTheDocument()
|
|
171
|
+
expect(screen.getByText('Item 2')).toBeInTheDocument()
|
|
172
|
+
expect(screen.getByText('Item 3')).toBeInTheDocument()
|
|
173
|
+
})
|
|
174
|
+
|
|
175
|
+
it('handles grid items with click events', () => {
|
|
176
|
+
const handleItemClick = vi.fn()
|
|
177
|
+
render(
|
|
178
|
+
<Grid onItemClick={handleItemClick} data-testid="grid">
|
|
179
|
+
<div>Clickable Item</div>
|
|
180
|
+
</Grid>
|
|
181
|
+
)
|
|
182
|
+
const item = screen.getByText('Clickable Item')
|
|
183
|
+
fireEvent.click(item)
|
|
184
|
+
expect(handleItemClick).toHaveBeenCalledWith(0, expect.any(Object))
|
|
185
|
+
})
|
|
186
|
+
|
|
187
|
+
it('handles grid items with hover events', () => {
|
|
188
|
+
const handleItemHover = vi.fn()
|
|
189
|
+
render(
|
|
190
|
+
<Grid onItemHover={handleItemHover} data-testid="grid">
|
|
191
|
+
<div>Hoverable Item</div>
|
|
192
|
+
</Grid>
|
|
193
|
+
)
|
|
194
|
+
const item = screen.getByText('Hoverable Item')
|
|
195
|
+
fireEvent.touchStart(item)
|
|
196
|
+
expect(handleItemHover).toHaveBeenCalledWith(0, expect.any(Object))
|
|
197
|
+
})
|
|
198
|
+
|
|
199
|
+
it('handles multiple item interactions', () => {
|
|
200
|
+
const handleItemClick = vi.fn()
|
|
201
|
+
const handleItemHover = vi.fn()
|
|
202
|
+
render(
|
|
203
|
+
<Grid onItemClick={handleItemClick} onItemHover={handleItemHover} data-testid="grid">
|
|
204
|
+
<div>Item 1</div>
|
|
205
|
+
<div>Item 2</div>
|
|
206
|
+
</Grid>
|
|
207
|
+
)
|
|
208
|
+
const item1 = screen.getByText('Item 1')
|
|
209
|
+
const item2 = screen.getByText('Item 2')
|
|
210
|
+
|
|
211
|
+
fireEvent.touchStart(item1)
|
|
212
|
+
fireEvent.click(item1)
|
|
213
|
+
fireEvent.touchStart(item2)
|
|
214
|
+
fireEvent.click(item2)
|
|
215
|
+
|
|
216
|
+
expect(handleItemHover).toHaveBeenCalledTimes(2)
|
|
217
|
+
expect(handleItemClick).toHaveBeenCalledTimes(2)
|
|
218
|
+
})
|
|
219
|
+
|
|
220
|
+
it('handles items with complex content', () => {
|
|
221
|
+
render(
|
|
222
|
+
<Grid cols={2} data-testid="grid">
|
|
223
|
+
<div>
|
|
224
|
+
<h3>Title</h3>
|
|
225
|
+
<p>Description</p>
|
|
226
|
+
<button>Action</button>
|
|
227
|
+
</div>
|
|
228
|
+
<div>
|
|
229
|
+
<img src="test.jpg" alt="Test" />
|
|
230
|
+
<span>Content</span>
|
|
231
|
+
</div>
|
|
232
|
+
</Grid>
|
|
233
|
+
)
|
|
234
|
+
const grid = screen.getByTestId('grid')
|
|
235
|
+
expect(grid).toBeInTheDocument()
|
|
236
|
+
expect(grid.children).toHaveLength(2)
|
|
237
|
+
expect(screen.getByText('Title')).toBeInTheDocument()
|
|
238
|
+
expect(screen.getByText('Description')).toBeInTheDocument()
|
|
239
|
+
expect(screen.getByText('Action')).toBeInTheDocument()
|
|
240
|
+
expect(screen.getByAltText('Test')).toBeInTheDocument()
|
|
241
|
+
expect(screen.getByText('Content')).toBeInTheDocument()
|
|
242
|
+
})
|
|
243
|
+
})
|
|
244
|
+
|
|
245
|
+
describe('Event Handling', () => {
|
|
246
|
+
it('handles grid click events', () => {
|
|
247
|
+
const handleClick = vi.fn()
|
|
248
|
+
render(<Grid onClick={handleClick} data-testid="grid">Clickable Grid</Grid>)
|
|
249
|
+
const grid = screen.getByTestId('grid')
|
|
250
|
+
fireEvent.click(grid)
|
|
251
|
+
expect(handleClick).toHaveBeenCalledTimes(1)
|
|
252
|
+
})
|
|
253
|
+
|
|
254
|
+
it('handles grid click events with children', () => {
|
|
255
|
+
const handleClick = vi.fn()
|
|
256
|
+
render(
|
|
257
|
+
<Grid onClick={handleClick} data-testid="grid">
|
|
258
|
+
<div>Child Content</div>
|
|
259
|
+
</Grid>
|
|
260
|
+
)
|
|
261
|
+
const grid = screen.getByTestId('grid')
|
|
262
|
+
fireEvent.click(grid)
|
|
263
|
+
expect(handleClick).toHaveBeenCalledTimes(1)
|
|
264
|
+
})
|
|
265
|
+
|
|
266
|
+
it('handles item click events', () => {
|
|
267
|
+
const handleItemClick = vi.fn()
|
|
268
|
+
render(
|
|
269
|
+
<Grid onItemClick={handleItemClick} data-testid="grid">
|
|
270
|
+
<div>Item 1</div>
|
|
271
|
+
<div>Item 2</div>
|
|
272
|
+
</Grid>
|
|
273
|
+
)
|
|
274
|
+
const item1 = screen.getByText('Item 1')
|
|
275
|
+
const item2 = screen.getByText('Item 2')
|
|
276
|
+
fireEvent.click(item1)
|
|
277
|
+
fireEvent.click(item2)
|
|
278
|
+
expect(handleItemClick).toHaveBeenCalledTimes(2)
|
|
279
|
+
expect(handleItemClick).toHaveBeenCalledWith(0, expect.any(Object))
|
|
280
|
+
expect(handleItemClick).toHaveBeenCalledWith(1, expect.any(Object))
|
|
281
|
+
})
|
|
282
|
+
|
|
283
|
+
it('handles item hover events', () => {
|
|
284
|
+
const handleItemHover = vi.fn()
|
|
285
|
+
render(
|
|
286
|
+
<Grid onItemHover={handleItemHover} data-testid="grid">
|
|
287
|
+
<div>Item 1</div>
|
|
288
|
+
<div>Item 2</div>
|
|
289
|
+
</Grid>
|
|
290
|
+
)
|
|
291
|
+
const item1 = screen.getByText('Item 1')
|
|
292
|
+
fireEvent.touchStart(item1)
|
|
293
|
+
fireEvent.touchEnd(item1)
|
|
294
|
+
expect(handleItemHover).toHaveBeenCalledTimes(2)
|
|
295
|
+
})
|
|
296
|
+
|
|
297
|
+
it('does not interfere with child click events', () => {
|
|
298
|
+
const handleGridClick = vi.fn()
|
|
299
|
+
const handleItemClick = vi.fn()
|
|
300
|
+
const handleChildClick = vi.fn((e: any) => e.stopPropagation())
|
|
301
|
+
render(
|
|
302
|
+
<Grid onClick={handleGridClick} onItemClick={handleItemClick} data-testid="grid">
|
|
303
|
+
<div onClick={handleChildClick} data-testid="child">Child</div>
|
|
304
|
+
</Grid>
|
|
305
|
+
)
|
|
306
|
+
const child = screen.getByTestId('child')
|
|
307
|
+
fireEvent.click(child)
|
|
308
|
+
expect(handleChildClick).toHaveBeenCalledTimes(1)
|
|
309
|
+
expect(handleGridClick).not.toHaveBeenCalled()
|
|
310
|
+
})
|
|
311
|
+
})
|
|
312
|
+
|
|
313
|
+
describe('Props Updates', () => {
|
|
314
|
+
it('updates cols prop correctly', () => {
|
|
315
|
+
const { rerender } = render(<Grid cols={2} data-testid="grid">Cols Test</Grid>)
|
|
316
|
+
const grid = screen.getByTestId('grid')
|
|
317
|
+
rerender(<Grid cols={4} data-testid="grid">Cols Test</Grid>)
|
|
318
|
+
expect(grid).toBeInTheDocument()
|
|
319
|
+
})
|
|
320
|
+
|
|
321
|
+
it('updates rows prop correctly', () => {
|
|
322
|
+
const { rerender } = render(<Grid rows={1} data-testid="grid">Rows Test</Grid>)
|
|
323
|
+
const grid = screen.getByTestId('grid')
|
|
324
|
+
rerender(<Grid rows={3} data-testid="grid">Rows Test</Grid>)
|
|
325
|
+
expect(grid).toBeInTheDocument()
|
|
326
|
+
})
|
|
327
|
+
|
|
328
|
+
it('updates gap prop correctly', () => {
|
|
329
|
+
const { rerender } = render(<Grid gap={8} data-testid="grid">Gap Test</Grid>)
|
|
330
|
+
const grid = screen.getByTestId('grid')
|
|
331
|
+
rerender(<Grid gap={16} data-testid="grid">Gap Test</Grid>)
|
|
332
|
+
expect(grid).toBeInTheDocument()
|
|
333
|
+
})
|
|
334
|
+
|
|
335
|
+
it('updates align prop correctly', () => {
|
|
336
|
+
const { rerender } = render(<Grid align="start" data-testid="grid">Align Test</Grid>)
|
|
337
|
+
const grid = screen.getByTestId('grid')
|
|
338
|
+
rerender(<Grid align="center" data-testid="grid">Align Test</Grid>)
|
|
339
|
+
expect(grid).toBeInTheDocument()
|
|
340
|
+
})
|
|
341
|
+
|
|
342
|
+
it('updates justify prop correctly', () => {
|
|
343
|
+
const { rerender } = render(<Grid justify="start" data-testid="grid">Justify Test</Grid>)
|
|
344
|
+
const grid = screen.getByTestId('grid')
|
|
345
|
+
rerender(<Grid justify="center" data-testid="grid">Justify Test</Grid>)
|
|
346
|
+
expect(grid).toBeInTheDocument()
|
|
347
|
+
})
|
|
348
|
+
|
|
349
|
+
it('updates rowGap prop correctly', () => {
|
|
350
|
+
const { rerender } = render(<Grid rowGap={8} data-testid="grid">Row Gap Test</Grid>)
|
|
351
|
+
const grid = screen.getByTestId('grid')
|
|
352
|
+
rerender(<Grid rowGap={16} data-testid="grid">Row Gap Test</Grid>)
|
|
353
|
+
expect(grid).toBeInTheDocument()
|
|
354
|
+
})
|
|
355
|
+
|
|
356
|
+
it('updates columnGap prop correctly', () => {
|
|
357
|
+
const { rerender } = render(<Grid columnGap={8} data-testid="grid">Column Gap Test</Grid>)
|
|
358
|
+
const grid = screen.getByTestId('grid')
|
|
359
|
+
rerender(<Grid columnGap={16} data-testid="grid">Column Gap Test</Grid>)
|
|
360
|
+
expect(grid).toBeInTheDocument()
|
|
361
|
+
})
|
|
362
|
+
})
|
|
363
|
+
|
|
364
|
+
describe('Ref API', () => {
|
|
365
|
+
it('exposes ref methods correctly', () => {
|
|
366
|
+
render(<Grid ref={mockRef} data-testid="grid">Ref Test</Grid>)
|
|
367
|
+
|
|
368
|
+
expect(mockRef.current).toBeDefined()
|
|
369
|
+
expect(mockRef.current?.getCols()).toBe(1)
|
|
370
|
+
expect(mockRef.current?.getAlign()).toBe('stretch')
|
|
371
|
+
expect(mockRef.current?.getJustify()).toBe('start')
|
|
372
|
+
expect(mockRef.current?.getGap()).toBe('default')
|
|
373
|
+
})
|
|
374
|
+
|
|
375
|
+
it('sets cols via ref method', () => {
|
|
376
|
+
render(<Grid ref={mockRef} data-testid="grid">Ref Cols Test</Grid>)
|
|
377
|
+
|
|
378
|
+
if (mockRef.current) {
|
|
379
|
+
expect(() => mockRef.current!.setCols(3)).not.toThrow()
|
|
380
|
+
}
|
|
381
|
+
})
|
|
382
|
+
|
|
383
|
+
it('sets align via ref method', () => {
|
|
384
|
+
render(<Grid ref={mockRef} data-testid="grid">Ref Align Test</Grid>)
|
|
385
|
+
|
|
386
|
+
if (mockRef.current) {
|
|
387
|
+
expect(() => mockRef.current!.setAlign('center')).not.toThrow()
|
|
388
|
+
}
|
|
389
|
+
})
|
|
390
|
+
|
|
391
|
+
it('sets justify via ref method', () => {
|
|
392
|
+
render(<Grid ref={mockRef} data-testid="grid">Ref Justify Test</Grid>)
|
|
393
|
+
|
|
394
|
+
if (mockRef.current) {
|
|
395
|
+
expect(() => mockRef.current!.setJustify('center')).not.toThrow()
|
|
396
|
+
}
|
|
397
|
+
})
|
|
398
|
+
|
|
399
|
+
it('sets gap via ref method', () => {
|
|
400
|
+
render(<Grid ref={mockRef} data-testid="grid">Ref Gap Test</Grid>)
|
|
401
|
+
|
|
402
|
+
if (mockRef.current) {
|
|
403
|
+
expect(() => mockRef.current!.setGap(16)).not.toThrow()
|
|
404
|
+
}
|
|
405
|
+
})
|
|
406
|
+
|
|
407
|
+
it('calls scrollIntoView via ref method', () => {
|
|
408
|
+
render(<Grid ref={mockRef} data-testid="grid">Ref Scroll Test</Grid>)
|
|
409
|
+
|
|
410
|
+
if (mockRef.current) {
|
|
411
|
+
expect(typeof mockRef.current.scrollIntoView).toBe('function')
|
|
412
|
+
}
|
|
413
|
+
})
|
|
414
|
+
|
|
415
|
+
it('provides element access via ref', () => {
|
|
416
|
+
render(<Grid ref={mockRef} data-testid="grid">Ref Element Test</Grid>)
|
|
417
|
+
|
|
418
|
+
expect(mockRef.current?.element).toBeDefined()
|
|
419
|
+
})
|
|
420
|
+
})
|
|
421
|
+
|
|
422
|
+
describe('Accessibility', () => {
|
|
423
|
+
it('has proper role attribute', () => {
|
|
424
|
+
render(<Grid data-testid="grid">Accessible Grid</Grid>)
|
|
425
|
+
const grid = screen.getByTestId('grid')
|
|
426
|
+
expect(grid).toBeInTheDocument()
|
|
427
|
+
})
|
|
428
|
+
|
|
429
|
+
it('supports aria-label', () => {
|
|
430
|
+
render(<Grid aria-label="Main grid" data-testid="grid">Labeled Grid</Grid>)
|
|
431
|
+
const grid = screen.getByTestId('grid')
|
|
432
|
+
expect(grid).toHaveAttribute('aria-label', 'Main grid')
|
|
433
|
+
})
|
|
434
|
+
|
|
435
|
+
it('supports aria-labelledby', () => {
|
|
436
|
+
render(<Grid aria-labelledby="grid-title" data-testid="grid">Labelled By Grid</Grid>)
|
|
437
|
+
const grid = screen.getByTestId('grid')
|
|
438
|
+
expect(grid).toHaveAttribute('aria-labelledby', 'grid-title')
|
|
439
|
+
})
|
|
440
|
+
|
|
441
|
+
it('supports tabIndex for keyboard navigation', () => {
|
|
442
|
+
render(<Grid data-testid="grid">Tabbable Grid</Grid>)
|
|
443
|
+
const grid = screen.getByTestId('grid')
|
|
444
|
+
expect(grid).toBeInTheDocument()
|
|
445
|
+
})
|
|
446
|
+
|
|
447
|
+
it('supports data attributes', () => {
|
|
448
|
+
render(<Grid data-testid="grid" data-custom="value">Data Attr Grid</Grid>)
|
|
449
|
+
const grid = screen.getByTestId('grid')
|
|
450
|
+
expect(grid).toHaveAttribute('data-custom', 'value')
|
|
451
|
+
})
|
|
452
|
+
})
|
|
453
|
+
|
|
454
|
+
describe('Edge Cases', () => {
|
|
455
|
+
it('handles cols greater than 12', () => {
|
|
456
|
+
render(<Grid cols={24} data-testid="grid">Many Columns</Grid>)
|
|
457
|
+
const grid = screen.getByTestId('grid')
|
|
458
|
+
expect(grid).toBeInTheDocument()
|
|
459
|
+
})
|
|
460
|
+
|
|
461
|
+
it('handles cols of 0', () => {
|
|
462
|
+
render(<Grid cols={0} data-testid="grid">Zero Columns</Grid>)
|
|
463
|
+
const grid = screen.getByTestId('grid')
|
|
464
|
+
expect(grid).toBeInTheDocument()
|
|
465
|
+
})
|
|
466
|
+
|
|
467
|
+
it('handles negative cols gracefully', () => {
|
|
468
|
+
const { container } = render(<Grid cols={-3} data-testid="grid">Negative Cols</Grid>)
|
|
469
|
+
expect(screen.getByTestId('grid')).toBeInTheDocument()
|
|
470
|
+
})
|
|
471
|
+
|
|
472
|
+
it('handles negative gap gracefully', () => {
|
|
473
|
+
const { container } = render(<Grid gap={-16} data-testid="grid">Negative Gap</Grid>)
|
|
474
|
+
expect(screen.getByTestId('grid')).toBeInTheDocument()
|
|
475
|
+
})
|
|
476
|
+
|
|
477
|
+
it('handles very large gap', () => {
|
|
478
|
+
render(<Grid gap={9999} data-testid="grid">Large Gap</Grid>)
|
|
479
|
+
const grid = screen.getByTestId('grid')
|
|
480
|
+
expect(grid).toBeInTheDocument()
|
|
481
|
+
})
|
|
482
|
+
|
|
483
|
+
it('handles undefined children', () => {
|
|
484
|
+
render(<Grid data-testid="grid">{undefined}</Grid>)
|
|
485
|
+
const grid = screen.getByTestId('grid')
|
|
486
|
+
expect(grid).toBeInTheDocument()
|
|
487
|
+
})
|
|
488
|
+
|
|
489
|
+
it('handles null children', () => {
|
|
490
|
+
render(<Grid data-testid="grid">{null}</Grid>)
|
|
491
|
+
const grid = screen.getByTestId('grid')
|
|
492
|
+
expect(grid).toBeInTheDocument()
|
|
493
|
+
})
|
|
494
|
+
|
|
495
|
+
it('handles boolean children', () => {
|
|
496
|
+
render(<Grid data-testid="grid">{true}</Grid>)
|
|
497
|
+
const grid = screen.getByTestId('grid')
|
|
498
|
+
expect(grid).toBeInTheDocument()
|
|
499
|
+
})
|
|
500
|
+
|
|
501
|
+
it('handles string cols value', () => {
|
|
502
|
+
render(<Grid cols="1fr 2fr 1fr" data-testid="grid">String Cols</Grid>)
|
|
503
|
+
const grid = screen.getByTestId('grid')
|
|
504
|
+
expect(grid).toBeInTheDocument()
|
|
505
|
+
})
|
|
506
|
+
|
|
507
|
+
it('handles complex template values', () => {
|
|
508
|
+
render(<Grid cols="repeat(auto-fill, minmax(200px, 1fr))" data-testid="grid">Auto Fill</Grid>)
|
|
509
|
+
const grid = screen.getByTestId('grid')
|
|
510
|
+
expect(grid).toBeInTheDocument()
|
|
511
|
+
})
|
|
512
|
+
})
|
|
513
|
+
|
|
514
|
+
describe('Responsive Behavior', () => {
|
|
515
|
+
it('applies responsive styles correctly', () => {
|
|
516
|
+
const responsiveProps = {
|
|
517
|
+
xs: { cols: 1, gap: 8 },
|
|
518
|
+
sm: { cols: 2, gap: 12 },
|
|
519
|
+
md: { cols: 3, gap: 16 },
|
|
520
|
+
lg: { cols: 4, gap: 20 }
|
|
521
|
+
}
|
|
522
|
+
render(<Grid responsive={responsiveProps} data-testid="grid">Responsive</Grid>)
|
|
523
|
+
const grid = screen.getByTestId('grid')
|
|
524
|
+
expect(grid).toBeInTheDocument()
|
|
525
|
+
})
|
|
526
|
+
|
|
527
|
+
it('handles empty responsive object', () => {
|
|
528
|
+
render(<Grid responsive={{}} data-testid="grid">Empty Responsive</Grid>)
|
|
529
|
+
const grid = screen.getByTestId('grid')
|
|
530
|
+
expect(grid).toBeInTheDocument()
|
|
531
|
+
})
|
|
532
|
+
|
|
533
|
+
it('handles partial responsive object', () => {
|
|
534
|
+
render(<Grid responsive={{ xs: { cols: 1 } }} data-testid="grid">Partial Responsive</Grid>)
|
|
535
|
+
const grid = screen.getByTestId('grid')
|
|
536
|
+
expect(grid).toBeInTheDocument()
|
|
537
|
+
})
|
|
538
|
+
})
|
|
539
|
+
|
|
540
|
+
describe('Grid Layout Patterns', () => {
|
|
541
|
+
it('handles responsive grid layout', () => {
|
|
542
|
+
render(
|
|
543
|
+
<Grid cols={{ xs: 1, sm: 2, md: 3, lg: 4 } as any} data-testid="grid">
|
|
544
|
+
<div>Item 1</div>
|
|
545
|
+
<div>Item 2</div>
|
|
546
|
+
<div>Item 3</div>
|
|
547
|
+
<div>Item 4</div>
|
|
548
|
+
</Grid>
|
|
549
|
+
)
|
|
550
|
+
const grid = screen.getByTestId('grid')
|
|
551
|
+
expect(grid).toBeInTheDocument()
|
|
552
|
+
expect(grid.children).toHaveLength(4)
|
|
553
|
+
})
|
|
554
|
+
|
|
555
|
+
it('handles complex grid templates', () => {
|
|
556
|
+
render(
|
|
557
|
+
<Grid
|
|
558
|
+
cols="4"
|
|
559
|
+
rows={3}
|
|
560
|
+
gap="16px"
|
|
561
|
+
data-testid="grid"
|
|
562
|
+
>
|
|
563
|
+
<div>Header</div>
|
|
564
|
+
<div>Main</div>
|
|
565
|
+
<div>Sidebar</div>
|
|
566
|
+
<div>Footer</div>
|
|
567
|
+
</Grid>
|
|
568
|
+
)
|
|
569
|
+
const grid = screen.getByTestId('grid')
|
|
570
|
+
expect(grid).toBeInTheDocument()
|
|
571
|
+
expect(grid.children).toHaveLength(4)
|
|
572
|
+
})
|
|
573
|
+
|
|
574
|
+
it('handles grid with mixed gap types', () => {
|
|
575
|
+
render(
|
|
576
|
+
<Grid
|
|
577
|
+
cols={3}
|
|
578
|
+
rowGap={12}
|
|
579
|
+
columnGap={24}
|
|
580
|
+
data-testid="grid"
|
|
581
|
+
>
|
|
582
|
+
<div>Item 1</div>
|
|
583
|
+
<div>Item 2</div>
|
|
584
|
+
<div>Item 3</div>
|
|
585
|
+
</Grid>
|
|
586
|
+
)
|
|
587
|
+
const grid = screen.getByTestId('grid')
|
|
588
|
+
expect(grid).toBeInTheDocument()
|
|
589
|
+
})
|
|
590
|
+
})
|
|
591
|
+
|
|
592
|
+
describe('Performance', () => {
|
|
593
|
+
it('renders efficiently with many items', () => {
|
|
594
|
+
const items = Array.from({ length: 100 }, (_, i) => <div key={i}>Item {i}</div>)
|
|
595
|
+
render(<Grid cols={10} data-testid="grid">{items}</Grid>)
|
|
596
|
+
const grid = screen.getByTestId('grid')
|
|
597
|
+
expect(grid).toBeInTheDocument()
|
|
598
|
+
expect(grid.children).toHaveLength(100)
|
|
599
|
+
})
|
|
600
|
+
|
|
601
|
+
it('handles frequent prop updates efficiently', () => {
|
|
602
|
+
const { rerender } = render(<Grid cols={2} data-testid="grid">Performance Grid</Grid>)
|
|
603
|
+
|
|
604
|
+
for (let i = 0; i < 10; i++) {
|
|
605
|
+
rerender(<Grid cols={i + 1} data-testid="grid">Performance Grid</Grid>)
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
expect(screen.getByTestId('grid')).toBeInTheDocument()
|
|
609
|
+
})
|
|
610
|
+
})
|
|
611
|
+
|
|
612
|
+
describe('Gap Types', () => {
|
|
613
|
+
it('handles string gap', () => {
|
|
614
|
+
render(<Grid gap="16px" data-testid="grid">String Gap</Grid>)
|
|
615
|
+
const grid = screen.getByTestId('grid')
|
|
616
|
+
expect(grid).toBeInTheDocument()
|
|
617
|
+
})
|
|
618
|
+
|
|
619
|
+
it('handles string rowGap', () => {
|
|
620
|
+
render(<Grid rowGap="12px" data-testid="grid">String Row Gap</Grid>)
|
|
621
|
+
const grid = screen.getByTestId('grid')
|
|
622
|
+
expect(grid).toBeInTheDocument()
|
|
623
|
+
})
|
|
624
|
+
|
|
625
|
+
it('handles string columnGap', () => {
|
|
626
|
+
render(<Grid columnGap="12px" data-testid="grid">String Column Gap</Grid>)
|
|
627
|
+
const grid = screen.getByTestId('grid')
|
|
628
|
+
expect(grid).toBeInTheDocument()
|
|
629
|
+
})
|
|
630
|
+
|
|
631
|
+
it('handles Size enum gap', () => {
|
|
632
|
+
render(<Grid gap="medium" data-testid="grid">Size Gap</Grid>)
|
|
633
|
+
const grid = screen.getByTestId('grid')
|
|
634
|
+
expect(grid).toBeInTheDocument()
|
|
635
|
+
})
|
|
636
|
+
})
|
|
637
|
+
})
|