@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.
Files changed (119) hide show
  1. package/README.md +215 -0
  2. package/components/_utils.scss +18 -0
  3. package/components/accordion/_accordion.scss +35 -0
  4. package/components/accordion/accordion.stories.jsx +33 -0
  5. package/components/accordion/accordion.tsx +55 -0
  6. package/components/anchor-links/_anchor-links.scss +67 -0
  7. package/components/anchor-links/anchor-link.tsx +50 -0
  8. package/components/anchor-links/anchor-links.stories.jsx +51 -0
  9. package/components/anchor-links/anchor-links.tsx +73 -0
  10. package/components/art-direction/art-direction.stories.jsx +44 -0
  11. package/components/art-direction/art-direction.tsx +63 -0
  12. package/components/art-direction/desktop.jpg +0 -0
  13. package/components/art-direction/mobile.jpg +0 -0
  14. package/components/art-direction/tablet.jpg +0 -0
  15. package/components/article-card/_article-card.scss +98 -0
  16. package/components/article-card/article-card.stories.jsx +59 -0
  17. package/components/article-card/article-card.tsx +208 -0
  18. package/components/article-card/article06.png +0 -0
  19. package/components/aside/_aside.scss +56 -0
  20. package/components/aside/aside.stories.jsx +50 -0
  21. package/components/aside/aside.tsx +72 -0
  22. package/components/caption/_caption.scss +30 -0
  23. package/components/caption/caption.stories.jsx +33 -0
  24. package/components/caption/caption.tsx +47 -0
  25. package/components/card-group/_card-group.scss +44 -0
  26. package/components/card-group/card-group.stories.jsx +85 -0
  27. package/components/card-group/card-group.tsx +65 -0
  28. package/components/card-group/sketch-icon.png +0 -0
  29. package/components/code/_code.scss +110 -0
  30. package/components/code/code.stories.jsx +32 -0
  31. package/components/code/code.tsx +71 -0
  32. package/components/code/inline-code.tsx +55 -0
  33. package/components/code/path.tsx +56 -0
  34. package/components/divider/_divider.scss +67 -0
  35. package/components/divider/divider.stories.jsx +74 -0
  36. package/components/divider/divider.tsx +54 -0
  37. package/components/do-dont/_do-dont.scss +191 -0
  38. package/components/do-dont/do-dont-row.tsx +51 -0
  39. package/components/do-dont/do-dont.stories.jsx +53 -0
  40. package/components/do-dont/do-dont.tsx +161 -0
  41. package/components/do-dont/light-theme.jpg +0 -0
  42. package/components/gif-player/_gif-player.scss +64 -0
  43. package/components/gif-player/cloud.gif +0 -0
  44. package/components/gif-player/cloud.jpg +0 -0
  45. package/components/gif-player/gif-player.stories.jsx +45 -0
  46. package/components/gif-player/gif-player.tsx +150 -0
  47. package/components/grid-transform/_grid.scss +13 -0
  48. package/components/grid-transform/column.tsx +102 -0
  49. package/components/grid-transform/grid.stories.jsx +72 -0
  50. package/components/grid-transform/grid.tsx +52 -0
  51. package/components/grid-transform/row.tsx +92 -0
  52. package/components/image-wrapper/_image-wrapper.scss +32 -0
  53. package/components/image-wrapper/accordion-style-3.png +0 -0
  54. package/components/image-wrapper/image-wrapper.stories.jsx +40 -0
  55. package/components/image-wrapper/image-wrapper.tsx +56 -0
  56. package/components/index.scss +31 -0
  57. package/components/inline-notification/_inline-notification.scss +29 -0
  58. package/components/inline-notification/inline-notification.stories.jsx +67 -0
  59. package/components/inline-notification/inline-notification.tsx +98 -0
  60. package/components/interfaces.ts +31 -0
  61. package/components/link/_link.scss +13 -0
  62. package/components/link/link.stories.jsx +36 -0
  63. package/components/link/link.tsx +51 -0
  64. package/components/markdown/_markdown.scss +140 -0
  65. package/components/markdown/autolink-header/_autolink-header.scss +57 -0
  66. package/components/markdown/autolink-header/autolink-header.tsx +107 -0
  67. package/components/markdown/blockquote.stories.jsx +38 -0
  68. package/components/markdown/blockquote.tsx +53 -0
  69. package/components/markdown/h1.tsx +92 -0
  70. package/components/markdown/h2.tsx +85 -0
  71. package/components/markdown/h3.tsx +72 -0
  72. package/components/markdown/h4.tsx +73 -0
  73. package/components/markdown/h5.tsx +59 -0
  74. package/components/markdown/h6.tsx +59 -0
  75. package/components/markdown/headings.stories.jsx +52 -0
  76. package/components/markdown/li.tsx +55 -0
  77. package/components/markdown/ol.stories.jsx +47 -0
  78. package/components/markdown/ol.tsx +93 -0
  79. package/components/markdown/p.stories.jsx +36 -0
  80. package/components/markdown/p.tsx +65 -0
  81. package/components/markdown/ul.stories.jsx +46 -0
  82. package/components/markdown/ul.tsx +93 -0
  83. package/components/mini-card/_mini-card.scss +55 -0
  84. package/components/mini-card/mini-card.stories.jsx +72 -0
  85. package/components/mini-card/mini-card.tsx +132 -0
  86. package/components/page-description/_page-description.scss +38 -0
  87. package/components/page-description/page-description.stories.jsx +36 -0
  88. package/components/page-description/page-description.tsx +61 -0
  89. package/components/page-table/_page-table.scss +51 -0
  90. package/components/page-table/page-table.stories.jsx +56 -0
  91. package/components/page-table/page-table.tsx +88 -0
  92. package/components/preview/_preview.scss +16 -0
  93. package/components/preview/preview.stories.jsx +41 -0
  94. package/components/preview/preview.tsx +80 -0
  95. package/components/resource-card/_resource-card.scss +165 -0
  96. package/components/resource-card/resource-card.stories.jsx +100 -0
  97. package/components/resource-card/resource-card.tsx +201 -0
  98. package/components/storybook-demo/_storybook-demo.scss +57 -0
  99. package/components/storybook-demo/storybook-demo.stories.jsx +70 -0
  100. package/components/storybook-demo/storybook-demo.tsx +190 -0
  101. package/components/tabs/_tabs.scss +98 -0
  102. package/components/tabs/select.tsx +60 -0
  103. package/components/tabs/tab-list.tsx +48 -0
  104. package/components/tabs/tab.tsx +125 -0
  105. package/components/tabs/tabs.stories.jsx +54 -0
  106. package/components/tabs/tabs.tsx +78 -0
  107. package/components/title/title.stories.jsx +43 -0
  108. package/components/title/title.tsx +47 -0
  109. package/components/utils.ts +102 -0
  110. package/components/video/_video.scss +89 -0
  111. package/components/video/local-poster.jpeg +0 -0
  112. package/components/video/local-video.mp4 +0 -0
  113. package/components/video/video.stories.jsx +45 -0
  114. package/components/video/video.tsx +255 -0
  115. package/es/index.js +71714 -0
  116. package/index.ts +59 -0
  117. package/lib/index.js +71767 -0
  118. package/package.json +64 -0
  119. package/telemetry.yml +21 -0
