@fluentui/react-storybook-addon 0.4.6 → 0.5.1

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 (87) hide show
  1. package/CHANGELOG.md +39 -10
  2. package/dist/index.d.ts +79 -0
  3. package/lib/components/DirectionSwitch.js +26 -0
  4. package/lib/components/DirectionSwitch.js.map +1 -0
  5. package/lib/components/ReactStrictMode.js +23 -0
  6. package/lib/components/ReactStrictMode.js.map +1 -0
  7. package/lib/components/ThemePicker.js +61 -0
  8. package/lib/components/ThemePicker.js.map +1 -0
  9. package/lib/constants.js +4 -0
  10. package/lib/constants.js.map +1 -0
  11. package/lib/decorators/withAriaLive.js +18 -0
  12. package/lib/decorators/withAriaLive.js.map +1 -0
  13. package/lib/decorators/withFluentProvider.js +48 -0
  14. package/lib/decorators/withFluentProvider.js.map +1 -0
  15. package/lib/decorators/withReactStrictMode.js +16 -0
  16. package/lib/decorators/withReactStrictMode.js.map +1 -0
  17. package/lib/docs/CopyAsMarkdownButton.js +177 -0
  18. package/lib/docs/CopyAsMarkdownButton.js.map +1 -0
  19. package/lib/docs/DirSwitch.js +51 -0
  20. package/lib/docs/DirSwitch.js.map +1 -0
  21. package/lib/docs/FluentDocsContainer.js +24 -0
  22. package/lib/docs/FluentDocsContainer.js.map +1 -0
  23. package/lib/docs/FluentDocsPage.js +294 -0
  24. package/lib/docs/FluentDocsPage.js.map +1 -0
  25. package/lib/docs/ThemePicker.js +61 -0
  26. package/lib/docs/ThemePicker.js.map +1 -0
  27. package/lib/docs/Toc.js +130 -0
  28. package/lib/docs/Toc.js.map +1 -0
  29. package/lib/docs/index.js +2 -0
  30. package/lib/docs/index.js.map +1 -0
  31. package/lib/docs/utils.js +74 -0
  32. package/lib/docs/utils.js.map +1 -0
  33. package/lib/hooks.js +16 -0
  34. package/lib/hooks.js.map +1 -0
  35. package/lib/index.js +3 -0
  36. package/lib/index.js.map +1 -0
  37. package/lib/preset/manager.js +28 -0
  38. package/lib/preset/manager.js.map +1 -0
  39. package/lib/preset/preview.js +26 -0
  40. package/lib/preset/preview.js.map +1 -0
  41. package/lib/theme.js +31 -0
  42. package/lib/theme.js.map +1 -0
  43. package/lib/utils/isDecoratorDisabled.js +6 -0
  44. package/lib/utils/isDecoratorDisabled.js.map +1 -0
  45. package/lib-commonjs/components/DirectionSwitch.js +37 -0
  46. package/lib-commonjs/components/DirectionSwitch.js.map +1 -0
  47. package/lib-commonjs/components/ReactStrictMode.js +34 -0
  48. package/lib-commonjs/components/ReactStrictMode.js.map +1 -0
  49. package/lib-commonjs/components/ThemePicker.js +72 -0
  50. package/lib-commonjs/components/ThemePicker.js.map +1 -0
  51. package/lib-commonjs/constants.js +28 -0
  52. package/lib-commonjs/constants.js.map +1 -0
  53. package/lib-commonjs/decorators/withAriaLive.js +29 -0
  54. package/lib-commonjs/decorators/withAriaLive.js.map +1 -0
  55. package/lib-commonjs/decorators/withFluentProvider.js +59 -0
  56. package/lib-commonjs/decorators/withFluentProvider.js.map +1 -0
  57. package/lib-commonjs/decorators/withReactStrictMode.js +27 -0
  58. package/lib-commonjs/decorators/withReactStrictMode.js.map +1 -0
  59. package/lib-commonjs/docs/CopyAsMarkdownButton.js +185 -0
  60. package/lib-commonjs/docs/CopyAsMarkdownButton.js.map +1 -0
  61. package/lib-commonjs/docs/DirSwitch.js +60 -0
  62. package/lib-commonjs/docs/DirSwitch.js.map +1 -0
  63. package/lib-commonjs/docs/FluentDocsContainer.js +33 -0
  64. package/lib-commonjs/docs/FluentDocsContainer.js.map +1 -0
  65. package/lib-commonjs/docs/FluentDocsPage.js +305 -0
  66. package/lib-commonjs/docs/FluentDocsPage.js.map +1 -0
  67. package/lib-commonjs/docs/ThemePicker.js +70 -0
  68. package/lib-commonjs/docs/ThemePicker.js.map +1 -0
  69. package/lib-commonjs/docs/Toc.js +149 -0
  70. package/lib-commonjs/docs/Toc.js.map +1 -0
  71. package/lib-commonjs/docs/index.js +20 -0
  72. package/lib-commonjs/docs/index.js.map +1 -0
  73. package/lib-commonjs/docs/utils.js +88 -0
  74. package/lib-commonjs/docs/utils.js.map +1 -0
  75. package/lib-commonjs/hooks.js +37 -0
  76. package/lib-commonjs/hooks.js.map +1 -0
  77. package/lib-commonjs/index.js +27 -0
  78. package/lib-commonjs/index.js.map +1 -0
  79. package/lib-commonjs/preset/manager.js +32 -0
  80. package/lib-commonjs/preset/manager.js.map +1 -0
  81. package/lib-commonjs/preset/preview.js +47 -0
  82. package/lib-commonjs/preset/preview.js.map +1 -0
  83. package/lib-commonjs/theme.js +49 -0
  84. package/lib-commonjs/theme.js.map +1 -0
  85. package/lib-commonjs/utils/isDecoratorDisabled.js +16 -0
  86. package/lib-commonjs/utils/isDecoratorDisabled.js.map +1 -0
  87. package/package.json +14 -10
