@12-apps/ui 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components-catalog.md +806 -0
- package/components-guidelines.md +347 -0
- package/dist/index.cjs +2 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -0
- package/eslint.config.js +77 -0
- package/package.json +247 -0
- package/src/__tests__/package-wiring.test.ts +37 -0
- package/src/__tests__/setup.ts +1 -0
- package/src/__tests__/social-login-button.test.tsx +186 -0
- package/src/__tests__/user-avatar.test.tsx +195 -0
- package/src/button.tsx +22 -0
- package/src/components/command/__tests__/command.test.tsx +112 -0
- package/src/components/data-display/Alert/Alert.md +209 -0
- package/src/components/data-display/Alert/Alert.stories.tsx +561 -0
- package/src/components/data-display/Alert/Alert.test.stories.tsx +709 -0
- package/src/components/data-display/Alert/Alert.tsx +449 -0
- package/src/components/data-display/Alert/Alert.types.ts +79 -0
- package/src/components/data-display/Alert/index.ts +2 -0
- package/src/components/data-display/AlertDialog/AlertDialog.md +408 -0
- package/src/components/data-display/AlertDialog/AlertDialog.stories.tsx +360 -0
- package/src/components/data-display/AlertDialog/AlertDialog.test.stories.tsx +753 -0
- package/src/components/data-display/AlertDialog/AlertDialog.tsx +273 -0
- package/src/components/data-display/AlertDialog/AlertDialog.types.ts +74 -0
- package/src/components/data-display/AlertDialog/index.ts +2 -0
- package/src/components/data-display/AsyncStateContainer/AsyncStateContainer.stories.tsx +230 -0
- package/src/components/data-display/AsyncStateContainer/AsyncStateContainer.test.stories.tsx +270 -0
- package/src/components/data-display/AsyncStateContainer/AsyncStateContainer.tsx +116 -0
- package/src/components/data-display/AsyncStateContainer/AsyncStateContainer.types.ts +70 -0
- package/src/components/data-display/AsyncStateContainer/index.ts +2 -0
- package/src/components/data-display/Avatar/Avatar.md +568 -0
- package/src/components/data-display/Avatar/Avatar.stories.tsx +718 -0
- package/src/components/data-display/Avatar/Avatar.test.stories.tsx +820 -0
- package/src/components/data-display/Avatar/Avatar.tsx +507 -0
- package/src/components/data-display/Avatar/Avatar.types.ts +88 -0
- package/src/components/data-display/Avatar/index.ts +2 -0
- package/src/components/data-display/Badge/Badge.md +469 -0
- package/src/components/data-display/Badge/Badge.stories.tsx +1136 -0
- package/src/components/data-display/Badge/Badge.test.stories.tsx +1193 -0
- package/src/components/data-display/Badge/Badge.tsx +606 -0
- package/src/components/data-display/Badge/Badge.types.ts +118 -0
- package/src/components/data-display/Badge/index.ts +2 -0
- package/src/components/data-display/Banner/Banner.stories.tsx +524 -0
- package/src/components/data-display/Banner/Banner.test.stories.tsx +503 -0
- package/src/components/data-display/Banner/Banner.tsx +350 -0
- package/src/components/data-display/Banner/Banner.types.ts +41 -0
- package/src/components/data-display/Banner/banner.md +141 -0
- package/src/components/data-display/Banner/index.ts +2 -0
- package/src/components/data-display/Carousel/Carousel.md +815 -0
- package/src/components/data-display/Carousel/Carousel.stories.tsx +607 -0
- package/src/components/data-display/Carousel/Carousel.test.stories.tsx +691 -0
- package/src/components/data-display/Carousel/Carousel.tsx +765 -0
- package/src/components/data-display/Carousel/Carousel.types.ts +79 -0
- package/src/components/data-display/Carousel/index.ts +8 -0
- package/src/components/data-display/Chart/Chart.md +352 -0
- package/src/components/data-display/Chart/Chart.stories.tsx +568 -0
- package/src/components/data-display/Chart/Chart.test.stories.tsx +174 -0
- package/src/components/data-display/Chart/Chart.tsx +520 -0
- package/src/components/data-display/Chart/Chart.types.ts +65 -0
- package/src/components/data-display/Chart/index.ts +2 -0
- package/src/components/data-display/Chip/Chip.stories.tsx +251 -0
- package/src/components/data-display/Chip/Chip.test.stories.tsx +263 -0
- package/src/components/data-display/Chip/Chip.tsx +134 -0
- package/src/components/data-display/Chip/Chip.types.ts +51 -0
- package/src/components/data-display/Chip/chip.md +395 -0
- package/src/components/data-display/Chip/index.ts +2 -0
- package/src/components/data-display/DataGrid/DataGrid.md +602 -0
- package/src/components/data-display/DataGrid/DataGrid.stories.tsx +515 -0
- package/src/components/data-display/DataGrid/DataGrid.test.stories.tsx +659 -0
- package/src/components/data-display/DataGrid/DataGrid.tsx +743 -0
- package/src/components/data-display/DataGrid/DataGrid.types.ts +171 -0
- package/src/components/data-display/DataGrid/index.ts +21 -0
- package/src/components/data-display/DateTimeDisplay/DateTimeDisplay.tsx +197 -0
- package/src/components/data-display/DateTimeDisplay/DateTimeDisplay.types.ts +46 -0
- package/src/components/data-display/DateTimeDisplay/index.ts +2 -0
- package/src/components/data-display/DescriptionItem/DescriptionItem.md +226 -0
- package/src/components/data-display/DescriptionItem/DescriptionItem.stories.tsx +254 -0
- package/src/components/data-display/DescriptionItem/DescriptionItem.tsx +100 -0
- package/src/components/data-display/DescriptionItem/DescriptionItem.types.ts +1 -0
- package/src/components/data-display/DescriptionItem/index.ts +2 -0
- package/src/components/data-display/EmptyState/EmptyState.md +265 -0
- package/src/components/data-display/EmptyState/EmptyState.stories.tsx +282 -0
- package/src/components/data-display/EmptyState/EmptyState.test.stories.tsx +441 -0
- package/src/components/data-display/EmptyState/EmptyState.tsx +180 -0
- package/src/components/data-display/EmptyState/EmptyState.types.ts +31 -0
- package/src/components/data-display/EmptyState/index.ts +2 -0
- package/src/components/data-display/ErrorState/ErrorState.stories.tsx +110 -0
- package/src/components/data-display/ErrorState/ErrorState.test.stories.tsx +133 -0
- package/src/components/data-display/ErrorState/ErrorState.tsx +118 -0
- package/src/components/data-display/ErrorState/ErrorState.types.ts +45 -0
- package/src/components/data-display/ErrorState/index.ts +2 -0
- package/src/components/data-display/HoverCard/HoverCard.md +389 -0
- package/src/components/data-display/HoverCard/HoverCard.stories.tsx +648 -0
- package/src/components/data-display/HoverCard/HoverCard.test.stories.tsx +929 -0
- package/src/components/data-display/HoverCard/HoverCard.tsx +657 -0
- package/src/components/data-display/HoverCard/HoverCard.types.ts +116 -0
- package/src/components/data-display/HoverCard/index.ts +2 -0
- package/src/components/data-display/InteractiveTooltip/InteractiveTooltip.md +532 -0
- package/src/components/data-display/InteractiveTooltip/InteractiveTooltip.stories.tsx +411 -0
- package/src/components/data-display/InteractiveTooltip/InteractiveTooltip.tsx +245 -0
- package/src/components/data-display/InteractiveTooltip/InteractiveTooltip.types.ts +64 -0
- package/src/components/data-display/InteractiveTooltip/index.ts +2 -0
- package/src/components/data-display/LazyImage/LazyImage.md +356 -0
- package/src/components/data-display/LazyImage/LazyImage.stories.tsx +387 -0
- package/src/components/data-display/LazyImage/LazyImage.tsx +323 -0
- package/src/components/data-display/LazyImage/LazyImage.types.ts +205 -0
- package/src/components/data-display/LazyImage/index.ts +2 -0
- package/src/components/data-display/Lightbox/Lightbox.stories.tsx +315 -0
- package/src/components/data-display/Lightbox/Lightbox.test.stories.tsx +605 -0
- package/src/components/data-display/Lightbox/Lightbox.tsx +666 -0
- package/src/components/data-display/Lightbox/Lightbox.types.ts +49 -0
- package/src/components/data-display/Lightbox/index.ts +2 -0
- package/src/components/data-display/Lightbox/lightbox.md +298 -0
- package/src/components/data-display/LoadingState/LoadingState.stories.tsx +124 -0
- package/src/components/data-display/LoadingState/LoadingState.test.stories.tsx +99 -0
- package/src/components/data-display/LoadingState/LoadingState.tsx +103 -0
- package/src/components/data-display/LoadingState/LoadingState.types.ts +37 -0
- package/src/components/data-display/LoadingState/index.ts +2 -0
- package/src/components/data-display/MapPreview/MapPreview.md +154 -0
- package/src/components/data-display/MapPreview/MapPreview.stories.tsx +458 -0
- package/src/components/data-display/MapPreview/MapPreview.test.stories.tsx +390 -0
- package/src/components/data-display/MapPreview/MapPreview.tsx +922 -0
- package/src/components/data-display/MapPreview/MapPreview.types.ts +56 -0
- package/src/components/data-display/MapPreview/index.ts +2 -0
- package/src/components/data-display/Popover/Popover.md +245 -0
- package/src/components/data-display/Popover/Popover.stories.tsx +295 -0
- package/src/components/data-display/Popover/Popover.test.stories.tsx +1168 -0
- package/src/components/data-display/Popover/Popover.tsx +132 -0
- package/src/components/data-display/Popover/Popover.types.ts +33 -0
- package/src/components/data-display/Popover/index.ts +2 -0
- package/src/components/data-display/Progress/Progress.md +450 -0
- package/src/components/data-display/Progress/Progress.stories.tsx +481 -0
- package/src/components/data-display/Progress/Progress.test.stories.tsx +2070 -0
- package/src/components/data-display/Progress/Progress.tsx +332 -0
- package/src/components/data-display/Progress/Progress.types.ts +61 -0
- package/src/components/data-display/Progress/index.ts +2 -0
- package/src/components/data-display/SectionOnboarding/SectionOnboarding.md +108 -0
- package/src/components/data-display/SectionOnboarding/SectionOnboarding.stories.tsx +160 -0
- package/src/components/data-display/SectionOnboarding/SectionOnboarding.test.stories.tsx +190 -0
- package/src/components/data-display/SectionOnboarding/SectionOnboarding.tsx +224 -0
- package/src/components/data-display/SectionOnboarding/SectionOnboarding.types.ts +101 -0
- package/src/components/data-display/SectionOnboarding/index.ts +7 -0
- package/src/components/data-display/Sheet/Sheet.md +475 -0
- package/src/components/data-display/Sheet/Sheet.stories.tsx +883 -0
- package/src/components/data-display/Sheet/Sheet.test.stories.tsx +1101 -0
- package/src/components/data-display/Sheet/Sheet.tsx +978 -0
- package/src/components/data-display/Sheet/Sheet.types.ts +93 -0
- package/src/components/data-display/Sheet/index.ts +8 -0
- package/src/components/data-display/Stepper/Stepper.md +542 -0
- package/src/components/data-display/Stepper/Stepper.stories.tsx +540 -0
- package/src/components/data-display/Stepper/Stepper.test.stories.tsx +607 -0
- package/src/components/data-display/Stepper/Stepper.tsx +328 -0
- package/src/components/data-display/Stepper/Stepper.types.ts +97 -0
- package/src/components/data-display/Stepper/index.ts +2 -0
- package/src/components/data-display/Table/Table.md +243 -0
- package/src/components/data-display/Table/Table.stories.tsx +801 -0
- package/src/components/data-display/Table/Table.test.stories.tsx +369 -0
- package/src/components/data-display/Table/Table.tsx +831 -0
- package/src/components/data-display/Table/Table.types.ts +335 -0
- package/src/components/data-display/Table/index.ts +2 -0
- package/src/components/data-display/Timeline/Timeline.md +201 -0
- package/src/components/data-display/Timeline/Timeline.stories.tsx +444 -0
- package/src/components/data-display/Timeline/Timeline.test.stories.tsx +944 -0
- package/src/components/data-display/Timeline/Timeline.tsx +348 -0
- package/src/components/data-display/Timeline/Timeline.types.ts +26 -0
- package/src/components/data-display/Timeline/index.ts +2 -0
- package/src/components/data-display/TimingDiagram/TimingDiagram.md +162 -0
- package/src/components/data-display/TimingDiagram/TimingDiagram.stories.tsx +475 -0
- package/src/components/data-display/TimingDiagram/TimingDiagram.test.stories.tsx +734 -0
- package/src/components/data-display/TimingDiagram/TimingDiagram.tsx +399 -0
- package/src/components/data-display/TimingDiagram/TimingDiagram.types.ts +19 -0
- package/src/components/data-display/TimingDiagram/index.ts +2 -0
- package/src/components/data-display/Tooltip/Tooltip.md +397 -0
- package/src/components/data-display/Tooltip/Tooltip.stories.tsx +465 -0
- package/src/components/data-display/Tooltip/Tooltip.test.stories.tsx +1168 -0
- package/src/components/data-display/Tooltip/Tooltip.tsx +161 -0
- package/src/components/data-display/Tooltip/Tooltip.types.ts +33 -0
- package/src/components/data-display/Tooltip/index.ts +2 -0
- package/src/components/data-display/index.ts +29 -0
- package/src/components/feedback/Dialog/Dialog.md +527 -0
- package/src/components/feedback/Dialog/Dialog.stories.tsx +833 -0
- package/src/components/feedback/Dialog/Dialog.styles.ts +171 -0
- package/src/components/feedback/Dialog/Dialog.test.stories.tsx +955 -0
- package/src/components/feedback/Dialog/Dialog.tsx +256 -0
- package/src/components/feedback/Dialog/Dialog.types.ts +46 -0
- package/src/components/feedback/Dialog/index.ts +9 -0
- package/src/components/feedback/Modal/Modal.md +629 -0
- package/src/components/feedback/Modal/Modal.stories.tsx +765 -0
- package/src/components/feedback/Modal/Modal.test.stories.tsx +251 -0
- package/src/components/feedback/Modal/Modal.tsx +279 -0
- package/src/components/feedback/Modal/Modal.types.ts +26 -0
- package/src/components/feedback/Modal/index.ts +7 -0
- package/src/components/feedback/Sonner/Sonner.stories.tsx +698 -0
- package/src/components/feedback/Sonner/Sonner.test.stories.tsx +896 -0
- package/src/components/feedback/Sonner/Sonner.tsx +493 -0
- package/src/components/feedback/Sonner/Sonner.types.ts +65 -0
- package/src/components/feedback/Sonner/index.ts +8 -0
- package/src/components/feedback/StackedModal/StackedModal.md +273 -0
- package/src/components/feedback/StackedModal/StackedModal.stories.tsx +1785 -0
- package/src/components/feedback/StackedModal/StackedModal.test.stories.tsx +975 -0
- package/src/components/feedback/StackedModal/StackedModal.tsx +664 -0
- package/src/components/feedback/StackedModal/StackedModal.types.ts +70 -0
- package/src/components/feedback/StackedModal/index.ts +11 -0
- package/src/components/feedback/Toast/Toast.md +547 -0
- package/src/components/feedback/Toast/Toast.stories.tsx +548 -0
- package/src/components/feedback/Toast/Toast.test.stories.tsx +834 -0
- package/src/components/feedback/Toast/Toast.tsx +279 -0
- package/src/components/feedback/Toast/Toast.types.ts +59 -0
- package/src/components/feedback/Toast/index.ts +8 -0
- package/src/components/feedback/TutorialOverlay/TutorialOverlay.md +610 -0
- package/src/components/feedback/TutorialOverlay/TutorialOverlay.stories.tsx +691 -0
- package/src/components/feedback/TutorialOverlay/TutorialOverlay.test.stories.tsx +634 -0
- package/src/components/feedback/TutorialOverlay/TutorialOverlay.tsx +554 -0
- package/src/components/feedback/TutorialOverlay/TutorialOverlay.types.ts +30 -0
- package/src/components/feedback/TutorialOverlay/index.ts +2 -0
- package/src/components/feedback/index.ts +6 -0
- package/src/components/form/AddressAutocomplete/AddressAutocomplete.md +633 -0
- package/src/components/form/AddressAutocomplete/AddressAutocomplete.stories.tsx +663 -0
- package/src/components/form/AddressAutocomplete/AddressAutocomplete.test.stories.tsx +723 -0
- package/src/components/form/AddressAutocomplete/AddressAutocomplete.tsx +836 -0
- package/src/components/form/AddressAutocomplete/AddressAutocomplete.types.ts +37 -0
- package/src/components/form/AddressAutocomplete/index.ts +2 -0
- package/src/components/form/Autocomplete/Autocomplete.helpers.ts +115 -0
- package/src/components/form/Autocomplete/Autocomplete.keys.ts +134 -0
- package/src/components/form/Autocomplete/Autocomplete.parts.tsx +337 -0
- package/src/components/form/Autocomplete/Autocomplete.stories.tsx +715 -0
- package/src/components/form/Autocomplete/Autocomplete.test.stories.tsx +825 -0
- package/src/components/form/Autocomplete/Autocomplete.tsx +166 -0
- package/src/components/form/Autocomplete/Autocomplete.types.ts +116 -0
- package/src/components/form/Autocomplete/autocomplete.md +789 -0
- package/src/components/form/Autocomplete/index.ts +8 -0
- package/src/components/form/Autocomplete/useAutocomplete.ts +311 -0
- package/src/components/form/Button/Button.md +411 -0
- package/src/components/form/Button/Button.stories.tsx +362 -0
- package/src/components/form/Button/Button.test.stories.tsx +603 -0
- package/src/components/form/Button/Button.tsx +326 -0
- package/src/components/form/Button/Button.types.ts +74 -0
- package/src/components/form/Button/index.ts +2 -0
- package/src/components/form/Calendar/Calendar.md +807 -0
- package/src/components/form/Calendar/Calendar.stories.tsx +349 -0
- package/src/components/form/Calendar/Calendar.test.stories.tsx +465 -0
- package/src/components/form/Calendar/Calendar.tsx +571 -0
- package/src/components/form/Calendar/Calendar.types.ts +81 -0
- package/src/components/form/Calendar/index.ts +11 -0
- package/src/components/form/Checkbox/Checkbox.md +200 -0
- package/src/components/form/Checkbox/Checkbox.stories.tsx +265 -0
- package/src/components/form/Checkbox/Checkbox.test.stories.tsx +181 -0
- package/src/components/form/Checkbox/Checkbox.tsx +170 -0
- package/src/components/form/Checkbox/Checkbox.types.ts +20 -0
- package/src/components/form/Checkbox/index.ts +2 -0
- package/src/components/form/CodeEditor/CodeEditor.md +350 -0
- package/src/components/form/CodeEditor/CodeEditor.stories.tsx +871 -0
- package/src/components/form/CodeEditor/CodeEditor.test.stories.tsx +575 -0
- package/src/components/form/CodeEditor/CodeEditor.tsx +415 -0
- package/src/components/form/CodeEditor/CodeEditor.types.ts +38 -0
- package/src/components/form/CodeEditor/index.ts +2 -0
- package/src/components/form/Command/Command.md +468 -0
- package/src/components/form/Command/Command.stories.tsx +580 -0
- package/src/components/form/Command/Command.test.stories.tsx +215 -0
- package/src/components/form/Command/Command.tsx +545 -0
- package/src/components/form/Command/Command.types.ts +116 -0
- package/src/components/form/Command/index.ts +12 -0
- package/src/components/form/CreatableSelect/CreatableSelect.md +114 -0
- package/src/components/form/CreatableSelect/CreatableSelect.stories.tsx +112 -0
- package/src/components/form/CreatableSelect/CreatableSelect.test.stories.tsx +134 -0
- package/src/components/form/CreatableSelect/CreatableSelect.tsx +149 -0
- package/src/components/form/CreatableSelect/CreatableSelect.types.ts +37 -0
- package/src/components/form/CreatableSelect/index.ts +2 -0
- package/src/components/form/Form/Form.md +325 -0
- package/src/components/form/Form/Form.stories.tsx +687 -0
- package/src/components/form/Form/Form.test.stories.tsx +601 -0
- package/src/components/form/Form/Form.tsx +136 -0
- package/src/components/form/Form/Form.types.ts +42 -0
- package/src/components/form/Form/index.ts +8 -0
- package/src/components/form/Input/Input.md +252 -0
- package/src/components/form/Input/Input.stories.tsx +256 -0
- package/src/components/form/Input/Input.test.stories.tsx +1184 -0
- package/src/components/form/Input/Input.tsx +263 -0
- package/src/components/form/Input/Input.types.ts +24 -0
- package/src/components/form/Input/index.ts +2 -0
- package/src/components/form/InputOTP/InputOTP.md +419 -0
- package/src/components/form/InputOTP/InputOTP.stories.tsx +774 -0
- package/src/components/form/InputOTP/InputOTP.test.stories.tsx +596 -0
- package/src/components/form/InputOTP/InputOTP.tsx +231 -0
- package/src/components/form/InputOTP/InputOTP.types.ts +68 -0
- package/src/components/form/InputOTP/index.ts +2 -0
- package/src/components/form/Label/Label.md +426 -0
- package/src/components/form/Label/Label.stories.tsx +473 -0
- package/src/components/form/Label/Label.test.stories.tsx +909 -0
- package/src/components/form/Label/Label.tsx +367 -0
- package/src/components/form/Label/Label.types.ts +35 -0
- package/src/components/form/Label/index.ts +2 -0
- package/src/components/form/Menubar/Menubar.md +275 -0
- package/src/components/form/Menubar/Menubar.stories.tsx +472 -0
- package/src/components/form/Menubar/Menubar.test.stories.tsx +588 -0
- package/src/components/form/Menubar/Menubar.tsx +467 -0
- package/src/components/form/Menubar/Menubar.types.ts +71 -0
- package/src/components/form/Menubar/index.ts +8 -0
- package/src/components/form/PasswordStrength/PasswordStrength.md +139 -0
- package/src/components/form/PasswordStrength/PasswordStrength.stories.tsx +562 -0
- package/src/components/form/PasswordStrength/PasswordStrength.test.stories.tsx +327 -0
- package/src/components/form/PasswordStrength/PasswordStrength.tsx +419 -0
- package/src/components/form/PasswordStrength/PasswordStrength.types.ts +18 -0
- package/src/components/form/PasswordStrength/index.ts +2 -0
- package/src/components/form/PhoneInput/PhoneInput.md +578 -0
- package/src/components/form/PhoneInput/PhoneInput.stories.tsx +495 -0
- package/src/components/form/PhoneInput/PhoneInput.test.stories.tsx +666 -0
- package/src/components/form/PhoneInput/PhoneInput.tsx +376 -0
- package/src/components/form/PhoneInput/PhoneInput.types.ts +25 -0
- package/src/components/form/PhoneInput/index.ts +2 -0
- package/src/components/form/RadioGroup/RadioGroup.md +477 -0
- package/src/components/form/RadioGroup/RadioGroup.stories.tsx +518 -0
- package/src/components/form/RadioGroup/RadioGroup.test.stories.tsx +685 -0
- package/src/components/form/RadioGroup/RadioGroup.tsx +664 -0
- package/src/components/form/RadioGroup/RadioGroup.types.ts +82 -0
- package/src/components/form/RadioGroup/index.ts +2 -0
- package/src/components/form/RichTextEditor/RichTextEditor.md +710 -0
- package/src/components/form/RichTextEditor/RichTextEditor.stories.tsx +261 -0
- package/src/components/form/RichTextEditor/RichTextEditor.test.stories.tsx +498 -0
- package/src/components/form/RichTextEditor/RichTextEditor.tsx +468 -0
- package/src/components/form/RichTextEditor/RichTextEditor.types.ts +72 -0
- package/src/components/form/RichTextEditor/index.ts +2 -0
- package/src/components/form/SearchPalette/SearchPalette.md +69 -0
- package/src/components/form/SearchPalette/SearchPalette.parts.tsx +358 -0
- package/src/components/form/SearchPalette/SearchPalette.stories.tsx +135 -0
- package/src/components/form/SearchPalette/SearchPalette.tsx +141 -0
- package/src/components/form/SearchPalette/SearchPalette.types.ts +82 -0
- package/src/components/form/SearchPalette/index.ts +7 -0
- package/src/components/form/Select/Select.md +254 -0
- package/src/components/form/Select/Select.stories.tsx +364 -0
- package/src/components/form/Select/Select.test.stories.tsx +977 -0
- package/src/components/form/Select/Select.tsx +239 -0
- package/src/components/form/Select/Select.types.ts +57 -0
- package/src/components/form/Select/index.ts +2 -0
- package/src/components/form/Slider/Slider.md +326 -0
- package/src/components/form/Slider/Slider.stories.tsx +418 -0
- package/src/components/form/Slider/Slider.test.stories.tsx +1044 -0
- package/src/components/form/Slider/Slider.tsx +374 -0
- package/src/components/form/Slider/Slider.types.ts +113 -0
- package/src/components/form/Slider/index.ts +2 -0
- package/src/components/form/Switch/Switch.md +565 -0
- package/src/components/form/Switch/Switch.stories.tsx +697 -0
- package/src/components/form/Switch/Switch.test.stories.tsx +597 -0
- package/src/components/form/Switch/Switch.tsx +578 -0
- package/src/components/form/Switch/Switch.types.ts +130 -0
- package/src/components/form/Switch/index.ts +2 -0
- package/src/components/form/Textarea/Textarea.stories.tsx +473 -0
- package/src/components/form/Textarea/Textarea.test.stories.tsx +708 -0
- package/src/components/form/Textarea/Textarea.tsx +678 -0
- package/src/components/form/Textarea/Textarea.types.ts +84 -0
- package/src/components/form/Textarea/index.ts +2 -0
- package/src/components/form/Toggle/Toggle.md +234 -0
- package/src/components/form/Toggle/Toggle.stories.tsx +638 -0
- package/src/components/form/Toggle/Toggle.test.stories.tsx +1167 -0
- package/src/components/form/Toggle/Toggle.tsx +265 -0
- package/src/components/form/Toggle/Toggle.types.ts +79 -0
- package/src/components/form/Toggle/index.ts +2 -0
- package/src/components/form/ToggleGroup/ToggleGroup.md +329 -0
- package/src/components/form/ToggleGroup/ToggleGroup.stories.tsx +617 -0
- package/src/components/form/ToggleGroup/ToggleGroup.test.stories.tsx +918 -0
- package/src/components/form/ToggleGroup/ToggleGroup.tsx +129 -0
- package/src/components/form/ToggleGroup/ToggleGroup.types.ts +53 -0
- package/src/components/form/ToggleGroup/index.ts +2 -0
- package/src/components/form/UploadButton/UploadButton.md +44 -0
- package/src/components/form/UploadButton/UploadButton.stories.tsx +366 -0
- package/src/components/form/UploadButton/UploadButton.test.stories.tsx +454 -0
- package/src/components/form/UploadButton/UploadButton.tsx +312 -0
- package/src/components/form/UploadButton/UploadButton.types.ts +58 -0
- package/src/components/form/UploadButton/index.ts +2 -0
- package/src/components/form/index.ts +25 -0
- package/src/components/form/total-form/Fields/SelectField.tsx +57 -0
- package/src/components/form/total-form/Fields/TextField.tsx +58 -0
- package/src/components/form/total-form/Fields/index.ts +4 -0
- package/src/components/form/total-form/FormContainer.tsx +104 -0
- package/src/components/form/total-form/FormContext.tsx +38 -0
- package/src/components/form/total-form/FormErrorSnackbar.tsx +35 -0
- package/src/components/form/total-form/SubmitButton.tsx +27 -0
- package/src/components/form/total-form/index.ts +12 -0
- package/src/components/form/total-form/total-form.test.tsx +97 -0
- package/src/components/index.ts +7 -0
- package/src/components/layout/Accordion/Accordion.md +725 -0
- package/src/components/layout/Accordion/Accordion.stories.tsx +690 -0
- package/src/components/layout/Accordion/Accordion.test.stories.tsx +1362 -0
- package/src/components/layout/Accordion/Accordion.tsx +242 -0
- package/src/components/layout/Accordion/Accordion.types.ts +32 -0
- package/src/components/layout/Accordion/index.ts +8 -0
- package/src/components/layout/Card/Card.md +533 -0
- package/src/components/layout/Card/Card.stories.tsx +593 -0
- package/src/components/layout/Card/Card.test.stories.tsx +1134 -0
- package/src/components/layout/Card/Card.tsx +404 -0
- package/src/components/layout/Card/Card.types.ts +57 -0
- package/src/components/layout/Card/index.ts +8 -0
- package/src/components/layout/Collapsible/Collapsible.md +135 -0
- package/src/components/layout/Collapsible/Collapsible.stories.tsx +180 -0
- package/src/components/layout/Collapsible/Collapsible.test.stories.tsx +304 -0
- package/src/components/layout/Collapsible/Collapsible.tsx +198 -0
- package/src/components/layout/Collapsible/Collapsible.types.ts +35 -0
- package/src/components/layout/Collapsible/index.ts +6 -0
- package/src/components/layout/Container/Container.md +420 -0
- package/src/components/layout/Container/Container.stories.tsx +557 -0
- package/src/components/layout/Container/Container.test.stories.tsx +750 -0
- package/src/components/layout/Container/Container.tsx +72 -0
- package/src/components/layout/Container/Container.types.ts +11 -0
- package/src/components/layout/Container/index.ts +2 -0
- package/src/components/layout/ContentToolbar/ColumnsMenu.tsx +99 -0
- package/src/components/layout/ContentToolbar/ContentToolbar.md +75 -0
- package/src/components/layout/ContentToolbar/ContentToolbar.stories.tsx +129 -0
- package/src/components/layout/ContentToolbar/ContentToolbar.test.stories.tsx +251 -0
- package/src/components/layout/ContentToolbar/ContentToolbar.tsx +108 -0
- package/src/components/layout/ContentToolbar/ContentToolbar.types.ts +229 -0
- package/src/components/layout/ContentToolbar/FilterTrigger.tsx +71 -0
- package/src/components/layout/ContentToolbar/MultiSelectDropdown.tsx +297 -0
- package/src/components/layout/ContentToolbar/SavedViewsMenu.tsx +334 -0
- package/src/components/layout/ContentToolbar/SortByDropdown.tsx +213 -0
- package/src/components/layout/ContentToolbar/ViewSelector.tsx +98 -0
- package/src/components/layout/ContentToolbar/__tests__/ColumnsMenu.test.tsx +39 -0
- package/src/components/layout/ContentToolbar/__tests__/MultiSelectDropdown.test.tsx +110 -0
- package/src/components/layout/ContentToolbar/__tests__/SavedViewsMenu.test.tsx +99 -0
- package/src/components/layout/ContentToolbar/index.ts +24 -0
- package/src/components/layout/ContentToolbar/tests.md +42 -0
- package/src/components/layout/ContentToolbar/track.md +41 -0
- package/src/components/layout/Dashboard/Dashboard.md +71 -0
- package/src/components/layout/Dashboard/Dashboard.stories.tsx +104 -0
- package/src/components/layout/Dashboard/Dashboard.test.stories.tsx +164 -0
- package/src/components/layout/Dashboard/Dashboard.tsx +297 -0
- package/src/components/layout/Dashboard/Dashboard.types.ts +157 -0
- package/src/components/layout/Dashboard/DashboardContext.tsx +47 -0
- package/src/components/layout/Dashboard/DashboardParts.tsx +216 -0
- package/src/components/layout/Dashboard/index.ts +18 -0
- package/src/components/layout/Dashboard/tests.md +46 -0
- package/src/components/layout/Dashboard/track.md +50 -0
- package/src/components/layout/Drawer/Drawer.md +479 -0
- package/src/components/layout/Drawer/Drawer.stories.tsx +660 -0
- package/src/components/layout/Drawer/Drawer.test.stories.tsx +1339 -0
- package/src/components/layout/Drawer/Drawer.tsx +150 -0
- package/src/components/layout/Drawer/Drawer.types.ts +34 -0
- package/src/components/layout/Drawer/index.ts +2 -0
- package/src/components/layout/Resizable/Resizable.md +308 -0
- package/src/components/layout/Resizable/Resizable.stories.tsx +1039 -0
- package/src/components/layout/Resizable/Resizable.test.stories.tsx +750 -0
- package/src/components/layout/Resizable/Resizable.tsx +190 -0
- package/src/components/layout/Resizable/Resizable.types.ts +34 -0
- package/src/components/layout/Resizable/index.ts +2 -0
- package/src/components/layout/ScrollArea/ScrollArea.md +122 -0
- package/src/components/layout/ScrollArea/ScrollArea.stories.tsx +651 -0
- package/src/components/layout/ScrollArea/ScrollArea.test.stories.tsx +619 -0
- package/src/components/layout/ScrollArea/ScrollArea.tsx +449 -0
- package/src/components/layout/ScrollArea/ScrollArea.types.ts +80 -0
- package/src/components/layout/ScrollArea/index.ts +7 -0
- package/src/components/layout/Separator/Separator.stories.tsx +563 -0
- package/src/components/layout/Separator/Separator.test.stories.tsx +527 -0
- package/src/components/layout/Separator/Separator.tsx +187 -0
- package/src/components/layout/Separator/Separator.types.ts +17 -0
- package/src/components/layout/Separator/index.ts +2 -0
- package/src/components/layout/SettingsLayout/SettingsLayout.md +139 -0
- package/src/components/layout/SettingsLayout/SettingsLayout.parts.tsx +357 -0
- package/src/components/layout/SettingsLayout/SettingsLayout.stories.tsx +194 -0
- package/src/components/layout/SettingsLayout/SettingsLayout.test.stories.tsx +175 -0
- package/src/components/layout/SettingsLayout/SettingsLayout.tsx +69 -0
- package/src/components/layout/SettingsLayout/SettingsLayout.types.ts +61 -0
- package/src/components/layout/SettingsLayout/index.ts +6 -0
- package/src/components/layout/Sidebar/Sidebar.md +367 -0
- package/src/components/layout/Sidebar/Sidebar.stories.tsx +611 -0
- package/src/components/layout/Sidebar/Sidebar.test.stories.tsx +1326 -0
- package/src/components/layout/Sidebar/Sidebar.tsx +131 -0
- package/src/components/layout/Sidebar/Sidebar.types.ts +30 -0
- package/src/components/layout/Sidebar/index.ts +7 -0
- package/src/components/layout/Skeleton/Skeleton.md +240 -0
- package/src/components/layout/Skeleton/Skeleton.stories.tsx +689 -0
- package/src/components/layout/Skeleton/Skeleton.test.stories.tsx +521 -0
- package/src/components/layout/Skeleton/Skeleton.tsx +166 -0
- package/src/components/layout/Skeleton/Skeleton.types.ts +19 -0
- package/src/components/layout/Skeleton/index.ts +2 -0
- package/src/components/layout/Spacer/Spacer.md +84 -0
- package/src/components/layout/Spacer/Spacer.stories.tsx +502 -0
- package/src/components/layout/Spacer/Spacer.test.stories.tsx +472 -0
- package/src/components/layout/Spacer/Spacer.tsx +68 -0
- package/src/components/layout/Spacer/Spacer.types.ts +12 -0
- package/src/components/layout/Spacer/index.ts +2 -0
- package/src/components/layout/TableFilter/TableFilter.md +55 -0
- package/src/components/layout/TableFilter/TableFilter.stories.tsx +82 -0
- package/src/components/layout/TableFilter/TableFilter.test.stories.tsx +87 -0
- package/src/components/layout/TableFilter/TableFilter.tsx +383 -0
- package/src/components/layout/TableFilter/TableFilter.types.ts +87 -0
- package/src/components/layout/TableFilter/TableFilterContext.tsx +29 -0
- package/src/components/layout/TableFilter/index.ts +15 -0
- package/src/components/layout/TableFilter/tests.md +37 -0
- package/src/components/layout/TableFilter/track.md +36 -0
- package/src/components/layout/index.ts +14 -0
- package/src/components/navigation/Breadcrumbs/Breadcrumbs.md +558 -0
- package/src/components/navigation/Breadcrumbs/Breadcrumbs.stories.tsx +640 -0
- package/src/components/navigation/Breadcrumbs/Breadcrumbs.test.stories.tsx +1007 -0
- package/src/components/navigation/Breadcrumbs/Breadcrumbs.tsx +516 -0
- package/src/components/navigation/Breadcrumbs/Breadcrumbs.types.ts +132 -0
- package/src/components/navigation/Breadcrumbs/index.ts +2 -0
- package/src/components/navigation/CommandPalette/CommandPalette.md +201 -0
- package/src/components/navigation/CommandPalette/CommandPalette.stories.tsx +384 -0
- package/src/components/navigation/CommandPalette/CommandPalette.test.stories.tsx +437 -0
- package/src/components/navigation/CommandPalette/CommandPalette.tsx +434 -0
- package/src/components/navigation/CommandPalette/CommandPalette.types.ts +25 -0
- package/src/components/navigation/CommandPalette/index.ts +2 -0
- package/src/components/navigation/ContextMenu/ContextMenu.md +535 -0
- package/src/components/navigation/ContextMenu/ContextMenu.stories.tsx +611 -0
- package/src/components/navigation/ContextMenu/ContextMenu.test.stories.tsx +850 -0
- package/src/components/navigation/ContextMenu/ContextMenu.tsx +254 -0
- package/src/components/navigation/ContextMenu/ContextMenu.types.ts +96 -0
- package/src/components/navigation/ContextMenu/index.ts +2 -0
- package/src/components/navigation/DropdownMenu/DropdownMenu.md +514 -0
- package/src/components/navigation/DropdownMenu/DropdownMenu.stories.tsx +580 -0
- package/src/components/navigation/DropdownMenu/DropdownMenu.test.stories.tsx +660 -0
- package/src/components/navigation/DropdownMenu/DropdownMenu.tsx +305 -0
- package/src/components/navigation/DropdownMenu/DropdownMenu.types.ts +116 -0
- package/src/components/navigation/DropdownMenu/index.ts +2 -0
- package/src/components/navigation/NavigationMenu/NavigationMenu.md +580 -0
- package/src/components/navigation/NavigationMenu/NavigationMenu.tsx +874 -0
- package/src/components/navigation/NavigationMenu/NavigationMenu.types.ts +135 -0
- package/src/components/navigation/NavigationMenu/index.ts +2 -0
- package/src/components/navigation/NavigationMenu/stories/NavigationMenu.stories.tsx +518 -0
- package/src/components/navigation/NavigationMenu/stories/NavigationMenu.test.stories.tsx +931 -0
- package/src/components/navigation/NavigationMenu/stories/NavigationMenuHorizontal.stories.tsx +503 -0
- package/src/components/navigation/NavigationMenu/stories/NavigationMenuVertical.stories.tsx +455 -0
- package/src/components/navigation/Pagination/Pagination.md +699 -0
- package/src/components/navigation/Pagination/Pagination.stories.tsx +604 -0
- package/src/components/navigation/Pagination/Pagination.test.stories.tsx +520 -0
- package/src/components/navigation/Pagination/Pagination.tsx +356 -0
- package/src/components/navigation/Pagination/Pagination.types.ts +129 -0
- package/src/components/navigation/Pagination/index.ts +2 -0
- package/src/components/navigation/Tabs/Tabs.md +774 -0
- package/src/components/navigation/Tabs/Tabs.stories.tsx +1006 -0
- package/src/components/navigation/Tabs/Tabs.test.stories.tsx +1225 -0
- package/src/components/navigation/Tabs/Tabs.tsx +433 -0
- package/src/components/navigation/Tabs/Tabs.types.ts +239 -0
- package/src/components/navigation/Tabs/index.ts +2 -0
- package/src/components/navigation/index.ts +7 -0
- package/src/components/typography/Blockquote/Blockquote.md +130 -0
- package/src/components/typography/Blockquote/Blockquote.stories.tsx +359 -0
- package/src/components/typography/Blockquote/Blockquote.test.stories.tsx +432 -0
- package/src/components/typography/Blockquote/Blockquote.tsx +166 -0
- package/src/components/typography/Blockquote/Blockquote.types.ts +11 -0
- package/src/components/typography/Blockquote/index.ts +2 -0
- package/src/components/typography/Code/Code.md +182 -0
- package/src/components/typography/Code/Code.stories.tsx +686 -0
- package/src/components/typography/Code/Code.test.stories.tsx +703 -0
- package/src/components/typography/Code/Code.tsx +228 -0
- package/src/components/typography/Code/Code.types.ts +12 -0
- package/src/components/typography/Code/index.ts +2 -0
- package/src/components/typography/Heading/Heading.md +143 -0
- package/src/components/typography/Heading/Heading.stories.tsx +451 -0
- package/src/components/typography/Heading/Heading.test.stories.tsx +830 -0
- package/src/components/typography/Heading/Heading.tsx +178 -0
- package/src/components/typography/Heading/Heading.types.ts +11 -0
- package/src/components/typography/Heading/index.ts +2 -0
- package/src/components/typography/Paragraph/Paragraph.md +80 -0
- package/src/components/typography/Paragraph/Paragraph.stories.tsx +280 -0
- package/src/components/typography/Paragraph/Paragraph.test.stories.tsx +238 -0
- package/src/components/typography/Paragraph/Paragraph.tsx +99 -0
- package/src/components/typography/Paragraph/Paragraph.types.ts +10 -0
- package/src/components/typography/Paragraph/index.ts +2 -0
- package/src/components/typography/Text/Text.md +129 -0
- package/src/components/typography/Text/Text.stories.tsx +359 -0
- package/src/components/typography/Text/Text.test.stories.tsx +762 -0
- package/src/components/typography/Text/Text.tsx +159 -0
- package/src/components/typography/Text/Text.types.ts +15 -0
- package/src/components/typography/Text/index.ts +2 -0
- package/src/components/typography/index.ts +5 -0
- package/src/components/utility/AnimatedIcon/AnimatedIcon.md +359 -0
- package/src/components/utility/AnimatedIcon/AnimatedIcon.stories.tsx +947 -0
- package/src/components/utility/AnimatedIcon/AnimatedIcon.test.stories.tsx +596 -0
- package/src/components/utility/AnimatedIcon/AnimatedIcon.tsx +595 -0
- package/src/components/utility/AnimatedIcon/AnimatedIcon.types.ts +98 -0
- package/src/components/utility/AnimatedIcon/index.ts +2 -0
- package/src/components/utility/AspectRatio/AspectRatio.md +200 -0
- package/src/components/utility/AspectRatio/AspectRatio.stories.tsx +414 -0
- package/src/components/utility/AspectRatio/AspectRatio.test.stories.tsx +859 -0
- package/src/components/utility/AspectRatio/AspectRatio.tsx +76 -0
- package/src/components/utility/AspectRatio/AspectRatio.types.ts +13 -0
- package/src/components/utility/AspectRatio/index.ts +2 -0
- package/src/components/utility/InfiniteScroll/InfiniteScroll.md +531 -0
- package/src/components/utility/InfiniteScroll/InfiniteScroll.stories.tsx +620 -0
- package/src/components/utility/InfiniteScroll/InfiniteScroll.test.stories.tsx +358 -0
- package/src/components/utility/InfiniteScroll/InfiniteScroll.tsx +204 -0
- package/src/components/utility/InfiniteScroll/InfiniteScroll.types.ts +39 -0
- package/src/components/utility/InfiniteScroll/index.ts +6 -0
- package/src/components/utility/Portal/Portal.button-container.example.tsx +99 -0
- package/src/components/utility/Portal/Portal.md +593 -0
- package/src/components/utility/Portal/Portal.stories.tsx +340 -0
- package/src/components/utility/Portal/Portal.test.stories.tsx +2086 -0
- package/src/components/utility/Portal/Portal.tsx +39 -0
- package/src/components/utility/Portal/Portal.types.ts +7 -0
- package/src/components/utility/Portal/index.ts +2 -0
- package/src/components/utility/Transition/Transition.md +684 -0
- package/src/components/utility/Transition/Transition.stories.tsx +493 -0
- package/src/components/utility/Transition/Transition.test.stories.tsx +854 -0
- package/src/components/utility/Transition/Transition.tsx +140 -0
- package/src/components/utility/Transition/Transition.types.ts +14 -0
- package/src/components/utility/Transition/index.ts +6 -0
- package/src/components/utility/VirtualList/VirtualList.md +520 -0
- package/src/components/utility/VirtualList/VirtualList.stories.tsx +1073 -0
- package/src/components/utility/VirtualList/VirtualList.test.stories.tsx +1074 -0
- package/src/components/utility/VirtualList/VirtualList.tsx +369 -0
- package/src/components/utility/VirtualList/VirtualList.types.ts +56 -0
- package/src/components/utility/VirtualList/index.ts +7 -0
- package/src/components/utility/WorkflowStep/WorkflowStep.md +187 -0
- package/src/components/utility/WorkflowStep/WorkflowStep.stories.tsx +433 -0
- package/src/components/utility/WorkflowStep/WorkflowStep.test.stories.tsx +364 -0
- package/src/components/utility/WorkflowStep/WorkflowStep.tsx +506 -0
- package/src/components/utility/WorkflowStep/WorkflowStep.types.ts +133 -0
- package/src/components/utility/WorkflowStep/index.ts +13 -0
- package/src/components/utility/index.ts +7 -0
- package/src/index.ts +17 -0
- package/src/mui/AppBar.ts +2 -0
- package/src/mui/Box.ts +2 -0
- package/src/mui/CssBaseline.ts +2 -0
- package/src/mui/FormControl.ts +2 -0
- package/src/mui/FormControlLabel.ts +2 -0
- package/src/mui/Grid2.ts +2 -0
- package/src/mui/InputLabel.ts +2 -0
- package/src/mui/List.ts +2 -0
- package/src/mui/ListItem.ts +2 -0
- package/src/mui/ListItemButton.ts +2 -0
- package/src/mui/ListItemText.ts +2 -0
- package/src/mui/Stack.ts +2 -0
- package/src/mui/SvgIcon.ts +2 -0
- package/src/mui/Toolbar.ts +2 -0
- package/src/mui/styles.ts +2 -0
- package/src/mui/useMediaQuery.ts +1 -0
- package/src/social-login-button.tsx +199 -0
- package/src/user-avatar.tsx +102 -0
- package/src/utils/cn.ts +9 -0
- package/src/utils/index.ts +1 -0
|
@@ -0,0 +1,568 @@
|
|
|
1
|
+
# Avatar Component
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
The Avatar component displays user profile pictures, initials, or icons in a visually appealing format. It provides comprehensive fallback mechanisms when images fail to load and supports various sizes, variants, and visual effects.
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- **Image Support**: Display user profile pictures with automatic loading states
|
|
10
|
+
- **Fallback Handling**: Graceful degradation to initials or icons when images fail
|
|
11
|
+
- **Multiple Variants**: Circle, square, rounded, and status indicator variants
|
|
12
|
+
- **Size Options**: Six predefined sizes from xs to xxl
|
|
13
|
+
- **Visual Effects**: Glow, pulse, and bordered styles
|
|
14
|
+
- **Status Indicators**: Online, offline, away, and busy status badges
|
|
15
|
+
- **Theme Integration**: Full MUI theme color support
|
|
16
|
+
- **Accessibility**: WCAG 2.1 AA compliant with proper ARIA attributes
|
|
17
|
+
- **Interactive States**: Hover, focus, and click interactions
|
|
18
|
+
- **Group Support**: AvatarGroup for displaying multiple avatars with overflow handling
|
|
19
|
+
- **Loading States**: Shimmer animation during image loading
|
|
20
|
+
- **Error Handling**: Automatic fallback display on image load errors
|
|
21
|
+
|
|
22
|
+
## Usage
|
|
23
|
+
|
|
24
|
+
### Basic Usage
|
|
25
|
+
|
|
26
|
+
```tsx
|
|
27
|
+
import { Avatar } from '@procurement/ui';
|
|
28
|
+
|
|
29
|
+
// With image
|
|
30
|
+
<Avatar
|
|
31
|
+
src="/path/to/image.jpg"
|
|
32
|
+
alt="User Name"
|
|
33
|
+
/>
|
|
34
|
+
|
|
35
|
+
// With fallback text
|
|
36
|
+
<Avatar fallback="JD" />
|
|
37
|
+
|
|
38
|
+
// With icon
|
|
39
|
+
<Avatar icon={<PersonIcon />} />
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Size Variations
|
|
43
|
+
|
|
44
|
+
```tsx
|
|
45
|
+
<Avatar fallback="XS" size="xs" /> // 24x24px
|
|
46
|
+
<Avatar fallback="SM" size="sm" /> // 32x32px
|
|
47
|
+
<Avatar fallback="MD" size="md" /> // 40x40px (default)
|
|
48
|
+
<Avatar fallback="LG" size="lg" /> // 48x48px
|
|
49
|
+
<Avatar fallback="XL" size="xl" /> // 64x64px
|
|
50
|
+
<Avatar fallback="XXL" size="xxl" /> // 80x80px
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Variants
|
|
54
|
+
|
|
55
|
+
```tsx
|
|
56
|
+
// Circle (default)
|
|
57
|
+
<Avatar variant="circle" fallback="CI" />
|
|
58
|
+
|
|
59
|
+
// Square
|
|
60
|
+
<Avatar variant="square" fallback="SQ" />
|
|
61
|
+
|
|
62
|
+
// Rounded
|
|
63
|
+
<Avatar variant="rounded" fallback="RN" />
|
|
64
|
+
|
|
65
|
+
// With status indicator
|
|
66
|
+
<Avatar variant="status" status="online" fallback="ON" />
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Visual Effects
|
|
70
|
+
|
|
71
|
+
```tsx
|
|
72
|
+
// Glow effect
|
|
73
|
+
<Avatar glow fallback="GL" />
|
|
74
|
+
|
|
75
|
+
// Pulse animation
|
|
76
|
+
<Avatar pulse fallback="PL" />
|
|
77
|
+
|
|
78
|
+
// Bordered
|
|
79
|
+
<Avatar bordered fallback="BD" />
|
|
80
|
+
|
|
81
|
+
// Combined effects
|
|
82
|
+
<Avatar glow pulse bordered fallback="CB" />
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Status Indicators
|
|
86
|
+
|
|
87
|
+
```tsx
|
|
88
|
+
<Avatar variant="status" status="online" fallback="ON" />
|
|
89
|
+
<Avatar variant="status" status="offline" fallback="OF" />
|
|
90
|
+
<Avatar variant="status" status="away" fallback="AW" />
|
|
91
|
+
<Avatar variant="status" status="busy" fallback="BS" />
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Interactive Avatars
|
|
95
|
+
|
|
96
|
+
```tsx
|
|
97
|
+
// Clickable avatar
|
|
98
|
+
<Avatar
|
|
99
|
+
interactive
|
|
100
|
+
onClick={handleClick}
|
|
101
|
+
fallback="CL"
|
|
102
|
+
/>
|
|
103
|
+
|
|
104
|
+
// With custom interaction handler
|
|
105
|
+
<Avatar
|
|
106
|
+
onClick={(e) => console.log('Avatar clicked')}
|
|
107
|
+
fallback="IN"
|
|
108
|
+
/>
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### Avatar Groups
|
|
112
|
+
|
|
113
|
+
```tsx
|
|
114
|
+
import { AvatarGroup } from '@procurement/ui';
|
|
115
|
+
|
|
116
|
+
<AvatarGroup max={3} overlap={8}>
|
|
117
|
+
<Avatar fallback="A1" />
|
|
118
|
+
<Avatar fallback="A2" />
|
|
119
|
+
<Avatar fallback="A3" />
|
|
120
|
+
<Avatar fallback="A4" />
|
|
121
|
+
<Avatar fallback="A5" />
|
|
122
|
+
</AvatarGroup>;
|
|
123
|
+
// Displays first 3 avatars plus "+2" overflow indicator
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### Loading States
|
|
127
|
+
|
|
128
|
+
```tsx
|
|
129
|
+
// Manual loading state
|
|
130
|
+
<Avatar loading fallback="LD" />
|
|
131
|
+
|
|
132
|
+
// Automatic loading during image fetch
|
|
133
|
+
<Avatar src="/slow-loading-image.jpg" fallback="SL" />
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### Error Handling
|
|
137
|
+
|
|
138
|
+
```tsx
|
|
139
|
+
<Avatar
|
|
140
|
+
src="/invalid-image.jpg"
|
|
141
|
+
fallback="ER"
|
|
142
|
+
onError={(e) => console.log('Image failed to load')}
|
|
143
|
+
showFallbackOnError={true}
|
|
144
|
+
/>
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### Theme Integration
|
|
148
|
+
|
|
149
|
+
```tsx
|
|
150
|
+
// Using theme colors
|
|
151
|
+
<Avatar color="primary" fallback="PR" />
|
|
152
|
+
<Avatar color="secondary" fallback="SC" />
|
|
153
|
+
<Avatar color="error" fallback="ER" />
|
|
154
|
+
<Avatar color="warning" fallback="WN" />
|
|
155
|
+
<Avatar color="success" fallback="SU" />
|
|
156
|
+
<Avatar color="neutral" fallback="NT" />
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
## Props
|
|
160
|
+
|
|
161
|
+
| Prop | Type | Default | Description |
|
|
162
|
+
| --------------------- | ---------------------------------------------------------------------------- | ----------- | ------------------------------------------------------ |
|
|
163
|
+
| `variant` | `'circle' \| 'square' \| 'rounded' \| 'status'` | `'circle'` | Shape variant of the avatar |
|
|
164
|
+
| `size` | `'xs' \| 'sm' \| 'md' \| 'lg' \| 'xl' \| 'xxl'` | `'md'` | Size of the avatar |
|
|
165
|
+
| `src` | `string` | - | Image URL for the avatar |
|
|
166
|
+
| `alt` | `string` | - | Alternative text for the image |
|
|
167
|
+
| `fallback` | `string \| ReactNode` | - | Content to display when image is not available |
|
|
168
|
+
| `icon` | `ReactNode` | - | Icon to display instead of image or text |
|
|
169
|
+
| `glow` | `boolean` | `false` | Apply glow effect to the avatar |
|
|
170
|
+
| `pulse` | `boolean` | `false` | Apply pulse animation to the avatar |
|
|
171
|
+
| `bordered` | `boolean` | `false` | Add border to the avatar |
|
|
172
|
+
| `status` | `'online' \| 'offline' \| 'away' \| 'busy'` | - | Status indicator (requires variant="status") |
|
|
173
|
+
| `color` | `'primary' \| 'secondary' \| 'error' \| 'warning' \| 'success' \| 'neutral'` | `'primary'` | Theme color for the avatar background |
|
|
174
|
+
| `loading` | `boolean` | `false` | Show loading state with shimmer effect |
|
|
175
|
+
| `interactive` | `boolean` | `false` | Enable interactive hover/focus states |
|
|
176
|
+
| `onClick` | `(event: MouseEvent) => void` | - | Click handler (automatically makes avatar interactive) |
|
|
177
|
+
| `onError` | `(event: SyntheticEvent) => void` | - | Error handler for image load failures |
|
|
178
|
+
| `showFallbackOnError` | `boolean` | `true` | Show fallback content when image fails to load |
|
|
179
|
+
| `animationDelay` | `number` | `0` | Delay before fade-in animation (ms) |
|
|
180
|
+
| `className` | `string` | - | Additional CSS classes |
|
|
181
|
+
| `children` | `ReactNode` | - | Custom content for the avatar |
|
|
182
|
+
| `dataTestId` | `string` | - | Test ID for automated testing |
|
|
183
|
+
|
|
184
|
+
## AvatarGroup Props
|
|
185
|
+
|
|
186
|
+
| Prop | Type | Default | Description |
|
|
187
|
+
| ------------ | ----------- | ------- | ------------------------------------ |
|
|
188
|
+
| `max` | `number` | `4` | Maximum number of avatars to display |
|
|
189
|
+
| `overlap` | `number` | `8` | Pixel overlap between avatars |
|
|
190
|
+
| `className` | `string` | - | Additional CSS classes |
|
|
191
|
+
| `children` | `ReactNode` | - | Avatar components to group |
|
|
192
|
+
| `dataTestId` | `string` | - | Test ID for automated testing |
|
|
193
|
+
|
|
194
|
+
## Accessibility
|
|
195
|
+
|
|
196
|
+
The Avatar component is fully accessible with:
|
|
197
|
+
|
|
198
|
+
- **ARIA Labels**: Proper aria-label attributes for screen readers
|
|
199
|
+
- **Alt Text**: Support for alt text on images
|
|
200
|
+
- **Keyboard Navigation**: Full keyboard support for interactive avatars
|
|
201
|
+
- **Focus Management**: Clear focus indicators with proper outline
|
|
202
|
+
- **Role Attributes**: Correct role="button" for interactive avatars
|
|
203
|
+
- **Status Announcements**: Screen reader friendly status indicators
|
|
204
|
+
- **Color Contrast**: WCAG 2.1 AA compliant color combinations
|
|
205
|
+
|
|
206
|
+
### Best Practices
|
|
207
|
+
|
|
208
|
+
1. Always provide `alt` text for image avatars
|
|
209
|
+
2. Use descriptive `aria-label` for icon-only avatars
|
|
210
|
+
3. Include status descriptions for screen readers when using status indicators
|
|
211
|
+
4. Ensure sufficient color contrast between avatar background and text
|
|
212
|
+
5. Use semantic HTML and proper ARIA attributes
|
|
213
|
+
|
|
214
|
+
## Examples
|
|
215
|
+
|
|
216
|
+
### User Profile Card
|
|
217
|
+
|
|
218
|
+
```tsx
|
|
219
|
+
<Card>
|
|
220
|
+
<CardContent sx={{ display: 'flex', alignItems: 'center', gap: 2 }}>
|
|
221
|
+
<Avatar src="/user-profile.jpg" alt="John Doe" size="lg" bordered />
|
|
222
|
+
<Box>
|
|
223
|
+
<Typography variant="h6">John Doe</Typography>
|
|
224
|
+
<Typography variant="body2" color="text.secondary">
|
|
225
|
+
Senior Developer
|
|
226
|
+
</Typography>
|
|
227
|
+
</Box>
|
|
228
|
+
</CardContent>
|
|
229
|
+
</Card>
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
### Team Members List
|
|
233
|
+
|
|
234
|
+
```tsx
|
|
235
|
+
<AvatarGroup max={5}>
|
|
236
|
+
{teamMembers.map((member) => (
|
|
237
|
+
<Avatar key={member.id} src={member.avatar} alt={member.name} fallback={member.initials} />
|
|
238
|
+
))}
|
|
239
|
+
</AvatarGroup>
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
### Status Indicator in Chat
|
|
243
|
+
|
|
244
|
+
```tsx
|
|
245
|
+
<ListItem>
|
|
246
|
+
<ListItemAvatar>
|
|
247
|
+
<Avatar variant="status" status={user.status} src={user.avatar} fallback={user.initials} />
|
|
248
|
+
</ListItemAvatar>
|
|
249
|
+
<ListItemText primary={user.name} secondary={user.lastMessage} />
|
|
250
|
+
</ListItem>
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
## Performance Considerations
|
|
254
|
+
|
|
255
|
+
- Images are lazy-loaded with loading states
|
|
256
|
+
- Animations use CSS transforms for better performance
|
|
257
|
+
- Shimmer effects use CSS animations instead of JavaScript
|
|
258
|
+
- Component uses React.memo for optimization when appropriate
|
|
259
|
+
- Proper image sizing prevents layout shifts
|
|
260
|
+
|
|
261
|
+
## Browser Support
|
|
262
|
+
|
|
263
|
+
- Chrome/Edge: Full support
|
|
264
|
+
- Firefox: Full support
|
|
265
|
+
- Safari: Full support
|
|
266
|
+
- Mobile browsers: Full support with touch interactions
|
|
267
|
+
|
|
268
|
+
## Testing
|
|
269
|
+
|
|
270
|
+
The Avatar component includes comprehensive test IDs for automated testing. Use the `dataTestId` prop to enable test identification.
|
|
271
|
+
|
|
272
|
+
### Test ID Structure
|
|
273
|
+
|
|
274
|
+
When `dataTestId` is provided, the following test IDs are automatically generated:
|
|
275
|
+
|
|
276
|
+
| Element | Test ID Pattern | Description |
|
|
277
|
+
| -------------------- | ---------------------------- | ------------------------------------------------ |
|
|
278
|
+
| Main Avatar | `{dataTestId}` | The main avatar container element |
|
|
279
|
+
| Image Content | `{dataTestId}-children` | When custom children are rendered |
|
|
280
|
+
| Fallback Content | `{dataTestId}-fallback` | When fallback text/initials are displayed |
|
|
281
|
+
| Icon Content | `{dataTestId}-icon` | When an icon is displayed |
|
|
282
|
+
| Default Content | `{dataTestId}-default` | When default Person icon is displayed |
|
|
283
|
+
| Loading Overlay | `{dataTestId}-loading` | Loading state overlay with spinner |
|
|
284
|
+
| Status Badge | `{dataTestId}-badge` | Status indicator badge (variant="status") |
|
|
285
|
+
| AvatarGroup | `{dataTestId}` | The AvatarGroup container |
|
|
286
|
+
| Overflow Avatar | `{dataTestId}-overflow` | The "+N" overflow counter avatar in AvatarGroup |
|
|
287
|
+
|
|
288
|
+
### Testing Examples
|
|
289
|
+
|
|
290
|
+
#### Basic Avatar Tests
|
|
291
|
+
|
|
292
|
+
```tsx
|
|
293
|
+
import { render, screen } from '@testing-library/react';
|
|
294
|
+
import { Avatar } from '@procurement/ui';
|
|
295
|
+
|
|
296
|
+
describe('Avatar', () => {
|
|
297
|
+
it('should render with image', () => {
|
|
298
|
+
render(<Avatar src="/user.jpg" alt="John Doe" dataTestId="user-avatar" />);
|
|
299
|
+
const avatar = screen.getByTestId('user-avatar');
|
|
300
|
+
expect(avatar).toBeInTheDocument();
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
it('should display fallback text', () => {
|
|
304
|
+
render(<Avatar fallback="JD" dataTestId="user-avatar" />);
|
|
305
|
+
const fallback = screen.getByTestId('user-avatar-fallback');
|
|
306
|
+
expect(fallback).toHaveTextContent('JD');
|
|
307
|
+
});
|
|
308
|
+
|
|
309
|
+
it('should show loading state', () => {
|
|
310
|
+
render(<Avatar loading dataTestId="user-avatar" />);
|
|
311
|
+
const loadingOverlay = screen.getByTestId('user-avatar-loading');
|
|
312
|
+
expect(loadingOverlay).toBeInTheDocument();
|
|
313
|
+
});
|
|
314
|
+
|
|
315
|
+
it('should display icon', () => {
|
|
316
|
+
render(<Avatar icon={<PersonIcon />} dataTestId="user-avatar" />);
|
|
317
|
+
const iconContent = screen.getByTestId('user-avatar-icon');
|
|
318
|
+
expect(iconContent).toBeInTheDocument();
|
|
319
|
+
});
|
|
320
|
+
});
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
#### Status Badge Tests
|
|
324
|
+
|
|
325
|
+
```tsx
|
|
326
|
+
it('should render status badge', () => {
|
|
327
|
+
render(
|
|
328
|
+
<Avatar
|
|
329
|
+
variant="status"
|
|
330
|
+
status="online"
|
|
331
|
+
fallback="JD"
|
|
332
|
+
dataTestId="status-avatar"
|
|
333
|
+
/>
|
|
334
|
+
);
|
|
335
|
+
const badge = screen.getByTestId('status-avatar-badge');
|
|
336
|
+
expect(badge).toBeInTheDocument();
|
|
337
|
+
});
|
|
338
|
+
|
|
339
|
+
it('should not render badge without status variant', () => {
|
|
340
|
+
render(<Avatar fallback="JD" dataTestId="regular-avatar" />);
|
|
341
|
+
const badge = screen.queryByTestId('regular-avatar-badge');
|
|
342
|
+
expect(badge).not.toBeInTheDocument();
|
|
343
|
+
});
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
#### Interactive Avatar Tests
|
|
347
|
+
|
|
348
|
+
```tsx
|
|
349
|
+
import { render, screen, fireEvent } from '@testing-library/react';
|
|
350
|
+
|
|
351
|
+
it('should handle click events', () => {
|
|
352
|
+
const handleClick = vi.fn();
|
|
353
|
+
render(
|
|
354
|
+
<Avatar
|
|
355
|
+
interactive
|
|
356
|
+
onClick={handleClick}
|
|
357
|
+
fallback="CL"
|
|
358
|
+
dataTestId="clickable-avatar"
|
|
359
|
+
/>
|
|
360
|
+
);
|
|
361
|
+
|
|
362
|
+
const avatar = screen.getByTestId('clickable-avatar');
|
|
363
|
+
fireEvent.click(avatar);
|
|
364
|
+
expect(handleClick).toHaveBeenCalledTimes(1);
|
|
365
|
+
});
|
|
366
|
+
|
|
367
|
+
it('should be keyboard accessible', () => {
|
|
368
|
+
render(<Avatar interactive fallback="KB" dataTestId="keyboard-avatar" />);
|
|
369
|
+
const avatar = screen.getByTestId('keyboard-avatar');
|
|
370
|
+
|
|
371
|
+
expect(avatar).toHaveAttribute('tabIndex', '0');
|
|
372
|
+
expect(avatar).toHaveAttribute('role', 'button');
|
|
373
|
+
});
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
#### Image Error Handling Tests
|
|
377
|
+
|
|
378
|
+
```tsx
|
|
379
|
+
it('should display fallback on image error', async () => {
|
|
380
|
+
render(
|
|
381
|
+
<Avatar
|
|
382
|
+
src="/broken-image.jpg"
|
|
383
|
+
fallback="ER"
|
|
384
|
+
dataTestId="error-avatar"
|
|
385
|
+
showFallbackOnError
|
|
386
|
+
/>
|
|
387
|
+
);
|
|
388
|
+
|
|
389
|
+
const avatar = screen.getByTestId('error-avatar');
|
|
390
|
+
const img = avatar.querySelector('img');
|
|
391
|
+
|
|
392
|
+
// Trigger image error
|
|
393
|
+
fireEvent.error(img!);
|
|
394
|
+
|
|
395
|
+
// Fallback should be displayed
|
|
396
|
+
const fallback = await screen.findByTestId('error-avatar-fallback');
|
|
397
|
+
expect(fallback).toHaveTextContent('ER');
|
|
398
|
+
});
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
#### AvatarGroup Tests
|
|
402
|
+
|
|
403
|
+
```tsx
|
|
404
|
+
it('should render avatar group with overflow', () => {
|
|
405
|
+
render(
|
|
406
|
+
<AvatarGroup max={3} dataTestId="team-avatars">
|
|
407
|
+
<Avatar fallback="A1" />
|
|
408
|
+
<Avatar fallback="A2" />
|
|
409
|
+
<Avatar fallback="A3" />
|
|
410
|
+
<Avatar fallback="A4" />
|
|
411
|
+
<Avatar fallback="A5" />
|
|
412
|
+
</AvatarGroup>
|
|
413
|
+
);
|
|
414
|
+
|
|
415
|
+
const group = screen.getByTestId('team-avatars');
|
|
416
|
+
expect(group).toBeInTheDocument();
|
|
417
|
+
|
|
418
|
+
const overflow = screen.getByTestId('team-avatars-overflow');
|
|
419
|
+
expect(overflow).toHaveTextContent('+2');
|
|
420
|
+
});
|
|
421
|
+
|
|
422
|
+
it('should not render overflow when under max', () => {
|
|
423
|
+
render(
|
|
424
|
+
<AvatarGroup max={5} dataTestId="small-team">
|
|
425
|
+
<Avatar fallback="A1" />
|
|
426
|
+
<Avatar fallback="A2" />
|
|
427
|
+
</AvatarGroup>
|
|
428
|
+
);
|
|
429
|
+
|
|
430
|
+
const overflow = screen.queryByTestId('small-team-overflow');
|
|
431
|
+
expect(overflow).not.toBeInTheDocument();
|
|
432
|
+
});
|
|
433
|
+
```
|
|
434
|
+
|
|
435
|
+
#### Size and Variant Tests
|
|
436
|
+
|
|
437
|
+
```tsx
|
|
438
|
+
it('should render different sizes', () => {
|
|
439
|
+
const { rerender } = render(<Avatar size="xs" fallback="XS" dataTestId="sized-avatar" />);
|
|
440
|
+
let avatar = screen.getByTestId('sized-avatar');
|
|
441
|
+
expect(avatar).toHaveStyle({ width: '24px', height: '24px' });
|
|
442
|
+
|
|
443
|
+
rerender(<Avatar size="xl" fallback="XL" dataTestId="sized-avatar" />);
|
|
444
|
+
avatar = screen.getByTestId('sized-avatar');
|
|
445
|
+
expect(avatar).toHaveStyle({ width: '64px', height: '64px' });
|
|
446
|
+
});
|
|
447
|
+
|
|
448
|
+
it('should apply variant styles', () => {
|
|
449
|
+
const { rerender } = render(
|
|
450
|
+
<Avatar variant="circle" fallback="CI" dataTestId="variant-avatar" />
|
|
451
|
+
);
|
|
452
|
+
let avatar = screen.getByTestId('variant-avatar');
|
|
453
|
+
expect(avatar).toHaveStyle({ borderRadius: '50%' });
|
|
454
|
+
|
|
455
|
+
rerender(<Avatar variant="square" fallback="SQ" dataTestId="variant-avatar" />);
|
|
456
|
+
avatar = screen.getByTestId('variant-avatar');
|
|
457
|
+
expect(avatar).toHaveStyle({ borderRadius: '0' });
|
|
458
|
+
});
|
|
459
|
+
```
|
|
460
|
+
|
|
461
|
+
#### Accessibility Tests
|
|
462
|
+
|
|
463
|
+
```tsx
|
|
464
|
+
it('should have proper ARIA attributes', () => {
|
|
465
|
+
render(
|
|
466
|
+
<Avatar
|
|
467
|
+
src="/user.jpg"
|
|
468
|
+
alt="John Doe"
|
|
469
|
+
dataTestId="accessible-avatar"
|
|
470
|
+
/>
|
|
471
|
+
);
|
|
472
|
+
|
|
473
|
+
const avatar = screen.getByTestId('accessible-avatar');
|
|
474
|
+
expect(avatar).toHaveAttribute('aria-label', 'John Doe');
|
|
475
|
+
});
|
|
476
|
+
|
|
477
|
+
it('should use custom aria-label', () => {
|
|
478
|
+
render(
|
|
479
|
+
<Avatar
|
|
480
|
+
fallback="JD"
|
|
481
|
+
aria-label="User Profile Picture"
|
|
482
|
+
dataTestId="custom-aria-avatar"
|
|
483
|
+
/>
|
|
484
|
+
);
|
|
485
|
+
|
|
486
|
+
const avatar = screen.getByTestId('custom-aria-avatar');
|
|
487
|
+
expect(avatar).toHaveAttribute('aria-label', 'User Profile Picture');
|
|
488
|
+
});
|
|
489
|
+
```
|
|
490
|
+
|
|
491
|
+
#### Visual Effects Tests
|
|
492
|
+
|
|
493
|
+
```tsx
|
|
494
|
+
it('should apply glow effect', () => {
|
|
495
|
+
render(<Avatar glow fallback="GL" dataTestId="glow-avatar" />);
|
|
496
|
+
const avatar = screen.getByTestId('glow-avatar');
|
|
497
|
+
expect(avatar).toHaveStyle({ boxShadow: expect.stringContaining('0 0 20px') });
|
|
498
|
+
});
|
|
499
|
+
|
|
500
|
+
it('should apply pulse animation', () => {
|
|
501
|
+
render(<Avatar pulse fallback="PL" dataTestId="pulse-avatar" />);
|
|
502
|
+
const avatar = screen.getByTestId('pulse-avatar');
|
|
503
|
+
const styles = window.getComputedStyle(avatar);
|
|
504
|
+
expect(styles.position).toBe('relative');
|
|
505
|
+
});
|
|
506
|
+
|
|
507
|
+
it('should apply bordered style', () => {
|
|
508
|
+
render(<Avatar bordered fallback="BD" dataTestId="bordered-avatar" />);
|
|
509
|
+
const avatar = screen.getByTestId('bordered-avatar');
|
|
510
|
+
expect(avatar).toHaveStyle({ border: expect.stringContaining('2px solid') });
|
|
511
|
+
});
|
|
512
|
+
```
|
|
513
|
+
|
|
514
|
+
### Testing Best Practices
|
|
515
|
+
|
|
516
|
+
1. **Always provide dataTestId**: Include `dataTestId` for all avatars in your application
|
|
517
|
+
2. **Test content types**: Verify correct content rendering (image, fallback, icon)
|
|
518
|
+
3. **Test loading states**: Ensure loading indicators appear and disappear correctly
|
|
519
|
+
4. **Test error scenarios**: Verify fallback behavior when images fail to load
|
|
520
|
+
5. **Test interactions**: Validate click handlers and keyboard navigation
|
|
521
|
+
6. **Test accessibility**: Ensure ARIA attributes and screen reader support
|
|
522
|
+
7. **Test visual effects**: Verify glow, pulse, and other visual enhancements
|
|
523
|
+
8. **Test groups**: Validate AvatarGroup overflow counting and layout
|
|
524
|
+
|
|
525
|
+
### Integration Testing
|
|
526
|
+
|
|
527
|
+
For E2E testing with Playwright:
|
|
528
|
+
|
|
529
|
+
```typescript
|
|
530
|
+
import { test, expect } from '@playwright/test';
|
|
531
|
+
|
|
532
|
+
test('avatar displays user profile', async ({ page }) => {
|
|
533
|
+
await page.goto('/profile');
|
|
534
|
+
|
|
535
|
+
const avatar = page.getByTestId('user-avatar');
|
|
536
|
+
await expect(avatar).toBeVisible();
|
|
537
|
+
|
|
538
|
+
// Check if image loaded
|
|
539
|
+
const img = avatar.locator('img');
|
|
540
|
+
await expect(img).toHaveAttribute('src', /user-profile/);
|
|
541
|
+
});
|
|
542
|
+
|
|
543
|
+
test('avatar group shows overflow count', async ({ page }) => {
|
|
544
|
+
await page.goto('/team');
|
|
545
|
+
|
|
546
|
+
const avatarGroup = page.getByTestId('team-avatars');
|
|
547
|
+
await expect(avatarGroup).toBeVisible();
|
|
548
|
+
|
|
549
|
+
const overflow = page.getByTestId('team-avatars-overflow');
|
|
550
|
+
await expect(overflow).toContainText('+');
|
|
551
|
+
});
|
|
552
|
+
|
|
553
|
+
test('interactive avatar responds to clicks', async ({ page }) => {
|
|
554
|
+
await page.goto('/profile');
|
|
555
|
+
|
|
556
|
+
const avatar = page.getByTestId('clickable-avatar');
|
|
557
|
+
await avatar.click();
|
|
558
|
+
|
|
559
|
+
// Verify navigation or modal opened
|
|
560
|
+
await expect(page).toHaveURL(/profile-details/);
|
|
561
|
+
});
|
|
562
|
+
```
|
|
563
|
+
|
|
564
|
+
## Related Components
|
|
565
|
+
|
|
566
|
+
- [Badge](../Badge/Badge.md) - For notification indicators
|
|
567
|
+
- [Chip](../Chip/Chip.md) - For compact user representations
|
|
568
|
+
- [Skeleton](../../layout/Skeleton/Skeleton.md) - For loading placeholders
|