From d477fc80013171d88bf8013d2a3c949037d0bf58 Mon Sep 17 00:00:00 2001 From: Kamil Emeleev Date: Mon, 6 Jul 2026 10:43:49 +0300 Subject: [PATCH] docs(Tabs): add customization story --- .../components/src/components/Tabs/Tabs.mdx | 10 ++++ .../src/components/Tabs/Tabs.stories.tsx | 59 ++++++++++++++++++- .../Tabs/__stories__/customization.styles.css | 7 +++ 3 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 packages/components/src/components/Tabs/__stories__/customization.styles.css 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); +}