@@ -0,0 +1,185 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "CopyAsMarkdownButton", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return CopyAsMarkdownButton;
9
+ }
10
+ });
11
+ const _interop_require_wildcard = require("@swc/helpers/_/_interop_require_wildcard");
12
+ const _react = /*#__PURE__*/ _interop_require_wildcard._(require("react"));
13
+ const _reactbutton = require("@fluentui/react-button");
14
+ const _reactmenu = require("@fluentui/react-menu");
15
+ const _reactspinner = require("@fluentui/react-spinner");
16
+ const _reacttoast = require("@fluentui/react-toast");
17
+ const _reactutilities = require("@fluentui/react-utilities");
18
+ const _react1 = require("@griffel/react");
19
+ const _reacticons = require("@fluentui/react-icons");
20
+ const _reactsharedcontexts = require("@fluentui/react-shared-contexts");
21
+ const MarkdownIcon = (0, _reacticons.bundleIcon)(_reacticons.MarkdownFilled, _reacticons.MarkdownRegular);
22
+ const useStyles = (0, _react1.makeStyles)({
23
+ button: {
24
+ marginInlineStart: 'auto'
25
+ }
26
+ });
27
+ const CopyAsMarkdownButton = ({ storyId = '' })=>{
28
+ const { targetDocument } = (0, _reactsharedcontexts.useFluent_unstable)();
29
+ const targetWindow = targetDocument === null || targetDocument === void 0 ? void 0 : targetDocument.defaultView;
30
+ const styles = useStyles();
31
+ const toastId = (0, _reactutilities.useId)('copy-toast');
32
+ const toasterId = (0, _reactutilities.useId)('toaster');
33
+ const { dispatchToast, updateToast } = (0, _reacttoast.useToastController)(toasterId);
34
+ // Cache for the fetched markdown content to avoid redundant network requests
35
+ const markdownContentCache = _react.useRef(null);
36
+ // AbortController to track and cancel fetch requests
37
+ const abortControllerRef = _react.useRef(null);
38
+ // Full URL to the markdown endpoint for this story
39
+ const markdownUrl = _react.useMemo(()=>{
40
+ return targetWindow ? convertStoryIdToMarkdownUrl(targetWindow, storyId) : '';
41
+ }, [
42
+ storyId,
43
+ targetWindow
44
+ ]);
45
+ // Cleanup: abort pending requests on unmount
46
+ _react.useEffect(()=>{
47
+ return ()=>{
48
+ var _abortControllerRef_current;
49
+ (_abortControllerRef_current = abortControllerRef.current) === null || _abortControllerRef_current === void 0 ? void 0 : _abortControllerRef_current.abort();
50
+ };
51
+ }, []);
52
+ /**
53
+ * Fetches the markdown content (with caching) and copies it to the clipboard.
54
+ * Shows a toast notification with loading, success, or error states.
55
+ * Skips the request if one is already in progress.
56
+ */ const copyPageContentToClipboard = _react.useCallback(async ()=>{
57
+ // Skip if a request is already in progress (abort controller exists and not aborted)
58
+ if (abortControllerRef.current && !abortControllerRef.current.signal.aborted) {
59
+ return;
60
+ }
61
+ // Ensure we have a window context to use for clipboard and fetch
62
+ if (!targetWindow) {
63
+ return;
64
+ }
65
+ // Create new AbortController for this request
66
+ const abortController = new AbortController();
67
+ abortControllerRef.current = abortController;
68
+ // Show loading toast that persists until updated
69
+ dispatchToast(/*#__PURE__*/ _react.createElement(_reacttoast.Toast, null, /*#__PURE__*/ _react.createElement(_reacttoast.ToastTitle, {
70
+ media: /*#__PURE__*/ _react.createElement(_reactspinner.Spinner, null)
71
+ }, "Copying page content...")), {
72
+ toastId,
73
+ intent: 'info',
74
+ timeout: -1
75
+ });
76
+ try {
77
+ // Use cached content if available, otherwise fetch from API
78
+ if (!markdownContentCache.current) {
79
+ markdownContentCache.current = await fetchMarkdownContent(targetWindow, markdownUrl, abortController.signal);
80
+ }
81
+ // Copy to clipboard
82
+ await (targetWindow === null || targetWindow === void 0 ? void 0 : targetWindow.navigator.clipboard.writeText(markdownContentCache.current));
83
+ // Update toast to success
84
+ updateToast({
85
+ content: /*#__PURE__*/ _react.createElement(_reacttoast.Toast, null, /*#__PURE__*/ _react.createElement(_reacttoast.ToastTitle, null, "Page content copied to clipboard!")),
86
+ intent: 'success',
87
+ toastId,
88
+ timeout: 3000
89
+ });
90
+ } catch (error) {
91
+ // Don't show error if request was aborted
92
+ if (abortController.signal.aborted) {
93
+ return;
94
+ }
95
+ const errorMessage = error instanceof Error ? error.message : String(error);
96
+ // Update toast to error
97
+ updateToast({
98
+ content: /*#__PURE__*/ _react.createElement(_reacttoast.Toast, null, /*#__PURE__*/ _react.createElement(_reacttoast.ToastTitle, null, "Failed to copy page content: ", errorMessage)),
99
+ intent: 'error',
100
+ toastId,
101
+ timeout: 3000
102
+ });
103
+ } finally{
104
+ // Clear the abort controller ref to allow new requests
105
+ abortControllerRef.current = null;
106
+ }
107
+ }, [
108
+ dispatchToast,
109
+ updateToast,
110
+ toastId,
111
+ markdownUrl,
112
+ targetWindow
113
+ ]);
114
+ /** Opens the markdown content in a new browser tab */ const openInNewTab = _react.useCallback(()=>{
115
+ targetWindow === null || targetWindow === void 0 ? void 0 : targetWindow.open(markdownUrl, '_blank');
116
+ }, [
117
+ markdownUrl,
118
+ targetWindow
119
+ ]);
120
+ if (!storyId) {
121
+ return null;
122
+ }
123
+ return /*#__PURE__*/ _react.createElement(_react.Fragment, null, /*#__PURE__*/ _react.createElement(_reactmenu.Menu, {
124
+ positioning: "below-end"
125
+ }, /*#__PURE__*/ _react.createElement(_reactmenu.MenuTrigger, {
126
+ disableButtonEnhancement: true
127
+ }, (triggerProps)=>/*#__PURE__*/ _react.createElement(_reactbutton.SplitButton, {
128
+ className: styles.button,
129
+ menuButton: triggerProps,
130
+ primaryActionButton: {
131
+ appearance: 'secondary',
132
+ icon: /*#__PURE__*/ _react.createElement(MarkdownIcon, null),
133
+ onClick: copyPageContentToClipboard,
134
+ 'aria-label': 'Copy page content as markdown to clipboard'
135
+ },
136
+ "aria-label": "Copy page as markdown"
137
+ }, "Copy Page")), /*#__PURE__*/ _react.createElement(_reactmenu.MenuPopover, null, /*#__PURE__*/ _react.createElement(_reactmenu.MenuList, null, /*#__PURE__*/ _react.createElement(_reactmenu.MenuItem, {
138
+ icon: /*#__PURE__*/ _react.createElement(MarkdownIcon, null),
139
+ onClick: openInNewTab
140
+ }, "View as Markdown")))), /*#__PURE__*/ _react.createElement(_reacttoast.Toaster, {
141
+ toasterId: toasterId
142
+ }));
143
+ };
144
+ /**
145
+ * Regex pattern to remove the story variant suffix from Storybook story IDs.
146
+ * @example "button--primary" -> "button"
147
+ */ const STORYBOOK_VARIANT_SUFFIX_PATTERN = /--\w+$/g;
148
+ /**
149
+ * Gets the base URL for fetching markdown content from the Storybook LLM endpoint.
150
+ * Each story's markdown is available at: {BASE_URL}/{storyId}.txt
151
+ * @param targetWindow - The window object to use for location access
152
+ * @returns The base URL constructed from current location origin and pathname
153
+ */ function getStorybookMarkdownApiBaseUrl(targetWindow) {
154
+ // Remove the [page].html file from pathname and append /llms/
155
+ const basePath = targetWindow.location.pathname.replace(/\/[^/]*\.html$/, '');
156
+ return `${targetWindow.location.origin}${basePath}/llms/`;
157
+ }
158
+ /**
159
+ * Converts a Storybook story ID to a markdown URL.
160
+ * @param targetWindow - The window object to use for location access
161
+ * @param storyId - The Storybook story ID
162
+ * @returns The full URL to the markdown endpoint for the story
163
+ * @example "button--primary" -> "https://storybooks.fluentui.dev/llms/button.txt"
164
+ */ function convertStoryIdToMarkdownUrl(targetWindow, storyId) {
165
+ return `${getStorybookMarkdownApiBaseUrl(targetWindow)}${storyId.replace(STORYBOOK_VARIANT_SUFFIX_PATTERN, '.txt')}`;
166
+ }
167
+ /**
168
+ * Fetches markdown content from the Storybook API.
169
+ * @param targetWindow - The window object to use for fetch access
170
+ * @param url - The URL to fetch markdown content from
171
+ * @param signal - Optional AbortSignal to cancel the request
172
+ * @returns Promise resolving to the markdown text content
173
+ * @throws Error if the fetch request fails or is aborted
174
+ */ async function fetchMarkdownContent(targetWindow, url, signal) {
175
+ const response = await targetWindow.fetch(url, {
176
+ headers: {
177
+ 'Content-Type': 'text/plain'
178
+ },
179
+ signal
180
+ });
181
+ if (!response.ok) {
182
+ throw new Error(`Failed to fetch markdown: ${response.status} ${response.statusText}`);
183
+ }
184
+ return response.text();
185
+ }
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/docs/CopyAsMarkdownButton.tsx"],"sourcesContent":["import * as React from 'react';\nimport { SplitButton, type MenuButtonProps } from '@fluentui/react-button';\nimport { Menu, MenuItem, MenuList, MenuPopover, MenuTrigger } from '@fluentui/react-menu';\nimport { Spinner } from '@fluentui/react-spinner';\nimport { Toast, Toaster, ToastTitle, useToastController } from '@fluentui/react-toast';\nimport { useId } from '@fluentui/react-utilities';\nimport { makeStyles } from '@griffel/react';\nimport { bundleIcon, MarkdownFilled, MarkdownRegular } from '@fluentui/react-icons';\nimport { useFluent_unstable as useFluent } from '@fluentui/react-shared-contexts';\n\nconst MarkdownIcon = bundleIcon(MarkdownFilled, MarkdownRegular);\n\nconst useStyles = makeStyles({\n button: {\n marginInlineStart: 'auto',\n },\n});\n\nexport interface CopyAsMarkdownProps {\n /** The Storybook story ID used to generate the markdown URL */\n storyId?: string;\n}\n\n/**\n * A button that allows users to copy the current page as markdown to their clipboard or view it in a new tab.\n * The markdown content is fetched from the Storybook API and cached for subsequent requests.\n */\nexport const CopyAsMarkdownButton: React.FC<CopyAsMarkdownProps> = ({ storyId = '' }) => {\n const { targetDocument } = useFluent();\n const targetWindow = targetDocument?.defaultView;\n const styles = useStyles();\n const toastId = useId('copy-toast');\n const toasterId = useId('toaster');\n const { dispatchToast, updateToast } = useToastController(toasterId);\n\n // Cache for the fetched markdown content to avoid redundant network requests\n const markdownContentCache = React.useRef<string | null>(null);\n\n // AbortController to track and cancel fetch requests\n const abortControllerRef = React.useRef<AbortController | null>(null);\n\n // Full URL to the markdown endpoint for this story\n const markdownUrl = React.useMemo(() => {\n return targetWindow ? convertStoryIdToMarkdownUrl(targetWindow, storyId) : '';\n }, [storyId, targetWindow]);\n\n // Cleanup: abort pending requests on unmount\n React.useEffect(() => {\n return () => {\n abortControllerRef.current?.abort();\n };\n }, []);\n\n /**\n * Fetches the markdown content (with caching) and copies it to the clipboard.\n * Shows a toast notification with loading, success, or error states.\n * Skips the request if one is already in progress.\n */\n const copyPageContentToClipboard = React.useCallback(async () => {\n // Skip if a request is already in progress (abort controller exists and not aborted)\n if (abortControllerRef.current && !abortControllerRef.current.signal.aborted) {\n return;\n }\n\n // Ensure we have a window context to use for clipboard and fetch\n if (!targetWindow) {\n return;\n }\n\n // Create new AbortController for this request\n const abortController = new AbortController();\n abortControllerRef.current = abortController;\n\n // Show loading toast that persists until updated\n dispatchToast(\n <Toast>\n <ToastTitle media={<Spinner />}>Copying page content...</ToastTitle>\n </Toast>,\n {\n toastId,\n intent: 'info',\n timeout: -1, // Never auto-dismiss\n },\n );\n\n try {\n // Use cached content if available, otherwise fetch from API\n if (!markdownContentCache.current) {\n markdownContentCache.current = await fetchMarkdownContent(targetWindow, markdownUrl, abortController.signal);\n }\n\n // Copy to clipboard\n await targetWindow?.navigator.clipboard.writeText(markdownContentCache.current);\n\n // Update toast to success\n updateToast({\n content: (\n <Toast>\n <ToastTitle>Page content copied to clipboard!</ToastTitle>\n </Toast>\n ),\n intent: 'success',\n toastId,\n timeout: 3000,\n });\n } catch (error) {\n // Don't show error if request was aborted\n if (abortController.signal.aborted) {\n return;\n }\n\n const errorMessage = error instanceof Error ? error.message : String(error);\n\n // Update toast to error\n updateToast({\n content: (\n <Toast>\n <ToastTitle>Failed to copy page content: {errorMessage}</ToastTitle>\n </Toast>\n ),\n intent: 'error',\n toastId,\n timeout: 3000,\n });\n } finally {\n // Clear the abort controller ref to allow new requests\n abortControllerRef.current = null;\n }\n }, [dispatchToast, updateToast, toastId, markdownUrl, targetWindow]);\n\n /** Opens the markdown content in a new browser tab */\n const openInNewTab = React.useCallback(() => {\n targetWindow?.open(markdownUrl, '_blank');\n }, [markdownUrl, targetWindow]);\n\n if (!storyId) {\n return null;\n }\n\n return (\n <>\n <Menu positioning=\"below-end\">\n <MenuTrigger disableButtonEnhancement>\n {(triggerProps: MenuButtonProps) => (\n <SplitButton\n className={styles.button}\n menuButton={triggerProps}\n primaryActionButton={{\n appearance: 'secondary',\n icon: <MarkdownIcon />,\n onClick: copyPageContentToClipboard,\n 'aria-label': 'Copy page content as markdown to clipboard',\n }}\n aria-label=\"Copy page as markdown\"\n >\n Copy Page\n </SplitButton>\n )}\n </MenuTrigger>\n\n <MenuPopover>\n <MenuList>\n <MenuItem icon={<MarkdownIcon />} onClick={openInNewTab}>\n View as Markdown\n </MenuItem>\n </MenuList>\n </MenuPopover>\n </Menu>\n <Toaster toasterId={toasterId} />\n </>\n );\n};\n\n/**\n * Regex pattern to remove the story variant suffix from Storybook story IDs.\n * @example \"button--primary\" -> \"button\"\n */\nconst STORYBOOK_VARIANT_SUFFIX_PATTERN = /--\\w+$/g;\n\n/**\n * Gets the base URL for fetching markdown content from the Storybook LLM endpoint.\n * Each story's markdown is available at: {BASE_URL}/{storyId}.txt\n * @param targetWindow - The window object to use for location access\n * @returns The base URL constructed from current location origin and pathname\n */\nfunction getStorybookMarkdownApiBaseUrl(targetWindow: Window): string {\n // Remove the [page].html file from pathname and append /llms/\n const basePath = targetWindow.location.pathname.replace(/\\/[^/]*\\.html$/, '');\n return `${targetWindow.location.origin}${basePath}/llms/`;\n}\n\n/**\n * Converts a Storybook story ID to a markdown URL.\n * @param targetWindow - The window object to use for location access\n * @param storyId - The Storybook story ID\n * @returns The full URL to the markdown endpoint for the story\n * @example \"button--primary\" -> \"https://storybooks.fluentui.dev/llms/button.txt\"\n */\nfunction convertStoryIdToMarkdownUrl(targetWindow: Window, storyId: string): string {\n return `${getStorybookMarkdownApiBaseUrl(targetWindow)}${storyId.replace(STORYBOOK_VARIANT_SUFFIX_PATTERN, '.txt')}`;\n}\n\n/**\n * Fetches markdown content from the Storybook API.\n * @param targetWindow - The window object to use for fetch access\n * @param url - The URL to fetch markdown content from\n * @param signal - Optional AbortSignal to cancel the request\n * @returns Promise resolving to the markdown text content\n * @throws Error if the fetch request fails or is aborted\n */\nasync function fetchMarkdownContent(\n targetWindow: Window,\n url: string,\n signal: AbortSignal | undefined,\n): Promise<string> {\n const response = await targetWindow.fetch(url, {\n headers: {\n 'Content-Type': 'text/plain',\n },\n signal,\n });\n\n if (!response.ok) {\n throw new Error(`Failed to fetch markdown: ${response.status} ${response.statusText}`);\n }\n\n return response.text();\n}\n"],"names":["CopyAsMarkdownButton","MarkdownIcon","bundleIcon","MarkdownFilled","MarkdownRegular","useStyles","makeStyles","button","marginInlineStart","storyId","targetDocument","useFluent","targetWindow","defaultView","styles","toastId","useId","toasterId","dispatchToast","updateToast","useToastController","markdownContentCache","React","useRef","abortControllerRef","markdownUrl","useMemo","convertStoryIdToMarkdownUrl","useEffect","current","abort","copyPageContentToClipboard","useCallback","signal","aborted","abortController","AbortController","Toast","ToastTitle","media","Spinner","intent","timeout","fetchMarkdownContent","navigator","clipboard","writeText","content","error","errorMessage","Error","message","String","openInNewTab","open","Menu","positioning","MenuTrigger","disableButtonEnhancement","triggerProps","SplitButton","className","menuButton","primaryActionButton","appearance","icon","onClick","aria-label","MenuPopover","MenuList","MenuItem","Toaster","STORYBOOK_VARIANT_SUFFIX_PATTERN","getStorybookMarkdownApiBaseUrl","basePath","location","pathname","replace","origin","url","response","fetch","headers","ok","status","statusText","text"],"mappings":"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"}
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "DirSwitch", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return DirSwitch;
9
+ }
10
+ });
11
+ const _interop_require_wildcard = require("@swc/helpers/_/_interop_require_wildcard");
12
+ const _react = /*#__PURE__*/ _interop_require_wildcard._(require("react"));
13
+ const _previewapi = require("@storybook/preview-api");
14
+ const _reactlabel = require("@fluentui/react-label");
15
+ const _reactswitch = require("@fluentui/react-switch");
16
+ const _reactutilities = require("@fluentui/react-utilities");
17
+ const _reacttheme = require("@fluentui/react-theme");
18
+ const _react1 = require("@griffel/react");
19
+ const _constants = require("../constants");
20
+ const useStyles = (0, _react1.makeStyles)({
21
+ container: {
22
+ alignItems: 'center',
23
+ display: 'flex',
24
+ justifyContent: 'start'
25
+ },
26
+ label: {
27
+ ..._reacttheme.typographyStyles.subtitle2
28
+ }
29
+ });
30
+ const DirSwitch = ({ dir })=>{
31
+ const switchId = (0, _reactutilities.useId)('dir-switch');
32
+ const styles = useStyles();
33
+ const [currentDir, setCurrentDir] = _react.useState(dir);
34
+ const checked = currentDir === 'rtl';
35
+ const setGlobalDir = (newDir)=>{
36
+ _previewapi.addons.getChannel().emit('updateGlobals', {
37
+ globals: {
38
+ [_constants.DIR_ID]: newDir
39
+ }
40
+ });
41
+ };
42
+ const onChange = _react.useCallback((_, data)=>{
43
+ const newDir = data.checked ? 'rtl' : 'ltr';
44
+ setGlobalDir(newDir);
45
+ setCurrentDir(newDir);
46
+ }, []);
47
+ return /*#__PURE__*/ _react.createElement("div", {
48
+ className: styles.container
49
+ }, /*#__PURE__*/ _react.createElement(_reactlabel.Label, {
50
+ className: styles.label,
51
+ htmlFor: currentDir === 'ltr' ? undefined : switchId
52
+ }, "LTR"), /*#__PURE__*/ _react.createElement(_reactswitch.Switch, {
53
+ checked: checked,
54
+ id: switchId,
55
+ onChange: onChange
56
+ }), /*#__PURE__*/ _react.createElement(_reactlabel.Label, {
57
+ className: styles.label,
58
+ htmlFor: currentDir === 'rtl' ? switchId : undefined
59
+ }, "RTL"));
60
+ };
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/docs/DirSwitch.tsx"],"sourcesContent":["import * as React from 'react';\nimport { addons } from '@storybook/preview-api';\n\nimport { Label } from '@fluentui/react-label';\nimport { Switch, type SwitchProps } from '@fluentui/react-switch';\nimport { useId } from '@fluentui/react-utilities';\nimport { typographyStyles } from '@fluentui/react-theme';\nimport { makeStyles } from '@griffel/react';\n\nimport { DIR_ID } from '../constants';\n\nconst useStyles = makeStyles({\n container: {\n alignItems: 'center',\n display: 'flex',\n justifyContent: 'start',\n },\n label: {\n ...typographyStyles.subtitle2,\n },\n});\n\n/**\n * Dir switch used in the react-components docs header\n */\nexport const DirSwitch: React.FC<{ dir?: 'ltr' | 'rtl' }> = ({ dir }) => {\n const switchId = useId('dir-switch');\n\n const styles = useStyles();\n\n const [currentDir, setCurrentDir] = React.useState(dir);\n const checked = currentDir === 'rtl';\n\n const setGlobalDir = (newDir: 'ltr' | 'rtl'): void => {\n addons.getChannel().emit('updateGlobals', { globals: { [DIR_ID]: newDir } });\n };\n\n const onChange = React.useCallback<NonNullable<SwitchProps['onChange']>>((_, data) => {\n const newDir = data.checked ? 'rtl' : 'ltr';\n setGlobalDir(newDir);\n setCurrentDir(newDir);\n }, []);\n\n return (\n <div className={styles.container}>\n <Label className={styles.label} htmlFor={currentDir === 'ltr' ? undefined : switchId}>\n LTR\n </Label>\n <Switch checked={checked} id={switchId} onChange={onChange} />\n <Label className={styles.label} htmlFor={currentDir === 'rtl' ? switchId : undefined}>\n RTL\n </Label>\n </div>\n );\n};\n"],"names":["DirSwitch","useStyles","makeStyles","container","alignItems","display","justifyContent","label","typographyStyles","subtitle2","dir","switchId","useId","styles","currentDir","setCurrentDir","React","useState","checked","setGlobalDir","newDir","addons","getChannel","emit","globals","DIR_ID","onChange","useCallback","_","data","div","className","Label","htmlFor","undefined","Switch","id"],"mappings":";;;;+BAyBaA;;;eAAAA;;;;iEAzBU;4BACA;4BAED;6BACmB;gCACnB;4BACW;wBACN;2BAEJ;AAEvB,MAAMC,YAAYC,IAAAA,kBAAU,EAAC;IAC3BC,WAAW;QACTC,YAAY;QACZC,SAAS;QACTC,gBAAgB;IAClB;IACAC,OAAO;QACL,GAAGC,4BAAgB,CAACC,SAAS;IAC/B;AACF;AAKO,MAAMT,YAA+C,CAAC,EAAEU,GAAG,EAAE;IAClE,MAAMC,WAAWC,IAAAA,qBAAK,EAAC;IAEvB,MAAMC,SAASZ;IAEf,MAAM,CAACa,YAAYC,cAAc,GAAGC,OAAMC,QAAQ,CAACP;IACnD,MAAMQ,UAAUJ,eAAe;IAE/B,MAAMK,eAAe,CAACC;QACpBC,kBAAM,CAACC,UAAU,GAAGC,IAAI,CAAC,iBAAiB;YAAEC,SAAS;gBAAE,CAACC,iBAAM,CAAC,EAAEL;YAAO;QAAE;IAC5E;IAEA,MAAMM,WAAWV,OAAMW,WAAW,CAAuC,CAACC,GAAGC;QAC3E,MAAMT,SAASS,KAAKX,OAAO,GAAG,QAAQ;QACtCC,aAAaC;QACbL,cAAcK;IAChB,GAAG,EAAE;IAEL,qBACE,qBAACU;QAAIC,WAAWlB,OAAOV,SAAS;qBAC9B,qBAAC6B,iBAAK;QAACD,WAAWlB,OAAON,KAAK;QAAE0B,SAASnB,eAAe,QAAQoB,YAAYvB;OAAU,sBAGtF,qBAACwB,mBAAM;QAACjB,SAASA;QAASkB,IAAIzB;QAAUe,UAAUA;sBAClD,qBAACM,iBAAK;QAACD,WAAWlB,OAAON,KAAK;QAAE0B,SAASnB,eAAe,QAAQH,WAAWuB;OAAW;AAK5F"}
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "FluentDocsContainer", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return FluentDocsContainer;
9
+ }
10
+ });
11
+ const _interop_require_wildcard = require("@swc/helpers/_/_interop_require_wildcard");
12
+ const _react = /*#__PURE__*/ _interop_require_wildcard._(require("react"));
13
+ const _addondocs = require("@storybook/addon-docs");
14
+ const _reacttheme = require("@fluentui/react-theme");
15
+ const _reactprovider = require("@fluentui/react-provider");
16
+ const _utils = require("./utils");
17
+ const FluentDocsContainer = ({ children, context })=>{
18
+ if ((0, _utils.isDocsEnabled)(context)) {
19
+ return /*#__PURE__*/ _react.createElement(_react.Fragment, null, /*#__PURE__*/ _react.createElement(_reactprovider.FluentProvider, {
20
+ className: "sb-unstyled",
21
+ style: {
22
+ backgroundColor: 'transparent'
23
+ },
24
+ theme: _reacttheme.webLightTheme
25
+ }, /*#__PURE__*/ _react.createElement(_addondocs.DocsContainer, {
26
+ context: context
27
+ }, children)));
28
+ }
29
+ // If docs container is not enabled, fall back to Storybook's default DocsContainer
30
+ return /*#__PURE__*/ _react.createElement(_addondocs.DocsContainer, {
31
+ context: context
32
+ }, children);
33
+ };
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/docs/FluentDocsContainer.tsx"],"sourcesContent":["import * as React from 'react';\nimport { DocsContainer, type DocsContextProps } from '@storybook/addon-docs';\nimport { webLightTheme } from '@fluentui/react-theme';\nimport { FluentProvider } from '@fluentui/react-provider';\n\nimport { isDocsEnabled } from './utils';\n\ninterface FluentDocsContainerProps {\n context: DocsContextProps;\n children: React.ReactNode;\n}\n\n/**\n * A container that wraps storybook's native docs container to add extra components to the docs experience\n */\nexport const FluentDocsContainer: React.FC<FluentDocsContainerProps> = ({ children, context }) => {\n if (isDocsEnabled(context)) {\n return (\n <>\n {/** TODO add table of contents */}\n <FluentProvider className=\"sb-unstyled\" style={{ backgroundColor: 'transparent' }} theme={webLightTheme}>\n <DocsContainer context={context}>{children}</DocsContainer>\n </FluentProvider>\n </>\n );\n }\n\n // If docs container is not enabled, fall back to Storybook's default DocsContainer\n return <DocsContainer context={context}>{children}</DocsContainer>;\n};\n"],"names":["FluentDocsContainer","children","context","isDocsEnabled","FluentProvider","className","style","backgroundColor","theme","webLightTheme","DocsContainer"],"mappings":";;;;+BAeaA;;;eAAAA;;;;iEAfU;2BAC8B;4BACvB;+BACC;uBAED;AAUvB,MAAMA,sBAA0D,CAAC,EAAEC,QAAQ,EAAEC,OAAO,EAAE;IAC3F,IAAIC,IAAAA,oBAAa,EAACD,UAAU;QAC1B,qBACE,0DAEE,qBAACE,6BAAc;YAACC,WAAU;YAAcC,OAAO;gBAAEC,iBAAiB;YAAc;YAAGC,OAAOC,yBAAa;yBACrG,qBAACC,wBAAa;YAACR,SAASA;WAAUD;IAI1C;IAEA,mFAAmF;IACnF,qBAAO,qBAACS,wBAAa;QAACR,SAASA;OAAUD;AAC3C"}
@@ -0,0 +1,305 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "FluentDocsPage", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return FluentDocsPage;
9
+ }
10
+ });
11
+ const _interop_require_wildcard = require("@swc/helpers/_/_interop_require_wildcard");
12
+ const _react = /*#__PURE__*/ _interop_require_wildcard._(require("react"));
13
+ const _addondocs = require("@storybook/addon-docs");
14
+ const _reacttheme = require("@fluentui/react-theme");
15
+ const _reactlink = require("@fluentui/react-link");
16
+ const _reacttext = require("@fluentui/react-text");
17
+ const _react1 = require("@griffel/react");
18
+ const _reacticons = require("@fluentui/react-icons");
19
+ const _constants = require("../constants");
20
+ const _theme = require("../theme");
21
+ const _utils = require("./utils");
22
+ const _DirSwitch = require("./DirSwitch");
23
+ const _ThemePicker = require("./ThemePicker");
24
+ const _Toc = require("./Toc");
25
+ const _CopyAsMarkdownButton = require("./CopyAsMarkdownButton");
26
+ const useStyles = (0, _react1.makeStyles)({
27
+ divider: {
28
+ height: '1px',
29
+ backgroundColor: '#e1dfdd',
30
+ border: '0px none',
31
+ margin: '48px 0px'
32
+ },
33
+ wrapper: {
34
+ display: 'flex',
35
+ gap: '16px'
36
+ },
37
+ toc: {
38
+ flexBasis: '200px',
39
+ flexShrink: 0,
40
+ [`@media screen and (max-width: 1000px)`]: {
41
+ display: 'none'
42
+ }
43
+ },
44
+ container: {
45
+ // without a width, this div grows wider than its parent
46
+ width: '200px',
47
+ flexGrow: 1
48
+ },
49
+ globalTogglesContainer: {
50
+ columnGap: _reacttheme.tokens.spacingHorizontalXXXL,
51
+ display: 'flex'
52
+ },
53
+ description: {
54
+ display: 'grid',
55
+ gridTemplateColumns: '1fr min-content'
56
+ },
57
+ additionalInfoWrapper: {
58
+ display: 'flex',
59
+ flexDirection: 'column',
60
+ gap: _reacttheme.tokens.spacingVerticalM
61
+ },
62
+ additionalInfo: {
63
+ display: 'flex',
64
+ flexDirection: 'column',
65
+ gap: _reacttheme.tokens.spacingVerticalM,
66
+ border: `1px solid ${_reacttheme.tokens.colorNeutralStroke1}`,
67
+ borderRadius: _reacttheme.tokens.borderRadiusMedium,
68
+ padding: _reacttheme.tokens.spacingHorizontalM,
69
+ margin: `0 ${_reacttheme.tokens.spacingHorizontalM}`
70
+ },
71
+ additionalInfoIcon: {
72
+ alignSelf: 'center',
73
+ color: _reacttheme.tokens.colorBrandForeground1,
74
+ fontSize: '24px',
75
+ marginRight: _reacttheme.tokens.spacingHorizontalM
76
+ },
77
+ additionalInfoMessage: {
78
+ display: 'flex',
79
+ flexDirection: 'row',
80
+ alignItems: 'center',
81
+ gap: _reacttheme.tokens.spacingVerticalXS
82
+ },
83
+ infoIcon: {
84
+ display: 'flex',
85
+ flexDirection: 'column',
86
+ gap: _reacttheme.tokens.spacingVerticalXS,
87
+ flex: 1
88
+ }
89
+ });
90
+ const useVideoClasses = (0, _react1.makeStyles)({
91
+ container: {
92
+ display: 'flex',
93
+ flexDirection: 'column',
94
+ gap: _reacttheme.tokens.spacingHorizontalMNudge
95
+ },
96
+ preview: {
97
+ borderRadius: _reacttheme.tokens.borderRadiusSmall,
98
+ display: 'flex',
99
+ flexDirection: 'column',
100
+ gap: _reacttheme.tokens.spacingHorizontalM,
101
+ padding: _reacttheme.tokens.spacingHorizontalM,
102
+ backgroundColor: _reacttheme.tokens.colorNeutralBackground2,
103
+ ':hover': {
104
+ backgroundColor: _reacttheme.tokens.colorNeutralBackground2Hover
105
+ }
106
+ },
107
+ image: {
108
+ width: '200px'
109
+ }
110
+ });
111
+ const VideoPreviews = (props)=>{
112
+ const { videos } = props;
113
+ const classes = useVideoClasses();
114
+ return /*#__PURE__*/ _react.createElement("div", {
115
+ className: classes.container
116
+ }, videos.map((video)=>/*#__PURE__*/ _react.createElement(_reactlink.Link, {
117
+ className: classes.preview,
118
+ href: video.href,
119
+ target: "_blank",
120
+ key: video.href
121
+ }, /*#__PURE__*/ _react.createElement("img", {
122
+ alt: `Video: ${video.preview}`,
123
+ src: video.preview,
124
+ className: classes.image
125
+ }), /*#__PURE__*/ _react.createElement(_reacttext.Text, null, video.title))));
126
+ };
127
+ const getNativeElementsList = (elements)=>{
128
+ const elementsArr = elements === null || elements === void 0 ? void 0 : elements.map((el, idx)=>[
129
+ /*#__PURE__*/ _react.createElement("code", {
130
+ key: idx
131
+ }, `<${el}>`),
132
+ idx !== elements.length - 1 ? ', ' : ' '
133
+ ]);
134
+ return /*#__PURE__*/ _react.createElement(_react.Fragment, null, elementsArr, elementsArr.length > 1 ? 'elements' : 'element');
135
+ };
136
+ const slotRegex = /as\?:\s*"([^"]+)"/;
137
+ /**
138
+ * NOTE: this function mutates original story argTypes including all story subcomponents if they are present
139
+ */ function withSlotEnhancer(story, options) {
140
+ var _story_argTypes_as_type, _story_argTypes_as;
141
+ const hasArgAsProp = options.nativePropsApi ? ((_story_argTypes_as = story.argTypes.as) === null || _story_argTypes_as === void 0 ? void 0 : (_story_argTypes_as_type = _story_argTypes_as.type) === null || _story_argTypes_as_type === void 0 ? void 0 : _story_argTypes_as_type.name) === 'enum' : false;
142
+ const argAsProp = hasArgAsProp ? story.argTypes.as.type.value : null;
143
+ let hasArgAsSlot = false;
144
+ const transformPropsWithSlotShorthand = (props)=>{
145
+ Object.entries(props).forEach(([key, argType])=>{
146
+ var _argType_type;
147
+ const value = argType === null || argType === void 0 ? void 0 : (_argType_type = argType.type) === null || _argType_type === void 0 ? void 0 : _argType_type.name;
148
+ const match = value.match(slotRegex);
149
+ // Transformation for Slot with `AlternateAs` specified (mutates DocGen Object reference)
150
+ if (match) {
151
+ props[key].type.name = `Slot<\"${match[1]}\">`;
152
+ } else if (value.includes('WithSlotShorthandValue')) {
153
+ props[key].type.name = `Slot`;
154
+ }
155
+ if (value.includes('Slot')) {
156
+ hasArgAsSlot = true;
157
+ }
158
+ });
159
+ };
160
+ const transformComponent = (component)=>{
161
+ var _component___docgenInfo;
162
+ const docGenProps = component === null || component === void 0 ? void 0 : (_component___docgenInfo = component.__docgenInfo) === null || _component___docgenInfo === void 0 ? void 0 : _component___docgenInfo.props;
163
+ if (docGenProps) {
164
+ transformPropsWithSlotShorthand(docGenProps);
165
+ }
166
+ };
167
+ const component = story.component;
168
+ const subcomponents = story.subcomponents;
169
+ if (options.slotsApi) {
170
+ transformComponent(component);
171
+ if (subcomponents) {
172
+ Object.values(subcomponents).forEach((subcomponent)=>{
173
+ transformComponent(subcomponent);
174
+ });
175
+ }
176
+ }
177
+ return {
178
+ component,
179
+ hasArgAsSlot,
180
+ hasArgAsProp,
181
+ argAsProp
182
+ };
183
+ }
184
+ const AdditionalApiDocs = ({ children })=>{
185
+ const styles = useStyles();
186
+ return /*#__PURE__*/ _react.createElement("div", {
187
+ className: styles.additionalInfo
188
+ }, /*#__PURE__*/ _react.createElement("div", {
189
+ className: styles.additionalInfoMessage
190
+ }, /*#__PURE__*/ _react.createElement(_reacticons.InfoFilled, {
191
+ className: styles.additionalInfoIcon
192
+ }), /*#__PURE__*/ _react.createElement("div", {
193
+ className: styles.infoIcon
194
+ }, children)));
195
+ };
196
+ const RenderArgsTable = ({ story, hideArgsTable, showSlotsApi, showNativePropsApi })=>{
197
+ const { component, hasArgAsProp, hasArgAsSlot, argAsProp } = withSlotEnhancer(story, {
198
+ slotsApi: showSlotsApi,
199
+ nativePropsApi: showNativePropsApi
200
+ });
201
+ const styles = useStyles();
202
+ return hideArgsTable ? null : /*#__PURE__*/ _react.createElement(_react.Fragment, null, /*#__PURE__*/ _react.createElement("div", {
203
+ className: styles.additionalInfoWrapper
204
+ }, hasArgAsProp && /*#__PURE__*/ _react.createElement(AdditionalApiDocs, null, /*#__PURE__*/ _react.createElement("p", null, /*#__PURE__*/ _react.createElement("b", null, "Native props are supported ", /*#__PURE__*/ _react.createElement("span", {
205
+ role: "presentation"
206
+ }, "🙌"), /*#__PURE__*/ _react.createElement("br", null)), /*#__PURE__*/ _react.createElement("span", null, "All HTML attributes native to the", getNativeElementsList(argAsProp), ", including all ", /*#__PURE__*/ _react.createElement("code", null, "aria-*"), " and ", /*#__PURE__*/ _react.createElement("code", null, "data-*"), ' ', "attributes, can be applied as native props on this component."))), hasArgAsSlot && /*#__PURE__*/ _react.createElement(AdditionalApiDocs, null, /*#__PURE__*/ _react.createElement("p", null, /*#__PURE__*/ _react.createElement("b", null, "Customizing components with slots ", /*#__PURE__*/ _react.createElement("span", {
207
+ role: "presentation"
208
+ }, "🙌")), /*#__PURE__*/ _react.createElement("br", null), /*#__PURE__*/ _react.createElement("span", null, "Slots in Fluent UI React components are designed to be modified or replaced, providing a flexible approach to customizing components. Each slot is exposed as a top-level prop and can be filled with primitive values, JSX/TSX, props objects, or render functions. This allows for more dynamic and reusable component structures, similar to slots in other frameworks.", ' ', /*#__PURE__*/ _react.createElement(_reactlink.Link, {
209
+ href: "/?path=/docs/concepts-developer-customizing-components-with-slots--docs"
210
+ }, "Customizing components with slots", ' '))))), /*#__PURE__*/ _react.createElement(_addondocs.ArgsTable, {
211
+ of: component
212
+ }));
213
+ };
214
+ const RenderPrimaryStory = ({ primaryStory, skipPrimaryStory })=>{
215
+ const styles = useStyles();
216
+ return skipPrimaryStory ? null : /*#__PURE__*/ _react.createElement(_react.Fragment, null, /*#__PURE__*/ _react.createElement("hr", {
217
+ className: styles.divider
218
+ }), /*#__PURE__*/ _react.createElement(_addondocs.HeaderMdx, {
219
+ as: "h3",
220
+ id: (0, _Toc.nameToHash)(primaryStory.name)
221
+ }, primaryStory.name), /*#__PURE__*/ _react.createElement(_addondocs.Primary, null));
222
+ };
223
+ const FluentDocsPage = ()=>{
224
+ var _primaryStoryContext_parameters, _primaryStoryContext_globals, _primaryStoryContext_parameters_docs, _primaryStoryContext_parameters1, _primaryStoryContext_parameters_docs1, _primaryStoryContext_parameters2, _primaryStoryContext_parameters3;
225
+ const context = _react.useContext(_addondocs.DocsContext);
226
+ // Get the fluent docs page configuration from context
227
+ const docsPageConfig = (0, _utils.getDocsPageConfig)(context);
228
+ const stories = context.componentStories();
229
+ const primaryStory = stories[0];
230
+ const primaryStoryContext = context.getStoryContext(primaryStory);
231
+ assertStoryMetaValues(primaryStory);
232
+ var _primaryStoryContext_parameters_dir, _ref;
233
+ const dir = (_ref = (_primaryStoryContext_parameters_dir = (_primaryStoryContext_parameters = primaryStoryContext.parameters) === null || _primaryStoryContext_parameters === void 0 ? void 0 : _primaryStoryContext_parameters.dir) !== null && _primaryStoryContext_parameters_dir !== void 0 ? _primaryStoryContext_parameters_dir : (_primaryStoryContext_globals = primaryStoryContext.globals) === null || _primaryStoryContext_globals === void 0 ? void 0 : _primaryStoryContext_globals[_constants.DIR_ID]) !== null && _ref !== void 0 ? _ref : 'ltr';
234
+ const selectedTheme = _theme.themes.find((theme)=>theme.id === primaryStoryContext.globals[_constants.THEME_ID]);
235
+ const hideArgsTable = Boolean((_primaryStoryContext_parameters1 = primaryStoryContext.parameters) === null || _primaryStoryContext_parameters1 === void 0 ? void 0 : (_primaryStoryContext_parameters_docs = _primaryStoryContext_parameters1.docs) === null || _primaryStoryContext_parameters_docs === void 0 ? void 0 : _primaryStoryContext_parameters_docs.hideArgsTable);
236
+ const skipPrimaryStory = Boolean((_primaryStoryContext_parameters2 = primaryStoryContext.parameters) === null || _primaryStoryContext_parameters2 === void 0 ? void 0 : (_primaryStoryContext_parameters_docs1 = _primaryStoryContext_parameters2.docs) === null || _primaryStoryContext_parameters_docs1 === void 0 ? void 0 : _primaryStoryContext_parameters_docs1.skipPrimaryStory);
237
+ var _primaryStoryContext_parameters_videos;
238
+ const videos = (_primaryStoryContext_parameters_videos = (_primaryStoryContext_parameters3 = primaryStoryContext.parameters) === null || _primaryStoryContext_parameters3 === void 0 ? void 0 : _primaryStoryContext_parameters3.videos) !== null && _primaryStoryContext_parameters_videos !== void 0 ? _primaryStoryContext_parameters_videos : null;
239
+ const styles = useStyles();
240
+ // If docs page is disabled, return Storybook's default docs page
241
+ if (!docsPageConfig) {
242
+ return /*#__PURE__*/ _react.createElement("div", {
243
+ className: "sb-unstyled"
244
+ }, /*#__PURE__*/ _react.createElement(_addondocs.Title, null), /*#__PURE__*/ _react.createElement(_addondocs.Subtitle, null), /*#__PURE__*/ _react.createElement(_addondocs.Description, null), /*#__PURE__*/ _react.createElement(RenderPrimaryStory, {
245
+ primaryStory: primaryStory,
246
+ skipPrimaryStory: skipPrimaryStory
247
+ }), /*#__PURE__*/ _react.createElement(RenderArgsTable, {
248
+ story: primaryStory,
249
+ hideArgsTable: hideArgsTable
250
+ }), /*#__PURE__*/ _react.createElement(_addondocs.Stories, null));
251
+ }
252
+ // Determine what to show based on configuration
253
+ const { tableOfContents: showTableOfContents, dirSwitcher: showDirSwitcher, themePicker: showThemePicker, copyAsMarkdown: showCopyAsMarkdown, argTable } = docsPageConfig;
254
+ // DEBUG
255
+ // console.log('FluentDocsPage', context);
256
+ // console.table(stories.map((s: StoreItem) => ({ id: s.id, kind: s.kind, name: s.name, story: s.story })));
257
+ // console.table(
258
+ // Object.values((context as any).argTypes).map(arg => ({
259
+ // name: arg.name,
260
+ // description: arg.description,
261
+ // type: arg.table?.type?.summary ?? '?',
262
+ // default: arg.table?.defaultValue?.summary ?? '-',
263
+ // })),
264
+ // );
265
+ return /*#__PURE__*/ _react.createElement("div", {
266
+ className: "sb-unstyled"
267
+ }, /*#__PURE__*/ _react.createElement(_addondocs.Title, null), /*#__PURE__*/ _react.createElement("div", {
268
+ className: styles.wrapper
269
+ }, /*#__PURE__*/ _react.createElement("div", {
270
+ className: styles.container
271
+ }, (showThemePicker || showDirSwitcher || showCopyAsMarkdown) && /*#__PURE__*/ _react.createElement("div", {
272
+ className: styles.globalTogglesContainer
273
+ }, showThemePicker && /*#__PURE__*/ _react.createElement(_ThemePicker.ThemePicker, {
274
+ selectedThemeId: selectedTheme === null || selectedTheme === void 0 ? void 0 : selectedTheme.id
275
+ }), showDirSwitcher && /*#__PURE__*/ _react.createElement(_DirSwitch.DirSwitch, {
276
+ dir: dir
277
+ }), showCopyAsMarkdown && /*#__PURE__*/ _react.createElement(_CopyAsMarkdownButton.CopyAsMarkdownButton, {
278
+ storyId: primaryStory.id
279
+ })), /*#__PURE__*/ _react.createElement(_addondocs.Subtitle, null), /*#__PURE__*/ _react.createElement("div", {
280
+ className: styles.description
281
+ }, /*#__PURE__*/ _react.createElement(_addondocs.Description, null), videos && /*#__PURE__*/ _react.createElement(VideoPreviews, {
282
+ videos: videos
283
+ })), /*#__PURE__*/ _react.createElement(RenderPrimaryStory, {
284
+ primaryStory: primaryStory,
285
+ skipPrimaryStory: skipPrimaryStory
286
+ }), /*#__PURE__*/ _react.createElement(RenderArgsTable, {
287
+ story: primaryStory,
288
+ hideArgsTable: hideArgsTable,
289
+ showSlotsApi: argTable.slotsApi,
290
+ showNativePropsApi: argTable.nativePropsApi
291
+ }), /*#__PURE__*/ _react.createElement(_addondocs.Stories, null)), showTableOfContents && /*#__PURE__*/ _react.createElement("div", {
292
+ className: styles.toc
293
+ }, /*#__PURE__*/ _react.createElement(_Toc.Toc, {
294
+ stories: stories
295
+ }))));
296
+ };
297
+ function assertStoryMetaValues(story) {
298
+ if (story.component === null) {
299
+ throw new Error([
300
+ '🚨 Invalid Story Meta declaration:',
301
+ `- primaryStory.component of componentId:${story.componentId} is "null"`,
302
+ '- to resolve this error, please update "component" property value in your story definition to reference a React Component or remove it if it is not needed.'
303
+ ].join('\n'));
304
+ }
305
+ }