@nypl/design-system-react-components 0.25.4 → 0.25.8
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 +52 -0
- package/dist/components/Breadcrumbs/BreadcrumbsTypes.d.ts +1 -0
- package/dist/components/Icons/IconSvgs.d.ts +1 -0
- package/dist/components/Icons/IconTypes.d.ts +1 -0
- package/dist/components/Image/ImageTypes.d.ts +3 -1
- package/dist/components/Link/LinkTypes.d.ts +1 -0
- package/dist/components/Notification/Notification.d.ts +2 -0
- package/dist/components/Select/Select.d.ts +2 -0
- package/dist/components/Toggle/Toggle.d.ts +47 -0
- package/dist/components/Toggle/ToggleSizes.d.ts +4 -0
- package/dist/components/VideoPlayer/VideoPlayer.d.ts +5 -3
- package/dist/design-system-react-components.cjs.development.js +921 -360
- 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 +917 -353
- package/dist/design-system-react-components.esm.js.map +1 -1
- package/dist/index.d.ts +5 -0
- package/dist/theme/components/breadcrumb.d.ts +9 -0
- package/dist/theme/components/notification.d.ts +8 -4
- package/dist/theme/components/toggle.d.ts +68 -0
- package/dist/theme/foundations/spacing.d.ts +2 -0
- package/package.json +2 -2
- package/src/components/Accordion/Accordion.stories.mdx +1 -2
- package/src/components/Breadcrumbs/Breadcrumbs.stories.mdx +20 -3
- package/src/components/Breadcrumbs/Breadcrumbs.test.tsx +20 -0
- package/src/components/Breadcrumbs/BreadcrumbsTypes.tsx +1 -0
- package/src/components/Breadcrumbs/__snapshots__/Breadcrumbs.test.tsx.snap +198 -0
- package/src/components/Button/Button.tsx +0 -1
- package/src/components/Card/Card.stories.mdx +74 -7
- package/src/components/Card/Card.tsx +9 -8
- package/src/components/Card/__snapshots__/Card.test.tsx.snap +67 -35
- package/src/components/Chakra/Grid.stories.mdx +11 -14
- package/src/components/DatePicker/DatePicker.test.tsx +8 -6
- package/src/components/DatePicker/__snapshots__/DatePicker.test.tsx.snap +5 -4
- package/src/components/Icons/Icon.stories.mdx +3 -2
- package/src/components/Icons/IconSvgs.tsx +2 -0
- package/src/components/Icons/IconTypes.tsx +1 -0
- package/src/components/Image/Image.stories.mdx +152 -90
- package/src/components/Image/Image.test.tsx +10 -0
- package/src/components/Image/ImageTypes.ts +2 -0
- package/src/components/Image/__snapshots__/Image.test.tsx.snap +24 -8
- package/src/components/Label/Label.stories.mdx +1 -1
- package/src/components/Link/Link.stories.mdx +2 -3
- package/src/components/Link/Link.test.tsx +71 -0
- package/src/components/Link/Link.tsx +41 -9
- package/src/components/Link/LinkTypes.tsx +1 -0
- package/src/components/Link/__snapshots__/Link.test.tsx.snap +201 -0
- package/src/components/Notification/Notification.stories.mdx +36 -3
- package/src/components/Notification/Notification.test.tsx +62 -16
- package/src/components/Notification/Notification.tsx +17 -5
- package/src/components/Notification/__snapshots__/Notification.test.tsx.snap +117 -0
- package/src/components/Pagination/Pagination.stories.mdx +1 -2
- package/src/components/Pagination/__snapshots__/Pagination.test.tsx.snap +42 -0
- package/src/components/ProgressIndicator/ProgressIndicator.stories.mdx +2 -3
- package/src/components/SearchBar/SearchBar.Test.tsx +64 -20
- package/src/components/SearchBar/SearchBar.stories.mdx +3 -4
- package/src/components/SearchBar/SearchBar.tsx +4 -1
- package/src/components/Select/Select.stories.mdx +132 -55
- package/src/components/Select/Select.test.tsx +2 -2
- package/src/components/Select/Select.tsx +6 -2
- package/src/components/Slider/Slider.stories.mdx +3 -2
- package/src/components/Slider/Slider.test.tsx +35 -0
- package/src/components/Slider/Slider.tsx +8 -2
- package/src/components/Template/Template.stories.mdx +1 -2
- package/src/components/Toggle/Toggle.stories.mdx +176 -0
- package/src/components/Toggle/Toggle.test.tsx +140 -0
- package/src/components/Toggle/Toggle.tsx +118 -0
- package/src/components/Toggle/ToggleSizes.tsx +4 -0
- package/src/components/Toggle/__snapshots__/Toggle.test.tsx.snap +255 -0
- package/src/components/VideoPlayer/VideoPlayer.stories.mdx +39 -18
- package/src/components/VideoPlayer/VideoPlayer.test.tsx +103 -1
- package/src/components/VideoPlayer/VideoPlayer.tsx +57 -17
- package/src/components/VideoPlayer/__snapshots__/VideoPlayer.test.tsx.snap +48 -0
- package/src/index.ts +8 -0
- package/src/theme/components/breadcrumb.ts +11 -1
- package/src/theme/components/card.ts +4 -5
- package/src/theme/components/global.ts +1 -1
- package/src/theme/components/icon.ts +2 -2
- package/src/theme/components/image.ts +8 -0
- package/src/theme/components/notification.ts +8 -6
- package/src/theme/components/toggle.ts +65 -0
- package/src/theme/foundations/spacing.ts +3 -0
- package/src/theme/index.ts +2 -0
- package/src/utils/componentCategories.ts +3 -1
|
@@ -37,11 +37,13 @@ import { getCategory } from "../../utils/componentCategories";
|
|
|
37
37
|
| Component Version | DS Version |
|
|
38
38
|
| ----------------- | ---------- |
|
|
39
39
|
| Added | `0.23.2` |
|
|
40
|
-
| Latest | `0.25.
|
|
40
|
+
| Latest | `0.25.8` |
|
|
41
41
|
|
|
42
42
|
<Description of={VideoPlayer} />
|
|
43
43
|
|
|
44
|
-
The `VideoPlayer` component is used to embed a `Vimeo` or `YouTube` video player on a page. The component requires both the `videoType` and `videoId` props.
|
|
44
|
+
The `VideoPlayer` component is used to embed a `Vimeo` or `YouTube` video player on a page. The component requires the `embedCode` prop or both the `videoType` and `videoId` props. The component will not function properly if you try to set all of them.
|
|
45
|
+
|
|
46
|
+
You can extract the videoId from the video's URL. **IMPORTANT:** Do not try to enter the full video URL as the `videoId` value.
|
|
45
47
|
|
|
46
48
|
The `aspectRatio` prop is used to control the sizing of the space allotted for the video rendering. Ultimately, the `aspectRatio` prop should be set to match the aspect ratio of the video that is being rendered. The default aspect ratio is `16:9`.
|
|
47
49
|
|
|
@@ -49,27 +51,15 @@ The `aspectRatio` prop is used to control the sizing of the space allotted for t
|
|
|
49
51
|
<Story
|
|
50
52
|
name="VideoPlayer"
|
|
51
53
|
args={{
|
|
52
|
-
videoType: VideoPlayerTypes.Vimeo,
|
|
53
|
-
videoId: "",
|
|
54
|
-
headingText: "NYPL Video",
|
|
55
54
|
descriptionText:
|
|
56
55
|
"Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.",
|
|
56
|
+
embedCode: `<iframe src="https://player.vimeo.com/video/421404144?h=5467db7edd" width="640" height="360" frameborder="0" allow="autoplay; fullscreen; picture-in-picture" allowfullscreen></iframe>`,
|
|
57
|
+
headingText: "NYPL Video",
|
|
57
58
|
helperText:
|
|
58
59
|
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor.",
|
|
59
60
|
}}
|
|
60
61
|
>
|
|
61
|
-
{(args) =>
|
|
62
|
-
<VideoPlayer
|
|
63
|
-
{...args}
|
|
64
|
-
videoType={args.videoType}
|
|
65
|
-
videoId={
|
|
66
|
-
args.videoType === "vimeo"
|
|
67
|
-
? args.videoId || "474719268"
|
|
68
|
-
: args.videoId || "nm-dD2tx6bk"
|
|
69
|
-
}
|
|
70
|
-
aspectRatio={args.aspectRatio}
|
|
71
|
-
/>
|
|
72
|
-
)}
|
|
62
|
+
{(args) => <VideoPlayer {...args} />}
|
|
73
63
|
</Story>
|
|
74
64
|
</Canvas>
|
|
75
65
|
|
|
@@ -94,6 +84,37 @@ https://www.youtube.com/watch?v=[VIDEO_ID]
|
|
|
94
84
|
https://www.youtube.com/watch?v=nm-dD2tx6bk
|
|
95
85
|
```
|
|
96
86
|
|
|
87
|
+
## Example Embed Code Snippets
|
|
88
|
+
|
|
89
|
+
The examples below are shown with precise HTML formatting. However, often the embed code snippets provided by 3rd party video services are delivered as one long string.
|
|
90
|
+
|
|
91
|
+
### Vimeo
|
|
92
|
+
|
|
93
|
+
```html
|
|
94
|
+
<iframe
|
|
95
|
+
src="https://player.vimeo.com/video/421404144?h=5467db7edd"
|
|
96
|
+
width="640"
|
|
97
|
+
height="360"
|
|
98
|
+
frameborder="0"
|
|
99
|
+
allow="autoplay; fullscreen; picture-in-picture"
|
|
100
|
+
allowfullscreen
|
|
101
|
+
></iframe>
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### YouTube
|
|
105
|
+
|
|
106
|
+
```html
|
|
107
|
+
<iframe
|
|
108
|
+
width="560"
|
|
109
|
+
height="315"
|
|
110
|
+
src="https://www.youtube.com/embed/nm-dD2tx6bk"
|
|
111
|
+
title="YouTube video player"
|
|
112
|
+
frameborder="0"
|
|
113
|
+
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
|
|
114
|
+
allowfullscreen
|
|
115
|
+
></iframe>
|
|
116
|
+
```
|
|
117
|
+
|
|
97
118
|
## Errored
|
|
98
119
|
|
|
99
120
|
If the necessary props are not passed to the `VideoPlayer` component, the component UI will display an error message.
|
|
@@ -101,8 +122,8 @@ If the necessary props are not passed to the `VideoPlayer` component, the compon
|
|
|
101
122
|
<Canvas>
|
|
102
123
|
<DSProvider>
|
|
103
124
|
<VideoPlayer
|
|
104
|
-
type={VideoPlayerTypes.Vimeo}
|
|
105
125
|
videoId="https://vimeo.com/474719268"
|
|
126
|
+
videoType={VideoPlayerTypes.Vimeo}
|
|
106
127
|
/>
|
|
107
128
|
</DSProvider>
|
|
108
129
|
</Canvas>
|
|
@@ -63,6 +63,46 @@ describe("VideoPlayer", () => {
|
|
|
63
63
|
});
|
|
64
64
|
});
|
|
65
65
|
|
|
66
|
+
describe("using embedCode prop", () => {
|
|
67
|
+
const embedCode = `<iframe src="https://player.vimeo.com/video/421404144?h=5467db7edd" width="640" height="360" frameborder="0" allow="autoplay; fullscreen; picture-in-picture" allowfullscreen></iframe>`;
|
|
68
|
+
const embedCodeWithTitle = `<iframe title="Pre-Existing iFrame Title" src="https://player.vimeo.com/video/421404144?h=5467db7edd" width="640" height="360" frameborder="0" allow="autoplay; fullscreen; picture-in-picture" allowfullscreen></iframe>`;
|
|
69
|
+
|
|
70
|
+
it("Renders custom embed code", () => {
|
|
71
|
+
render(<VideoPlayer embedCode={embedCode} />);
|
|
72
|
+
expect(screen.getByTitle("Video player")).toBeInTheDocument();
|
|
73
|
+
expect(screen.getByTitle("Video player")).toHaveAttribute(
|
|
74
|
+
"src",
|
|
75
|
+
`https://player.vimeo.com/video/421404144?h=5467db7edd`
|
|
76
|
+
);
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
it("Renders custom embed code with custom iframe title", () => {
|
|
80
|
+
render(
|
|
81
|
+
<VideoPlayer embedCode={embedCode} iframeTitle="Custom iFrame Title" />
|
|
82
|
+
);
|
|
83
|
+
expect(screen.getByTitle("Custom iFrame Title")).toBeInTheDocument();
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
it("Renders custom embed code with pre-existing title", () => {
|
|
87
|
+
render(<VideoPlayer embedCode={embedCodeWithTitle} />);
|
|
88
|
+
expect(
|
|
89
|
+
screen.getByTitle("Pre-Existing iFrame Title")
|
|
90
|
+
).toBeInTheDocument();
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
it("Renders custom embed code with pre-existing title and ignores `iframeTitle` prop", () => {
|
|
94
|
+
render(
|
|
95
|
+
<VideoPlayer
|
|
96
|
+
embedCode={embedCodeWithTitle}
|
|
97
|
+
iframeTitle="Custom iFrame Title"
|
|
98
|
+
/>
|
|
99
|
+
);
|
|
100
|
+
expect(
|
|
101
|
+
screen.getByTitle("Pre-Existing iFrame Title")
|
|
102
|
+
).toBeInTheDocument();
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
|
|
66
106
|
describe("text elements", () => {
|
|
67
107
|
beforeEach(() => {
|
|
68
108
|
utils = render(
|
|
@@ -121,7 +161,7 @@ describe("VideoPlayer", () => {
|
|
|
121
161
|
});
|
|
122
162
|
|
|
123
163
|
describe("prop validation", () => {
|
|
124
|
-
it("Throws error if videoId not formatted properly", () => {
|
|
164
|
+
it("Throws error if the videoId prop not is formatted properly", () => {
|
|
125
165
|
render(
|
|
126
166
|
<VideoPlayer
|
|
127
167
|
videoType={VideoPlayerTypes.Vimeo}
|
|
@@ -135,6 +175,56 @@ describe("VideoPlayer", () => {
|
|
|
135
175
|
)
|
|
136
176
|
).toBeInTheDocument();
|
|
137
177
|
});
|
|
178
|
+
|
|
179
|
+
it("Throws appropriate error if VideoPlayer props are not configured properly", () => {
|
|
180
|
+
const warn = jest.spyOn(console, "warn");
|
|
181
|
+
|
|
182
|
+
render(<VideoPlayer />);
|
|
183
|
+
expect(warn).toHaveBeenCalledWith(
|
|
184
|
+
"VideoPlayer requires either the `embedCode` prop or both the `videoType` and `videoId` props."
|
|
185
|
+
);
|
|
186
|
+
|
|
187
|
+
render(<VideoPlayer videoId="http://vimeo.com/474719268" />);
|
|
188
|
+
expect(warn).toHaveBeenCalledWith(
|
|
189
|
+
"VideoPlayer also requires the `videoType` prop. You have only set the `videoId` prop."
|
|
190
|
+
);
|
|
191
|
+
|
|
192
|
+
render(<VideoPlayer videoType={VideoPlayerTypes.Vimeo} />);
|
|
193
|
+
expect(warn).toHaveBeenCalledWith(
|
|
194
|
+
"VideoPlayer also requires the `videoId` prop. You have only set the `videoType` prop."
|
|
195
|
+
);
|
|
196
|
+
|
|
197
|
+
render(
|
|
198
|
+
<VideoPlayer
|
|
199
|
+
embedCode="<iframe src='https://player.vimeo.com/video/421404144?h=5467db7edd' width='640' height='360' frameborder='0' allow='autoplay; fullscreen; picture-in-picture' allowfullscreen></iframe>"
|
|
200
|
+
videoType={VideoPlayerTypes.Vimeo}
|
|
201
|
+
videoId="http://vimeo.com/474719268"
|
|
202
|
+
/>
|
|
203
|
+
);
|
|
204
|
+
expect(warn).toHaveBeenCalledWith(
|
|
205
|
+
"VideoPlayer can accept the `embedCode` prop or the `videoType` and `videoId` props. You have set both."
|
|
206
|
+
);
|
|
207
|
+
|
|
208
|
+
render(
|
|
209
|
+
<VideoPlayer
|
|
210
|
+
embedCode="<iframe src='https://player.vimeo.com/video/421404144?h=5467db7edd' width='640' height='360' frameborder='0' allow='autoplay; fullscreen; picture-in-picture' allowfullscreen></iframe>"
|
|
211
|
+
videoType={VideoPlayerTypes.Vimeo}
|
|
212
|
+
/>
|
|
213
|
+
);
|
|
214
|
+
expect(warn).toHaveBeenCalledWith(
|
|
215
|
+
"VideoPlayer can accept the `embedCode` prop or the `videoType` and `videoId` props. You have set both."
|
|
216
|
+
);
|
|
217
|
+
|
|
218
|
+
render(
|
|
219
|
+
<VideoPlayer
|
|
220
|
+
embedCode="<iframe src='https://player.vimeo.com/video/421404144?h=5467db7edd' width='640' height='360' frameborder='0' allow='autoplay; fullscreen; picture-in-picture' allowfullscreen></iframe>"
|
|
221
|
+
videoId="http://vimeo.com/474719268"
|
|
222
|
+
/>
|
|
223
|
+
);
|
|
224
|
+
expect(warn).toHaveBeenCalledWith(
|
|
225
|
+
"VideoPlayer can accept the `embedCode` prop or the `videoType` and `videoId` props. You have set both."
|
|
226
|
+
);
|
|
227
|
+
});
|
|
138
228
|
});
|
|
139
229
|
|
|
140
230
|
it("renders the UI snapshot correctly", () => {
|
|
@@ -159,6 +249,17 @@ describe("VideoPlayer", () => {
|
|
|
159
249
|
/>
|
|
160
250
|
)
|
|
161
251
|
.toJSON();
|
|
252
|
+
const videoPlayerUsingEmbedCode = renderer
|
|
253
|
+
.create(
|
|
254
|
+
<VideoPlayer
|
|
255
|
+
descriptionText="VideoPlayer description"
|
|
256
|
+
embedCode="<iframe src='https://player.vimeo.com/video/421404144?h=5467db7edd' width='640' height='360' frameborder='0' allow='autoplay; fullscreen; picture-in-picture' allowfullscreen></iframe>"
|
|
257
|
+
headingText="VideoPlayer Heading"
|
|
258
|
+
id="video-player-with-text"
|
|
259
|
+
helperText="VideoPlayer helper test."
|
|
260
|
+
/>
|
|
261
|
+
)
|
|
262
|
+
.toJSON();
|
|
162
263
|
const videoPlayerError = renderer
|
|
163
264
|
.create(
|
|
164
265
|
<VideoPlayer
|
|
@@ -171,6 +272,7 @@ describe("VideoPlayer", () => {
|
|
|
171
272
|
|
|
172
273
|
expect(videoPlayerWithoutText).toMatchSnapshot();
|
|
173
274
|
expect(videoPlayerWithText).toMatchSnapshot();
|
|
275
|
+
expect(videoPlayerUsingEmbedCode).toMatchSnapshot();
|
|
174
276
|
expect(videoPlayerError).toMatchSnapshot();
|
|
175
277
|
});
|
|
176
278
|
});
|
|
@@ -12,20 +12,22 @@ export interface VideoPlayerProps {
|
|
|
12
12
|
className?: string;
|
|
13
13
|
/** Optional string to set the text for a video description */
|
|
14
14
|
descriptionText?: string;
|
|
15
|
+
/** Optional string to set a code snippet provided by YouTube or Vimeo; the `videoPlayer` component will accept the `embedCode` prop or the `videoId` and `videoType` props */
|
|
16
|
+
embedCode?: string;
|
|
15
17
|
/** Optional string to set the text for a `Heading` component */
|
|
16
18
|
headingText?: string;
|
|
17
19
|
/** Optional string to set the text for a `HelperErrorText` component */
|
|
18
20
|
helperText?: string;
|
|
19
21
|
/** ID that other components can cross reference for accessibility purposes */
|
|
20
22
|
id?: string;
|
|
21
|
-
/** Optional title to be added to the `<iframe>` element for improved accessibility; this title should describe in a few words the content of the video; if omitted, a generic title will be added */
|
|
23
|
+
/** Optional title to be added to the `<iframe>` element for improved accessibility; this title should describe in a few words the content of the video; if omitted, a generic title will be added; if a `title` attribute is already present in the `embedCode` prop, this prop will be ignored */
|
|
22
24
|
iframeTitle?: string;
|
|
23
25
|
/** Offers the ability to hide the helper/invalid text. */
|
|
24
26
|
showHelperInvalidText?: boolean;
|
|
25
27
|
/** Required YouTube or Vimeo video ID. This value can be pulled from a video's YouTube or Vimeo URL. */
|
|
26
|
-
videoId
|
|
28
|
+
videoId?: string;
|
|
27
29
|
/** Required. Used to specify which video service is being used. */
|
|
28
|
-
videoType
|
|
30
|
+
videoType?: VideoPlayerTypes;
|
|
29
31
|
}
|
|
30
32
|
|
|
31
33
|
export default function VideoPlayer(
|
|
@@ -35,6 +37,7 @@ export default function VideoPlayer(
|
|
|
35
37
|
aspectRatio,
|
|
36
38
|
className,
|
|
37
39
|
descriptionText,
|
|
40
|
+
embedCode,
|
|
38
41
|
headingText,
|
|
39
42
|
helperText,
|
|
40
43
|
id = generateUUID(),
|
|
@@ -54,29 +57,64 @@ export default function VideoPlayer(
|
|
|
54
57
|
? `https://player.vimeo.com/video/${videoId}?autoplay=0&loop=0`
|
|
55
58
|
: `https://www.youtube.com/embed/${videoId}?disablekb=1&autoplay=0&fs=1&modestbranding=0`;
|
|
56
59
|
|
|
60
|
+
const iFrameTitleEmbedCode = iframeTitle ? `${iframeTitle}` : `Video player`;
|
|
61
|
+
|
|
62
|
+
const embedCodeFinal =
|
|
63
|
+
embedCode && embedCode.includes("<iframe") && !embedCode.includes("title=")
|
|
64
|
+
? embedCode.replace(
|
|
65
|
+
`<iframe `,
|
|
66
|
+
`<iframe title="${iFrameTitleEmbedCode}" `
|
|
67
|
+
)
|
|
68
|
+
: embedCode;
|
|
69
|
+
|
|
57
70
|
const errorMessage =
|
|
58
71
|
"<strong>Error:</strong> This video player has not been configured properly. Please contact the site administrator.";
|
|
59
72
|
|
|
60
73
|
let isInvalid = false;
|
|
61
|
-
if (!videoType && !videoId) {
|
|
62
|
-
console.warn(
|
|
74
|
+
if (!embedCodeFinal && !videoType && !videoId) {
|
|
75
|
+
console.warn(
|
|
76
|
+
"VideoPlayer requires either the `embedCode` prop or both the `videoType` and `videoId` props."
|
|
77
|
+
);
|
|
78
|
+
isInvalid = true;
|
|
79
|
+
} else if (!embedCodeFinal && !videoType) {
|
|
80
|
+
console.warn(
|
|
81
|
+
"VideoPlayer also requires the `videoType` prop. You have only set the `videoId` prop."
|
|
82
|
+
);
|
|
83
|
+
isInvalid = true;
|
|
84
|
+
} else if (!embedCodeFinal && !videoId) {
|
|
85
|
+
console.warn(
|
|
86
|
+
"VideoPlayer also requires the `videoId` prop. You have only set the `videoType` prop."
|
|
87
|
+
);
|
|
63
88
|
isInvalid = true;
|
|
64
|
-
} else if (
|
|
65
|
-
console.warn(
|
|
89
|
+
} else if (embedCodeFinal && (videoType || videoId)) {
|
|
90
|
+
console.warn(
|
|
91
|
+
"VideoPlayer can accept the `embedCode` prop or the `videoType` and `videoId` props. You have set both."
|
|
92
|
+
);
|
|
66
93
|
isInvalid = true;
|
|
67
|
-
}
|
|
68
|
-
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (
|
|
97
|
+
videoId &&
|
|
98
|
+
(videoId.includes("://") ||
|
|
99
|
+
videoId.includes("http") ||
|
|
100
|
+
videoId.includes(".") ||
|
|
101
|
+
videoId.includes("youtube") ||
|
|
102
|
+
videoId.includes("vimeo"))
|
|
103
|
+
) {
|
|
104
|
+
console.warn("The VideoPlayer `videoId` prop is not configured properly.");
|
|
69
105
|
isInvalid = true;
|
|
70
106
|
}
|
|
71
107
|
|
|
72
108
|
if (
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
109
|
+
embedCodeFinal &&
|
|
110
|
+
((!embedCodeFinal.includes("vimeo.com") &&
|
|
111
|
+
!embedCodeFinal.includes("youtube.com")) ||
|
|
112
|
+
!embedCodeFinal.includes("<iframe") ||
|
|
113
|
+
!embedCodeFinal.includes("</iframe"))
|
|
78
114
|
) {
|
|
79
|
-
console.warn(
|
|
115
|
+
console.warn(
|
|
116
|
+
"The VideoPlayer `embedCode` prop is not configured properly."
|
|
117
|
+
);
|
|
80
118
|
isInvalid = true;
|
|
81
119
|
}
|
|
82
120
|
|
|
@@ -85,7 +123,9 @@ export default function VideoPlayer(
|
|
|
85
123
|
: getVariant(aspectRatio, VideoPlayerAspectRatios);
|
|
86
124
|
const styles = useMultiStyleConfig("VideoPlayer", { variant });
|
|
87
125
|
|
|
88
|
-
const
|
|
126
|
+
const embedElement = embedCodeFinal ? (
|
|
127
|
+
<span dangerouslySetInnerHTML={{ __html: embedCodeFinal }} />
|
|
128
|
+
) : (
|
|
89
129
|
<Box
|
|
90
130
|
as="iframe"
|
|
91
131
|
src={videoSrc}
|
|
@@ -113,7 +153,7 @@ export default function VideoPlayer(
|
|
|
113
153
|
helperText={helperText && showHelperInvalidText ? helperText : null}
|
|
114
154
|
id={`${id}-componentWrapper`}
|
|
115
155
|
>
|
|
116
|
-
<Box __css={styles.inside}>{
|
|
156
|
+
<Box __css={styles.inside}>{embedElement}</Box>
|
|
117
157
|
</ComponentWrapper>
|
|
118
158
|
)}
|
|
119
159
|
</Box>
|
|
@@ -75,6 +75,54 @@ exports[`VideoPlayer renders the UI snapshot correctly 2`] = `
|
|
|
75
75
|
`;
|
|
76
76
|
|
|
77
77
|
exports[`VideoPlayer renders the UI snapshot correctly 3`] = `
|
|
78
|
+
<div
|
|
79
|
+
className="css-0"
|
|
80
|
+
data-testid="video-player-component"
|
|
81
|
+
id="video-player-with-text"
|
|
82
|
+
>
|
|
83
|
+
<div
|
|
84
|
+
className="css-0"
|
|
85
|
+
>
|
|
86
|
+
<h2
|
|
87
|
+
className="chakra-heading css-0"
|
|
88
|
+
id="video-player-with-text-componentWrapper-heading"
|
|
89
|
+
>
|
|
90
|
+
VideoPlayer Heading
|
|
91
|
+
</h2>
|
|
92
|
+
<p
|
|
93
|
+
className="chakra-text css-0"
|
|
94
|
+
>
|
|
95
|
+
VideoPlayer description
|
|
96
|
+
</p>
|
|
97
|
+
<div
|
|
98
|
+
className="css-0"
|
|
99
|
+
>
|
|
100
|
+
<span
|
|
101
|
+
dangerouslySetInnerHTML={
|
|
102
|
+
Object {
|
|
103
|
+
"__html": "<iframe title=\\"Video player\\" src='https://player.vimeo.com/video/421404144?h=5467db7edd' width='640' height='360' frameborder='0' allow='autoplay; fullscreen; picture-in-picture' allowfullscreen></iframe>",
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
/>
|
|
107
|
+
</div>
|
|
108
|
+
<div
|
|
109
|
+
className="css-0"
|
|
110
|
+
>
|
|
111
|
+
<div
|
|
112
|
+
aria-atomic={true}
|
|
113
|
+
aria-live="off"
|
|
114
|
+
className=" css-0"
|
|
115
|
+
data-isinvalid={false}
|
|
116
|
+
id="video-player-with-text-componentWrapper-helperText"
|
|
117
|
+
>
|
|
118
|
+
VideoPlayer helper test.
|
|
119
|
+
</div>
|
|
120
|
+
</div>
|
|
121
|
+
</div>
|
|
122
|
+
</div>
|
|
123
|
+
`;
|
|
124
|
+
|
|
125
|
+
exports[`VideoPlayer renders the UI snapshot correctly 4`] = `
|
|
78
126
|
<div
|
|
79
127
|
className="css-0"
|
|
80
128
|
data-testid="video-player-component"
|
package/src/index.ts
CHANGED
|
@@ -73,6 +73,11 @@ export { default as Modal } from "./components/Modal/Modal";
|
|
|
73
73
|
export { default as Notification } from "./components/Notification/Notification";
|
|
74
74
|
export { NotificationTypes } from "./components/Notification/NotificationTypes";
|
|
75
75
|
export { default as Pagination } from "./components/Pagination/Pagination";
|
|
76
|
+
export { default as ProgressIndicator } from "./components/ProgressIndicator/ProgressIndicator";
|
|
77
|
+
export {
|
|
78
|
+
ProgressIndicatorSizes,
|
|
79
|
+
ProgressIndicatorTypes,
|
|
80
|
+
} from "./components/ProgressIndicator/ProgressIndicatorTypes";
|
|
76
81
|
export { default as Radio } from "./components/Radio/Radio";
|
|
77
82
|
export { default as RadioGroup } from "./components/RadioGroup/RadioGroup";
|
|
78
83
|
export { RadioGroupLayoutTypes } from "./components/RadioGroup/RadioGroupLayoutTypes";
|
|
@@ -84,6 +89,7 @@ export {
|
|
|
84
89
|
SkeletonLoaderImageRatios,
|
|
85
90
|
SkeletonLoaderLayouts,
|
|
86
91
|
} from "./components/SkeletonLoader/SkeletonLoaderTypes";
|
|
92
|
+
export { default as Slider } from "./components/Slider/Slider";
|
|
87
93
|
export { default as StatusBadge } from "./components/StatusBadge/StatusBadge";
|
|
88
94
|
export { StatusBadgeTypes } from "./components/StatusBadge/StatusBadgeTypes";
|
|
89
95
|
export {
|
|
@@ -111,6 +117,8 @@ export {
|
|
|
111
117
|
TextInputRefType,
|
|
112
118
|
} from "./components/TextInput/TextInput";
|
|
113
119
|
export { TextInputTypes } from "./components/TextInput/TextInputTypes";
|
|
120
|
+
export { default as Toggle } from "./components/Toggle/Toggle";
|
|
121
|
+
export { ToggleSizes } from "./components/Toggle/ToggleSizes";
|
|
114
122
|
export { default as useNYPLTheme } from "./hooks/useNYPLTheme";
|
|
115
123
|
export { default as VideoPlayer } from "./components/VideoPlayer/VideoPlayer";
|
|
116
124
|
export {
|
|
@@ -1,9 +1,18 @@
|
|
|
1
1
|
// Variant styling
|
|
2
|
+
const blogs = {
|
|
3
|
+
bg: "section.blogs.secondary",
|
|
4
|
+
color: "ui.black",
|
|
5
|
+
a: {
|
|
6
|
+
_hover: {
|
|
7
|
+
color: "ui.gray.xdark",
|
|
8
|
+
},
|
|
9
|
+
},
|
|
10
|
+
};
|
|
2
11
|
const booksAndMore = {
|
|
3
12
|
bg: "section.books-and-more.secondary",
|
|
4
13
|
};
|
|
5
14
|
const locations = {
|
|
6
|
-
bg: "section.locations.
|
|
15
|
+
bg: "section.locations.primary",
|
|
7
16
|
};
|
|
8
17
|
const research = {
|
|
9
18
|
bg: "section.research.secondary",
|
|
@@ -67,6 +76,7 @@ const Breadcrumb = {
|
|
|
67
76
|
},
|
|
68
77
|
// Available variants:
|
|
69
78
|
variants: {
|
|
79
|
+
blogs,
|
|
70
80
|
booksAndMore,
|
|
71
81
|
locations,
|
|
72
82
|
research,
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
const imageSizes = {
|
|
2
|
+
xxsmall: { flex: { base: "0 0 100%", md: "0 0 64px" }, width: "100%" },
|
|
3
|
+
xsmall: { flex: { md: "0 0 96px" } },
|
|
2
4
|
small: { flex: { md: "0 0 165px" } },
|
|
3
5
|
medium: { flex: { md: "0 0 225px" } },
|
|
4
6
|
large: { flex: { md: "0 0 360px" } },
|
|
@@ -137,11 +139,6 @@ const CardImage = {
|
|
|
137
139
|
const layoutStyles =
|
|
138
140
|
layout === "row"
|
|
139
141
|
? {
|
|
140
|
-
display: "flex",
|
|
141
|
-
flexFlow: {
|
|
142
|
-
base: "column nowrap",
|
|
143
|
-
md: "row",
|
|
144
|
-
},
|
|
145
142
|
flex: { md: "0 0 225px" },
|
|
146
143
|
maxWidth: { base: "100%", md: "50%" },
|
|
147
144
|
textAlign: "left",
|
|
@@ -152,10 +149,12 @@ const CardImage = {
|
|
|
152
149
|
? "0 0 0 var(--nypl-space-m)"
|
|
153
150
|
: "0 var(--nypl-space-m) 0 0",
|
|
154
151
|
},
|
|
152
|
+
width: { base: "100%", md: null },
|
|
155
153
|
...size,
|
|
156
154
|
}
|
|
157
155
|
: {
|
|
158
156
|
marginBottom: "xs",
|
|
157
|
+
width: "100%",
|
|
159
158
|
};
|
|
160
159
|
const imageAtEndStyles = imageAtEnd
|
|
161
160
|
? {
|
|
@@ -49,25 +49,26 @@ const Notification = {
|
|
|
49
49
|
|
|
50
50
|
const NotificationContent = {
|
|
51
51
|
parts: ["content"],
|
|
52
|
-
baseStyle: ({ alignText, notificationType }) => ({
|
|
52
|
+
baseStyle: ({ alignText, icon, notificationType }) => ({
|
|
53
53
|
display: "flex",
|
|
54
54
|
justifyContent: "center",
|
|
55
55
|
content: {
|
|
56
|
-
width: "100%",
|
|
57
|
-
paddingLeft: alignText
|
|
58
|
-
? "calc(var(--nypl-space-m) + var(--nypl-space-s))"
|
|
59
|
-
: null,
|
|
60
56
|
color:
|
|
61
57
|
notificationType === NotificationTypes.Warning
|
|
62
58
|
? "brand.primary"
|
|
63
59
|
: "currentColor",
|
|
60
|
+
marginTop: icon ? "xxxs" : "0",
|
|
61
|
+
paddingLeft: alignText
|
|
62
|
+
? "calc(var(--nypl-space-m) + var(--nypl-space-s))"
|
|
63
|
+
: null,
|
|
64
|
+
width: "100%",
|
|
64
65
|
},
|
|
65
66
|
}),
|
|
66
67
|
};
|
|
67
68
|
|
|
68
69
|
const NotificationHeading = {
|
|
69
70
|
parts: ["heading"],
|
|
70
|
-
baseStyle: ({ centered, notificationType }) => {
|
|
71
|
+
baseStyle: ({ centered, icon, notificationType }) => {
|
|
71
72
|
let color = "ui.black";
|
|
72
73
|
if (notificationType === NotificationTypes.Announcement) {
|
|
73
74
|
color = "section.research.secondary";
|
|
@@ -80,6 +81,7 @@ const NotificationHeading = {
|
|
|
80
81
|
justifyContent: centered ? "center" : null,
|
|
81
82
|
heading: {
|
|
82
83
|
marginBottom: "0",
|
|
84
|
+
marginTop: icon ? "xxxs" : "0",
|
|
83
85
|
color,
|
|
84
86
|
},
|
|
85
87
|
};
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { helperTextMargin } from "./global";
|
|
2
|
+
|
|
3
|
+
const baseStyle = {
|
|
4
|
+
label: { display: "flex", alignItems: "center", width: "fit-content" },
|
|
5
|
+
helper: {
|
|
6
|
+
...helperTextMargin,
|
|
7
|
+
marginLeft: "xs",
|
|
8
|
+
},
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
const Switch = {
|
|
12
|
+
baseStyle: {
|
|
13
|
+
opacity: 0.4,
|
|
14
|
+
track: {
|
|
15
|
+
p: "4px",
|
|
16
|
+
border: "1px solid",
|
|
17
|
+
borderColor: "ui.gray.medium",
|
|
18
|
+
_checked: {
|
|
19
|
+
borderColor: "ui.link.primary",
|
|
20
|
+
bg: "ui.link.primary",
|
|
21
|
+
opacity: 1,
|
|
22
|
+
},
|
|
23
|
+
_invalid: {
|
|
24
|
+
borderColor: "ui.error.primary",
|
|
25
|
+
bg: "inherit",
|
|
26
|
+
"> span": {
|
|
27
|
+
bg: "ui.error.primary",
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
_disabled: {
|
|
31
|
+
borderColor: "ui.gray.medium",
|
|
32
|
+
bg: "ui.gray.medium",
|
|
33
|
+
_checked: {
|
|
34
|
+
opacity: 0.4,
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
_focus: {
|
|
38
|
+
outline: "2px solid",
|
|
39
|
+
outlineColor: "ui.focus",
|
|
40
|
+
outlineOffset: "2px",
|
|
41
|
+
zIndex: "9999",
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
label: { fontSize: -1, marginLeft: "xs" },
|
|
45
|
+
thumb: {
|
|
46
|
+
_disabled: {
|
|
47
|
+
bg: "ui.error.primary",
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
defaultProps: {
|
|
52
|
+
colorScheme: "white",
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const Toggle = {
|
|
57
|
+
parts: ["helper"],
|
|
58
|
+
baseStyle,
|
|
59
|
+
// Default values
|
|
60
|
+
defaultProps: {
|
|
61
|
+
size: "lg",
|
|
62
|
+
},
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
export default { Toggle, Switch };
|
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
*
|
|
23
23
|
* Chakra Number Value | Chakra Name value | DS Variable
|
|
24
24
|
* ------------------- | ----------------- | -----------------
|
|
25
|
+
* 0.5 | xxxs | --nypl-space-xxxs
|
|
25
26
|
* 1 | xxs | --nypl-space-xxs
|
|
26
27
|
* 2 | xs | --nypl-space-xs
|
|
27
28
|
* 4 | s | --nypl-space-s
|
|
@@ -34,6 +35,8 @@
|
|
|
34
35
|
export const spacing = {
|
|
35
36
|
px: "1px",
|
|
36
37
|
0: "0",
|
|
38
|
+
// --nypl-space-xxxs = 2px
|
|
39
|
+
xxxs: "0.125rem",
|
|
37
40
|
0.5: "0.125rem",
|
|
38
41
|
// --nypl-space-xxs = 4px
|
|
39
42
|
xxs: "0.25rem",
|