@mitodl/smoot-design 0.0.0-0a23f44
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 +28 -0
- package/README.md +35 -0
- package/dist/bundles/aiDrawerManager.es.js +38832 -0
- package/dist/bundles/aiDrawerManager.es.js.map +1 -0
- package/dist/bundles/aiDrawerManager.umd.js +245 -0
- package/dist/bundles/aiDrawerManager.umd.js.map +1 -0
- package/dist/bundles/remoteTutorDrawer.es.js +38832 -0
- package/dist/bundles/remoteTutorDrawer.es.js.map +1 -0
- package/dist/bundles/remoteTutorDrawer.umd.js +245 -0
- package/dist/bundles/remoteTutorDrawer.umd.js.map +1 -0
- package/dist/cjs/VERSION.d.ts +12 -0
- package/dist/cjs/VERSION.js +15 -0
- package/dist/cjs/ai.d.ts +3 -0
- package/dist/cjs/ai.js +9 -0
- package/dist/cjs/bundles/AiDrawer/AiDrawer.d.ts +55 -0
- package/dist/cjs/bundles/AiDrawer/AiDrawer.js +262 -0
- package/dist/cjs/bundles/AiDrawer/AiDrawer.stories.d.ts +17 -0
- package/dist/cjs/bundles/AiDrawer/AiDrawer.stories.js +264 -0
- package/dist/cjs/bundles/AiDrawer/AiDrawerManager.d.ts +12 -0
- package/dist/cjs/bundles/AiDrawer/AiDrawerManager.js +51 -0
- package/dist/cjs/bundles/AiDrawer/AiDrawerManager.stories.d.ts +6 -0
- package/dist/cjs/bundles/AiDrawer/AiDrawerManager.stories.js +267 -0
- package/dist/cjs/bundles/AiDrawer/AiDrawerManager.test.d.ts +1 -0
- package/dist/cjs/bundles/AiDrawer/AiDrawerManager.test.js +245 -0
- package/dist/cjs/bundles/AiDrawer/FlashcardsScreen.d.ts +9 -0
- package/dist/cjs/bundles/AiDrawer/FlashcardsScreen.js +87 -0
- package/dist/cjs/bundles/aiDrawerManager.d.ts +6 -0
- package/dist/cjs/bundles/aiDrawerManager.js +44 -0
- package/dist/cjs/components/AiChat/AiChat.d.ts +5 -0
- package/dist/cjs/components/AiChat/AiChat.js +267 -0
- package/dist/cjs/components/AiChat/AiChat.stories.d.ts +17 -0
- package/dist/cjs/components/AiChat/AiChat.stories.js +194 -0
- package/dist/cjs/components/AiChat/AiChat.test.d.ts +1 -0
- package/dist/cjs/components/AiChat/AiChat.test.js +211 -0
- package/dist/cjs/components/AiChat/AiChatContext.d.ts +26 -0
- package/dist/cjs/components/AiChat/AiChatContext.js +106 -0
- package/dist/cjs/components/AiChat/AiChatContext.stories.d.ts +14 -0
- package/dist/cjs/components/AiChat/AiChatContext.stories.js +75 -0
- package/dist/cjs/components/AiChat/AiChatMarkdown.stories.d.ts +15 -0
- package/dist/cjs/components/AiChat/AiChatMarkdown.stories.js +282 -0
- package/dist/cjs/components/AiChat/ChatTitle.d.ts +8 -0
- package/dist/cjs/components/AiChat/ChatTitle.js +43 -0
- package/dist/cjs/components/AiChat/EllipsisIcon.d.ts +6 -0
- package/dist/cjs/components/AiChat/EllipsisIcon.js +17 -0
- package/dist/cjs/components/AiChat/EntryScreen.d.ts +11 -0
- package/dist/cjs/components/AiChat/EntryScreen.js +123 -0
- package/dist/cjs/components/AiChat/Markdown.d.ts +7 -0
- package/dist/cjs/components/AiChat/Markdown.js +14 -0
- package/dist/cjs/components/AiChat/TimLogo.d.ts +5 -0
- package/dist/cjs/components/AiChat/TimLogo.js +15 -0
- package/dist/cjs/components/AiChat/test-utils/api.d.ts +2 -0
- package/dist/cjs/components/AiChat/test-utils/api.js +164 -0
- package/dist/cjs/components/AiChat/types.d.ts +96 -0
- package/dist/cjs/components/AiChat/types.js +3 -0
- package/dist/cjs/components/AiChat/utils.d.ts +9 -0
- package/dist/cjs/components/AiChat/utils.js +41 -0
- package/dist/cjs/components/Alert/Alert.d.ts +15 -0
- package/dist/cjs/components/Alert/Alert.js +62 -0
- package/dist/cjs/components/Alert/Alert.stories.d.ts +8 -0
- package/dist/cjs/components/Alert/Alert.stories.js +53 -0
- package/dist/cjs/components/Button/ActionButton.d.ts +30 -0
- package/dist/cjs/components/Button/ActionButton.js +73 -0
- package/dist/cjs/components/Button/ActionButton.stories.d.ts +15 -0
- package/dist/cjs/components/Button/ActionButton.stories.js +113 -0
- package/dist/cjs/components/Button/Button.d.ts +58 -0
- package/dist/cjs/components/Button/Button.js +261 -0
- package/dist/cjs/components/Button/Button.stories.d.ts +18 -0
- package/dist/cjs/components/Button/Button.stories.js +148 -0
- package/dist/cjs/components/Button/Button.test.d.ts +1 -0
- package/dist/cjs/components/Button/Button.test.js +46 -0
- package/dist/cjs/components/Checkbox/Checkbox.d.ts +20 -0
- package/dist/cjs/components/Checkbox/Checkbox.js +85 -0
- package/dist/cjs/components/Checkbox/Checkbox.stories.d.ts +8 -0
- package/dist/cjs/components/Checkbox/Checkbox.stories.js +33 -0
- package/dist/cjs/components/CheckboxChoiceField/CheckboxChoiceField.d.ts +21 -0
- package/dist/cjs/components/CheckboxChoiceField/CheckboxChoiceField.js +43 -0
- package/dist/cjs/components/CheckboxChoiceField/CheckboxChoiceField.stories.d.ts +8 -0
- package/dist/cjs/components/CheckboxChoiceField/CheckboxChoiceField.stories.js +50 -0
- package/dist/cjs/components/CheckboxChoiceField/CheckboxChoiceField.test.d.ts +1 -0
- package/dist/cjs/components/CheckboxChoiceField/CheckboxChoiceField.test.js +52 -0
- package/dist/cjs/components/ImageAdapter/ImageAdapter.d.ts +23 -0
- package/dist/cjs/components/ImageAdapter/ImageAdapter.js +30 -0
- package/dist/cjs/components/Input/Input.d.ts +116 -0
- package/dist/cjs/components/Input/Input.js +237 -0
- package/dist/cjs/components/Input/Input.stories.d.ts +19 -0
- package/dist/cjs/components/Input/Input.stories.js +135 -0
- package/dist/cjs/components/Input/Input.test.d.ts +1 -0
- package/dist/cjs/components/Input/Input.test.js +32 -0
- package/dist/cjs/components/LinkAdapter/LinkAdapter.d.ts +23 -0
- package/dist/cjs/components/LinkAdapter/LinkAdapter.js +34 -0
- package/dist/cjs/components/RadioChoiceField/BooleanRadioChoiceField.stories.d.ts +6 -0
- package/dist/cjs/components/RadioChoiceField/BooleanRadioChoiceField.stories.js +47 -0
- package/dist/cjs/components/RadioChoiceField/RadioChoiceField.d.ts +45 -0
- package/dist/cjs/components/RadioChoiceField/RadioChoiceField.js +69 -0
- package/dist/cjs/components/RadioChoiceField/RadioChoiceField.stories.d.ts +6 -0
- package/dist/cjs/components/RadioChoiceField/RadioChoiceField.stories.js +55 -0
- package/dist/cjs/components/RadioChoiceField/RadioChoiceField.test.d.ts +1 -0
- package/dist/cjs/components/RadioChoiceField/RadioChoiceField.test.js +53 -0
- package/dist/cjs/components/ScrollSnap/ScrollSnap.d.ts +19 -0
- package/dist/cjs/components/ScrollSnap/ScrollSnap.js +59 -0
- package/dist/cjs/components/ScrollSnap/ScrollSnap.stories.d.ts +6 -0
- package/dist/cjs/components/ScrollSnap/ScrollSnap.stories.js +43 -0
- package/dist/cjs/components/ScrollSnap/useScrollSnap.d.ts +6 -0
- package/dist/cjs/components/ScrollSnap/useScrollSnap.js +36 -0
- package/dist/cjs/components/SrAnnouncer/SrAnnouncer.d.ts +25 -0
- package/dist/cjs/components/SrAnnouncer/SrAnnouncer.js +43 -0
- package/dist/cjs/components/SrAnnouncer/SrAnnouncer.stories.d.ts +6 -0
- package/dist/cjs/components/SrAnnouncer/SrAnnouncer.stories.js +44 -0
- package/dist/cjs/components/SrAnnouncer/SrAnnouncer.test.d.ts +1 -0
- package/dist/cjs/components/SrAnnouncer/SrAnnouncer.test.js +62 -0
- package/dist/cjs/components/TabButtons/TabButtonList.d.ts +25 -0
- package/dist/cjs/components/TabButtons/TabButtonList.js +97 -0
- package/dist/cjs/components/TabButtons/TabButtonList.stories.d.ts +24 -0
- package/dist/cjs/components/TabButtons/TabButtonList.stories.js +139 -0
- package/dist/cjs/components/TextField/TextField.d.ts +29 -0
- package/dist/cjs/components/TextField/TextField.js +33 -0
- package/dist/cjs/components/TextField/TextField.stories.d.ts +10 -0
- package/dist/cjs/components/TextField/TextField.stories.js +136 -0
- package/dist/cjs/components/TextField/TextField.test.d.ts +1 -0
- package/dist/cjs/components/TextField/TextField.test.js +77 -0
- package/dist/cjs/components/ThemeProvider/ThemeProvider.d.ts +21 -0
- package/dist/cjs/components/ThemeProvider/ThemeProvider.js +86 -0
- package/dist/cjs/components/ThemeProvider/ThemeProvider.stories.d.ts +63 -0
- package/dist/cjs/components/ThemeProvider/ThemeProvider.stories.js +102 -0
- package/dist/cjs/components/ThemeProvider/Typography.stories.d.ts +39 -0
- package/dist/cjs/components/ThemeProvider/Typography.stories.js +65 -0
- package/dist/cjs/components/ThemeProvider/breakpoints.d.ts +4 -0
- package/dist/cjs/components/ThemeProvider/breakpoints.js +19 -0
- package/dist/cjs/components/ThemeProvider/buttons.d.ts +7 -0
- package/dist/cjs/components/ThemeProvider/buttons.js +20 -0
- package/dist/cjs/components/ThemeProvider/chips.d.ts +3 -0
- package/dist/cjs/components/ThemeProvider/chips.js +154 -0
- package/dist/cjs/components/ThemeProvider/colors.d.ts +32 -0
- package/dist/cjs/components/ThemeProvider/colors.js +35 -0
- package/dist/cjs/components/ThemeProvider/typography.d.ts +18 -0
- package/dist/cjs/components/ThemeProvider/typography.js +173 -0
- package/dist/cjs/components/VisuallyHidden/VisuallyHidden.d.ts +24 -0
- package/dist/cjs/components/VisuallyHidden/VisuallyHidden.js +33 -0
- package/dist/cjs/components/VisuallyHidden/VisuallyHidden.stories.d.ts +6 -0
- package/dist/cjs/components/VisuallyHidden/VisuallyHidden.stories.js +13 -0
- package/dist/cjs/components/internal/FormHelpers/FormHelpers.d.ts +39 -0
- package/dist/cjs/components/internal/FormHelpers/FormHelpers.js +78 -0
- package/dist/cjs/components/internal/FormHelpers/FormHelpers.test.d.ts +1 -0
- package/dist/cjs/components/internal/FormHelpers/FormHelpers.test.js +93 -0
- package/dist/cjs/index.d.ts +25 -0
- package/dist/cjs/index.js +44 -0
- package/dist/cjs/jest-setup.d.ts +1 -0
- package/dist/cjs/jest-setup.js +18 -0
- package/dist/cjs/jsdom-extended.d.ts +6 -0
- package/dist/cjs/jsdom-extended.js +14 -0
- package/dist/cjs/story-utils/index.d.ts +6 -0
- package/dist/cjs/story-utils/index.js +17 -0
- package/dist/cjs/utils/composeRefs.d.ts +7 -0
- package/dist/cjs/utils/composeRefs.js +20 -0
- package/dist/cjs/utils/composeRefs.test.d.ts +1 -0
- package/dist/cjs/utils/composeRefs.test.js +19 -0
- package/dist/cjs/utils/retryingFetch.d.ts +19 -0
- package/dist/cjs/utils/retryingFetch.js +98 -0
- package/dist/cjs/utils/retryingFetch.test.d.ts +1 -0
- package/dist/cjs/utils/retryingFetch.test.js +48 -0
- package/dist/cjs/utils/useDevCheckStable.d.ts +8 -0
- package/dist/cjs/utils/useDevCheckStable.js +29 -0
- package/dist/cjs/utils/useInterval.d.ts +7 -0
- package/dist/cjs/utils/useInterval.js +25 -0
- package/dist/esm/VERSION.d.ts +12 -0
- package/dist/esm/VERSION.js +12 -0
- package/dist/esm/ai.d.ts +3 -0
- package/dist/esm/ai.js +2 -0
- package/dist/esm/bundles/AiDrawer/AiDrawer.d.ts +55 -0
- package/dist/esm/bundles/AiDrawer/AiDrawer.js +259 -0
- package/dist/esm/bundles/AiDrawer/AiDrawer.stories.d.ts +17 -0
- package/dist/esm/bundles/AiDrawer/AiDrawer.stories.js +261 -0
- package/dist/esm/bundles/AiDrawer/AiDrawerManager.d.ts +12 -0
- package/dist/esm/bundles/AiDrawer/AiDrawerManager.js +48 -0
- package/dist/esm/bundles/AiDrawer/AiDrawerManager.stories.d.ts +6 -0
- package/dist/esm/bundles/AiDrawer/AiDrawerManager.stories.js +264 -0
- package/dist/esm/bundles/AiDrawer/AiDrawerManager.test.d.ts +1 -0
- package/dist/esm/bundles/AiDrawer/AiDrawerManager.test.js +243 -0
- package/dist/esm/bundles/AiDrawer/FlashcardsScreen.d.ts +9 -0
- package/dist/esm/bundles/AiDrawer/FlashcardsScreen.js +83 -0
- package/dist/esm/bundles/aiDrawerManager.d.ts +6 -0
- package/dist/esm/bundles/aiDrawerManager.js +41 -0
- package/dist/esm/components/AiChat/AiChat.d.ts +5 -0
- package/dist/esm/components/AiChat/AiChat.js +263 -0
- package/dist/esm/components/AiChat/AiChat.stories.d.ts +17 -0
- package/dist/esm/components/AiChat/AiChat.stories.js +191 -0
- package/dist/esm/components/AiChat/AiChat.test.d.ts +1 -0
- package/dist/esm/components/AiChat/AiChat.test.js +209 -0
- package/dist/esm/components/AiChat/AiChatContext.d.ts +26 -0
- package/dist/esm/components/AiChat/AiChatContext.js +102 -0
- package/dist/esm/components/AiChat/AiChatContext.stories.d.ts +14 -0
- package/dist/esm/components/AiChat/AiChatContext.stories.js +72 -0
- package/dist/esm/components/AiChat/AiChatMarkdown.stories.d.ts +15 -0
- package/dist/esm/components/AiChat/AiChatMarkdown.stories.js +279 -0
- package/dist/esm/components/AiChat/ChatTitle.d.ts +8 -0
- package/dist/esm/components/AiChat/ChatTitle.js +40 -0
- package/dist/esm/components/AiChat/EllipsisIcon.d.ts +6 -0
- package/dist/esm/components/AiChat/EllipsisIcon.js +15 -0
- package/dist/esm/components/AiChat/EntryScreen.d.ts +11 -0
- package/dist/esm/components/AiChat/EntryScreen.js +120 -0
- package/dist/esm/components/AiChat/Markdown.d.ts +7 -0
- package/dist/esm/components/AiChat/Markdown.js +12 -0
- package/dist/esm/components/AiChat/TimLogo.d.ts +5 -0
- package/dist/esm/components/AiChat/TimLogo.js +13 -0
- package/dist/esm/components/AiChat/test-utils/api.d.ts +2 -0
- package/dist/esm/components/AiChat/test-utils/api.js +161 -0
- package/dist/esm/components/AiChat/types.d.ts +96 -0
- package/dist/esm/components/AiChat/types.js +2 -0
- package/dist/esm/components/AiChat/utils.d.ts +9 -0
- package/dist/esm/components/AiChat/utils.js +38 -0
- package/dist/esm/components/Alert/Alert.d.ts +15 -0
- package/dist/esm/components/Alert/Alert.js +59 -0
- package/dist/esm/components/Alert/Alert.stories.d.ts +8 -0
- package/dist/esm/components/Alert/Alert.stories.js +50 -0
- package/dist/esm/components/Button/ActionButton.d.ts +30 -0
- package/dist/esm/components/Button/ActionButton.js +68 -0
- package/dist/esm/components/Button/ActionButton.stories.d.ts +15 -0
- package/dist/esm/components/Button/ActionButton.stories.js +110 -0
- package/dist/esm/components/Button/Button.d.ts +58 -0
- package/dist/esm/components/Button/Button.js +252 -0
- package/dist/esm/components/Button/Button.stories.d.ts +18 -0
- package/dist/esm/components/Button/Button.stories.js +145 -0
- package/dist/esm/components/Button/Button.test.d.ts +1 -0
- package/dist/esm/components/Button/Button.test.js +44 -0
- package/dist/esm/components/Checkbox/Checkbox.d.ts +20 -0
- package/dist/esm/components/Checkbox/Checkbox.js +81 -0
- package/dist/esm/components/Checkbox/Checkbox.stories.d.ts +8 -0
- package/dist/esm/components/Checkbox/Checkbox.stories.js +30 -0
- package/dist/esm/components/CheckboxChoiceField/CheckboxChoiceField.d.ts +21 -0
- package/dist/esm/components/CheckboxChoiceField/CheckboxChoiceField.js +40 -0
- package/dist/esm/components/CheckboxChoiceField/CheckboxChoiceField.stories.d.ts +8 -0
- package/dist/esm/components/CheckboxChoiceField/CheckboxChoiceField.stories.js +47 -0
- package/dist/esm/components/CheckboxChoiceField/CheckboxChoiceField.test.d.ts +1 -0
- package/dist/esm/components/CheckboxChoiceField/CheckboxChoiceField.test.js +50 -0
- package/dist/esm/components/ImageAdapter/ImageAdapter.d.ts +23 -0
- package/dist/esm/components/ImageAdapter/ImageAdapter.js +27 -0
- package/dist/esm/components/Input/Input.d.ts +116 -0
- package/dist/esm/components/Input/Input.js +232 -0
- package/dist/esm/components/Input/Input.stories.d.ts +19 -0
- package/dist/esm/components/Input/Input.stories.js +132 -0
- package/dist/esm/components/Input/Input.test.d.ts +1 -0
- package/dist/esm/components/Input/Input.test.js +30 -0
- package/dist/esm/components/LinkAdapter/LinkAdapter.d.ts +23 -0
- package/dist/esm/components/LinkAdapter/LinkAdapter.js +31 -0
- package/dist/esm/components/RadioChoiceField/BooleanRadioChoiceField.stories.d.ts +6 -0
- package/dist/esm/components/RadioChoiceField/BooleanRadioChoiceField.stories.js +44 -0
- package/dist/esm/components/RadioChoiceField/RadioChoiceField.d.ts +45 -0
- package/dist/esm/components/RadioChoiceField/RadioChoiceField.js +65 -0
- package/dist/esm/components/RadioChoiceField/RadioChoiceField.stories.d.ts +6 -0
- package/dist/esm/components/RadioChoiceField/RadioChoiceField.stories.js +52 -0
- package/dist/esm/components/RadioChoiceField/RadioChoiceField.test.d.ts +1 -0
- package/dist/esm/components/RadioChoiceField/RadioChoiceField.test.js +51 -0
- package/dist/esm/components/ScrollSnap/ScrollSnap.d.ts +19 -0
- package/dist/esm/components/ScrollSnap/ScrollSnap.js +56 -0
- package/dist/esm/components/ScrollSnap/ScrollSnap.stories.d.ts +6 -0
- package/dist/esm/components/ScrollSnap/ScrollSnap.stories.js +40 -0
- package/dist/esm/components/ScrollSnap/useScrollSnap.d.ts +6 -0
- package/dist/esm/components/ScrollSnap/useScrollSnap.js +33 -0
- package/dist/esm/components/SrAnnouncer/SrAnnouncer.d.ts +25 -0
- package/dist/esm/components/SrAnnouncer/SrAnnouncer.js +40 -0
- package/dist/esm/components/SrAnnouncer/SrAnnouncer.stories.d.ts +6 -0
- package/dist/esm/components/SrAnnouncer/SrAnnouncer.stories.js +41 -0
- package/dist/esm/components/SrAnnouncer/SrAnnouncer.test.d.ts +1 -0
- package/dist/esm/components/SrAnnouncer/SrAnnouncer.test.js +60 -0
- package/dist/esm/components/TabButtons/TabButtonList.d.ts +25 -0
- package/dist/esm/components/TabButtons/TabButtonList.js +92 -0
- package/dist/esm/components/TabButtons/TabButtonList.stories.d.ts +24 -0
- package/dist/esm/components/TabButtons/TabButtonList.stories.js +136 -0
- package/dist/esm/components/TextField/TextField.d.ts +29 -0
- package/dist/esm/components/TextField/TextField.js +30 -0
- package/dist/esm/components/TextField/TextField.stories.d.ts +10 -0
- package/dist/esm/components/TextField/TextField.stories.js +133 -0
- package/dist/esm/components/TextField/TextField.test.d.ts +1 -0
- package/dist/esm/components/TextField/TextField.test.js +75 -0
- package/dist/esm/components/ThemeProvider/ThemeProvider.d.ts +21 -0
- package/dist/esm/components/ThemeProvider/ThemeProvider.js +82 -0
- package/dist/esm/components/ThemeProvider/ThemeProvider.stories.d.ts +63 -0
- package/dist/esm/components/ThemeProvider/ThemeProvider.stories.js +99 -0
- package/dist/esm/components/ThemeProvider/Typography.stories.d.ts +39 -0
- package/dist/esm/components/ThemeProvider/Typography.stories.js +62 -0
- package/dist/esm/components/ThemeProvider/breakpoints.d.ts +4 -0
- package/dist/esm/components/ThemeProvider/breakpoints.js +15 -0
- package/dist/esm/components/ThemeProvider/buttons.d.ts +7 -0
- package/dist/esm/components/ThemeProvider/buttons.js +17 -0
- package/dist/esm/components/ThemeProvider/chips.d.ts +3 -0
- package/dist/esm/components/ThemeProvider/chips.js +151 -0
- package/dist/esm/components/ThemeProvider/colors.d.ts +32 -0
- package/dist/esm/components/ThemeProvider/colors.js +32 -0
- package/dist/esm/components/ThemeProvider/typography.d.ts +18 -0
- package/dist/esm/components/ThemeProvider/typography.js +167 -0
- package/dist/esm/components/VisuallyHidden/VisuallyHidden.d.ts +24 -0
- package/dist/esm/components/VisuallyHidden/VisuallyHidden.js +30 -0
- package/dist/esm/components/VisuallyHidden/VisuallyHidden.stories.d.ts +6 -0
- package/dist/esm/components/VisuallyHidden/VisuallyHidden.stories.js +10 -0
- package/dist/esm/components/internal/FormHelpers/FormHelpers.d.ts +39 -0
- package/dist/esm/components/internal/FormHelpers/FormHelpers.js +73 -0
- package/dist/esm/components/internal/FormHelpers/FormHelpers.test.d.ts +1 -0
- package/dist/esm/components/internal/FormHelpers/FormHelpers.test.js +91 -0
- package/dist/esm/index.d.ts +25 -0
- package/dist/esm/index.js +16 -0
- package/dist/esm/jest-setup.d.ts +1 -0
- package/dist/esm/jest-setup.js +16 -0
- package/dist/esm/jsdom-extended.d.ts +6 -0
- package/dist/esm/jsdom-extended.js +12 -0
- package/dist/esm/story-utils/index.d.ts +6 -0
- package/dist/esm/story-utils/index.js +13 -0
- package/dist/esm/utils/composeRefs.d.ts +7 -0
- package/dist/esm/utils/composeRefs.js +17 -0
- package/dist/esm/utils/composeRefs.test.d.ts +1 -0
- package/dist/esm/utils/composeRefs.test.js +17 -0
- package/dist/esm/utils/retryingFetch.d.ts +19 -0
- package/dist/esm/utils/retryingFetch.js +96 -0
- package/dist/esm/utils/retryingFetch.test.d.ts +1 -0
- package/dist/esm/utils/retryingFetch.test.js +46 -0
- package/dist/esm/utils/useDevCheckStable.d.ts +8 -0
- package/dist/esm/utils/useDevCheckStable.js +26 -0
- package/dist/esm/utils/useInterval.d.ts +7 -0
- package/dist/esm/utils/useInterval.js +22 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/dist/type-augmentation/TypescriptDocs.mdx +17 -0
- package/dist/type-augmentation/imports.d.ts +3 -0
- package/dist/type-augmentation/index.d.ts +3 -0
- package/dist/type-augmentation/theme.d.ts +105 -0
- package/dist/type-augmentation/typography.d.ts +54 -0
- package/package.json +159 -0
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { useArgs } from "@storybook/preview-api";
|
|
3
|
+
import { RadioChoiceField } from "./RadioChoiceField";
|
|
4
|
+
const meta = {
|
|
5
|
+
title: "smoot-design/RadioChoiceField",
|
|
6
|
+
argTypes: {
|
|
7
|
+
onChange: {
|
|
8
|
+
action: "changed",
|
|
9
|
+
},
|
|
10
|
+
},
|
|
11
|
+
};
|
|
12
|
+
export default meta;
|
|
13
|
+
export const Simple = {
|
|
14
|
+
args: {
|
|
15
|
+
label: "Radio choice field label",
|
|
16
|
+
value: "option-1",
|
|
17
|
+
name: "simple-story",
|
|
18
|
+
choices: [
|
|
19
|
+
{
|
|
20
|
+
value: "option-1",
|
|
21
|
+
label: "Option 1",
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
value: "option-2",
|
|
25
|
+
label: "Option 2",
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
value: "option-3",
|
|
29
|
+
label: "Option 3",
|
|
30
|
+
},
|
|
31
|
+
],
|
|
32
|
+
},
|
|
33
|
+
argTypes: {
|
|
34
|
+
value: {
|
|
35
|
+
options: ["option-1", "option-2", "option-3"],
|
|
36
|
+
defaultValue: "option-1",
|
|
37
|
+
control: {
|
|
38
|
+
type: "select",
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
render: function Render(args) {
|
|
43
|
+
const [_args, setArgs] = useArgs();
|
|
44
|
+
const onChange = (event) => {
|
|
45
|
+
var _a;
|
|
46
|
+
const { currentTarget } = event;
|
|
47
|
+
(_a = args.onChange) === null || _a === void 0 ? void 0 : _a.call(args, event, currentTarget.value);
|
|
48
|
+
setArgs({ value: currentTarget.value });
|
|
49
|
+
};
|
|
50
|
+
return React.createElement(RadioChoiceField, Object.assign({}, args, { onChange: onChange }));
|
|
51
|
+
},
|
|
52
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import * as React from "react";
|
|
11
|
+
import { screen, render } from "@testing-library/react";
|
|
12
|
+
import user from "@testing-library/user-event";
|
|
13
|
+
import { BooleanRadioChoiceField } from "./RadioChoiceField";
|
|
14
|
+
import { ThemeProvider } from "../ThemeProvider/ThemeProvider";
|
|
15
|
+
describe("BooleanRadioChoiceField", () => {
|
|
16
|
+
it.each([
|
|
17
|
+
{
|
|
18
|
+
value: true,
|
|
19
|
+
expectedChecks: { yes: true, no: false },
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
value: false,
|
|
23
|
+
expectedChecks: { yes: false, no: true },
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
value: undefined,
|
|
27
|
+
expectedChecks: { yes: false, no: false },
|
|
28
|
+
},
|
|
29
|
+
])("renders correctly", ({ value, expectedChecks }) => {
|
|
30
|
+
const onChange = jest.fn();
|
|
31
|
+
render(React.createElement(BooleanRadioChoiceField, { value: value, label: "Test", name: "test", choices: [
|
|
32
|
+
{ label: "Yes", value: true },
|
|
33
|
+
{ label: "No", value: false },
|
|
34
|
+
], onChange: onChange }), { wrapper: ThemeProvider });
|
|
35
|
+
const yes = screen.getByLabelText("Yes");
|
|
36
|
+
const no = screen.getByLabelText("No");
|
|
37
|
+
expect(yes.checked).toBe(expectedChecks.yes);
|
|
38
|
+
expect(no.checked).toBe(expectedChecks.no);
|
|
39
|
+
});
|
|
40
|
+
it("calls onChange when clicking and converts value to boolean", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
41
|
+
const onChange = jest.fn();
|
|
42
|
+
render(React.createElement(BooleanRadioChoiceField, { label: "Test", name: "test", choices: [
|
|
43
|
+
{ label: "Yes", value: true },
|
|
44
|
+
{ label: "No", value: false },
|
|
45
|
+
], onChange: onChange }), { wrapper: ThemeProvider });
|
|
46
|
+
yield user.click(screen.getByLabelText("Yes"));
|
|
47
|
+
expect(onChange).toHaveBeenCalledWith({ name: "test", value: true });
|
|
48
|
+
yield user.click(screen.getByLabelText("No"));
|
|
49
|
+
expect(onChange).toHaveBeenCalledWith({ name: "test", value: false });
|
|
50
|
+
}));
|
|
51
|
+
});
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
type ScrollSnapProps = {
|
|
3
|
+
/**
|
|
4
|
+
* Tolerance within which scroll will be considered "at the bottom" of the element.
|
|
5
|
+
*/
|
|
6
|
+
threshold?: number;
|
|
7
|
+
/**
|
|
8
|
+
* Content to be displayed
|
|
9
|
+
*/
|
|
10
|
+
children: React.ReactNode;
|
|
11
|
+
className?: string;
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Component that automatically scrolls to the bottom of the element when new
|
|
15
|
+
* content is added, unless the user has scrolled up.
|
|
16
|
+
*/
|
|
17
|
+
declare const ScrollSnap: React.ForwardRefExoticComponent<ScrollSnapProps & React.RefAttributes<HTMLDivElement>>;
|
|
18
|
+
export { ScrollSnap };
|
|
19
|
+
export type { ScrollSnapProps };
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { composeRefs } from "../../utils/composeRefs";
|
|
2
|
+
import styled from "@emotion/styled";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
/**
|
|
5
|
+
* Returns the distance between visible content and the bottom of the element.
|
|
6
|
+
*/
|
|
7
|
+
const distanceFromBottom = (el) => {
|
|
8
|
+
return el.scrollHeight - el.clientHeight - el.scrollTop;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Scrolls to the bottom of the element.
|
|
12
|
+
*/
|
|
13
|
+
const scrollToBottom = (el) => {
|
|
14
|
+
el.scrollTop = el.scrollHeight;
|
|
15
|
+
};
|
|
16
|
+
const Scroller = styled.div({
|
|
17
|
+
overflow: "auto",
|
|
18
|
+
});
|
|
19
|
+
/**
|
|
20
|
+
* Component that automatically scrolls to the bottom of the element when new
|
|
21
|
+
* content is added, unless the user has scrolled up.
|
|
22
|
+
*/
|
|
23
|
+
const ScrollSnap = React.forwardRef(function ScrollSnap({ children, threshold = 2, className }, ref) {
|
|
24
|
+
const el = React.useRef(null);
|
|
25
|
+
// `content` a delayed version of children to allow measuring scroll position
|
|
26
|
+
// using the old children.
|
|
27
|
+
const [content, setContent] = React.useState(children);
|
|
28
|
+
const wasAtBottom = React.useRef(null);
|
|
29
|
+
/**
|
|
30
|
+
* The next two effects:
|
|
31
|
+
* 1. Check if the element is at the bottom.
|
|
32
|
+
* 2. Then set children -> content
|
|
33
|
+
* 3. Then scroll to bottom (if needed)
|
|
34
|
+
*
|
|
35
|
+
* In this way, we can measure the scroll position before the new content is set.
|
|
36
|
+
*
|
|
37
|
+
* In React 19, this started requiring useLayoutEffect.
|
|
38
|
+
*/
|
|
39
|
+
React.useLayoutEffect(() => {
|
|
40
|
+
if (!el.current)
|
|
41
|
+
return;
|
|
42
|
+
wasAtBottom.current = distanceFromBottom(el.current) < threshold;
|
|
43
|
+
setContent(children);
|
|
44
|
+
}, [children, threshold]);
|
|
45
|
+
React.useLayoutEffect(() => {
|
|
46
|
+
if (!el.current)
|
|
47
|
+
return;
|
|
48
|
+
const atBottom = distanceFromBottom(el.current) < threshold;
|
|
49
|
+
if (wasAtBottom.current && !atBottom) {
|
|
50
|
+
scrollToBottom(el.current);
|
|
51
|
+
wasAtBottom.current = null;
|
|
52
|
+
}
|
|
53
|
+
}, [content, threshold]);
|
|
54
|
+
return (React.createElement(Scroller, { className: className, ref: composeRefs(el, ref) }, content));
|
|
55
|
+
});
|
|
56
|
+
export { ScrollSnap };
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { ScrollSnap } from "./ScrollSnap";
|
|
3
|
+
import styled from "@emotion/styled";
|
|
4
|
+
import { faker } from "@faker-js/faker/locale/en";
|
|
5
|
+
import { useInterval } from "../../utils/useInterval";
|
|
6
|
+
import Slider from "@mui/material/Slider";
|
|
7
|
+
import Stack from "@mui/material/Stack";
|
|
8
|
+
import Typography from "@mui/material/Typography";
|
|
9
|
+
import { Button } from "../Button/Button";
|
|
10
|
+
const Scroller = styled(ScrollSnap)({
|
|
11
|
+
width: "200px",
|
|
12
|
+
height: "350px",
|
|
13
|
+
border: "1pt solid black",
|
|
14
|
+
});
|
|
15
|
+
const meta = {
|
|
16
|
+
title: "smoot-design/ScrollSnap",
|
|
17
|
+
component: ScrollSnap,
|
|
18
|
+
render: function Render(args) {
|
|
19
|
+
const MAX = 3000;
|
|
20
|
+
const [updateInterval, setUpdateInterval] = React.useState(MAX);
|
|
21
|
+
const [children, setChildren] = React.useState(faker.lorem.sentence());
|
|
22
|
+
const appendText = () => setChildren((current) => {
|
|
23
|
+
return `${current} ${faker.lorem.sentence()}`;
|
|
24
|
+
});
|
|
25
|
+
useInterval(() => {
|
|
26
|
+
appendText();
|
|
27
|
+
}, updateInterval === MAX ? null : updateInterval);
|
|
28
|
+
return (React.createElement(Stack, { gap: "12px", alignItems: "start" },
|
|
29
|
+
React.createElement(Typography, null, "Update interval (ms)"),
|
|
30
|
+
React.createElement(Slider, { sx: { width: "350px" }, marks: [
|
|
31
|
+
{ value: 100, label: "0.1s" },
|
|
32
|
+
{ value: 2000, label: "2s" },
|
|
33
|
+
{ value: MAX, label: "off" },
|
|
34
|
+
], value: updateInterval, min: 100, max: MAX, onChange: (_e, val) => setUpdateInterval(val) }),
|
|
35
|
+
React.createElement(Scroller, Object.assign({}, args), children),
|
|
36
|
+
React.createElement(Button, { onClick: appendText }, "Append Sentence")));
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
export default meta;
|
|
40
|
+
export const Chat = {};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { useEffect } from "react";
|
|
2
|
+
/**
|
|
3
|
+
* Returns the distance between visible content and the bottom of the element.
|
|
4
|
+
*/
|
|
5
|
+
const distanceFromBottom = (el) => {
|
|
6
|
+
return el.scrollHeight - el.clientHeight - el.scrollTop;
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* Scrolls to the bottom of the element.
|
|
10
|
+
*/
|
|
11
|
+
const scrollToBottom = (el) => {
|
|
12
|
+
el.scrollTop = el.scrollHeight;
|
|
13
|
+
};
|
|
14
|
+
const useScrollSnap = ({ scrollElement, contentElement, threshold = 2, }) => {
|
|
15
|
+
useEffect(() => {
|
|
16
|
+
const onGrow = () => {
|
|
17
|
+
if (!scrollElement)
|
|
18
|
+
return;
|
|
19
|
+
if (distanceFromBottom(scrollElement) < threshold) {
|
|
20
|
+
scrollToBottom(scrollElement);
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
onGrow();
|
|
24
|
+
const resizeObserver = new ResizeObserver(onGrow);
|
|
25
|
+
if (contentElement) {
|
|
26
|
+
resizeObserver.observe(contentElement);
|
|
27
|
+
}
|
|
28
|
+
return () => {
|
|
29
|
+
resizeObserver.disconnect();
|
|
30
|
+
};
|
|
31
|
+
}, [scrollElement, contentElement, threshold]);
|
|
32
|
+
};
|
|
33
|
+
export { useScrollSnap };
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
type SrAnnouncerProps = {
|
|
3
|
+
/**
|
|
4
|
+
* Message text to be read to user.
|
|
5
|
+
*
|
|
6
|
+
* Cannot contain HTML elements—only text.
|
|
7
|
+
*/
|
|
8
|
+
message: string;
|
|
9
|
+
/**
|
|
10
|
+
* Messages to display while the component is in a loading state.
|
|
11
|
+
*
|
|
12
|
+
* Identical consecutive messages may not be read on some screen readers.
|
|
13
|
+
*/
|
|
14
|
+
loadingMessages?: {
|
|
15
|
+
delay: number;
|
|
16
|
+
text: string;
|
|
17
|
+
}[];
|
|
18
|
+
isLoading: boolean;
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* A component that announces messages to screen readers as they come in.
|
|
22
|
+
*/
|
|
23
|
+
declare const SrAnnouncer: React.FC<SrAnnouncerProps>;
|
|
24
|
+
export { SrAnnouncer };
|
|
25
|
+
export type { SrAnnouncerProps };
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { VisuallyHidden } from "../VisuallyHidden/VisuallyHidden";
|
|
3
|
+
import { useEffect } from "react";
|
|
4
|
+
import { useDevCheckStable } from "../../utils/useDevCheckStable";
|
|
5
|
+
const DEFAULT_PROPS = {
|
|
6
|
+
loadingMessages: [
|
|
7
|
+
{ delay: 1500, text: "Loading" },
|
|
8
|
+
{ delay: 4000, text: "Still loading" },
|
|
9
|
+
],
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* A component that announces messages to screen readers as they come in.
|
|
13
|
+
*/
|
|
14
|
+
const SrAnnouncer = ({ message, isLoading, loadingMessages = DEFAULT_PROPS.loadingMessages, }) => {
|
|
15
|
+
var _a;
|
|
16
|
+
const [loadingMsgIndex, setLoadingMsgIndex] = React.useState(-1);
|
|
17
|
+
/**
|
|
18
|
+
* If loadingMessages changes, the timeouts are reset.
|
|
19
|
+
* Desirable if the change is real, undesirable if it's a mistake (e.g., by
|
|
20
|
+
* passing an array literal as a prop).
|
|
21
|
+
*/
|
|
22
|
+
useDevCheckStable(loadingMessages, "SrAnnouncer: loadingMessages changed (by ===) unexpectedly. This may interfere with loading message visibility");
|
|
23
|
+
useEffect(() => {
|
|
24
|
+
setLoadingMsgIndex(-1);
|
|
25
|
+
}, [isLoading, loadingMessages]);
|
|
26
|
+
useEffect(() => {
|
|
27
|
+
const next = loadingMessages[loadingMsgIndex + 1];
|
|
28
|
+
if (!isLoading || !next)
|
|
29
|
+
return () => { };
|
|
30
|
+
const id = setTimeout(() => {
|
|
31
|
+
setLoadingMsgIndex(loadingMsgIndex + 1);
|
|
32
|
+
}, next.delay);
|
|
33
|
+
return () => {
|
|
34
|
+
clearTimeout(id);
|
|
35
|
+
};
|
|
36
|
+
}, [isLoading, loadingMsgIndex, loadingMessages]);
|
|
37
|
+
const loadingTxt = (_a = loadingMessages[loadingMsgIndex]) === null || _a === void 0 ? void 0 : _a.text;
|
|
38
|
+
return (React.createElement(VisuallyHidden, { "aria-atomic": "true", "aria-live": "polite" }, isLoading ? loadingTxt : message));
|
|
39
|
+
};
|
|
40
|
+
export { SrAnnouncer };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import { SrAnnouncer } from "./SrAnnouncer";
|
|
3
|
+
declare const meta: Meta<typeof SrAnnouncer>;
|
|
4
|
+
export default meta;
|
|
5
|
+
type Story = StoryObj<typeof SrAnnouncer>;
|
|
6
|
+
export declare const ScreenreaderAnnouncements: Story;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { SrAnnouncer } from "./SrAnnouncer";
|
|
3
|
+
import styled from "@emotion/styled";
|
|
4
|
+
const Container = styled.div(({ forceVisible }) => [
|
|
5
|
+
forceVisible && {
|
|
6
|
+
width: "100% !important",
|
|
7
|
+
height: "100px !important",
|
|
8
|
+
"& > *:first-of-type": {
|
|
9
|
+
width: "unset !important",
|
|
10
|
+
height: "unset !important",
|
|
11
|
+
clipPath: "none !important",
|
|
12
|
+
clip: "unset !important",
|
|
13
|
+
position: "unset !important",
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
]);
|
|
17
|
+
const meta = {
|
|
18
|
+
title: "smoot-design/ScreenreaderAnnouncer",
|
|
19
|
+
component: SrAnnouncer,
|
|
20
|
+
decorators: function Decorator(Story) {
|
|
21
|
+
const [forceVisible, setForceVisible] = React.useState(true);
|
|
22
|
+
return (React.createElement(React.Fragment, null,
|
|
23
|
+
React.createElement("label", null,
|
|
24
|
+
"Force Visible:",
|
|
25
|
+
React.createElement("input", { type: "checkbox", checked: forceVisible, onChange: (e) => setForceVisible(e.target.checked) }),
|
|
26
|
+
React.createElement("p", null, "By default, the content of this story is visually hidden.")),
|
|
27
|
+
React.createElement("hr", null),
|
|
28
|
+
React.createElement(Container, { forceVisible: forceVisible },
|
|
29
|
+
React.createElement(Story, null))));
|
|
30
|
+
},
|
|
31
|
+
args: {
|
|
32
|
+
message: "A message to read to user",
|
|
33
|
+
isLoading: true,
|
|
34
|
+
loadingMessages: [
|
|
35
|
+
{ delay: 1000, text: "Loading" },
|
|
36
|
+
{ delay: 3000, text: "Still loading" },
|
|
37
|
+
],
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
export default meta;
|
|
41
|
+
export const ScreenreaderAnnouncements = {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import * as React from "react";
|
|
11
|
+
import { render, act } from "@testing-library/react";
|
|
12
|
+
import { SrAnnouncer } from "./SrAnnouncer";
|
|
13
|
+
const sleep = (ms) => {
|
|
14
|
+
act(() => {
|
|
15
|
+
jest.advanceTimersByTime(ms);
|
|
16
|
+
});
|
|
17
|
+
};
|
|
18
|
+
describe("SrAnnouncer", () => {
|
|
19
|
+
beforeEach(() => {
|
|
20
|
+
jest.useFakeTimers();
|
|
21
|
+
jest.clearAllTimers();
|
|
22
|
+
});
|
|
23
|
+
test("Renders a message when not loading", () => {
|
|
24
|
+
const { container } = render(React.createElement(SrAnnouncer, { message: "Hello, world!", isLoading: false }));
|
|
25
|
+
expect(container.textContent).toBe("Hello, world!");
|
|
26
|
+
});
|
|
27
|
+
test("Renders a loading message when loading", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
28
|
+
const loadingMessages = [
|
|
29
|
+
{ delay: 100, text: "Loading 1" },
|
|
30
|
+
{ delay: 200, text: "Loading 2" },
|
|
31
|
+
];
|
|
32
|
+
const { container, rerender } = render(React.createElement(SrAnnouncer, { message: "Hello, world!", loadingMessages: loadingMessages, isLoading: true }));
|
|
33
|
+
expect(container.textContent).toBe("");
|
|
34
|
+
sleep(100);
|
|
35
|
+
expect(container.textContent).toBe("Loading 1");
|
|
36
|
+
sleep(100);
|
|
37
|
+
expect(container.textContent).toBe("Loading 1");
|
|
38
|
+
sleep(100);
|
|
39
|
+
expect(container.textContent).toBe("Loading 2");
|
|
40
|
+
sleep(1000);
|
|
41
|
+
expect(container.textContent).toBe("Loading 2");
|
|
42
|
+
rerender(React.createElement(SrAnnouncer, { message: "Hello, world!", loadingMessages: loadingMessages, isLoading: false }));
|
|
43
|
+
expect(container.textContent).toBe("Hello, world!");
|
|
44
|
+
rerender(React.createElement(SrAnnouncer, { message: "Hello, world!", loadingMessages: loadingMessages, isLoading: true }));
|
|
45
|
+
expect(container.textContent).toBe("");
|
|
46
|
+
sleep(100);
|
|
47
|
+
expect(container.textContent).toBe("Loading 1");
|
|
48
|
+
sleep(100);
|
|
49
|
+
expect(container.textContent).toBe("Loading 1");
|
|
50
|
+
sleep(100);
|
|
51
|
+
expect(container.textContent).toBe("Loading 2");
|
|
52
|
+
}));
|
|
53
|
+
test("Warns if loadingMessages changes unexpectedly", () => {
|
|
54
|
+
const error = jest.spyOn(console, "error").mockImplementation(() => { });
|
|
55
|
+
const { rerender } = render(React.createElement(SrAnnouncer, { message: "Hello, world!", isLoading: true }));
|
|
56
|
+
rerender(React.createElement(SrAnnouncer, { message: "Hello, world!", isLoading: true, loadingMessages: [{ delay: 100, text: "Loading" }] }));
|
|
57
|
+
expect(error).toHaveBeenCalled();
|
|
58
|
+
error.mockRestore();
|
|
59
|
+
});
|
|
60
|
+
});
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import type { TabProps } from "@mui/material/Tab";
|
|
3
|
+
import type { TabListProps } from "@mui/lab/TabList";
|
|
4
|
+
import type { ButtonLinkProps } from "../Button/Button";
|
|
5
|
+
type StyleVariant = "chat";
|
|
6
|
+
type TabButtonListProps = TabListProps & {
|
|
7
|
+
styleVariant?: StyleVariant;
|
|
8
|
+
};
|
|
9
|
+
declare const TabButtonList: React.FC<TabButtonListProps>;
|
|
10
|
+
declare const TabLinkInner: React.ForwardRefExoticComponent<Omit<ButtonLinkProps, "ref"> & React.RefAttributes<HTMLAnchorElement>>;
|
|
11
|
+
type TabButtonProps = Omit<TabProps<"button">, "color"> & {
|
|
12
|
+
styleVariant?: StyleVariant;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Wrapper around [MUI Tab](https://mui.com/material-ui/api/tab/) using our
|
|
16
|
+
* Button as the `component` implementation.
|
|
17
|
+
*/
|
|
18
|
+
declare const TabButton: (props: TabButtonProps) => React.JSX.Element;
|
|
19
|
+
/**
|
|
20
|
+
* Wrapper around [MUI Tab](https://mui.com/material-ui/api/tab/) using our
|
|
21
|
+
* ButtonLink as the `component` implementation.
|
|
22
|
+
*/
|
|
23
|
+
declare const TabButtonLink: ({ ...props }: TabProps<typeof TabLinkInner>) => React.JSX.Element;
|
|
24
|
+
export { TabButtonList, TabButton, TabButtonLink };
|
|
25
|
+
export type { TabButtonListProps, TabButtonProps };
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
2
|
+
var t = {};
|
|
3
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
4
|
+
t[p] = s[p];
|
|
5
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
6
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
7
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
8
|
+
t[p[i]] = s[p[i]];
|
|
9
|
+
}
|
|
10
|
+
return t;
|
|
11
|
+
};
|
|
12
|
+
import * as React from "react";
|
|
13
|
+
import MuiTab from "@mui/material/Tab";
|
|
14
|
+
import MuiTabList from "@mui/lab/TabList";
|
|
15
|
+
import styled from "@emotion/styled";
|
|
16
|
+
import { Button, ButtonLink } from "../Button/Button";
|
|
17
|
+
import { css } from "@emotion/react";
|
|
18
|
+
const defaultTabListProps = {
|
|
19
|
+
variant: "scrollable",
|
|
20
|
+
allowScrollButtonsMobile: true,
|
|
21
|
+
scrollButtons: "auto",
|
|
22
|
+
};
|
|
23
|
+
const TabButtonList = styled((_a) => {
|
|
24
|
+
var { styleVariant } = _a, props = __rest(_a, ["styleVariant"]);
|
|
25
|
+
return (React.createElement(MuiTabList, Object.assign({}, defaultTabListProps, props)));
|
|
26
|
+
})(({ theme, styleVariant }) => (Object.assign({ minHeight: "unset", ".MuiTabs-indicator": {
|
|
27
|
+
display: "none",
|
|
28
|
+
}, ".MuiTabs-flexContainer": {
|
|
29
|
+
gap: "8px",
|
|
30
|
+
alignItems: "center",
|
|
31
|
+
}, ".MuiTabs-scroller": {
|
|
32
|
+
display: "flex",
|
|
33
|
+
} }, (styleVariant === "chat" && {
|
|
34
|
+
flexGrow: 1,
|
|
35
|
+
".MuiTabs-flexContainer": {
|
|
36
|
+
flexGrow: 1,
|
|
37
|
+
gap: "8px",
|
|
38
|
+
alignItems: "center",
|
|
39
|
+
backgroundColor: theme.custom.colors.lightGray1,
|
|
40
|
+
padding: "4px",
|
|
41
|
+
borderRadius: "8px",
|
|
42
|
+
},
|
|
43
|
+
button: Object.assign({ flexGrow: 1, backgroundColor: "transparent" }, theme.typography.body2),
|
|
44
|
+
"button[aria-selected=true], button[aria-selected=true]:hover": {
|
|
45
|
+
backgroundColor: theme.custom.colors.darkGray1,
|
|
46
|
+
color: theme.custom.colors.white,
|
|
47
|
+
cursor: "default",
|
|
48
|
+
},
|
|
49
|
+
}))));
|
|
50
|
+
const tabStyles = ({ theme }) => css({
|
|
51
|
+
minWidth: "auto",
|
|
52
|
+
":focus-visible": {
|
|
53
|
+
outlineOffset: "-1px",
|
|
54
|
+
},
|
|
55
|
+
'&[aria-selected="true"]': {
|
|
56
|
+
backgroundColor: theme.custom.colors.white,
|
|
57
|
+
borderColor: theme.custom.colors.darkGray2,
|
|
58
|
+
},
|
|
59
|
+
});
|
|
60
|
+
const TabButtonStyled = styled(Button)(tabStyles);
|
|
61
|
+
const TabLinkStyled = styled(ButtonLink)(tabStyles);
|
|
62
|
+
const defaultTabButtonProps = {
|
|
63
|
+
variant: "tertiary",
|
|
64
|
+
size: "small",
|
|
65
|
+
};
|
|
66
|
+
const TabButtonInner = React.forwardRef(
|
|
67
|
+
// Omits the `className` prop from the underlying Button so that MUI does not
|
|
68
|
+
// style it. We style it ourselves.
|
|
69
|
+
(props, ref) => {
|
|
70
|
+
const { className } = props, others = __rest(props, ["className"]);
|
|
71
|
+
return React.createElement(TabButtonStyled, Object.assign({}, defaultTabButtonProps, others, { ref: ref }));
|
|
72
|
+
});
|
|
73
|
+
TabButtonInner.displayName = "TabButtonInner";
|
|
74
|
+
const TabLinkInner = React.forwardRef((props, ref) => {
|
|
75
|
+
const { className } = props, others = __rest(props, ["className"]);
|
|
76
|
+
return (React.createElement(TabLinkStyled, Object.assign({}, defaultTabButtonProps, others, { ref: ref }), props.children));
|
|
77
|
+
});
|
|
78
|
+
TabLinkInner.displayName = "TabLinkInner";
|
|
79
|
+
/**
|
|
80
|
+
* Wrapper around [MUI Tab](https://mui.com/material-ui/api/tab/) using our
|
|
81
|
+
* Button as the `component` implementation.
|
|
82
|
+
*/
|
|
83
|
+
const TabButton = (props) => (React.createElement(MuiTab, Object.assign({}, props, { component: TabButtonInner })));
|
|
84
|
+
/**
|
|
85
|
+
* Wrapper around [MUI Tab](https://mui.com/material-ui/api/tab/) using our
|
|
86
|
+
* ButtonLink as the `component` implementation.
|
|
87
|
+
*/
|
|
88
|
+
const TabButtonLink = (_a) => {
|
|
89
|
+
var props = __rest(_a, []);
|
|
90
|
+
return (React.createElement(MuiTab, Object.assign({}, props, { component: TabLinkInner })));
|
|
91
|
+
};
|
|
92
|
+
export { TabButtonList, TabButton, TabButtonLink };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import type { TabButtonListProps } from "./TabButtonList";
|
|
3
|
+
type StoryProps = TabButtonListProps & {
|
|
4
|
+
count: number;
|
|
5
|
+
};
|
|
6
|
+
declare const meta: Meta<StoryProps>;
|
|
7
|
+
export default meta;
|
|
8
|
+
type Story = StoryObj<StoryProps>;
|
|
9
|
+
/**
|
|
10
|
+
* Use `TabButtonList` and `TabButton` to render a list of tabs styled as our tertiary buttons:
|
|
11
|
+
*/
|
|
12
|
+
export declare const ButtonTabs: Story;
|
|
13
|
+
/**
|
|
14
|
+
* `TabButtonList` chat style variant:
|
|
15
|
+
*/
|
|
16
|
+
export declare const ButtonTabsChatVariant: Story;
|
|
17
|
+
/**
|
|
18
|
+
* By default, the tabs will be scrollable if there are too many to fit in the container:
|
|
19
|
+
*/
|
|
20
|
+
export declare const ManyButtonTabs: Story;
|
|
21
|
+
/**
|
|
22
|
+
* Use `TabButtonLink` for tabs that should affect the URL:
|
|
23
|
+
*/
|
|
24
|
+
export declare const LinkTabs: Story;
|