@nypl/design-system-react-components 0.25.1 → 0.25.5
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/CHANGELOG.md +118 -1
- package/README.md +98 -50
- package/dist/components/Breadcrumbs/Breadcrumbs.d.ts +4 -0
- package/dist/components/Button/Button.d.ts +13 -8
- package/dist/components/Button/ButtonTypes.d.ts +2 -1
- package/dist/components/Card/Card.d.ts +36 -52
- package/dist/components/Card/CardTypes.d.ts +0 -15
- package/dist/components/Checkbox/Checkbox.d.ts +17 -13
- package/dist/components/CheckboxGroup/CheckboxGroup.d.ts +4 -2
- package/dist/components/ComponentWrapper/ComponentWrapper.d.ts +15 -0
- package/dist/components/DatePicker/DatePicker.d.ts +36 -34
- package/dist/components/Fieldset/Fieldset.d.ts +25 -0
- package/dist/components/Heading/Heading.d.ts +4 -4
- package/dist/components/HelperErrorText/HelperErrorText.d.ts +17 -14
- package/dist/components/HorizontalRule/HorizontalRule.d.ts +10 -9
- package/dist/components/Icons/Icon.d.ts +8 -0
- package/dist/components/Icons/IconSvgs.d.ts +11 -0
- package/dist/components/Icons/IconTypes.d.ts +11 -0
- package/dist/components/Image/Image.d.ts +19 -9
- package/dist/components/Image/ImageTypes.d.ts +20 -0
- package/dist/components/Link/Link.d.ts +4 -0
- package/dist/components/List/List.d.ts +19 -14
- package/dist/components/Notification/Notification.d.ts +37 -16
- package/dist/components/Pagination/Pagination.d.ts +16 -13
- package/dist/components/Pagination/Pagination.stories.d.ts +2 -0
- package/dist/components/ProgressIndicator/ProgressIndicator.d.ts +29 -0
- package/dist/components/ProgressIndicator/ProgressIndicatorTypes.d.ts +8 -0
- package/dist/components/Radio/Radio.d.ts +2 -0
- package/dist/components/RadioGroup/RadioGroup.d.ts +4 -2
- package/dist/components/SearchBar/SearchBar.d.ts +3 -3
- package/dist/components/Select/Select.d.ts +2 -0
- package/dist/components/SkeletonLoader/SkeletonLoader.d.ts +18 -14
- package/dist/components/Slider/Slider.d.ts +57 -0
- package/dist/components/StyleGuide/ColorCard.d.ts +12 -0
- package/dist/components/Tabs/Tabs.d.ts +1 -1
- package/dist/components/TextInput/TextInput.d.ts +12 -0
- package/dist/components/VideoPlayer/VideoPlayer.d.ts +6 -8
- package/dist/components/VideoPlayer/VideoPlayerTypes.d.ts +2 -2
- package/dist/design-system-react-components.cjs.development.js +6131 -3715
- package/dist/design-system-react-components.cjs.development.js.map +1 -1
- package/dist/design-system-react-components.cjs.production.min.js +1 -1
- package/dist/design-system-react-components.cjs.production.min.js.map +1 -1
- package/dist/design-system-react-components.esm.js +6124 -3699
- package/dist/design-system-react-components.esm.js.map +1 -1
- package/dist/hooks/tests/useCarouselStyles.test.d.ts +1 -0
- package/dist/hooks/useCarouselStyles.d.ts +16 -0
- package/dist/hooks/useNYPLTheme.d.ts +54 -0
- package/dist/hooks/useWindowSize.d.ts +10 -0
- package/dist/index.d.ts +13 -8
- package/dist/resources.scss +180 -170
- package/dist/styles.css +1 -1
- package/dist/theme/components/button.d.ts +22 -8
- package/dist/theme/components/card.d.ts +168 -0
- package/dist/theme/components/checkbox.d.ts +5 -1
- package/dist/theme/components/checkboxGroup.d.ts +12 -0
- package/dist/theme/components/componentWrapper.d.ts +11 -0
- package/dist/theme/components/datePicker.d.ts +16 -0
- package/dist/theme/components/fieldset.d.ts +27 -0
- package/dist/theme/components/global.d.ts +23 -13
- package/dist/theme/components/globalMixins.d.ts +9 -1
- package/dist/theme/components/heading.d.ts +5 -0
- package/dist/theme/components/helperErrorText.d.ts +10 -0
- package/dist/theme/components/hero.d.ts +1 -0
- package/dist/theme/components/horizontalRule.d.ts +14 -0
- package/dist/theme/components/image.d.ts +31 -0
- package/dist/theme/components/label.d.ts +5 -3
- package/dist/theme/components/link.d.ts +4 -0
- package/dist/theme/components/list.d.ts +89 -0
- package/dist/theme/components/notification.d.ts +75 -0
- package/dist/theme/components/pagination.d.ts +19 -0
- package/dist/theme/components/progressIndicator.d.ts +50 -0
- package/dist/theme/components/radioGroup.d.ts +12 -0
- package/dist/theme/components/select.d.ts +11 -2
- package/dist/theme/components/skeletonLoader.d.ts +98 -0
- package/dist/theme/components/slider.d.ts +51 -0
- package/dist/theme/components/tabs.d.ts +54 -3
- package/dist/theme/components/textInput.d.ts +8 -1
- package/dist/theme/components/videoPlayer.d.ts +40 -0
- package/dist/theme/foundations/breakpoints.d.ts +8 -8
- package/dist/theme/foundations/global.d.ts +6 -1
- package/dist/theme/foundations/radii.d.ts +5 -0
- package/dist/theme/foundations/spacing.d.ts +16 -16
- package/package.json +72 -83
- package/src/__tests__/setup.ts +2 -2
- package/src/components/Accordion/Accordion.stories.mdx +39 -44
- package/src/components/Autosuggest/Autosuggest.stories.mdx +3 -3
- package/src/components/Autosuggest/Autosuggest.stories.tsx +2 -1
- package/src/components/Autosuggest/_Autosuggest.scss +5 -5
- package/src/components/Breadcrumbs/Breadcrumbs.stories.mdx +14 -10
- package/src/components/Breadcrumbs/Breadcrumbs.test.tsx +23 -0
- package/src/components/Breadcrumbs/Breadcrumbs.tsx +5 -1
- package/src/components/Breadcrumbs/__snapshots__/Breadcrumbs.test.tsx.snap +199 -1
- package/src/components/Button/Button.stories.mdx +15 -10
- package/src/components/Button/Button.test.tsx +21 -7
- package/src/components/Button/Button.tsx +22 -34
- package/src/components/Button/ButtonTypes.tsx +1 -0
- package/src/components/Button/__snapshots__/Button.test.tsx.snap +41 -10
- package/src/components/Card/Card.stories.mdx +296 -259
- package/src/components/Card/Card.test.tsx +156 -84
- package/src/components/Card/Card.tsx +195 -145
- package/src/components/Card/CardTypes.tsx +0 -17
- package/src/components/Card/__snapshots__/Card.test.tsx.snap +410 -0
- package/src/components/CardEdition/CardEdition.stories.tsx +15 -47
- package/src/components/CardEdition/_CardEdition.scss +22 -23
- package/src/components/Chakra/Box.stories.mdx +15 -16
- package/src/components/Chakra/Center.stories.mdx +31 -16
- package/src/components/Chakra/Grid.stories.mdx +28 -15
- package/src/components/Chakra/Stack.stories.mdx +35 -18
- package/src/components/Checkbox/Checkbox.stories.mdx +33 -11
- package/src/components/Checkbox/Checkbox.test.tsx +47 -2
- package/src/components/Checkbox/Checkbox.tsx +39 -33
- package/src/components/Checkbox/__snapshots__/Checkbox.test.tsx.snap +90 -2
- package/src/components/CheckboxGroup/CheckboxGroup.stories.mdx +82 -2
- package/src/components/CheckboxGroup/CheckboxGroup.test.tsx +29 -2
- package/src/components/CheckboxGroup/CheckboxGroup.tsx +22 -18
- package/src/components/CheckboxGroup/__snapshots__/CheckboxGroup.test.tsx.snap +47 -81
- package/src/components/ComponentWrapper/ComponentWrapper.tsx +63 -0
- package/src/components/DatePicker/DatePicker.stories.mdx +163 -62
- package/src/components/DatePicker/DatePicker.test.tsx +264 -64
- package/src/components/DatePicker/DatePicker.tsx +159 -128
- package/src/components/DatePicker/_DatePicker.scss +33 -67
- package/src/components/DatePicker/__snapshots__/DatePicker.test.tsx.snap +818 -0
- package/src/components/Fieldset/Fieldset.stories.mdx +55 -0
- package/src/components/Fieldset/Fieldset.test.tsx +125 -0
- package/src/components/Fieldset/Fieldset.tsx +52 -0
- package/src/components/Fieldset/__snapshots__/Fieldset.test.tsx.snap +68 -0
- package/src/components/Form/Form.stories.mdx +24 -6
- package/src/components/Form/Form.test.tsx +1 -1
- package/src/components/Form/Form.tsx +1 -0
- package/src/components/Grid/SimpleGrid.stories.mdx +32 -39
- package/src/components/Grid/SimpleGrid.test.tsx +4 -4
- package/src/components/Heading/Heading.stories.mdx +3 -4
- package/src/components/Heading/Heading.tsx +5 -5
- package/src/components/HelperErrorText/HelperErrorText.stories.mdx +124 -0
- package/src/components/HelperErrorText/HelperErrorText.test.tsx +39 -44
- package/src/components/HelperErrorText/HelperErrorText.tsx +37 -39
- package/src/components/HelperErrorText/__snapshots__/HelperErrorText.test.tsx.snap +25 -0
- package/src/components/Hero/Hero.stories.mdx +12 -2
- package/src/components/Hero/Hero.tsx +1 -1
- package/src/components/Hero/HeroTypes.tsx +1 -0
- package/src/components/Hero/__snapshots__/Hero.test.tsx.snap +7 -7
- package/src/components/HorizontalRule/HorizontalRule.stories.mdx +8 -6
- package/src/components/HorizontalRule/HorizontalRule.test.tsx +33 -28
- package/src/components/HorizontalRule/HorizontalRule.tsx +27 -29
- package/src/components/HorizontalRule/__snapshots__/HorizontalRule.test.tsx.snap +27 -9
- package/src/components/Icons/Icon.stories.mdx +12 -4
- package/src/components/Icons/Icon.test.tsx +18 -0
- package/src/components/Icons/Icon.tsx +16 -1
- package/src/components/Icons/IconSvgs.tsx +22 -0
- package/src/components/Icons/IconTypes.tsx +11 -0
- package/src/components/Image/Image.stories.mdx +220 -0
- package/src/components/Image/Image.test.tsx +131 -29
- package/src/components/Image/Image.tsx +84 -56
- package/src/components/Image/ImageTypes.ts +22 -0
- package/src/components/Image/__snapshots__/Image.test.tsx.snap +190 -0
- package/src/components/Input/Input.stories.tsx +23 -67
- package/src/components/Input/Input.test.tsx +4 -4
- package/src/components/Input/_Input.scss +23 -14
- package/src/components/Link/Link.tsx +4 -1
- package/src/components/List/List.stories.mdx +124 -49
- package/src/components/List/List.test.tsx +142 -63
- package/src/components/List/List.tsx +89 -93
- package/src/components/List/__snapshots__/List.test.tsx.snap +109 -0
- package/src/components/Modal/Modal.stories.mdx +3 -3
- package/src/components/Modal/_Modal.scss +2 -2
- package/src/components/Notification/Notification.stories.mdx +109 -112
- package/src/components/Notification/Notification.test.tsx +99 -110
- package/src/components/Notification/Notification.tsx +156 -159
- package/src/components/Notification/__snapshots__/Notification.test.tsx.snap +159 -8
- package/src/components/Pagination/Pagination.stories.mdx +26 -27
- package/src/components/Pagination/Pagination.stories.tsx +11 -16
- package/src/components/Pagination/Pagination.test.tsx +276 -146
- package/src/components/Pagination/Pagination.tsx +174 -154
- package/src/components/Pagination/__snapshots__/Pagination.test.tsx.snap +285 -0
- package/src/components/ProgressIndicator/ProgressIndicator.stories.mdx +292 -0
- package/src/components/ProgressIndicator/ProgressIndicator.test.tsx +225 -0
- package/src/components/ProgressIndicator/ProgressIndicator.tsx +126 -0
- package/src/components/ProgressIndicator/ProgressIndicatorTypes.ts +8 -0
- package/src/components/ProgressIndicator/__snapshots__/ProgressIndicator.test.tsx.snap +357 -0
- package/src/components/Radio/Radio.test.tsx +20 -4
- package/src/components/Radio/Radio.tsx +6 -3
- package/src/components/Radio/__snapshots__/Radio.test.tsx.snap +3 -0
- package/src/components/RadioGroup/RadioGroup.stories.mdx +3 -4
- package/src/components/RadioGroup/RadioGroup.test.tsx +24 -1
- package/src/components/RadioGroup/RadioGroup.tsx +19 -19
- package/src/components/RadioGroup/__snapshots__/RadioGroup.test.tsx.snap +42 -72
- package/src/components/SearchBar/SearchBar.Test.tsx +20 -1
- package/src/components/SearchBar/SearchBar.stories.mdx +113 -8
- package/src/components/SearchBar/SearchBar.tsx +20 -10
- package/src/components/Select/Select.test.tsx +12 -0
- package/src/components/Select/Select.tsx +5 -2
- package/src/components/Select/SelectTypes.tsx +1 -0
- package/src/components/SkeletonLoader/SkeletonLoader.stories.mdx +28 -59
- package/src/components/SkeletonLoader/SkeletonLoader.test.tsx +97 -177
- package/src/components/SkeletonLoader/SkeletonLoader.tsx +74 -71
- package/src/components/SkeletonLoader/__snapshots__/SkeletonLoader.test.tsx.snap +739 -0
- package/src/components/Slider/Slider.stories.mdx +529 -0
- package/src/components/Slider/Slider.test.tsx +653 -0
- package/src/components/Slider/Slider.tsx +303 -0
- package/src/components/Slider/__snapshots__/Slider.test.tsx.snap +1946 -0
- package/src/components/StyleGuide/Bidirectionality.stories.mdx +1 -1
- package/src/components/StyleGuide/Breakpoints.stories.mdx +34 -10
- package/src/components/StyleGuide/Buttons.stories.mdx +89 -73
- package/src/components/StyleGuide/ColorCard.tsx +46 -0
- package/src/components/StyleGuide/Colors.stories.mdx +171 -311
- package/src/components/StyleGuide/DesignTokens.stories.mdx +170 -0
- package/src/components/StyleGuide/Forms.stories.mdx +9 -7
- package/src/components/StyleGuide/Iconography.stories.mdx +85 -91
- package/src/components/StyleGuide/Spacing.stories.mdx +31 -23
- package/src/components/StyleGuide/Typography.stories.mdx +202 -189
- package/src/components/StyleGuide/UIDocCard.tsx +1 -1
- package/src/components/Tabs/Tabs.stories.mdx +73 -11
- package/src/components/Tabs/Tabs.tsx +87 -64
- package/src/components/Template/Template.stories.mdx +25 -27
- package/src/components/TextInput/TextInput.stories.mdx +1 -1
- package/src/components/TextInput/TextInput.test.tsx +22 -2
- package/src/components/TextInput/TextInput.tsx +28 -8
- package/src/components/TextInput/TextInputTypes.tsx +2 -0
- package/src/components/VideoPlayer/VideoPlayer.stories.mdx +17 -4
- package/src/components/VideoPlayer/VideoPlayer.test.tsx +54 -53
- package/src/components/VideoPlayer/VideoPlayer.tsx +50 -51
- package/src/components/VideoPlayer/VideoPlayerTypes.tsx +2 -2
- package/src/components/VideoPlayer/__snapshots__/VideoPlayer.test.tsx.snap +91 -0
- package/src/docs/Chakra.stories.mdx +244 -63
- package/src/docs/Intro.stories.mdx +5 -2
- package/src/hooks/tests/useCarouselStyles.test.ts +140 -0
- package/src/hooks/tests/useNYPLTheme.test.tsx +36 -0
- package/src/hooks/useCarouselStyles.ts +34 -0
- package/src/hooks/useNYPLTheme.ts +67 -0
- package/src/hooks/useWindowSize.ts +40 -0
- package/src/index.ts +22 -19
- package/src/resources.scss +5 -5
- package/src/styles/base/{_02-breakpoints.scss → _01-breakpoints.scss} +9 -10
- package/src/styles/base/{_03-mixins.scss → _02-mixins.scss} +16 -5
- package/src/styles/base/{_04-base.scss → _03-base.scss} +7 -2
- package/src/styles/base/{_05-focus.scss → _04-focus.scss} +0 -15
- package/src/styles/base/_place-holder.scss +14 -3
- package/src/styles/{03-space → space}/_space-inline.scss +14 -14
- package/src/styles/{03-space → space}/_space-inset.scss +10 -10
- package/src/styles/space/_space-stack.scss +116 -0
- package/src/styles.scss +13 -60
- package/src/theme/components/button.ts +21 -15
- package/src/theme/components/card.ts +174 -0
- package/src/theme/components/checkbox.ts +8 -3
- package/src/theme/components/checkboxGroup.ts +8 -0
- package/src/theme/components/componentWrapper.ts +10 -0
- package/src/theme/components/datePicker.ts +17 -0
- package/src/theme/components/fieldset.ts +18 -0
- package/src/theme/components/global.ts +26 -15
- package/src/theme/components/globalMixins.ts +9 -1
- package/src/theme/components/heading.ts +10 -5
- package/src/theme/components/helperErrorText.ts +9 -0
- package/src/theme/components/hero.ts +4 -3
- package/src/theme/components/horizontalRule.ts +13 -0
- package/src/theme/components/icon.ts +9 -9
- package/src/theme/components/image.ts +116 -0
- package/src/theme/components/label.ts +3 -10
- package/src/theme/components/link.ts +5 -1
- package/src/theme/components/list.ts +73 -0
- package/src/theme/components/notification.ts +93 -0
- package/src/theme/components/pagination.ts +20 -0
- package/src/theme/components/progressIndicator.ts +62 -0
- package/src/theme/components/radio.ts +2 -2
- package/src/theme/components/radioGroup.ts +8 -0
- package/src/theme/components/select.ts +6 -3
- package/src/theme/components/skeletonLoader.ts +107 -0
- package/src/theme/components/slider.ts +79 -0
- package/src/theme/components/statusBadge.ts +1 -2
- package/src/theme/components/tabs.ts +49 -19
- package/src/theme/components/template.ts +8 -8
- package/src/theme/components/textInput.ts +5 -4
- package/src/theme/components/videoPlayer.ts +49 -0
- package/src/theme/foundations/breakpoints.ts +8 -8
- package/src/theme/foundations/global.ts +6 -1
- package/src/theme/foundations/radii.ts +6 -0
- package/src/theme/foundations/spacing.ts +24 -24
- package/src/theme/index.ts +41 -10
- package/src/utils/componentCategories.ts +4 -3
- package/dist/components/HelperErrorText/HelperErrorText.stories.d.ts +0 -16
- package/dist/components/Image/Image.stories.d.ts +0 -18
- package/dist/components/List/List.stories.d.ts +0 -7
- package/dist/theme/components/customCheckboxGroup.d.ts +0 -18
- package/dist/theme/components/customRadioGroup.d.ts +0 -18
- package/src/components/Button/_Button.scss +0 -32
- package/src/components/Card/_Card.scss +0 -308
- package/src/components/HelperErrorText/HelperErrorText.stories.tsx +0 -48
- package/src/components/HelperErrorText/_HelperErrorText.scss +0 -9
- package/src/components/HorizontalRule/_HorizontalRule.scss +0 -15
- package/src/components/Image/Image.stories.tsx +0 -54
- package/src/components/Image/_Image.scss +0 -38
- package/src/components/List/List.stories.tsx +0 -139
- package/src/components/List/_List.scss +0 -76
- package/src/components/Notification/_Notification.scss +0 -110
- package/src/components/Pagination/_Pagination.scss +0 -40
- package/src/components/SkeletonLoader/_SkeletonLoader.scss +0 -142
- package/src/components/VideoPlayer/_VideoPlayer.scss +0 -38
- package/src/styles/01-colors/_colors-brand.scss +0 -62
- package/src/styles/01-colors/_colors-utility.scss +0 -67
- package/src/styles/02-typography/_type-scale.css +0 -11
- package/src/styles/02-typography/_type-weight.css +0 -7
- package/src/styles/02-typography/_typefaces.css +0 -4
- package/src/styles/03-space/_space-stack.scss +0 -116
- package/src/styles/03-space/_space.css +0 -30
- package/src/styles/base/_card-grid.scss +0 -78
- package/src/styles/base/_typography.scss +0 -11
- package/src/theme/components/customCheckboxGroup.ts +0 -12
- package/src/theme/components/customRadioGroup.ts +0 -12
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, { useState } from "react";
|
|
2
|
+
import { Box, useMultiStyleConfig } from "@chakra-ui/react";
|
|
2
3
|
|
|
3
|
-
import bem from "../../utils/bem";
|
|
4
4
|
import Button from "../Button/Button";
|
|
5
5
|
import { ButtonTypes } from "../Button/ButtonTypes";
|
|
6
6
|
import Heading from "../Heading/Heading";
|
|
@@ -8,194 +8,191 @@ import { HeadingLevels } from "../Heading/HeadingTypes";
|
|
|
8
8
|
import Icon from "../Icons/Icon";
|
|
9
9
|
import { IconColors, IconNames, IconSizes } from "../Icons/IconTypes";
|
|
10
10
|
import { NotificationTypes } from "./NotificationTypes";
|
|
11
|
+
import generateUUID from "../../helpers/generateUUID";
|
|
11
12
|
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
|
|
13
|
+
interface BaseProps {
|
|
14
|
+
/** Optional prop to control text alignment in `NotificationContent` */
|
|
15
|
+
alignText?: boolean;
|
|
15
16
|
/** Optional prop to control horizontal alignment of the `Notification` content */
|
|
16
17
|
centered?: boolean;
|
|
17
|
-
/** Optional `
|
|
18
|
+
/** Optional custom `Icon` that will override the default `Icon`. */
|
|
19
|
+
icon?: JSX.Element;
|
|
20
|
+
/** Optional prop to control the coloring of the `Notification` text and the
|
|
21
|
+
* visibility of an applicable icon. */
|
|
22
|
+
notificationType?: NotificationTypes;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Used for `NotificationHeading` and `Notification`
|
|
26
|
+
type BasePropsWithoutAlignText = Omit<BaseProps, "alignText">;
|
|
27
|
+
// Used for `NotificationContent`
|
|
28
|
+
type BasePropsWithoutCentered = Omit<BaseProps, "centered">;
|
|
29
|
+
|
|
30
|
+
export interface NotificationProps extends BasePropsWithoutAlignText {
|
|
31
|
+
/** Additional `className` to add. */
|
|
18
32
|
className?: string;
|
|
19
|
-
/** Optional prop to control whether a `Notification` can be dismissed
|
|
33
|
+
/** Optional prop to control whether a `Notification` can be dismissed
|
|
34
|
+
* (closed) by a user. */
|
|
20
35
|
dismissible?: boolean;
|
|
21
|
-
/** Optional custom `Icon` that will override the default `Icon
|
|
22
|
-
icon?:
|
|
23
|
-
/** ID that other components can cross reference for accessibility purposes */
|
|
36
|
+
/** Optional custom `Icon` that will override the default `Icon`. */
|
|
37
|
+
icon?: JSX.Element;
|
|
38
|
+
/** ID that other components can cross reference for accessibility purposes. */
|
|
24
39
|
id?: string;
|
|
25
|
-
/** Optional prop to control the margin around the `Notification` component */
|
|
40
|
+
/** Optional prop to control the margin around the `Notification` component. */
|
|
26
41
|
noMargin?: boolean;
|
|
27
|
-
/**
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
|
|
42
|
+
/** Content to be rendered in a `NotificationContent` component. */
|
|
43
|
+
notificationContent: string | JSX.Element;
|
|
44
|
+
/** Content to be rendered in a `NotificationHeading` component. */
|
|
45
|
+
notificationHeading?: string;
|
|
31
46
|
}
|
|
32
47
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
48
|
+
/**
|
|
49
|
+
* NotificationHeading child-component.
|
|
50
|
+
*/
|
|
51
|
+
export function NotificationHeading(
|
|
52
|
+
props: React.PropsWithChildren<BasePropsWithoutAlignText>
|
|
53
|
+
) {
|
|
54
|
+
const { centered, children, icon, notificationType } = props;
|
|
55
|
+
const styles = useMultiStyleConfig("NotificationHeading", {
|
|
56
|
+
centered,
|
|
57
|
+
notificationType,
|
|
58
|
+
});
|
|
36
59
|
return (
|
|
37
|
-
<
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
</
|
|
60
|
+
<Box as="header" __css={styles}>
|
|
61
|
+
{icon}
|
|
62
|
+
<Heading level={HeadingLevels.Four} additionalStyles={styles.heading}>
|
|
63
|
+
{children}
|
|
64
|
+
</Heading>
|
|
65
|
+
</Box>
|
|
43
66
|
);
|
|
44
67
|
}
|
|
45
68
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
69
|
+
/**
|
|
70
|
+
* NotificationContent child-component.
|
|
71
|
+
*/
|
|
72
|
+
export function NotificationContent(
|
|
73
|
+
props: React.PropsWithChildren<BasePropsWithoutCentered>
|
|
74
|
+
) {
|
|
75
|
+
const { alignText, children, icon, notificationType } = props;
|
|
76
|
+
const styles = useMultiStyleConfig("NotificationContent", {
|
|
77
|
+
alignText,
|
|
78
|
+
notificationType,
|
|
79
|
+
});
|
|
49
80
|
return (
|
|
50
|
-
<
|
|
51
|
-
{
|
|
52
|
-
|
|
81
|
+
<Box __css={styles}>
|
|
82
|
+
{icon}
|
|
83
|
+
<Box __css={styles.content}>{children}</Box>
|
|
84
|
+
</Box>
|
|
53
85
|
);
|
|
54
86
|
}
|
|
55
87
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
88
|
+
/**
|
|
89
|
+
* Component used to present users with three different levels of notifications:
|
|
90
|
+
* standard, announcement, and warning.
|
|
91
|
+
*/
|
|
92
|
+
export default function Notification(props: NotificationProps) {
|
|
59
93
|
const {
|
|
60
|
-
|
|
61
|
-
centered,
|
|
62
|
-
children,
|
|
94
|
+
centered = false,
|
|
63
95
|
className,
|
|
64
96
|
dismissible = false,
|
|
65
|
-
noMargin = false,
|
|
66
97
|
icon,
|
|
67
|
-
id,
|
|
68
|
-
|
|
69
|
-
|
|
98
|
+
id = generateUUID(),
|
|
99
|
+
noMargin = false,
|
|
100
|
+
notificationContent,
|
|
101
|
+
notificationHeading,
|
|
102
|
+
notificationType = NotificationTypes.Standard,
|
|
70
103
|
} = props;
|
|
71
|
-
|
|
72
104
|
const [isOpen, setIsOpen] = useState(true);
|
|
73
|
-
|
|
74
|
-
if (!isOpen) {
|
|
75
|
-
return null;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
105
|
const handleClose = () => setIsOpen(false);
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
notificationModifiers.push(notificationType);
|
|
85
|
-
|
|
86
|
-
if (centered) notificationModifiers.push("centered");
|
|
87
|
-
|
|
88
|
-
if (noMargin) notificationModifiers.push("no-margin");
|
|
89
|
-
|
|
106
|
+
const styles = useMultiStyleConfig("Notification", {
|
|
107
|
+
centered,
|
|
108
|
+
noMargin,
|
|
109
|
+
notificationType,
|
|
110
|
+
});
|
|
90
111
|
const iconElement = () => {
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
112
|
+
const baseIconProps = {
|
|
113
|
+
decorative: false,
|
|
114
|
+
size: IconSizes.Large,
|
|
115
|
+
additionalStyles: styles.icon,
|
|
116
|
+
};
|
|
117
|
+
// If a custom icon is passed, add specific `Notification` styles.
|
|
118
|
+
if (icon)
|
|
119
|
+
return React.cloneElement(icon, {
|
|
120
|
+
id: `${id}-custom-notification-icon`,
|
|
121
|
+
...baseIconProps,
|
|
122
|
+
});
|
|
123
|
+
const iconProps = {
|
|
124
|
+
[NotificationTypes.Announcement]: {
|
|
125
|
+
name: IconNames.SpeakerNotes,
|
|
126
|
+
color: IconColors.SectionResearchSecondary,
|
|
127
|
+
},
|
|
128
|
+
[NotificationTypes.Warning]: {
|
|
129
|
+
name: IconNames.ErrorFilled,
|
|
130
|
+
color: IconColors.BrandPrimary,
|
|
131
|
+
},
|
|
132
|
+
};
|
|
133
|
+
return notificationType !== NotificationTypes.Standard ? (
|
|
134
|
+
<Icon
|
|
135
|
+
id={`${id}-notification-icon`}
|
|
136
|
+
{...baseIconProps}
|
|
137
|
+
{...iconProps[notificationType]}
|
|
138
|
+
/>
|
|
139
|
+
) : null;
|
|
116
140
|
};
|
|
141
|
+
const dismissibleButton = dismissible && (
|
|
142
|
+
<Button
|
|
143
|
+
buttonType={ButtonTypes.Link}
|
|
144
|
+
onClick={handleClose}
|
|
145
|
+
additionalStyles={styles.dismissibleButton}
|
|
146
|
+
>
|
|
147
|
+
<Icon
|
|
148
|
+
id={`${id}-notification-dismissible-icon`}
|
|
149
|
+
decorative={false}
|
|
150
|
+
name={IconNames.Close}
|
|
151
|
+
size={IconSizes.Large}
|
|
152
|
+
/>
|
|
153
|
+
</Button>
|
|
154
|
+
);
|
|
155
|
+
const iconElem = iconElement();
|
|
156
|
+
const childHeading = notificationHeading && (
|
|
157
|
+
<NotificationHeading
|
|
158
|
+
centered={centered}
|
|
159
|
+
icon={iconElem}
|
|
160
|
+
notificationType={notificationType}
|
|
161
|
+
>
|
|
162
|
+
{notificationHeading}
|
|
163
|
+
</NotificationHeading>
|
|
164
|
+
);
|
|
165
|
+
// Specific alignment styles for the content.
|
|
166
|
+
const alignText =
|
|
167
|
+
childHeading &&
|
|
168
|
+
(!!icon || (notificationType !== NotificationTypes.Standard && !centered));
|
|
169
|
+
const childContent = (
|
|
170
|
+
<NotificationContent
|
|
171
|
+
alignText={alignText}
|
|
172
|
+
icon={!childHeading ? iconElem : null}
|
|
173
|
+
notificationType={notificationType}
|
|
174
|
+
>
|
|
175
|
+
{notificationContent}
|
|
176
|
+
</NotificationContent>
|
|
177
|
+
);
|
|
117
178
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
let contentCount = 0;
|
|
122
|
-
|
|
123
|
-
React.Children.map(children, (child: React.ReactElement) => {
|
|
124
|
-
if (
|
|
125
|
-
child.type === NotificationHeading ||
|
|
126
|
-
child.props.mdxType === "NotificationHeading"
|
|
127
|
-
) {
|
|
128
|
-
childHeading = child;
|
|
129
|
-
headingCount++;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
if (
|
|
133
|
-
child.type === NotificationContent ||
|
|
134
|
-
child.props.mdxType === "NotificationContent"
|
|
135
|
-
) {
|
|
136
|
-
childContent = child;
|
|
137
|
-
contentCount++;
|
|
138
|
-
}
|
|
139
|
-
});
|
|
140
|
-
|
|
141
|
-
if (headingCount > 1) {
|
|
142
|
-
console.error(
|
|
143
|
-
`Only one NotificationHeading child component may be passed to Notification.`
|
|
144
|
-
);
|
|
145
|
-
childHeading =
|
|
146
|
-
"Error: Only one NotificationHeading child component may be passed to Notification.";
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
if (contentCount > 1) {
|
|
150
|
-
console.error(
|
|
151
|
-
`Only one NotificationContent child component may be passed to Notification.`
|
|
152
|
-
);
|
|
153
|
-
childContent =
|
|
154
|
-
"Error: Only one NotificationContent child component may be passed to Notification.";
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
if (
|
|
158
|
-
headingCount &&
|
|
159
|
-
(icon ||
|
|
160
|
-
((notificationType === NotificationTypes.Announcement ||
|
|
161
|
-
notificationType === NotificationTypes.Warning) &&
|
|
162
|
-
!centered))
|
|
163
|
-
) {
|
|
164
|
-
notificationModifiers.push("align-text");
|
|
179
|
+
// If the `Notification` is closed, don't render anything.
|
|
180
|
+
if (!isOpen) {
|
|
181
|
+
return null;
|
|
165
182
|
}
|
|
166
|
-
|
|
167
183
|
return (
|
|
168
|
-
<
|
|
169
|
-
|
|
184
|
+
<Box
|
|
185
|
+
as="aside"
|
|
170
186
|
id={id}
|
|
187
|
+
className={className}
|
|
188
|
+
__css={styles}
|
|
189
|
+
data-type={notificationType}
|
|
171
190
|
>
|
|
172
|
-
<
|
|
173
|
-
{
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
) : null}
|
|
179
|
-
{contentCount ? (
|
|
180
|
-
<div className="content__container">
|
|
181
|
-
{!headingCount ? iconElement() : null}
|
|
182
|
-
{childContent}
|
|
183
|
-
</div>
|
|
184
|
-
) : null}
|
|
185
|
-
</div>
|
|
186
|
-
{dismissible ? (
|
|
187
|
-
<Button
|
|
188
|
-
buttonType={ButtonTypes.Link}
|
|
189
|
-
className="dismissible-button"
|
|
190
|
-
onClick={handleClose}
|
|
191
|
-
>
|
|
192
|
-
<Icon
|
|
193
|
-
decorative={false}
|
|
194
|
-
name={IconNames.Close}
|
|
195
|
-
size={IconSizes.Large}
|
|
196
|
-
/>
|
|
197
|
-
</Button>
|
|
198
|
-
) : null}
|
|
199
|
-
</aside>
|
|
191
|
+
<Box __css={styles.container}>
|
|
192
|
+
{childHeading}
|
|
193
|
+
{childContent}
|
|
194
|
+
</Box>
|
|
195
|
+
{dismissibleButton}
|
|
196
|
+
</Box>
|
|
200
197
|
);
|
|
201
198
|
}
|
|
@@ -1,25 +1,176 @@
|
|
|
1
1
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
2
|
|
|
3
|
-
exports[`Notification
|
|
3
|
+
exports[`Notification renders the UI snapshot correctly 1`] = `
|
|
4
4
|
<aside
|
|
5
|
-
className="
|
|
6
|
-
|
|
5
|
+
className="css-0"
|
|
6
|
+
data-type="standard"
|
|
7
|
+
id="notificationID1"
|
|
7
8
|
>
|
|
8
9
|
<div
|
|
9
|
-
className="
|
|
10
|
+
className="css-0"
|
|
10
11
|
>
|
|
11
|
-
<header
|
|
12
|
+
<header
|
|
13
|
+
className="css-0"
|
|
14
|
+
>
|
|
15
|
+
<h4
|
|
16
|
+
className="chakra-heading css-0"
|
|
17
|
+
>
|
|
18
|
+
Notification Heading
|
|
19
|
+
</h4>
|
|
20
|
+
</header>
|
|
21
|
+
<div
|
|
22
|
+
className="css-0"
|
|
23
|
+
>
|
|
24
|
+
<div
|
|
25
|
+
className="css-0"
|
|
26
|
+
>
|
|
27
|
+
Notification content.
|
|
28
|
+
</div>
|
|
29
|
+
</div>
|
|
30
|
+
</div>
|
|
31
|
+
</aside>
|
|
32
|
+
`;
|
|
33
|
+
|
|
34
|
+
exports[`Notification renders the UI snapshot correctly 2`] = `
|
|
35
|
+
<aside
|
|
36
|
+
className="css-0"
|
|
37
|
+
data-type="announcement"
|
|
38
|
+
id="notificationID2"
|
|
39
|
+
>
|
|
40
|
+
<div
|
|
41
|
+
className="css-0"
|
|
42
|
+
>
|
|
43
|
+
<header
|
|
44
|
+
className="css-0"
|
|
45
|
+
>
|
|
46
|
+
<svg
|
|
47
|
+
aria-hidden={false}
|
|
48
|
+
className="chakra-icon css-onkibi"
|
|
49
|
+
focusable={false}
|
|
50
|
+
id="notificationID2-notification-icon"
|
|
51
|
+
role="img"
|
|
52
|
+
title="speaker_notes icon"
|
|
53
|
+
viewBox="0 0 24 24"
|
|
54
|
+
>
|
|
55
|
+
<g
|
|
56
|
+
stroke="currentColor"
|
|
57
|
+
strokeWidth="1.5"
|
|
58
|
+
>
|
|
59
|
+
<path
|
|
60
|
+
d="M9,9a3,3,0,1,1,4,2.829,1.5,1.5,0,0,0-1,1.415V14.25"
|
|
61
|
+
fill="none"
|
|
62
|
+
strokeLinecap="round"
|
|
63
|
+
/>
|
|
64
|
+
<path
|
|
65
|
+
d="M12,17.25a.375.375,0,1,0,.375.375A.375.375,0,0,0,12,17.25h0"
|
|
66
|
+
fill="currentColor"
|
|
67
|
+
strokeLinecap="round"
|
|
68
|
+
/>
|
|
69
|
+
<circle
|
|
70
|
+
cx="12"
|
|
71
|
+
cy="12"
|
|
72
|
+
fill="none"
|
|
73
|
+
r="11.25"
|
|
74
|
+
strokeMiterlimit="10"
|
|
75
|
+
/>
|
|
76
|
+
</g>
|
|
77
|
+
</svg>
|
|
78
|
+
<h4
|
|
79
|
+
className="chakra-heading css-0"
|
|
80
|
+
>
|
|
81
|
+
Notification Heading
|
|
82
|
+
</h4>
|
|
83
|
+
</header>
|
|
84
|
+
<div
|
|
85
|
+
className="css-0"
|
|
86
|
+
>
|
|
87
|
+
<div
|
|
88
|
+
className="css-0"
|
|
89
|
+
>
|
|
90
|
+
Notification content.
|
|
91
|
+
</div>
|
|
92
|
+
</div>
|
|
93
|
+
</div>
|
|
94
|
+
</aside>
|
|
95
|
+
`;
|
|
96
|
+
|
|
97
|
+
exports[`Notification renders the UI snapshot correctly 3`] = `
|
|
98
|
+
<aside
|
|
99
|
+
className="css-0"
|
|
100
|
+
data-type="warning"
|
|
101
|
+
id="notificationID3"
|
|
102
|
+
>
|
|
103
|
+
<div
|
|
104
|
+
className="css-0"
|
|
105
|
+
>
|
|
106
|
+
<header
|
|
107
|
+
className="css-0"
|
|
108
|
+
>
|
|
109
|
+
<svg
|
|
110
|
+
aria-hidden={false}
|
|
111
|
+
className="chakra-icon css-onkibi"
|
|
112
|
+
focusable={false}
|
|
113
|
+
id="notificationID3-notification-icon"
|
|
114
|
+
role="img"
|
|
115
|
+
title="error_filled icon"
|
|
116
|
+
viewBox="0 0 24 24"
|
|
117
|
+
>
|
|
118
|
+
<g
|
|
119
|
+
stroke="currentColor"
|
|
120
|
+
strokeWidth="1.5"
|
|
121
|
+
>
|
|
122
|
+
<path
|
|
123
|
+
d="M9,9a3,3,0,1,1,4,2.829,1.5,1.5,0,0,0-1,1.415V14.25"
|
|
124
|
+
fill="none"
|
|
125
|
+
strokeLinecap="round"
|
|
126
|
+
/>
|
|
127
|
+
<path
|
|
128
|
+
d="M12,17.25a.375.375,0,1,0,.375.375A.375.375,0,0,0,12,17.25h0"
|
|
129
|
+
fill="currentColor"
|
|
130
|
+
strokeLinecap="round"
|
|
131
|
+
/>
|
|
132
|
+
<circle
|
|
133
|
+
cx="12"
|
|
134
|
+
cy="12"
|
|
135
|
+
fill="none"
|
|
136
|
+
r="11.25"
|
|
137
|
+
strokeMiterlimit="10"
|
|
138
|
+
/>
|
|
139
|
+
</g>
|
|
140
|
+
</svg>
|
|
12
141
|
<h4
|
|
13
|
-
className="chakra-heading
|
|
142
|
+
className="chakra-heading css-0"
|
|
14
143
|
>
|
|
15
144
|
Notification Heading
|
|
16
145
|
</h4>
|
|
17
146
|
</header>
|
|
18
147
|
<div
|
|
19
|
-
className="
|
|
148
|
+
className="css-0"
|
|
149
|
+
>
|
|
150
|
+
<div
|
|
151
|
+
className="css-0"
|
|
152
|
+
>
|
|
153
|
+
Notification content.
|
|
154
|
+
</div>
|
|
155
|
+
</div>
|
|
156
|
+
</div>
|
|
157
|
+
</aside>
|
|
158
|
+
`;
|
|
159
|
+
|
|
160
|
+
exports[`Notification renders the UI snapshot correctly 4`] = `
|
|
161
|
+
<aside
|
|
162
|
+
className="css-0"
|
|
163
|
+
data-type="standard"
|
|
164
|
+
id="notificationID4"
|
|
165
|
+
>
|
|
166
|
+
<div
|
|
167
|
+
className="css-0"
|
|
168
|
+
>
|
|
169
|
+
<div
|
|
170
|
+
className="css-0"
|
|
20
171
|
>
|
|
21
172
|
<div
|
|
22
|
-
className="
|
|
173
|
+
className="css-0"
|
|
23
174
|
>
|
|
24
175
|
Notification content.
|
|
25
176
|
</div>
|
|
@@ -15,11 +15,6 @@ import { getCategory } from "../../utils/componentCategories";
|
|
|
15
15
|
title={getCategory("Pagination")}
|
|
16
16
|
component={Pagination}
|
|
17
17
|
decorators={[withDesign, withQuery]}
|
|
18
|
-
argTypes={{
|
|
19
|
-
blockName: { table: { disable: true } },
|
|
20
|
-
modifiers: { table: { disable: true } },
|
|
21
|
-
className: { table: { disable: true } },
|
|
22
|
-
}}
|
|
23
18
|
parameters={{
|
|
24
19
|
design: {
|
|
25
20
|
type: "figma",
|
|
@@ -28,6 +23,11 @@ import { getCategory } from "../../utils/componentCategories";
|
|
|
28
23
|
},
|
|
29
24
|
jest: ["Pagination.test.tsx"],
|
|
30
25
|
}}
|
|
26
|
+
argTypes={{
|
|
27
|
+
id: { table: { disable: true } },
|
|
28
|
+
getPageHref: { table: { disable: true } },
|
|
29
|
+
onPageChange: { table: { disable: true } },
|
|
30
|
+
}}
|
|
31
31
|
/>
|
|
32
32
|
|
|
33
33
|
# Pagination
|
|
@@ -35,7 +35,7 @@ import { getCategory } from "../../utils/componentCategories";
|
|
|
35
35
|
| Component Version | DS Version |
|
|
36
36
|
| ----------------- | ---------- |
|
|
37
37
|
| Added | `0.0.10` |
|
|
38
|
-
| Latest | `0.
|
|
38
|
+
| Latest | `0.25.3` |
|
|
39
39
|
|
|
40
40
|
<Description of={Pagination} />
|
|
41
41
|
|
|
@@ -49,17 +49,20 @@ Pagination uses anchor tags because it is navigating between URLs.
|
|
|
49
49
|
|
|
50
50
|
In order to update the URL with a query parameter, the parent component must
|
|
51
51
|
declare and pass a `getPageHref` function to the `Pagination` component. This
|
|
52
|
-
function
|
|
53
|
-
should
|
|
52
|
+
function takes a `selectedPage` number argument for the selected page and it
|
|
53
|
+
should return a string with the desired URL that the pagination links should go
|
|
54
|
+
to. Note that this will refresh the browser on every click.
|
|
54
55
|
|
|
55
56
|
In the following example, the `getPageHref` function will compute a new URL that
|
|
56
57
|
has `&page=` as a URL query. In your own application this query parameter can be
|
|
57
58
|
named anything but you have to pick up the value in the wrapper component.
|
|
58
59
|
|
|
59
|
-
```
|
|
60
|
+
```tsx
|
|
60
61
|
// Example in a search results page.
|
|
61
|
-
const getPageHref = (
|
|
62
|
-
|
|
62
|
+
const getPageHref = (selectedPage: number) => {
|
|
63
|
+
// This should be updated for your router system, if any, including the
|
|
64
|
+
// base or origin URL.
|
|
65
|
+
return `${location.origin}?q=celeste&page=${selectedPage}`;
|
|
63
66
|
};
|
|
64
67
|
```
|
|
65
68
|
|
|
@@ -67,8 +70,8 @@ const getPageHref = (page) => {
|
|
|
67
70
|
<Story
|
|
68
71
|
name="Pagination with URL Updates"
|
|
69
72
|
args={{
|
|
70
|
-
|
|
71
|
-
pageCount:
|
|
73
|
+
initialPage: 1,
|
|
74
|
+
pageCount: 10,
|
|
72
75
|
}}
|
|
73
76
|
>
|
|
74
77
|
{(args) => stories.PaginationGetPageHref(args)}
|
|
@@ -82,29 +85,25 @@ const getPageHref = (page) => {
|
|
|
82
85
|
It is preferred to use the `Pagination` component with the `getPageHref`
|
|
83
86
|
function passed as a prop and that the URL is updated whenever a page is
|
|
84
87
|
changed. However, the optional `onPageChange` prop is available in case URL
|
|
85
|
-
updating is not desired.
|
|
86
|
-
of the current page value.
|
|
88
|
+
updating is not desired.
|
|
87
89
|
|
|
88
|
-
the `
|
|
89
|
-
|
|
90
|
-
|
|
90
|
+
In the following example, the `onPageChange` function gets the current page as
|
|
91
|
+
its only function argument. This is computed internally in the `Pagination`
|
|
92
|
+
component through its own state.
|
|
91
93
|
|
|
92
|
-
|
|
93
|
-
current page through the use of React's `useState` feature.
|
|
94
|
-
|
|
95
|
-
```jsx
|
|
94
|
+
```tsx
|
|
96
95
|
// Example in a search results page.
|
|
97
|
-
const
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
96
|
+
const onPageChange = (currentPage: number) => {
|
|
97
|
+
console.log(`Current page: ${currentPage}`);
|
|
98
|
+
// Do what you need to with the `currentPage` value.
|
|
99
|
+
};
|
|
101
100
|
```
|
|
102
101
|
|
|
103
102
|
<Canvas withToolbar>
|
|
104
103
|
<Story
|
|
105
104
|
name="Pagination with Unchanging URL"
|
|
106
105
|
args={{
|
|
107
|
-
|
|
106
|
+
initialPage: 7,
|
|
108
107
|
pageCount: 100,
|
|
109
108
|
}}
|
|
110
109
|
>
|