@@ -0,0 +1,67 @@
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 { InlineNotification } from "./inline-notification";
19
+
20
+ const stories = {
21
+ title: "Components/MDX Components/InlineNotification",
22
+ component: InlineNotification,
23
+ argTypes: {
24
+ children: {
25
+ control: false,
26
+ },
27
+ className: {
28
+ control: false,
29
+ },
30
+ },
31
+ };
32
+
33
+ export default stories;
34
+
35
+ const Template = (args) => (
36
+ <InlineNotification {...args}>
37
+ Lorem ipsum: dolor sit amet, elit. Curabitur ac odio arcu. Vestibulum
38
+ egestas eleifend porttitor. Quisque malesuada pulvinar pellentesque. Nunc
39
+ dictum odio eu enim venenatis fringilla. Nunc finibus enim dui, a tempus
40
+ quam commodo vitae. Donec non eros gravida dolor porta suscipit non vel
41
+ quam.
42
+ </InlineNotification>
43
+ );
44
+
45
+ export const Default = Template.bind({});
46
+ Default.args = {};
47
+
48
+ export const Warning = Template.bind({});
49
+ Warning.args = {
50
+ kind: "warning",
51
+ };
52
+
53
+ export const Info = Template.bind({});
54
+ Info.args = {
55
+ kind: "info",
56
+ };
57
+
58
+ // Note: This is a lowercase "e" so it doesn't collide with the built-in JS Error class
59
+ export const error = Template.bind({});
60
+ error.args = {
61
+ kind: "error",
62
+ };
63
+
64
+ export const Success = Template.bind({});
65
+ Success.args = {
66
+ kind: "success",
67
+ };
@@ -0,0 +1,98 @@
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
+
17
+ import { Column, Grid } from "@octaviaflow/react";
18
+ import {
19
+ CheckmarkFilled,
20
+ ErrorFilled,
21
+ InformationFilled,
22
+ WarningFilled,
23
+ } from "@octaviaflow/icons-react";
24
+ import { clsx } from "clsx";
25
+ import PropTypes from "prop-types";
26
+ import React, { ReactNode } from "react";
27
+
28
+ import { MdxComponent } from "../interfaces";
29
+ import { withPrefix } from "../utils";
30
+
31
+ const iconTypes = {
32
+ error: ErrorFilled,
33
+ success: CheckmarkFilled,
34
+ warning: WarningFilled,
35
+ info: InformationFilled,
36
+ };
37
+
38
+ type Kind = "error" | "info" | "success" | "warning";
39
+
40
+ interface InlineNotificationProps {
41
+ children?: ReactNode;
42
+ className?: string | null;
43
+ kind: Kind;
44
+ }
45
+ /**
46
+ * The `<InlineNotification>` component is used to communicate important information to a user.
47
+ */
48
+ export const InlineNotification: MdxComponent<InlineNotificationProps> = ({
49
+ children,
50
+ className,
51
+ kind = "info",
52
+ }) => {
53
+ const containerClassName = clsx(className, {
54
+ "ods--inline-notification": true,
55
+ "ods--inline-notification--low-contrast": true,
56
+ [`ods--inline-notification--${kind}`]: kind,
57
+ "ods--inline-notification--hide-close-button": true,
58
+ });
59
+ const IconForKind = iconTypes[kind];
60
+
61
+ return (
62
+ <Grid>
63
+ <Column
64
+ sm={4}
65
+ md={8}
66
+ lg={8}
67
+ className={clsx(withPrefix("notification"), className)}
68
+ >
69
+ <div className={containerClassName}>
70
+ <div className="ods--inline-notification__details">
71
+ <IconForKind className="ods--inline-notification__icon" size={20}>
72
+ <title>{`${kind} icon`}</title>
73
+ </IconForKind>
74
+ <div className="ods--inline-notification__text-wrapper">
75
+ <div className={withPrefix("content")}>{children}</div>
76
+ </div>
77
+ </div>
78
+ </div>
79
+ </Column>
80
+ </Grid>
81
+ );
82
+ };
83
+
84
+ InlineNotification.propTypes = {
85
+ /**
86
+ * Provide the contents of the InlineNotification
87
+ */
88
+ children: PropTypes.node as unknown as React.Validator<React.ReactNode>,
89
+ /**
90
+ * Specify an optional className to be applied to the container node
91
+ */
92
+ className: PropTypes.string,
93
+ /**
94
+ * Notification kind
95
+ */
96
+ kind: PropTypes.oneOf<Kind>(["error", "info", "success", "warning"])
97
+ .isRequired,
98
+ };
@@ -0,0 +1,31 @@
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 { Validator } from "prop-types";
17
+ import { ReactElement, ReactPortal } from "react";
18
+
19
+ interface MdxComponent<Props> {
20
+ (props: Props): ReactElement<Props> | null;
21
+ propTypes: { [prop in keyof Props]: Validator<Props[prop]> };
22
+ defaultProps?: { [prop in keyof Props]?: Props[prop] };
23
+ displayName?: string;
24
+ }
25
+
26
+ type NonScalarNode =
27
+ | ReactElement
28
+ | ReactPortal
29
+ | Array<ReactElement | ReactPortal>;
30
+
31
+ export type { MdxComponent, NonScalarNode };
@@ -0,0 +1,13 @@
1
+ /*
2
+ * Copyright OctaviaFlow 2022, 2025
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
+
8
+ @use '../utils' as *;
9
+
10
+ .#{with-prefix('link')} {
11
+ /* stylelint-disable-next-line declaration-no-important */
12
+ font-size: inherit !important;
13
+ }
@@ -0,0 +1,36 @@
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 { Link } from "./link";
18
+
19
+ export default {
20
+ title: "Components/MDX Components/Markdown/Link",
21
+ component: Link,
22
+ argTypes: {
23
+ className: {
24
+ control: false,
25
+ },
26
+ },
27
+ };
28
+
29
+ const Template = (args) => (
30
+ <Link href="https://platform.carbondesignsystem.com" {...args}>
31
+ Carbon Platform Storybook
32
+ </Link>
33
+ );
34
+
35
+ export const Default = Template.bind({});
36
+ Default.args = {};
@@ -0,0 +1,51 @@
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
+
17
+ import { Link as CarbonLink } from "@octaviaflow/react";
18
+ import { clsx } from "clsx";
19
+ import PropTypes from "prop-types";
20
+ import React from "react";
21
+
22
+ import { MdxComponent } from "../interfaces";
23
+ import { withPrefix } from "../utils";
24
+
25
+ interface LinkProps {
26
+ className?: string | null;
27
+ [otherProp: string]: unknown;
28
+ }
29
+
30
+ /**
31
+ * For MDX files, steer away from using JSX components
32
+ * for link in favor of standard markdown syntax.
33
+ *
34
+ * ```
35
+ * > [Carbon Platform Storybook](https://platform.carbondesignsystem.com)
36
+ * ```
37
+ */
38
+ export const Link: MdxComponent<LinkProps> = ({ className, ...rest }) => (
39
+ <CarbonLink
40
+ inline
41
+ {...rest}
42
+ className={clsx(className, withPrefix("link"))}
43
+ />
44
+ );
45
+
46
+ Link.propTypes = {
47
+ /**
48
+ * Specify optional className
49
+ */
50
+ className: PropTypes.string,
51
+ };
@@ -0,0 +1,140 @@
1
+ /*
2
+ * Copyright OctaviaFlow 2022, 2025
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
+
8
+ @use '@carbon/react/scss/breakpoint' as breakpoint;
9
+ @use '@carbon/styles/scss/themes' as *;
10
+ @use '@carbon/styles/scss/theme' as *;
11
+ @use '@carbon/styles/scss/colors' as *;
12
+ @use '@carbon/react/scss/spacing' as spacing;
13
+ @use '@carbon/react/scss/type' as type;
14
+
15
+ @use '../utils' as *;
16
+ @use './autolink-header/autolink-header';
17
+
18
+ /* Spacing */
19
+ .#{with-prefix('h1-container')} + *,
20
+ .#{with-prefix('h2-container')} + *,
21
+ .#{with-prefix('h3-container')} + *,
22
+ .#{with-prefix('paragraph-container')} + * {
23
+ margin-block-start: spacing.$spacing-06;
24
+ }
25
+
26
+ .#{with-prefix('h4-container')} + *,
27
+ .#{with-prefix('h4-container')} + div {
28
+ margin-block-start: 0;
29
+ }
30
+
31
+ .#{with-prefix('h1-container')} {
32
+ margin-block-start: spacing.$spacing-12;
33
+ }
34
+
35
+ .#{with-prefix('h2-container')},
36
+ .#{with-prefix('paragraph-container')} + .#{with-prefix('h2-container')} {
37
+ margin-block-start: spacing.$spacing-09;
38
+
39
+ @include breakpoint.breakpoint(md) {
40
+ margin-block-start: spacing.$spacing-11;
41
+ }
42
+ }
43
+
44
+ .#{with-prefix('h3-container')},
45
+ .#{with-prefix('paragraph-container')} + .#{with-prefix('h3-container')} {
46
+ margin-block-start: spacing.$spacing-10;
47
+ }
48
+
49
+ .#{with-prefix('h4-container')},
50
+ .#{with-prefix('paragraph-container')} + .#{with-prefix('h4-container')} {
51
+ margin-block-start: spacing.$spacing-07;
52
+ }
53
+
54
+ .#{with-prefix('h5-container')},
55
+ .#{with-prefix('h6-container')} {
56
+ margin-block-start: 0;
57
+ }
58
+
59
+ .#{with-prefix('paragraph-container')} {
60
+ margin-block-start: spacing.$spacing-06;
61
+ }
62
+
63
+ /* Spacing List */
64
+ .#{with-prefix('list-container')} {
65
+ margin-block-start: spacing.$spacing-06;
66
+ }
67
+
68
+ .#{with-prefix('list')} .#{with-prefix('list')} {
69
+ margin-block-start: 0;
70
+ }
71
+
72
+ .#{with-prefix('ul')} {
73
+ /* override carbon remove hanging bullet */
74
+ /* stylelint-disable-next-line declaration-no-important */
75
+ margin-inline-start: spacing.$spacing-05 !important;
76
+ }
77
+
78
+ .#{with-prefix('ol')} {
79
+ /* override carbon remove hanging bullet */
80
+ /* stylelint-disable-next-line declaration-no-important */
81
+ margin-inline-start: spacing.$spacing-06 !important;
82
+ }
83
+
84
+ /* Headings */
85
+ .#{with-prefix('h1')} {
86
+ @include type.type-style('fluid-heading-05', true);
87
+ }
88
+
89
+ .#{with-prefix('h2')} {
90
+ @include type.type-style('fluid-heading-04', true);
91
+ }
92
+
93
+ .#{with-prefix('h3')} {
94
+ @include type.type-style('fluid-heading-03', true);
95
+ }
96
+
97
+ .#{with-prefix('h4')} {
98
+ @include type.type-style('heading-02');
99
+ }
100
+
101
+ .#{with-prefix('h5')},
102
+ .#{with-prefix('h6')} {
103
+ @include type.type-style('heading-01');
104
+ }
105
+
106
+ /* Paragraph */
107
+ .#{with-prefix('paragraph')} {
108
+ @include type.type-style('body-long-02');
109
+ }
110
+
111
+ .#{with-prefix('paragraph--large')} {
112
+ @include type.type-style('fluid-heading-03', true);
113
+ }
114
+
115
+ /* Blockquote */
116
+ .#{with-prefix('blockquote')} {
117
+ margin: spacing.$spacing-08 0;
118
+ margin-inline-start: spacing.$spacing-05;
119
+ padding-inline-start: 1ch;
120
+
121
+ @include breakpoint.breakpoint('md') {
122
+ margin-inline-start: spacing.$spacing-08;
123
+ }
124
+ }
125
+
126
+ .#{with-prefix('blockquote')} .#{with-prefix('paragraph')} {
127
+ @include type.type-style('fluid-heading-03', true);
128
+
129
+ font-style: italic;
130
+ }
131
+
132
+ .#{with-prefix('blockquote')} cite {
133
+ @include type.type-style('body-long-01');
134
+
135
+ display: block;
136
+ font-style: italic;
137
+ margin-block-start: spacing.$spacing-02;
138
+ padding-inline-start: spacing.$spacing-07;
139
+ text-indent: 0;
140
+ }
@@ -0,0 +1,57 @@
1
+ /*
2
+ * Copyright OctaviaFlow 2022, 2025
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/theme' as theme;
9
+ @use '@carbon/react/scss/spacing' as spacing;
10
+ @use '@carbon/react/scss/breakpoint' as breakpoint;
11
+
12
+ @use '../../utils' as *;
13
+
14
+ .#{with-prefix('header')} {
15
+ position: relative;
16
+
17
+ .#{with-prefix('anchor')} {
18
+ opacity: 0;
19
+
20
+ transition: opacity motion.$duration-fast-01 motion.$standard-easing;
21
+
22
+ &:hover,
23
+ &:active,
24
+ &:focus {
25
+ opacity: 1;
26
+ }
27
+
28
+ &:focus {
29
+ outline: 2px solid theme.$focus;
30
+ }
31
+
32
+ svg {
33
+ fill: theme.$link-primary;
34
+ }
35
+
36
+ @media screen and (prefers-reduced-motion: reduce) {
37
+ transition: none;
38
+ }
39
+ }
40
+
41
+ .#{with-prefix('left-anchor')} {
42
+ position: absolute;
43
+ inset-block-start: 0;
44
+ inset-inline-start: calc(#{spacing.$spacing-06} * -1);
45
+ }
46
+
47
+ .#{with-prefix('right-anchor')} {
48
+ margin-inline-start: spacing.$spacing-03;
49
+ white-space: nowrap;
50
+ }
51
+
52
+ &:hover .#{with-prefix('anchor')} {
53
+ @include breakpoint.breakpoint('md') {
54
+ opacity: 1;
55
+ }
56
+ }
57
+ }
@@ -0,0 +1,107 @@
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 { Link } from "@octaviaflow/icons-react";
17
+ import { clsx } from "clsx";
18
+ import PropTypes from "prop-types";
19
+ import React, { ReactNode } from "react";
20
+ import slugify from "slugify";
21
+
22
+ import { MdxComponent } from "../../interfaces";
23
+ import { mediaQueries, useMatchMedia, withPrefix } from "../../utils";
24
+
25
+ interface AutolinkHeaderProps {
26
+ is: "h1" | "h2" | "h3" | "h4" | "h5" | "h6";
27
+ className?: string | null;
28
+ children: ReactNode;
29
+ [otherProp: string]: unknown;
30
+ }
31
+
32
+ const Anchor = ({
33
+ id,
34
+ ariaLabel,
35
+ position,
36
+ }: {
37
+ id: string;
38
+ ariaLabel: string;
39
+ position: "left" | "right";
40
+ }) => {
41
+ const anchorClasses = clsx(withPrefix("anchor"), {
42
+ [withPrefix("left-anchor")]: position === "left",
43
+ [withPrefix("right-anchor")]: position === "right",
44
+ });
45
+
46
+ return (
47
+ <a
48
+ className={anchorClasses}
49
+ href={`#${id}`}
50
+ aria-label={`${ariaLabel} permalink`}
51
+ >
52
+ <Link size={20} />
53
+ </a>
54
+ );
55
+ };
56
+
57
+ const AutolinkHeader: MdxComponent<AutolinkHeaderProps> = ({
58
+ is: Component,
59
+ className,
60
+ children,
61
+ ...props
62
+ }) => {
63
+ const isSm = useMatchMedia(mediaQueries.sm);
64
+
65
+ const ariaLabel = React.Children.toArray(children).join("");
66
+
67
+ const id = `${slugify(ariaLabel, { lower: true })}`;
68
+
69
+ const anchorPosition = () => (isSm ? "left" : "right");
70
+
71
+ return (
72
+ <Component
73
+ className={clsx(withPrefix("header"), className)}
74
+ {...props}
75
+ id={id}
76
+ >
77
+ {children}
78
+ <Anchor id={id} ariaLabel={ariaLabel} position={anchorPosition()} />
79
+ </Component>
80
+ );
81
+ };
82
+
83
+ AutolinkHeader.propTypes = {
84
+ /**
85
+ * String title for Header
86
+ */
87
+ children: PropTypes.node as unknown as React.Validator<React.ReactNode>,
88
+ /**
89
+ * Specify optional className
90
+ */
91
+ className: PropTypes.string,
92
+ /**
93
+ * is: element to render as
94
+ */
95
+ is: PropTypes.oneOf<AutolinkHeaderProps["is"]>([
96
+ "h1",
97
+ "h2",
98
+ "h3",
99
+ "h4",
100
+ "h5",
101
+ "h6",
102
+ ]).isRequired,
103
+ };
104
+
105
+ AutolinkHeader.defaultProps = { is: "h2" };
106
+
107
+ export default AutolinkHeader;
@@ -0,0 +1,38 @@
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 { Blockquote } from "./blockquote";
18
+ import { P } from "./p";
19
+
20
+ export default {
21
+ title: "Components/MDX Components/Markdown/Blockquote",
22
+ component: Blockquote,
23
+ };
24
+
25
+ const Template = (args) => (
26
+ <Blockquote {...args}>
27
+ <P>
28
+ Without aesthetic, design is either the humdrum repetition of familiar
29
+ clichés or a wild scramble for novelty. Without aesthetic, the computer is
30
+ but a mindless speed machine, producing effects without substance, form
31
+ without relevant content, or content without meaningful form.
32
+ </P>
33
+ <cite>– Paul Rand</cite>
34
+ </Blockquote>
35
+ );
36
+
37
+ export const Default = Template.bind({});
38
+ Default.args = {};
@@ -0,0 +1,53 @@
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 { clsx } from "clsx";
17
+ import PropTypes from "prop-types";
18
+ import React from "react";
19
+
20
+ import { MdxComponent } from "../interfaces";
21
+ import { withPrefix } from "../utils";
22
+
23
+ interface BlockquoteProps {
24
+ className?: string | null;
25
+ [otherProp: string]: unknown;
26
+ }
27
+
28
+ /**
29
+ * For MDX files, steer away from using JSX components
30
+ * for blockquote in favor of standard markdown syntax.
31
+ *
32
+ *```
33
+ * > Without aesthetic, design is either the humdrum repetition of familiar clichés
34
+ * > or a wild scramble for novelty. Without aesthetic, the computer is but a
35
+ * > mindless speed machine, producing effects without substance, form without
36
+ * > relevant content, or content without meaningful form.
37
+ * >
38
+ * > <cite>– Paul Rand</cite>
39
+ * ```
40
+ */
41
+ export const Blockquote: MdxComponent<BlockquoteProps> = ({
42
+ className,
43
+ ...rest
44
+ }) => (
45
+ <blockquote className={clsx(className, withPrefix("blockquote"))} {...rest} />
46
+ );
47
+
48
+ Blockquote.propTypes = {
49
+ /**
50
+ * Specify optional className for container element
51
+ */
52
+ className: PropTypes.string,
53
+ };