@roadlittledawn/docs-design-system-react 0.3.0 → 0.4.0
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/dist/components/Tabs.d.ts +40 -0
- package/dist/components/Tabs.js +42 -0
- package/dist/components/Tabs.stories.d.ts +25 -0
- package/dist/components/Tabs.stories.js +89 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/styles.css +81 -0
- package/package.json +1 -1
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
interface TabsProps {
|
|
3
|
+
/** ID of the initially active tab */
|
|
4
|
+
defaultActiveTab?: string;
|
|
5
|
+
/** Controlled active tab ID */
|
|
6
|
+
activeTab?: string;
|
|
7
|
+
/** Callback when tab changes */
|
|
8
|
+
onTabChange?: (id: string) => void;
|
|
9
|
+
/** Tab content */
|
|
10
|
+
children: React.ReactNode;
|
|
11
|
+
/** Additional CSS classes */
|
|
12
|
+
className?: string;
|
|
13
|
+
}
|
|
14
|
+
export declare function Tabs({ defaultActiveTab, activeTab: controlledActiveTab, onTabChange, children, className, }: TabsProps): import("react/jsx-runtime").JSX.Element;
|
|
15
|
+
interface TabListProps {
|
|
16
|
+
/** Tab buttons */
|
|
17
|
+
children: React.ReactNode;
|
|
18
|
+
/** Additional CSS classes */
|
|
19
|
+
className?: string;
|
|
20
|
+
}
|
|
21
|
+
export declare function TabList({ children, className }: TabListProps): import("react/jsx-runtime").JSX.Element;
|
|
22
|
+
interface TabProps {
|
|
23
|
+
/** Unique identifier for this tab */
|
|
24
|
+
id: string;
|
|
25
|
+
/** Tab label */
|
|
26
|
+
children: React.ReactNode;
|
|
27
|
+
/** Additional CSS classes */
|
|
28
|
+
className?: string;
|
|
29
|
+
}
|
|
30
|
+
export declare function Tab({ id, children, className }: TabProps): import("react/jsx-runtime").JSX.Element;
|
|
31
|
+
interface TabPanelProps {
|
|
32
|
+
/** ID matching the corresponding Tab */
|
|
33
|
+
id: string;
|
|
34
|
+
/** Panel content */
|
|
35
|
+
children: React.ReactNode;
|
|
36
|
+
/** Additional CSS classes */
|
|
37
|
+
className?: string;
|
|
38
|
+
}
|
|
39
|
+
export declare function TabPanel({ id, children, className }: TabPanelProps): import("react/jsx-runtime").JSX.Element | null;
|
|
40
|
+
export {};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useState, createContext, useContext } from "react";
|
|
3
|
+
var TabsContext = createContext(null);
|
|
4
|
+
export function Tabs(_a) {
|
|
5
|
+
var defaultActiveTab = _a.defaultActiveTab, controlledActiveTab = _a.activeTab, onTabChange = _a.onTabChange, children = _a.children, _b = _a.className, className = _b === void 0 ? "" : _b;
|
|
6
|
+
var _c = useState(defaultActiveTab || ""), internalActiveTab = _c[0], setInternalActiveTab = _c[1];
|
|
7
|
+
var isControlled = controlledActiveTab !== undefined;
|
|
8
|
+
var activeTab = isControlled ? controlledActiveTab : internalActiveTab;
|
|
9
|
+
var setActiveTab = function (id) {
|
|
10
|
+
if (!isControlled) {
|
|
11
|
+
setInternalActiveTab(id);
|
|
12
|
+
}
|
|
13
|
+
onTabChange === null || onTabChange === void 0 ? void 0 : onTabChange(id);
|
|
14
|
+
};
|
|
15
|
+
return (_jsx(TabsContext.Provider, { value: { activeTab: activeTab, setActiveTab: setActiveTab }, children: _jsx("div", { className: "dds-tabs ".concat(className).trim(), children: children }) }));
|
|
16
|
+
}
|
|
17
|
+
export function TabList(_a) {
|
|
18
|
+
var children = _a.children, _b = _a.className, className = _b === void 0 ? "" : _b;
|
|
19
|
+
return (_jsx("div", { className: "dds-tabs-list ".concat(className).trim(), role: "tablist", children: children }));
|
|
20
|
+
}
|
|
21
|
+
export function Tab(_a) {
|
|
22
|
+
var id = _a.id, children = _a.children, _b = _a.className, className = _b === void 0 ? "" : _b;
|
|
23
|
+
var context = useContext(TabsContext);
|
|
24
|
+
if (!context) {
|
|
25
|
+
throw new Error("Tab must be used within Tabs component");
|
|
26
|
+
}
|
|
27
|
+
var activeTab = context.activeTab, setActiveTab = context.setActiveTab;
|
|
28
|
+
var isActive = activeTab === id;
|
|
29
|
+
return (_jsx("button", { className: "dds-tab ".concat(isActive ? "dds-tab-active" : "", " ").concat(className).trim(), onClick: function () { return setActiveTab(id); }, role: "tab", "aria-selected": isActive, "aria-controls": "panel-".concat(id), id: "tab-".concat(id), type: "button", children: children }));
|
|
30
|
+
}
|
|
31
|
+
export function TabPanel(_a) {
|
|
32
|
+
var id = _a.id, children = _a.children, _b = _a.className, className = _b === void 0 ? "" : _b;
|
|
33
|
+
var context = useContext(TabsContext);
|
|
34
|
+
if (!context) {
|
|
35
|
+
throw new Error("TabPanel must be used within Tabs component");
|
|
36
|
+
}
|
|
37
|
+
var activeTab = context.activeTab;
|
|
38
|
+
var isActive = activeTab === id;
|
|
39
|
+
if (!isActive)
|
|
40
|
+
return null;
|
|
41
|
+
return (_jsx("div", { className: "dds-tab-panel ".concat(className).trim(), role: "tabpanel", "aria-labelledby": "tab-".concat(id), id: "panel-".concat(id), children: children }));
|
|
42
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import { Tabs } from "./Tabs";
|
|
3
|
+
/**
|
|
4
|
+
* Tabs organize and segment related content, reducing cognitive load by allowing users
|
|
5
|
+
* to toggle between views without navigating to new pages.
|
|
6
|
+
*/
|
|
7
|
+
declare const meta: Meta<typeof Tabs>;
|
|
8
|
+
export default meta;
|
|
9
|
+
type Story = StoryObj<typeof Tabs>;
|
|
10
|
+
/**
|
|
11
|
+
* Basic tabs with three sections of content.
|
|
12
|
+
*/
|
|
13
|
+
export declare const Basic: Story;
|
|
14
|
+
/**
|
|
15
|
+
* Tabs showing code examples in different programming languages.
|
|
16
|
+
*/
|
|
17
|
+
export declare const CodeExamples: Story;
|
|
18
|
+
/**
|
|
19
|
+
* Tabs with longer content demonstrating scrollable tab list.
|
|
20
|
+
*/
|
|
21
|
+
export declare const ManyTabs: Story;
|
|
22
|
+
/**
|
|
23
|
+
* Controlled tabs where the active tab is managed by parent component state.
|
|
24
|
+
*/
|
|
25
|
+
export declare const Controlled: Story;
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
var __assign = (this && this.__assign) || function () {
|
|
2
|
+
__assign = Object.assign || function(t) {
|
|
3
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
4
|
+
s = arguments[i];
|
|
5
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
6
|
+
t[p] = s[p];
|
|
7
|
+
}
|
|
8
|
+
return t;
|
|
9
|
+
};
|
|
10
|
+
return __assign.apply(this, arguments);
|
|
11
|
+
};
|
|
12
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
13
|
+
import React from "react";
|
|
14
|
+
import { Tabs, TabList, Tab, TabPanel } from "./Tabs";
|
|
15
|
+
import { CodeBlock } from "./CodeBlock";
|
|
16
|
+
/**
|
|
17
|
+
* Tabs organize and segment related content, reducing cognitive load by allowing users
|
|
18
|
+
* to toggle between views without navigating to new pages.
|
|
19
|
+
*/
|
|
20
|
+
var meta = {
|
|
21
|
+
title: "Components/Tabs",
|
|
22
|
+
component: Tabs,
|
|
23
|
+
tags: ["autodocs"],
|
|
24
|
+
parameters: {
|
|
25
|
+
docs: {
|
|
26
|
+
description: {
|
|
27
|
+
component: "\nTabs are best used to organize, segment, and reduce cognitive load when presenting large amounts of related but distinct content.\n\n## When to Use\n\n- **Segmenting Related Alternatives**: Show different solutions for the same task (e.g., code examples in Python, Java, JavaScript)\n- **Managing Complex/Long Documents**: Break down extensive documentation into smaller, more manageable sections\n- **Context-Switching**: Allow users to switch between different views (e.g., \"Overview,\" \"Usage,\" \"API Reference\") while staying in the same context\n- **Organizing Workflows**: Separate complex workflows, such as student work from instructions, or setup steps from troubleshooting\n- **Reducing Clutter**: Hide non-essential or less frequently used information, showing only relevant details at one time\n\n## When Not to Use\n\n- When content is short and can be easily scrolled\n- When users need to compare all content simultaneously\n- If the information in the tabs is not related\n- For navigation between pages (use Link component instead)\n\n## Best Practices\n\n- **Default View**: Always set a logical default tab (e.g., the most commonly used language or platform)\n- **Clear Labels**: Ensure tab labels are concise, descriptive, and clearly distinguish between options\n- **Limit Number**: Avoid using too many tabs (more than 5-6 can clutter the interface)\n- **Avoid Nested Tabs**: Too many levels of navigation can confuse users\n\n## Tabs vs Collapsers\n\nUse **tabs** for a small number of distinct, parallel content sections where users rarely need to compare them simultaneously. Use **collapsers** (accordions) for long, vertical content, mobile-first layouts, or FAQs to minimize scrolling and allow users to see all options at once.\n\n## Accessibility\n\n- Uses proper ARIA attributes (`role=\"tab\"`, `role=\"tabpanel\"`, `aria-selected`)\n- Tab buttons are keyboard accessible\n- Active tab is clearly indicated visually and to screen readers\n ",
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
export default meta;
|
|
33
|
+
/**
|
|
34
|
+
* Basic tabs with three sections of content.
|
|
35
|
+
*/
|
|
36
|
+
export var Basic = {
|
|
37
|
+
args: {
|
|
38
|
+
defaultActiveTab: "overview",
|
|
39
|
+
},
|
|
40
|
+
parameters: {
|
|
41
|
+
docs: {
|
|
42
|
+
source: {
|
|
43
|
+
code: "<Tabs defaultActiveTab=\"overview\">\n <TabList>\n <Tab id=\"overview\">Overview</Tab>\n <Tab id=\"usage\">Usage</Tab>\n <Tab id=\"api\">API Reference</Tab>\n </TabList>\n <TabPanel id=\"overview\">\n <p>\n This is the overview section. It provides a high-level introduction\n to the topic.\n </p>\n </TabPanel>\n <TabPanel id=\"usage\">\n <p>\n This is the usage section. It contains practical examples and\n instructions.\n </p>\n </TabPanel>\n <TabPanel id=\"api\">\n <p>\n This is the API reference section. It documents the technical\n interface.\n </p>\n </TabPanel>\n</Tabs>",
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
render: function (args) { return (_jsxs(Tabs, __assign({}, args, { children: [_jsxs(TabList, { children: [_jsx(Tab, { id: "overview", children: "Overview" }), _jsx(Tab, { id: "usage", children: "Usage" }), _jsx(Tab, { id: "api", children: "API Reference" })] }), _jsx(TabPanel, { id: "overview", children: _jsx("p", { children: "This is the overview section. It provides a high-level introduction to the topic." }) }), _jsx(TabPanel, { id: "usage", children: _jsx("p", { children: "This is the usage section. It contains practical examples and instructions." }) }), _jsx(TabPanel, { id: "api", children: _jsx("p", { children: "This is the API reference section. It documents the technical interface." }) })] }))); },
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* Tabs showing code examples in different programming languages.
|
|
51
|
+
*/
|
|
52
|
+
export var CodeExamples = {
|
|
53
|
+
args: {
|
|
54
|
+
defaultActiveTab: "javascript",
|
|
55
|
+
},
|
|
56
|
+
parameters: {
|
|
57
|
+
docs: {
|
|
58
|
+
source: {
|
|
59
|
+
code: "<Tabs defaultActiveTab=\"javascript\">\n <TabList>\n <Tab id=\"javascript\">JavaScript</Tab>\n <Tab id=\"python\">Python</Tab>\n <Tab id=\"java\">Java</Tab>\n </TabList>\n <TabPanel id=\"javascript\">\n <CodeBlock \n language=\"javascript\" \n code={`const greeting = \"Hello, world!\";\nconsole.log(greeting);`} \n />\n </TabPanel>\n <TabPanel id=\"python\">\n <CodeBlock \n language=\"python\" \n code={`greeting = \"Hello, world!\"\nprint(greeting)`} \n />\n </TabPanel>\n <TabPanel id=\"java\">\n <CodeBlock \n language=\"java\" \n code={`String greeting = \"Hello, world!\";\nSystem.out.println(greeting);`} \n />\n </TabPanel>\n</Tabs>",
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
render: function (args) { return (_jsxs(Tabs, __assign({}, args, { children: [_jsxs(TabList, { children: [_jsx(Tab, { id: "javascript", children: "JavaScript" }), _jsx(Tab, { id: "python", children: "Python" }), _jsx(Tab, { id: "java", children: "Java" })] }), _jsx(TabPanel, { id: "javascript", children: _jsx(CodeBlock, { language: "javascript", code: "const greeting = \"Hello, world!\";\nconsole.log(greeting);" }) }), _jsx(TabPanel, { id: "python", children: _jsx(CodeBlock, { language: "python", code: "greeting = \"Hello, world!\"\nprint(greeting)" }) }), _jsx(TabPanel, { id: "java", children: _jsx(CodeBlock, { language: "java", code: "String greeting = \"Hello, world!\";\nSystem.out.println(greeting);" }) })] }))); },
|
|
64
|
+
};
|
|
65
|
+
/**
|
|
66
|
+
* Tabs with longer content demonstrating scrollable tab list.
|
|
67
|
+
*/
|
|
68
|
+
export var ManyTabs = {
|
|
69
|
+
args: {
|
|
70
|
+
defaultActiveTab: "tab1",
|
|
71
|
+
},
|
|
72
|
+
parameters: {
|
|
73
|
+
docs: {
|
|
74
|
+
source: {
|
|
75
|
+
code: "<Tabs defaultActiveTab=\"tab1\">\n <TabList>\n <Tab id=\"tab1\">Introduction</Tab>\n <Tab id=\"tab2\">Getting Started</Tab>\n <Tab id=\"tab3\">Configuration</Tab>\n <Tab id=\"tab4\">Advanced Usage</Tab>\n <Tab id=\"tab5\">Troubleshooting</Tab>\n <Tab id=\"tab6\">FAQ</Tab>\n </TabList>\n <TabPanel id=\"tab1\">\n <p>Introduction content goes here.</p>\n </TabPanel>\n <TabPanel id=\"tab2\">\n <p>Getting started content goes here.</p>\n </TabPanel>\n <TabPanel id=\"tab3\">\n <p>Configuration content goes here.</p>\n </TabPanel>\n <TabPanel id=\"tab4\">\n <p>Advanced usage content goes here.</p>\n </TabPanel>\n <TabPanel id=\"tab5\">\n <p>Troubleshooting content goes here.</p>\n </TabPanel>\n <TabPanel id=\"tab6\">\n <p>FAQ content goes here.</p>\n </TabPanel>\n</Tabs>",
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
render: function (args) { return (_jsxs(Tabs, __assign({}, args, { children: [_jsxs(TabList, { children: [_jsx(Tab, { id: "tab1", children: "Introduction" }), _jsx(Tab, { id: "tab2", children: "Getting Started" }), _jsx(Tab, { id: "tab3", children: "Configuration" }), _jsx(Tab, { id: "tab4", children: "Advanced Usage" }), _jsx(Tab, { id: "tab5", children: "Troubleshooting" }), _jsx(Tab, { id: "tab6", children: "FAQ" })] }), _jsx(TabPanel, { id: "tab1", children: _jsx("p", { children: "Introduction content goes here." }) }), _jsx(TabPanel, { id: "tab2", children: _jsx("p", { children: "Getting started content goes here." }) }), _jsx(TabPanel, { id: "tab3", children: _jsx("p", { children: "Configuration content goes here." }) }), _jsx(TabPanel, { id: "tab4", children: _jsx("p", { children: "Advanced usage content goes here." }) }), _jsx(TabPanel, { id: "tab5", children: _jsx("p", { children: "Troubleshooting content goes here." }) }), _jsx(TabPanel, { id: "tab6", children: _jsx("p", { children: "FAQ content goes here." }) })] }))); },
|
|
80
|
+
};
|
|
81
|
+
/**
|
|
82
|
+
* Controlled tabs where the active tab is managed by parent component state.
|
|
83
|
+
*/
|
|
84
|
+
export var Controlled = {
|
|
85
|
+
render: function ControlledExample() {
|
|
86
|
+
var _a = React.useState("tab1"), activeTab = _a[0], setActiveTab = _a[1];
|
|
87
|
+
return (_jsxs("div", { children: [_jsxs("p", { style: { marginBottom: "1rem", color: "var(--dds-tabs-panel-text)" }, children: ["Active tab: ", _jsx("strong", { children: activeTab })] }), _jsxs(Tabs, { activeTab: activeTab, onTabChange: setActiveTab, children: [_jsxs(TabList, { children: [_jsx(Tab, { id: "tab1", children: "Tab 1" }), _jsx(Tab, { id: "tab2", children: "Tab 2" }), _jsx(Tab, { id: "tab3", children: "Tab 3" })] }), _jsx(TabPanel, { id: "tab1", children: _jsx("p", { children: "Content for tab 1" }) }), _jsx(TabPanel, { id: "tab2", children: _jsx("p", { children: "Content for tab 2" }) }), _jsx(TabPanel, { id: "tab3", children: _jsx("p", { children: "Content for tab 3" }) })] })] }));
|
|
88
|
+
},
|
|
89
|
+
};
|
package/dist/index.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ export * from './components/CardGrid';
|
|
|
5
5
|
export * from './components/Collapser';
|
|
6
6
|
export * from './components/CollapserGroup';
|
|
7
7
|
export * from './components/CodeBlock';
|
|
8
|
+
export * from './components/Tabs';
|
|
8
9
|
export * from './components/Typography';
|
|
9
10
|
export * from './components/Heading';
|
|
10
11
|
export * from './components/Link';
|
package/dist/index.js
CHANGED
|
@@ -6,6 +6,7 @@ export * from './components/CardGrid';
|
|
|
6
6
|
export * from './components/Collapser';
|
|
7
7
|
export * from './components/CollapserGroup';
|
|
8
8
|
export * from './components/CodeBlock';
|
|
9
|
+
export * from './components/Tabs';
|
|
9
10
|
export * from './components/Typography';
|
|
10
11
|
export * from './components/Heading';
|
|
11
12
|
export * from './components/Link';
|
package/dist/styles.css
CHANGED
|
@@ -209,6 +209,21 @@
|
|
|
209
209
|
--dds-collapser-icon-color: #6b7280; /* gray-500 */
|
|
210
210
|
--dds-collapser-text: #374151; /* gray-700 */
|
|
211
211
|
--dds-collapser-content-padding: 1rem; /* p-4 */
|
|
212
|
+
|
|
213
|
+
/* Tabs */
|
|
214
|
+
--dds-tabs-margin: 1rem 0;
|
|
215
|
+
--dds-tabs-border: #e5e7eb; /* gray-200 */
|
|
216
|
+
--dds-tabs-tab-padding: 0.75rem 1rem;
|
|
217
|
+
--dds-tabs-tab-bg: transparent;
|
|
218
|
+
--dds-tabs-tab-text: #6b7280; /* gray-500 */
|
|
219
|
+
--dds-tabs-tab-size: 0.875rem;
|
|
220
|
+
--dds-tabs-tab-text-hover: #374151; /* gray-700 */
|
|
221
|
+
--dds-tabs-tab-bg-hover: transparent;
|
|
222
|
+
--dds-tabs-tab-text-active: #111827; /* gray-900 */
|
|
223
|
+
--dds-tabs-tab-bg-active: transparent;
|
|
224
|
+
--dds-tabs-tab-border-active: #3b82f6; /* blue-500 */
|
|
225
|
+
--dds-tabs-panel-padding: 1.25rem 0;
|
|
226
|
+
--dds-tabs-panel-text: #111827; /* gray-900 */
|
|
212
227
|
}
|
|
213
228
|
/* ==========================================================================
|
|
214
229
|
Dark Mode Tokens
|
|
@@ -297,6 +312,17 @@
|
|
|
297
312
|
--dds-collapser-icon-color: #9ca3af; /* gray-400 */
|
|
298
313
|
--dds-collapser-text: #e5e7eb; /* gray-200 */
|
|
299
314
|
|
|
315
|
+
/* Tabs */
|
|
316
|
+
--dds-tabs-border: #4b5563; /* gray-600 */
|
|
317
|
+
--dds-tabs-tab-bg: transparent;
|
|
318
|
+
--dds-tabs-tab-text: #9ca3af; /* gray-400 */
|
|
319
|
+
--dds-tabs-tab-text-hover: #e5e7eb; /* gray-200 */
|
|
320
|
+
--dds-tabs-tab-bg-hover: transparent;
|
|
321
|
+
--dds-tabs-tab-text-active: #f9fafb; /* gray-50 */
|
|
322
|
+
--dds-tabs-tab-bg-active: transparent;
|
|
323
|
+
--dds-tabs-tab-border-active: #60a5fa; /* blue-400 */
|
|
324
|
+
--dds-tabs-panel-text: #e5e7eb; /* gray-200 */
|
|
325
|
+
|
|
300
326
|
/* CodeBlock */
|
|
301
327
|
--dds-code-block-bg: #0a0a0a;
|
|
302
328
|
--dds-code-block-border: #2e2e2e; /* hsla(0,0%,18%,1) */
|
|
@@ -422,6 +448,17 @@
|
|
|
422
448
|
--dds-collapser-icon-color: #9ca3af;
|
|
423
449
|
--dds-collapser-text: #e5e7eb;
|
|
424
450
|
|
|
451
|
+
/* Tabs */
|
|
452
|
+
--dds-tabs-border: #4b5563;
|
|
453
|
+
--dds-tabs-tab-bg: transparent;
|
|
454
|
+
--dds-tabs-tab-text: #9ca3af;
|
|
455
|
+
--dds-tabs-tab-text-hover: #e5e7eb;
|
|
456
|
+
--dds-tabs-tab-bg-hover: transparent;
|
|
457
|
+
--dds-tabs-tab-text-active: #f9fafb;
|
|
458
|
+
--dds-tabs-tab-bg-active: transparent;
|
|
459
|
+
--dds-tabs-tab-border-active: #60a5fa;
|
|
460
|
+
--dds-tabs-panel-text: #e5e7eb;
|
|
461
|
+
|
|
425
462
|
/* CodeBlock */
|
|
426
463
|
--dds-code-block-bg: #0a0a0a;
|
|
427
464
|
--dds-code-block-border: #262626;
|
|
@@ -1279,6 +1316,50 @@ a.no-text-decoration {
|
|
|
1279
1316
|
.dds-code-block-content .token.variable {
|
|
1280
1317
|
color: var(--dds-prism-regex);
|
|
1281
1318
|
}
|
|
1319
|
+
.dds-tabs {
|
|
1320
|
+
margin: var(--dds-tabs-margin);
|
|
1321
|
+
}
|
|
1322
|
+
.dds-tabs-list {
|
|
1323
|
+
display: flex;
|
|
1324
|
+
gap: 0;
|
|
1325
|
+
border-bottom: 1px solid var(--dds-tabs-border);
|
|
1326
|
+
overflow-x: auto;
|
|
1327
|
+
overflow-y: hidden;
|
|
1328
|
+
-webkit-overflow-scrolling: touch;
|
|
1329
|
+
scrollbar-width: none;
|
|
1330
|
+
-ms-overflow-style: none;
|
|
1331
|
+
}
|
|
1332
|
+
.dds-tabs-list::-webkit-scrollbar {
|
|
1333
|
+
display: none;
|
|
1334
|
+
}
|
|
1335
|
+
.dds-tab {
|
|
1336
|
+
padding: var(--dds-tabs-tab-padding);
|
|
1337
|
+
background-color: var(--dds-tabs-tab-bg);
|
|
1338
|
+
border: none;
|
|
1339
|
+
border-bottom: 2px solid transparent;
|
|
1340
|
+
color: var(--dds-tabs-tab-text);
|
|
1341
|
+
font-size: var(--dds-tabs-tab-size);
|
|
1342
|
+
font-weight: var(--dds-font-medium);
|
|
1343
|
+
cursor: pointer;
|
|
1344
|
+
white-space: nowrap;
|
|
1345
|
+
transition: var(--dds-transition-colors);
|
|
1346
|
+
}
|
|
1347
|
+
.dds-tab:hover {
|
|
1348
|
+
color: var(--dds-tabs-tab-text-hover);
|
|
1349
|
+
background-color: var(--dds-tabs-tab-bg-hover);
|
|
1350
|
+
}
|
|
1351
|
+
.dds-tab-active {
|
|
1352
|
+
color: var(--dds-tabs-tab-text-active);
|
|
1353
|
+
background-color: var(--dds-tabs-tab-bg-active);
|
|
1354
|
+
border-bottom-color: var(--dds-tabs-tab-border-active);
|
|
1355
|
+
}
|
|
1356
|
+
.dds-tab-active:hover {
|
|
1357
|
+
background-color: var(--dds-tabs-tab-bg-active);
|
|
1358
|
+
}
|
|
1359
|
+
.dds-tab-panel {
|
|
1360
|
+
padding: var(--dds-tabs-panel-padding);
|
|
1361
|
+
color: var(--dds-tabs-panel-text);
|
|
1362
|
+
}
|
|
1282
1363
|
.dds-typography {
|
|
1283
1364
|
color: var(--dds-heading-color);
|
|
1284
1365
|
}
|