diff --git a/packages/components/src/components/Tabs/Tabs.mdx b/packages/components/src/components/Tabs/Tabs.mdx
index 948e7b6d..ae1b773f 100644
--- a/packages/components/src/components/Tabs/Tabs.mdx
+++ b/packages/components/src/components/Tabs/Tabs.mdx
@@ -2,10 +2,12 @@ import {
Meta,
Story,
Props,
+ Source,
Status,
} from '../../../../../.storybook/components/index.ts';
import * as Stories from './Tabs.stories.tsx';
+import customizationStyles from './__stories__/customization.styles.css?raw';
@@ -133,6 +135,14 @@ URL from your client side router. You can do this by doing the following:
- Set up your router at the root of your app.
- Use the `selectedKey` prop to set the selected tab based on the current URL.
+## Customization
+
+Use `className` to style tabs and public `data-*` attributes for state-specific styles.
+
+
+
+
+
## With Form
diff --git a/packages/components/src/components/Tabs/Tabs.stories.tsx b/packages/components/src/components/Tabs/Tabs.stories.tsx
index 2d868f4a..b4901e58 100644
--- a/packages/components/src/components/Tabs/Tabs.stories.tsx
+++ b/packages/components/src/components/Tabs/Tabs.stories.tsx
@@ -7,15 +7,18 @@ import {
IconBsd24,
IconBug16,
IconCircleInfo16,
+ IconHouse16,
IconUbuntu24,
+ IconUser16,
IconWindows24,
} from '@koobiq/react-icons';
import type { Meta, StoryObj } from '@storybook/react';
+import './__stories__/customization.styles.css';
import { Button } from '../Button';
import { FlexBox } from '../FlexBox';
import { Form } from '../Form';
-import { useListData } from '../index';
+import { BreadcrumbItem, Breadcrumbs, useListData } from '../index';
import { Input } from '../Input';
import { spacing } from '../layout';
import { Link } from '../Link';
@@ -797,3 +800,57 @@ export const VerticalScrolling: Story = {
);
},
};
+
+export const Customization: Story = {
+ render: function Render() {
+ const tabs = [
+ { key: '0', title: 'Phishing' },
+ {
+ key: '1',
+ title: 'Ransomware',
+ },
+ { key: '2', title: 'DDoS' },
+ { key: '3', title: 'Supply-chain attack' },
+ { key: '4', title: 'Zero-day (CVE-0)' },
+ { key: '5', title: 'Insider threats' },
+ { key: '6', title: 'Credential stuffing' },
+ { key: '7', title: 'IoT botnets' },
+ { key: '8', title: 'Self-propagating worms' },
+ { key: '9', title: 'Social engineering' },
+ { key: '10', title: 'Watering-hole attack' },
+ { key: '11', title: 'Man-in-the-Middle (MitM)' },
+ { key: '12', title: 'SQL/NoSQL injection' },
+ { key: '13', title: 'Cross-Site Scripting (XSS)' },
+ { key: '14', title: 'Kernel-level rootkits' },
+ { key: '15', title: 'Cryptojacking' },
+ { key: '16', title: 'Malvertising' },
+ { key: '17', title: 'Business Email Compromise (BEC)' },
+ { key: '18', title: 'Typosquatting and lookalike domains' },
+ { key: '19', title: 'Brute force and rate limits' },
+ ];
+
+ return (
+
+
+ } />
+ }>
+ Application List
+
+ Application
+
+
+ {({ key, title }) => (
+
+ {`${title} — brief overview of the attack scenario and typical indicators of compromise. Vector: network, email, supply chain, user action. Impact: data access, encryption, downtime. Mitigation: MFA, least privilege, segmentation, WAF, training.`}
+
+ )}
+
+
+ );
+ },
+};
diff --git a/packages/components/src/components/Tabs/__stories__/customization.styles.css b/packages/components/src/components/Tabs/__stories__/customization.styles.css
new file mode 100644
index 00000000..4397bb38
--- /dev/null
+++ b/packages/components/src/components/Tabs/__stories__/customization.styles.css
@@ -0,0 +1,7 @@
+.my-tab {
+ padding-block: 0;
+}
+
+.my-tab:not([data-selected]) > * {
+ color: var(--kbq-foreground-contrast-secondary);
+}