@octaviaflow/mdx-components 1.1.3
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/README.md +215 -0
- package/components/_utils.scss +18 -0
- package/components/accordion/_accordion.scss +35 -0
- package/components/accordion/accordion.stories.jsx +33 -0
- package/components/accordion/accordion.tsx +55 -0
- package/components/anchor-links/_anchor-links.scss +67 -0
- package/components/anchor-links/anchor-link.tsx +50 -0
- package/components/anchor-links/anchor-links.stories.jsx +51 -0
- package/components/anchor-links/anchor-links.tsx +73 -0
- package/components/art-direction/art-direction.stories.jsx +44 -0
- package/components/art-direction/art-direction.tsx +63 -0
- package/components/art-direction/desktop.jpg +0 -0
- package/components/art-direction/mobile.jpg +0 -0
- package/components/art-direction/tablet.jpg +0 -0
- package/components/article-card/_article-card.scss +98 -0
- package/components/article-card/article-card.stories.jsx +59 -0
- package/components/article-card/article-card.tsx +208 -0
- package/components/article-card/article06.png +0 -0
- package/components/aside/_aside.scss +56 -0
- package/components/aside/aside.stories.jsx +50 -0
- package/components/aside/aside.tsx +72 -0
- package/components/caption/_caption.scss +30 -0
- package/components/caption/caption.stories.jsx +33 -0
- package/components/caption/caption.tsx +47 -0
- package/components/card-group/_card-group.scss +44 -0
- package/components/card-group/card-group.stories.jsx +85 -0
- package/components/card-group/card-group.tsx +65 -0
- package/components/card-group/sketch-icon.png +0 -0
- package/components/code/_code.scss +110 -0
- package/components/code/code.stories.jsx +32 -0
- package/components/code/code.tsx +71 -0
- package/components/code/inline-code.tsx +55 -0
- package/components/code/path.tsx +56 -0
- package/components/divider/_divider.scss +67 -0
- package/components/divider/divider.stories.jsx +74 -0
- package/components/divider/divider.tsx +54 -0
- package/components/do-dont/_do-dont.scss +191 -0
- package/components/do-dont/do-dont-row.tsx +51 -0
- package/components/do-dont/do-dont.stories.jsx +53 -0
- package/components/do-dont/do-dont.tsx +161 -0
- package/components/do-dont/light-theme.jpg +0 -0
- package/components/gif-player/_gif-player.scss +64 -0
- package/components/gif-player/cloud.gif +0 -0
- package/components/gif-player/cloud.jpg +0 -0
- package/components/gif-player/gif-player.stories.jsx +45 -0
- package/components/gif-player/gif-player.tsx +150 -0
- package/components/grid-transform/_grid.scss +13 -0
- package/components/grid-transform/column.tsx +102 -0
- package/components/grid-transform/grid.stories.jsx +72 -0
- package/components/grid-transform/grid.tsx +52 -0
- package/components/grid-transform/row.tsx +92 -0
- package/components/image-wrapper/_image-wrapper.scss +32 -0
- package/components/image-wrapper/accordion-style-3.png +0 -0
- package/components/image-wrapper/image-wrapper.stories.jsx +40 -0
- package/components/image-wrapper/image-wrapper.tsx +56 -0
- package/components/index.scss +31 -0
- package/components/inline-notification/_inline-notification.scss +29 -0
- package/components/inline-notification/inline-notification.stories.jsx +67 -0
- package/components/inline-notification/inline-notification.tsx +98 -0
- package/components/interfaces.ts +31 -0
- package/components/link/_link.scss +13 -0
- package/components/link/link.stories.jsx +36 -0
- package/components/link/link.tsx +51 -0
- package/components/markdown/_markdown.scss +140 -0
- package/components/markdown/autolink-header/_autolink-header.scss +57 -0
- package/components/markdown/autolink-header/autolink-header.tsx +107 -0
- package/components/markdown/blockquote.stories.jsx +38 -0
- package/components/markdown/blockquote.tsx +53 -0
- package/components/markdown/h1.tsx +92 -0
- package/components/markdown/h2.tsx +85 -0
- package/components/markdown/h3.tsx +72 -0
- package/components/markdown/h4.tsx +73 -0
- package/components/markdown/h5.tsx +59 -0
- package/components/markdown/h6.tsx +59 -0
- package/components/markdown/headings.stories.jsx +52 -0
- package/components/markdown/li.tsx +55 -0
- package/components/markdown/ol.stories.jsx +47 -0
- package/components/markdown/ol.tsx +93 -0
- package/components/markdown/p.stories.jsx +36 -0
- package/components/markdown/p.tsx +65 -0
- package/components/markdown/ul.stories.jsx +46 -0
- package/components/markdown/ul.tsx +93 -0
- package/components/mini-card/_mini-card.scss +55 -0
- package/components/mini-card/mini-card.stories.jsx +72 -0
- package/components/mini-card/mini-card.tsx +132 -0
- package/components/page-description/_page-description.scss +38 -0
- package/components/page-description/page-description.stories.jsx +36 -0
- package/components/page-description/page-description.tsx +61 -0
- package/components/page-table/_page-table.scss +51 -0
- package/components/page-table/page-table.stories.jsx +56 -0
- package/components/page-table/page-table.tsx +88 -0
- package/components/preview/_preview.scss +16 -0
- package/components/preview/preview.stories.jsx +41 -0
- package/components/preview/preview.tsx +80 -0
- package/components/resource-card/_resource-card.scss +165 -0
- package/components/resource-card/resource-card.stories.jsx +100 -0
- package/components/resource-card/resource-card.tsx +201 -0
- package/components/storybook-demo/_storybook-demo.scss +57 -0
- package/components/storybook-demo/storybook-demo.stories.jsx +70 -0
- package/components/storybook-demo/storybook-demo.tsx +190 -0
- package/components/tabs/_tabs.scss +98 -0
- package/components/tabs/select.tsx +60 -0
- package/components/tabs/tab-list.tsx +48 -0
- package/components/tabs/tab.tsx +125 -0
- package/components/tabs/tabs.stories.jsx +54 -0
- package/components/tabs/tabs.tsx +78 -0
- package/components/title/title.stories.jsx +43 -0
- package/components/title/title.tsx +47 -0
- package/components/utils.ts +102 -0
- package/components/video/_video.scss +89 -0
- package/components/video/local-poster.jpeg +0 -0
- package/components/video/local-video.mp4 +0 -0
- package/components/video/video.stories.jsx +45 -0
- package/components/video/video.tsx +255 -0
- package/es/index.js +71714 -0
- package/index.ts +59 -0
- package/lib/index.js +71767 -0
- package/package.json +64 -0
- package/telemetry.yml +21 -0
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright OctaviaFlow
|
|
3
|
+
* Author: Vishal Kumar
|
|
4
|
+
* Created: 11/November/2025
|
|
5
|
+
*
|
|
6
|
+
* This source code is licensed under the Apache-2.0 license found in the
|
|
7
|
+
* LICENSE file in the root directory of this source tree.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/*
|
|
11
|
+
* Copyright OctaviaFlow 2022, 2025
|
|
12
|
+
*
|
|
13
|
+
* This source code is licensed under the Apache-2.0 license found in the
|
|
14
|
+
* LICENSE file in the root directory of this source tree.
|
|
15
|
+
*/
|
|
16
|
+
import PropTypes from "prop-types";
|
|
17
|
+
import React, { useContext } from "react";
|
|
18
|
+
|
|
19
|
+
import { MdxComponent, NonScalarNode } from "../interfaces";
|
|
20
|
+
import { withPrefix } from "../utils";
|
|
21
|
+
import { TabContext } from "./tabs";
|
|
22
|
+
|
|
23
|
+
interface TabListProps {
|
|
24
|
+
_id: string;
|
|
25
|
+
children: NonScalarNode;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export const TabList: MdxComponent<TabListProps> = ({ _id, children }) => {
|
|
29
|
+
const { activeTab } = useContext(TabContext);
|
|
30
|
+
|
|
31
|
+
return (
|
|
32
|
+
<ul className={withPrefix("tab-list")} role="tablist">
|
|
33
|
+
{React.Children.map(children, (child, index) => {
|
|
34
|
+
return React.cloneElement(child, {
|
|
35
|
+
_id: `${_id}__${index}`,
|
|
36
|
+
active: activeTab === index,
|
|
37
|
+
index,
|
|
38
|
+
tab: true,
|
|
39
|
+
});
|
|
40
|
+
})}
|
|
41
|
+
</ul>
|
|
42
|
+
);
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
TabList.propTypes = {
|
|
46
|
+
_id: PropTypes.string.isRequired,
|
|
47
|
+
children: PropTypes.array.isRequired,
|
|
48
|
+
};
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright OctaviaFlow
|
|
3
|
+
* Author: Vishal Kumar
|
|
4
|
+
* Created: 11/November/2025
|
|
5
|
+
*
|
|
6
|
+
* This source code is licensed under the Apache-2.0 license found in the
|
|
7
|
+
* LICENSE file in the root directory of this source tree.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/*
|
|
11
|
+
* Copyright OctaviaFlow 2022, 2025
|
|
12
|
+
*
|
|
13
|
+
* This source code is licensed under the Apache-2.0 license found in the
|
|
14
|
+
* LICENSE file in the root directory of this source tree.
|
|
15
|
+
*/
|
|
16
|
+
import PropTypes from "prop-types";
|
|
17
|
+
import React, {
|
|
18
|
+
KeyboardEvent,
|
|
19
|
+
ReactNode,
|
|
20
|
+
useCallback,
|
|
21
|
+
useContext,
|
|
22
|
+
} from "react";
|
|
23
|
+
|
|
24
|
+
import { MdxComponent } from "../interfaces";
|
|
25
|
+
import { withPrefix } from "../utils";
|
|
26
|
+
import { TabContext } from "./tabs";
|
|
27
|
+
|
|
28
|
+
interface TabProps {
|
|
29
|
+
_id: string;
|
|
30
|
+
active?: boolean | null;
|
|
31
|
+
children: ReactNode;
|
|
32
|
+
index: number;
|
|
33
|
+
label: string;
|
|
34
|
+
tab?: boolean | null;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export const Tab: MdxComponent<TabProps> = ({
|
|
38
|
+
_id,
|
|
39
|
+
label,
|
|
40
|
+
active,
|
|
41
|
+
index,
|
|
42
|
+
tab,
|
|
43
|
+
children,
|
|
44
|
+
}) => {
|
|
45
|
+
const { setActiveTab, tabList } = useContext(TabContext);
|
|
46
|
+
const buttonRef = useCallback((ref) => tabList.push(ref), [tabList]);
|
|
47
|
+
|
|
48
|
+
const onKeyDown = (e: KeyboardEvent) => {
|
|
49
|
+
let nextButton;
|
|
50
|
+
switch (e.key) {
|
|
51
|
+
case "End":
|
|
52
|
+
e.preventDefault();
|
|
53
|
+
tabList[tabList.length - 1]?.focus();
|
|
54
|
+
break;
|
|
55
|
+
case "Home":
|
|
56
|
+
e.preventDefault();
|
|
57
|
+
tabList[0]?.focus();
|
|
58
|
+
break;
|
|
59
|
+
case "ArrowLeft":
|
|
60
|
+
e.preventDefault();
|
|
61
|
+
nextButton = tabList[index - 1] || tabList[tabList.length - 1];
|
|
62
|
+
nextButton?.focus();
|
|
63
|
+
break;
|
|
64
|
+
case "ArrowRight":
|
|
65
|
+
e.preventDefault();
|
|
66
|
+
nextButton = tabList[index + 1] || tabList[0];
|
|
67
|
+
nextButton?.focus();
|
|
68
|
+
break;
|
|
69
|
+
default:
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
if (tab) {
|
|
74
|
+
return (
|
|
75
|
+
<li role="presentation">
|
|
76
|
+
<button
|
|
77
|
+
className={withPrefix("tab")}
|
|
78
|
+
ref={buttonRef}
|
|
79
|
+
onKeyDown={onKeyDown}
|
|
80
|
+
onClick={() => setActiveTab(index)}
|
|
81
|
+
onFocus={() => setActiveTab(index)}
|
|
82
|
+
type="button"
|
|
83
|
+
role="tab"
|
|
84
|
+
id={`${_id}--tab`}
|
|
85
|
+
tabIndex={!active ? -1 : 0}
|
|
86
|
+
aria-selected={active || undefined}
|
|
87
|
+
>
|
|
88
|
+
{label}
|
|
89
|
+
</button>
|
|
90
|
+
</li>
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return (
|
|
95
|
+
<section
|
|
96
|
+
className={withPrefix("tab-panel")}
|
|
97
|
+
hidden={!active}
|
|
98
|
+
role="tabpanel"
|
|
99
|
+
id={`${_id}--panel`}
|
|
100
|
+
aria-labelledby={`${_id}--tab`}
|
|
101
|
+
>
|
|
102
|
+
{children}
|
|
103
|
+
</section>
|
|
104
|
+
);
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
Tab.propTypes = {
|
|
108
|
+
/** tab id */
|
|
109
|
+
_id: PropTypes.string.isRequired,
|
|
110
|
+
/** Set active tab */
|
|
111
|
+
active: PropTypes.bool,
|
|
112
|
+
/** Provide the contents of the tab */
|
|
113
|
+
children: PropTypes.node as unknown as React.Validator<React.ReactNode>,
|
|
114
|
+
/** tab index */
|
|
115
|
+
index: PropTypes.number.isRequired,
|
|
116
|
+
/** Set tab label */
|
|
117
|
+
label: PropTypes.string.isRequired,
|
|
118
|
+
/** tab */
|
|
119
|
+
tab: PropTypes.bool,
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
Tab.defaultProps = {
|
|
123
|
+
_id: "none",
|
|
124
|
+
index: 0,
|
|
125
|
+
};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright OctaviaFlow
|
|
3
|
+
* Author: Vishal Kumar
|
|
4
|
+
* Created: 11/November/2025
|
|
5
|
+
*
|
|
6
|
+
* This source code is licensed under the Apache-2.0 license found in the
|
|
7
|
+
* LICENSE file in the root directory of this source tree.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/*
|
|
11
|
+
* Copyright IBM Corp. 2022, 2025
|
|
12
|
+
*
|
|
13
|
+
* This source code is licensed under the Apache-2.0 license found in the
|
|
14
|
+
* LICENSE file in the root directory of this source tree.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import React from "react";
|
|
18
|
+
import { Tab } from "./tab";
|
|
19
|
+
import { Tabs } from "./tabs";
|
|
20
|
+
|
|
21
|
+
export default {
|
|
22
|
+
title: "Components/MDX Components/Tabs",
|
|
23
|
+
component: Tabs,
|
|
24
|
+
subcomponents: { Tab },
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const Template = (args) => (
|
|
28
|
+
<Tabs {...args}>
|
|
29
|
+
<Tab label="Tab 1">
|
|
30
|
+
Maecenas ultrices sem nec blandit dictum. ermentum ullamcorper pretium.
|
|
31
|
+
Duis turpis elit, facilisis nec elit id, fermentum porttitor nisl. Nulla
|
|
32
|
+
dignissim euismod maximus. Cras euismod facilisis rutrum. Etiam nisi sem,
|
|
33
|
+
malesuada auctor pretium vel, ullamcorper sed mi. In hac habitasse platea
|
|
34
|
+
dictumst.
|
|
35
|
+
</Tab>
|
|
36
|
+
<Tab label="Tab 2">
|
|
37
|
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean feugiat ex
|
|
38
|
+
massa, in tincidunt ipsum tempor in. Maecenas ultrices sem nec blandit
|
|
39
|
+
dictum. ermentum ullamcorper pretium. Duis turpis elit, facilisis nec elit
|
|
40
|
+
id, fermentum porttitor nisl. Nulla dignissim euismod maximus. Cras
|
|
41
|
+
euismod facilisis rutrum.
|
|
42
|
+
</Tab>
|
|
43
|
+
<Tab label="Tab 3">
|
|
44
|
+
Duis turpis elit, facilisis nec elit id, fermentum porttitor nisl. Nulla
|
|
45
|
+
dignissim euismod maximus. Cras euismod facilisis rutrum. Etiam nisi sem,
|
|
46
|
+
malesuada auctor pretium vel, ullamcorper sed mi. In hac habitasse platea
|
|
47
|
+
dictumst. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean
|
|
48
|
+
feugiat ex massa, in tincidunt ipsum tempor in.
|
|
49
|
+
</Tab>
|
|
50
|
+
</Tabs>
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
export const Default = Template.bind({});
|
|
54
|
+
Default.args = {};
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright OctaviaFlow
|
|
3
|
+
* Author: Vishal Kumar
|
|
4
|
+
* Created: 11/November/2025
|
|
5
|
+
*
|
|
6
|
+
* This source code is licensed under the Apache-2.0 license found in the
|
|
7
|
+
* LICENSE file in the root directory of this source tree.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/*
|
|
11
|
+
* Copyright OctaviaFlow 2022, 2025
|
|
12
|
+
*
|
|
13
|
+
* This source code is licensed under the Apache-2.0 license found in the
|
|
14
|
+
* LICENSE file in the root directory of this source tree.
|
|
15
|
+
*/
|
|
16
|
+
import PropTypes from "prop-types";
|
|
17
|
+
import React, { createContext, useEffect, useRef, useState } from "react";
|
|
18
|
+
|
|
19
|
+
import { MdxComponent, NonScalarNode } from "../interfaces";
|
|
20
|
+
import { mediaQueries, useId, useMatchMedia } from "../utils";
|
|
21
|
+
import Select from "./select";
|
|
22
|
+
import { TabList } from "./tab-list";
|
|
23
|
+
|
|
24
|
+
interface TabContextInterface {
|
|
25
|
+
setActiveTab(tab: number): void;
|
|
26
|
+
activeTab: number;
|
|
27
|
+
tabList: Array<HTMLButtonElement>;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const TabContext = createContext<TabContextInterface>({
|
|
31
|
+
setActiveTab: () => undefined,
|
|
32
|
+
activeTab: -1,
|
|
33
|
+
tabList: [],
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
interface TabsProps {
|
|
37
|
+
children: NonScalarNode;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* The `<Tabs>` and `<Tab>` components are used together to display and swap between content.
|
|
42
|
+
*/
|
|
43
|
+
export const Tabs: MdxComponent<TabsProps> = (props) => {
|
|
44
|
+
const tabList = useRef([]);
|
|
45
|
+
const [activeTab, setActiveTab] = useState(0);
|
|
46
|
+
const isMd = useMatchMedia(mediaQueries.md);
|
|
47
|
+
const id = useId("tabs");
|
|
48
|
+
|
|
49
|
+
// clear tablist when unmounted (switching between Select and TabList)
|
|
50
|
+
useEffect(() => () => {
|
|
51
|
+
tabList.current = [];
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
return (
|
|
55
|
+
<TabContext.Provider
|
|
56
|
+
value={{ setActiveTab, activeTab, tabList: tabList.current }}
|
|
57
|
+
>
|
|
58
|
+
{isMd && <TabList _id={id}>{props.children}</TabList>}
|
|
59
|
+
{!isMd && <Select _id={id}>{props.children}</Select>}
|
|
60
|
+
{React.Children.map(props.children, (child, index) => {
|
|
61
|
+
return React.cloneElement(child, {
|
|
62
|
+
_id: `${id}__${index}`,
|
|
63
|
+
active: activeTab === index,
|
|
64
|
+
index,
|
|
65
|
+
});
|
|
66
|
+
})}
|
|
67
|
+
</TabContext.Provider>
|
|
68
|
+
);
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
Tabs.propTypes = {
|
|
72
|
+
/** Provide tab children */
|
|
73
|
+
children: PropTypes.array.isRequired,
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
Tabs.displayName = "Tabs";
|
|
77
|
+
|
|
78
|
+
export { TabContext };
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright OctaviaFlow
|
|
3
|
+
* Author: Vishal Kumar
|
|
4
|
+
* Created: 11/November/2025
|
|
5
|
+
*
|
|
6
|
+
* This source code is licensed under the Apache-2.0 license found in the
|
|
7
|
+
* LICENSE file in the root directory of this source tree.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/*
|
|
11
|
+
* Copyright IBM Corp. 2022, 2025
|
|
12
|
+
*
|
|
13
|
+
* This source code is licensed under the Apache-2.0 license found in the
|
|
14
|
+
* LICENSE file in the root directory of this source tree.
|
|
15
|
+
*/
|
|
16
|
+
import React from "react";
|
|
17
|
+
import { Title } from "./title";
|
|
18
|
+
import { P } from "../markdown/p";
|
|
19
|
+
|
|
20
|
+
export default {
|
|
21
|
+
title: "Components/MDX Components/Title",
|
|
22
|
+
component: Title,
|
|
23
|
+
argTypes: {
|
|
24
|
+
children: {
|
|
25
|
+
control: false,
|
|
26
|
+
},
|
|
27
|
+
className: {
|
|
28
|
+
control: false,
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const Template = (args) => (
|
|
34
|
+
<>
|
|
35
|
+
<Title {...args}>Lorem ipsum</Title>
|
|
36
|
+
<P>
|
|
37
|
+
This is the element after the title with its default top margin removed.
|
|
38
|
+
</P>
|
|
39
|
+
</>
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
export const Default = Template.bind({});
|
|
43
|
+
Default.args = {};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright OctaviaFlow
|
|
3
|
+
* Author: Vishal Kumar
|
|
4
|
+
* Created: 11/November/2025
|
|
5
|
+
*
|
|
6
|
+
* This source code is licensed under the Apache-2.0 license found in the
|
|
7
|
+
* LICENSE file in the root directory of this source tree.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/*
|
|
11
|
+
* Copyright OctaviaFlow 2022, 2025
|
|
12
|
+
*
|
|
13
|
+
* This source code is licensed under the Apache-2.0 license found in the
|
|
14
|
+
* LICENSE file in the root directory of this source tree.
|
|
15
|
+
*/
|
|
16
|
+
import PropTypes from "prop-types";
|
|
17
|
+
import React, { ReactNode } from "react";
|
|
18
|
+
|
|
19
|
+
import { H4 } from "../markdown/h4";
|
|
20
|
+
import { MdxComponent } from "../interfaces";
|
|
21
|
+
|
|
22
|
+
interface TitleProps {
|
|
23
|
+
children: ReactNode;
|
|
24
|
+
className?: string | null;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* The `<Title>` component is used to provide a title to a subsequent component
|
|
29
|
+
* (table, image, video, code block). The Title should be used in favor of other
|
|
30
|
+
* techniques for bolded text (h4s) to preserve page structure and heading hierarchy.
|
|
31
|
+
*/
|
|
32
|
+
export const Title: MdxComponent<TitleProps> = ({ children, className }) => (
|
|
33
|
+
<H4 autolink={false} className={className}>
|
|
34
|
+
{children}
|
|
35
|
+
</H4>
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
Title.propTypes = {
|
|
39
|
+
/**
|
|
40
|
+
* Provide the contents of Title
|
|
41
|
+
*/
|
|
42
|
+
children: PropTypes.node as unknown as React.Validator<React.ReactNode>,
|
|
43
|
+
/**
|
|
44
|
+
* Optional class name on the title.
|
|
45
|
+
*/
|
|
46
|
+
className: PropTypes.string,
|
|
47
|
+
};
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright OctaviaFlow
|
|
3
|
+
* Author: Vishal Kumar
|
|
4
|
+
* Created: 11/November/2025
|
|
5
|
+
*
|
|
6
|
+
* This source code is licensed under the Apache-2.0 license found in the
|
|
7
|
+
* LICENSE file in the root directory of this source tree.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/*
|
|
11
|
+
* Copyright OctaviaFlow 2022, 2025
|
|
12
|
+
*
|
|
13
|
+
* This source code is licensed under the Apache-2.0 license found in the
|
|
14
|
+
* LICENSE file in the root directory of this source tree.
|
|
15
|
+
*/
|
|
16
|
+
import { breakpoints } from "@octaviaflow/layout";
|
|
17
|
+
import { useEffect, useState } from "react";
|
|
18
|
+
|
|
19
|
+
const prefix = "carbon-mdx-components";
|
|
20
|
+
const mediaQueries = {
|
|
21
|
+
sm: `(min-width: ${breakpoints.sm.width})`,
|
|
22
|
+
md: `(min-width: ${breakpoints.md.width})`,
|
|
23
|
+
lg: `(min-width: ${breakpoints.lg.width})`,
|
|
24
|
+
xlg: `(min-width: ${breakpoints.xlg.width})`,
|
|
25
|
+
max: `(min-width: ${breakpoints.max.width})`,
|
|
26
|
+
};
|
|
27
|
+
let globalIndex = 0;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Queries the window if it exists.
|
|
31
|
+
* @param {string} query of the dimensions needed
|
|
32
|
+
* @returns the matchMedia function
|
|
33
|
+
*/
|
|
34
|
+
const getMatchMedia = (query: string) => {
|
|
35
|
+
return typeof window !== "undefined" && window.matchMedia
|
|
36
|
+
? window.matchMedia(query)
|
|
37
|
+
: null;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Gives an ID to the markdown components.
|
|
42
|
+
* @param {string} label component name string
|
|
43
|
+
* @returns string for component ID
|
|
44
|
+
*/
|
|
45
|
+
const useId = (label: string) => {
|
|
46
|
+
// TODO: delete this hook and use react 18 useId instead.
|
|
47
|
+
const [id] = useState(++globalIndex);
|
|
48
|
+
|
|
49
|
+
return `cp__${label}__${id}`;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Function that returns the viewport media dimensions.
|
|
54
|
+
* @param {string} query string
|
|
55
|
+
* @returns boolean stating if it matches viewport dimensions
|
|
56
|
+
*/
|
|
57
|
+
const useMatchMedia = (query: string) => {
|
|
58
|
+
const [matches, setMatches] = useState(getMatchMedia(query)?.matches);
|
|
59
|
+
|
|
60
|
+
useEffect(() => {
|
|
61
|
+
const matchMediaResult = getMatchMedia(query);
|
|
62
|
+
/**
|
|
63
|
+
*
|
|
64
|
+
* @param {any} e event
|
|
65
|
+
* @param {(
|
|
66
|
+
* boolean |
|
|
67
|
+
* ((prevState: boolean | undefined) => boolean | undefined) |
|
|
68
|
+
* undefined
|
|
69
|
+
* )} e.matches boolean stating if it matches
|
|
70
|
+
*/
|
|
71
|
+
const updateMatch = (e: {
|
|
72
|
+
matches:
|
|
73
|
+
| boolean
|
|
74
|
+
| ((prevState: boolean | undefined) => boolean | undefined)
|
|
75
|
+
| undefined;
|
|
76
|
+
}) => {
|
|
77
|
+
setMatches(e.matches);
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
matchMediaResult?.addEventListener("change", updateMatch);
|
|
81
|
+
|
|
82
|
+
return () => {
|
|
83
|
+
matchMediaResult?.removeEventListener("change", updateMatch);
|
|
84
|
+
};
|
|
85
|
+
}, [query]);
|
|
86
|
+
|
|
87
|
+
return matches;
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Adds a prefix specific to the carbon platform mdx components to the provided string. This is
|
|
92
|
+
* often used in conjunction with the scss utility `with-prefix` to assign unique class names to
|
|
93
|
+
* styles for components.
|
|
94
|
+
*
|
|
95
|
+
* @param {string} className The string to which to add a prefix.
|
|
96
|
+
* @returns A prefixed string.
|
|
97
|
+
*/
|
|
98
|
+
function withPrefix(className: string) {
|
|
99
|
+
return prefix + "--" + className;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export { mediaQueries, useId, useMatchMedia, withPrefix };
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright OctaviaFlow 2021, 2023
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the Apache-2.0 license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
@use '@carbon/react/scss/motion' as motion;
|
|
8
|
+
@use '@carbon/react/scss/colors' as colors;
|
|
9
|
+
@use '@carbon/react/scss/theme' as theme;
|
|
10
|
+
@use '@carbon/react/scss/spacing' as spacing;
|
|
11
|
+
|
|
12
|
+
@use '../utils' as *;
|
|
13
|
+
|
|
14
|
+
.#{with-prefix('video-container')} {
|
|
15
|
+
position: relative;
|
|
16
|
+
display: table;
|
|
17
|
+
inline-size: 100%;
|
|
18
|
+
|
|
19
|
+
.#{with-prefix('video')} {
|
|
20
|
+
block-size: 100%;
|
|
21
|
+
inline-size: 100%;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
div.#{with-prefix('video-button')} {
|
|
25
|
+
position: absolute;
|
|
26
|
+
z-index: 10;
|
|
27
|
+
display: flex;
|
|
28
|
+
align-items: center;
|
|
29
|
+
justify-content: center;
|
|
30
|
+
border-radius: 50%;
|
|
31
|
+
margin: auto;
|
|
32
|
+
background-color: colors.$blue-60;
|
|
33
|
+
block-size: 4.5rem;
|
|
34
|
+
inline-size: 4.5rem;
|
|
35
|
+
inset-block: 0% 0%;
|
|
36
|
+
inset-inline: 0% 0%;
|
|
37
|
+
transition: all motion.$duration-moderate-01 motion(entrance, productive);
|
|
38
|
+
|
|
39
|
+
@media screen and (prefers-reduced-motion: reduce) {
|
|
40
|
+
transition: none;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
&:focus {
|
|
44
|
+
outline: 2px solid theme.$focus;
|
|
45
|
+
outline-offset: -2px;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
&:hover {
|
|
49
|
+
background-color: colors.$gray-90;
|
|
50
|
+
opacity: 0.8;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
div.#{with-prefix('video-button')} > svg {
|
|
55
|
+
fill: theme.$icon-inverse;
|
|
56
|
+
margin-inline-start: spacing.$spacing-02;
|
|
57
|
+
transition: all motion.$duration-moderate-01 motion(entrance, productive);
|
|
58
|
+
|
|
59
|
+
@media screen and (prefers-reduced-motion: reduce) {
|
|
60
|
+
transition: none;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
div.#{with-prefix('video--is-playing')} > svg {
|
|
65
|
+
margin-inline-start: 0;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// iframe
|
|
69
|
+
.#{with-prefix('vimeo')} {
|
|
70
|
+
position: relative;
|
|
71
|
+
overflow: hidden;
|
|
72
|
+
block-size: 0;
|
|
73
|
+
// hack to allow vimeo videos to display correctly and assume full inline-size available
|
|
74
|
+
padding-block-end: 56.543%;
|
|
75
|
+
|
|
76
|
+
iframe {
|
|
77
|
+
position: absolute;
|
|
78
|
+
block-size: 100%;
|
|
79
|
+
inline-size: 100%;
|
|
80
|
+
inset-block-start: 0;
|
|
81
|
+
inset-inline-start: 0;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
&:not(:hover) div.#{with-prefix('video--is-playing')},
|
|
86
|
+
&:not(:hover) div.#{with-prefix('video--is-playing')} > svg {
|
|
87
|
+
opacity: 0;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright OctaviaFlow
|
|
3
|
+
* Author: Vishal Kumar
|
|
4
|
+
* Created: 11/November/2025
|
|
5
|
+
*
|
|
6
|
+
* This source code is licensed under the Apache-2.0 license found in the
|
|
7
|
+
* LICENSE file in the root directory of this source tree.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/*
|
|
11
|
+
* Copyright IBM Corp. 2022, 2025
|
|
12
|
+
*
|
|
13
|
+
* This source code is licensed under the Apache-2.0 license found in the
|
|
14
|
+
* LICENSE file in the root directory of this source tree.
|
|
15
|
+
*/
|
|
16
|
+
import React from "react";
|
|
17
|
+
import { Video } from "./video";
|
|
18
|
+
import localPoster from "./local-poster.jpeg";
|
|
19
|
+
import localVideo from "./local-video.mp4";
|
|
20
|
+
|
|
21
|
+
export default {
|
|
22
|
+
title: "Components/MDX Components/Images & Video/Video",
|
|
23
|
+
component: Video,
|
|
24
|
+
argTypes: {
|
|
25
|
+
poster: {
|
|
26
|
+
type: "string",
|
|
27
|
+
},
|
|
28
|
+
src: {
|
|
29
|
+
type: "string",
|
|
30
|
+
},
|
|
31
|
+
vimeoId: {
|
|
32
|
+
type: "string",
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const Template = (args) => (
|
|
38
|
+
<Video src={localVideo} poster={localPoster} {...args} />
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
export const Default = Template.bind({});
|
|
42
|
+
Default.args = {
|
|
43
|
+
width: 720,
|
|
44
|
+
height: 405,
|
|
45
|
+
};
|