@socprime/react-ui 0.0.5
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/CHANGELOG.md +56 -0
- package/LICENSE +21 -0
- package/README.md +537 -0
- package/attack-flow.d.ts +16 -0
- package/charts.d.ts +32 -0
- package/decorators/index.js +8 -0
- package/decorators/withRouter.js +10 -0
- package/decorators/withTheme.js +10 -0
- package/decorators.d.ts +10 -0
- package/domain.d.ts +23 -0
- package/editor.d.ts +25 -0
- package/index.d.ts +702 -0
- package/lib/cn.js +8 -0
- package/lib/theme.js +26 -0
- package/lib/useFullscreen.js +52 -0
- package/lib/useListenOnResizeDebounce.js +22 -0
- package/lib/useThemeColors.js +39 -0
- package/package.json +113 -0
- package/preset/createConfig.js +98 -0
- package/preset/createPreview.js +53 -0
- package/preset/index.js +6 -0
- package/preset/restoreNativeFocus.js +33 -0
- package/preset/types.js +0 -0
- package/preset.d.ts +27 -0
- package/theme-9m7j1UoI.d.ts +5 -0
- package/ui/Accordion/Accordion.js +82 -0
- package/ui/Accordion/AccordionSection.js +41 -0
- package/ui/Accordion/FolderTreeExpandTrigger.js +29 -0
- package/ui/Accordion/chevronVariants.js +31 -0
- package/ui/Accordion/index.js +16 -0
- package/ui/AnimatedDots/AnimatedDots.js +10 -0
- package/ui/AnimatedDots/index.js +4 -0
- package/ui/Aside/Aside.js +34 -0
- package/ui/Aside/index.js +4 -0
- package/ui/AttackFlow/AttackFlow.js +9 -0
- package/ui/AttackFlow/AttackFlowLayout.js +63 -0
- package/ui/AttackFlow/Controls.js +42 -0
- package/ui/AttackFlow/Node.js +47 -0
- package/ui/AttackFlow/OtherNode.js +44 -0
- package/ui/AttackFlow/index.js +4 -0
- package/ui/AttackFlow/prependData.js +153 -0
- package/ui/AttackFlow/types.js +0 -0
- package/ui/AttackFlow/useAttackFlow.js +193 -0
- package/ui/Badge/Badge.js +57 -0
- package/ui/Badge/index.js +5 -0
- package/ui/Button/Button.css +1 -0
- package/ui/Button/Button.js +109 -0
- package/ui/Button/index.js +5 -0
- package/ui/Charts/AreaChartWithGradient.js +79 -0
- package/ui/Charts/index.js +4 -0
- package/ui/Checkbox/Checkbox.js +31 -0
- package/ui/Checkbox/index.js +4 -0
- package/ui/ConditionalContent/ConditionalContent.js +10 -0
- package/ui/ConditionalContent/index.js +4 -0
- package/ui/CorrelationTimer/CorrelationTimer.js +62 -0
- package/ui/CorrelationTimer/index.js +4 -0
- package/ui/DeleteButtonConfirm/DeleteButtonConfirm.js +65 -0
- package/ui/DeleteButtonConfirm/index.js +4 -0
- package/ui/Dialog/ConfirmDialog.js +54 -0
- package/ui/Dialog/DefaultDialog.js +82 -0
- package/ui/Dialog/Dialog.js +120 -0
- package/ui/Dialog/index.js +32 -0
- package/ui/Dropdown/Dropdown.js +204 -0
- package/ui/Dropdown/DropdownsCheckbox.js +102 -0
- package/ui/Dropdown/DropdownsSelect.js +97 -0
- package/ui/Dropdown/index.js +38 -0
- package/ui/Editor/Editor.js +97 -0
- package/ui/Editor/index.js +4 -0
- package/ui/Editor/monacoSetup.js +38 -0
- package/ui/Editor/theme.js +50 -0
- package/ui/Editor/types.js +0 -0
- package/ui/EmptyState/EmptyState.js +26 -0
- package/ui/EmptyState/index.js +4 -0
- package/ui/Field/Field.js +204 -0
- package/ui/Field/index.js +24 -0
- package/ui/HelperText/HelperText.js +7 -0
- package/ui/HelperText/index.js +4 -0
- package/ui/Input/Input.js +40 -0
- package/ui/Input/index.js +4 -0
- package/ui/InputNumber/InputNumber.js +90 -0
- package/ui/InputNumber/index.js +4 -0
- package/ui/InputPassword/InputPassword.js +30 -0
- package/ui/InputPassword/index.js +4 -0
- package/ui/Label/Label.js +13 -0
- package/ui/Label/LabelInfo.js +14 -0
- package/ui/Label/index.js +6 -0
- package/ui/MultiSelect/MultiSelect.js +163 -0
- package/ui/MultiSelect/index.js +4 -0
- package/ui/PageHeader/PageHeader.js +51 -0
- package/ui/PageHeader/index.js +4 -0
- package/ui/Pagination/Pagination.js +97 -0
- package/ui/Pagination/PaginationWrap.js +149 -0
- package/ui/Pagination/index.js +20 -0
- package/ui/RadioGroup/RadioGroup.js +45 -0
- package/ui/RadioGroup/index.js +5 -0
- package/ui/ScrollArea/ScrollArea.js +57 -0
- package/ui/ScrollArea/index.js +5 -0
- package/ui/SearchInput/SearchInput.js +38 -0
- package/ui/SearchInput/index.js +4 -0
- package/ui/SearchInputFields/SearchInputFields.js +53 -0
- package/ui/SearchInputFields/index.js +4 -0
- package/ui/Select/Select.js +155 -0
- package/ui/Select/SelectDefault.js +43 -0
- package/ui/Select/index.js +26 -0
- package/ui/Separator/Separator.js +26 -0
- package/ui/Separator/index.js +4 -0
- package/ui/Severity/Severity.js +11 -0
- package/ui/Severity/index.js +4 -0
- package/ui/Severity/utils.js +53 -0
- package/ui/Skeleton/Skeleton.js +25 -0
- package/ui/Skeleton/index.js +5 -0
- package/ui/Slider/Slider.js +50 -0
- package/ui/Slider/index.js +4 -0
- package/ui/Spinner/Spinner.js +21 -0
- package/ui/Spinner/index.js +5 -0
- package/ui/SpinnerSquare/SpinnerSquare.css +1 -0
- package/ui/SpinnerSquare/SpinnerSquare.js +22 -0
- package/ui/SpinnerSquare/index.js +4 -0
- package/ui/StatisticCard/StatisticCard.js +27 -0
- package/ui/StatisticCard/index.js +4 -0
- package/ui/StatisticCard/types.js +0 -0
- package/ui/Suggestions/Suggestions.js +244 -0
- package/ui/Suggestions/index.js +4 -0
- package/ui/Switch/Switch.js +64 -0
- package/ui/Switch/index.js +4 -0
- package/ui/SyncProcessBar/SyncProcessBar.js +14 -0
- package/ui/SyncProcessBar/index.js +4 -0
- package/ui/Table/GroupHeaderRow.js +36 -0
- package/ui/Table/RowGrouped.js +19 -0
- package/ui/Table/ServerGroupedTableBody.js +89 -0
- package/ui/Table/SortableHeader.js +46 -0
- package/ui/Table/Table.js +110 -0
- package/ui/Table/TableWrap.js +124 -0
- package/ui/Table/columnStyle.js +14 -0
- package/ui/Table/index.js +28 -0
- package/ui/Tabs/Tabs.js +76 -0
- package/ui/Tabs/index.js +4 -0
- package/ui/TextTruncate/TextTruncate.js +107 -0
- package/ui/TextTruncate/index.js +4 -0
- package/ui/Textarea/Textarea.js +20 -0
- package/ui/Textarea/index.js +4 -0
- package/ui/ThemeToggle/ThemeToggle.js +23 -0
- package/ui/ThemeToggle/index.js +4 -0
- package/ui/Toast/Toast.js +23 -0
- package/ui/Toast/index.js +4 -0
- package/ui/Tooltip/Tooltip.js +17 -0
- package/ui/Tooltip/TooltipLayout.js +60 -0
- package/ui/Tooltip/index.js +14 -0
- package/ui/TreeGuide/TreeGuide.js +23 -0
- package/ui/TreeGuide/index.js +5 -0
- package/ui/entries/charts.js +2 -0
- package/ui/entries/domain.js +3 -0
- package/ui/index.js +45 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `@socprime/react-ui` are documented here.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
|
6
|
+
|
|
7
|
+
## [0.0.5] - 2026-07-27
|
|
8
|
+
|
|
9
|
+
First release published to the npm registry. Earlier versions existed only as git tags and were installed directly from the repository, so this is the initial entry point for anyone consuming the package from npm.
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- Root export with product-agnostic UI primitives built on Radix UI, CVA and Tailwind CSS v4 — forms, dialogs, dropdowns, tables, pagination, tabs, accordions, tooltips, toasts, and theming helpers (`applyTheme`, `useDocumentTheme`, `ThemeToggle`).
|
|
14
|
+
- Subpath exports so consumers only pay for what they import: `/domain` (SOC Prime domain components), `/editor` (Monaco), `/charts` (recharts), `/attack-flow` (`@xyflow/react` + dagre).
|
|
15
|
+
- `/preset` and `/decorators` for teams building their own Storybook on top of the design system.
|
|
16
|
+
- TypeScript definitions for every entry point, with props exported under the `<Name>Props` convention.
|
|
17
|
+
- A `./package.json` export, so tooling that resolves a dependency's manifest (Tailwind, Storybook, bundler plugins) can reach it.
|
|
18
|
+
- Documentation of the full theme contract in the README — the CSS custom properties, `@theme` tokens, keyframes and base styles the host application must provide.
|
|
19
|
+
|
|
20
|
+
### Notes for consumers
|
|
21
|
+
|
|
22
|
+
- The package is **ESM-only**. `require()` is not supported; use `import` or a dynamic `import()`.
|
|
23
|
+
- `dist/` is shipped as separate ESM modules rather than a single bundle, so importing one component does not pull in the rest. All relative imports are fully specified, which keeps the output valid under strict resolvers such as Node ESM and webpack 5 with `fullySpecified`.
|
|
24
|
+
- TypeScript consumers need `moduleResolution` set to `bundler` or `node16`; the legacy `"node"` mode ignores `exports` and resolves neither the subpath JavaScript nor its types.
|
|
25
|
+
- Required peer dependencies: `react`, `react-dom`, `react-router-dom`, `@tanstack/react-table`. Optional peers are listed in the README and are only needed for the matching subpath.
|
|
26
|
+
|
|
27
|
+
### Import paths
|
|
28
|
+
|
|
29
|
+
- `Severity`, `CorrelationTimer` and `SyncProcessBar` moved out of the root export into `@socprime/react-ui/domain`. The root export is now reserved for components with no business-domain coupling.
|
|
30
|
+
|
|
31
|
+
```diff
|
|
32
|
+
- import { Severity } from '@socprime/react-ui';
|
|
33
|
+
+ import { Severity } from '@socprime/react-ui/domain';
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
- `Editor`, `AreaChartWithGradient`, `StatisticCard` and `AttackFlow` moved to dedicated subpaths, so consumers who do not use them stop paying for Monaco, recharts and `@xyflow/react`.
|
|
37
|
+
|
|
38
|
+
```diff
|
|
39
|
+
- import { Editor, StatisticCard, AttackFlow } from '@socprime/react-ui';
|
|
40
|
+
+ import { Editor } from '@socprime/react-ui/editor';
|
|
41
|
+
+ import { StatisticCard } from '@socprime/react-ui/charts';
|
|
42
|
+
+ import { AttackFlow } from '@socprime/react-ui/attack-flow';
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
- The `@socprime/react-ui/ui` alias was removed — use the root export.
|
|
46
|
+
- The Storybook preset is available only through `@socprime/react-ui/preset`, no longer from the root export or from a separate `@socprime/storybook` package.
|
|
47
|
+
|
|
48
|
+
### Types
|
|
49
|
+
|
|
50
|
+
- `StatisticsGraphData` (`/charts`): fields `count_active` and `count_all` were renamed to `activeCount` and `totalCount`. The type no longer mirrors the backend response shape — map it at your API boundary.
|
|
51
|
+
|
|
52
|
+
### Dependencies
|
|
53
|
+
|
|
54
|
+
- `react-router-dom`, `@tanstack/react-table`, `monaco-editor`, `@monaco-editor/react`, `@xyflow/react`, `dagre` and `recharts` are peer dependencies rather than direct dependencies. Install `react-router-dom` and `@tanstack/react-table` explicitly; the rest are optional and only required if you import `/editor`, `/charts` or `/attack-flow`.
|
|
55
|
+
|
|
56
|
+
`react-router-dom` is required rather than optional because `Button`, `PageHeader` and `Aside` use React Router internally — a second copy in the bundle would carry its own context, and links rendered by the library would not see your `<BrowserRouter>`.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 SOC Prime
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,537 @@
|
|
|
1
|
+
# @socprime/react-ui
|
|
2
|
+
|
|
3
|
+
React component library for SOC Prime products. Ships pre-built ESM modules with TypeScript definitions: generic UI primitives built on Radix UI, CVA and Tailwind CSS, plus a set of SOC Prime domain components behind separate entry points.
|
|
4
|
+
|
|
5
|
+
## Requirements
|
|
6
|
+
|
|
7
|
+
| Requirement | Notes |
|
|
8
|
+
| --- | --- |
|
|
9
|
+
| React 19 | `react` and `react-dom` are peer dependencies |
|
|
10
|
+
| Tailwind CSS v4 | The library ships class names, not compiled utilities — your Tailwind build generates them |
|
|
11
|
+
| ESM-capable bundler | Vite, webpack 5, Next.js, Rollup, esbuild. The package is ESM-only; `require()` is not supported |
|
|
12
|
+
| TypeScript 5 (optional) | `moduleResolution` must be `bundler` or `node16` |
|
|
13
|
+
| Node.js 20+ | Only for the build/dev toolchain of your app |
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install @socprime/react-ui
|
|
19
|
+
# or
|
|
20
|
+
yarn add @socprime/react-ui
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Install the required peer dependencies alongside it:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
npm install react react-dom react-router-dom @tanstack/react-table
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Optional peers are only needed for the corresponding subpath — see [Peer dependencies](#peer-dependencies).
|
|
30
|
+
|
|
31
|
+
## Quick start
|
|
32
|
+
|
|
33
|
+
Adopting the library takes three steps. Skipping any of them produces components that render but look broken.
|
|
34
|
+
|
|
35
|
+
### 1. Add the theme
|
|
36
|
+
|
|
37
|
+
The library styles itself entirely through CSS custom properties and Tailwind theme tokens that **your app must define**. Copy the [reference theme](#theme-contract) into your global stylesheet (for example `src/index.css`), then import it once at your entry point:
|
|
38
|
+
|
|
39
|
+
```tsx
|
|
40
|
+
// src/main.tsx
|
|
41
|
+
import './index.css';
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### 2. Point Tailwind at the package
|
|
45
|
+
|
|
46
|
+
Tailwind only generates utilities it can find in scanned sources. Classes like `rounded-xs` or `bg-btn-primary` exist only inside the library, so your Tailwind build must scan it:
|
|
47
|
+
|
|
48
|
+
```css
|
|
49
|
+
/* src/index.css */
|
|
50
|
+
@import 'tailwindcss';
|
|
51
|
+
@source "../node_modules/@socprime/react-ui/**/*.js";
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Without this line every component renders unstyled.
|
|
55
|
+
|
|
56
|
+
### 3. Set up the app shell
|
|
57
|
+
|
|
58
|
+
```tsx
|
|
59
|
+
// src/App.tsx
|
|
60
|
+
import { BrowserRouter } from 'react-router-dom';
|
|
61
|
+
import { Button, Toaster, applyTheme } from '@socprime/react-ui';
|
|
62
|
+
import { useEffect } from 'react';
|
|
63
|
+
|
|
64
|
+
export function App() {
|
|
65
|
+
// Adds the `.dark` / `.light` class and `data-theme` attribute to <html>.
|
|
66
|
+
useEffect(() => applyTheme('dark'), []);
|
|
67
|
+
|
|
68
|
+
return (
|
|
69
|
+
<BrowserRouter>
|
|
70
|
+
<Button variant="primary" size="m" onClick={() => console.log('clicked')}>
|
|
71
|
+
Get started
|
|
72
|
+
</Button>
|
|
73
|
+
|
|
74
|
+
{/* Render once, anywhere in the tree — required for toast notifications. */}
|
|
75
|
+
<Toaster />
|
|
76
|
+
</BrowserRouter>
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
`BrowserRouter` (or any React Router provider) is required if you render `Aside`, `PageHeader`, or a `Button` with the `to` prop — those use React Router internally. Everything else works without a router.
|
|
82
|
+
|
|
83
|
+
`Tooltip` provides its own context, so no extra provider is needed for it.
|
|
84
|
+
|
|
85
|
+
## Entry points
|
|
86
|
+
|
|
87
|
+
The public API is deliberately narrow: seven entry points, no deep imports.
|
|
88
|
+
|
|
89
|
+
| Import path | Contents | Extra peers |
|
|
90
|
+
| --- | --- | --- |
|
|
91
|
+
| `@socprime/react-ui` | Generic, product-agnostic primitives | — |
|
|
92
|
+
| `@socprime/react-ui/domain` | SOC Prime domain components | — |
|
|
93
|
+
| `@socprime/react-ui/editor` | Monaco-based code editor | `monaco-editor`, `@monaco-editor/react` |
|
|
94
|
+
| `@socprime/react-ui/charts` | Charts and statistics cards | `recharts` |
|
|
95
|
+
| `@socprime/react-ui/attack-flow` | MITRE ATT&CK flow graph | `@xyflow/react`, `dagre` |
|
|
96
|
+
| `@socprime/react-ui/preset` | Storybook config factory | `@storybook/react-vite`, `vite`, `vite-plugin-svgr` |
|
|
97
|
+
| `@socprime/react-ui/decorators` | Storybook decorators | `@storybook/react-vite` |
|
|
98
|
+
|
|
99
|
+
Heavy modules live behind their own subpaths so that an app which never imports `/editor` does not pay for Monaco — neither in bundle size nor in installed dependencies.
|
|
100
|
+
|
|
101
|
+
```tsx
|
|
102
|
+
import { Button, Table, Toaster } from '@socprime/react-ui';
|
|
103
|
+
import { Severity, type TSeverity } from '@socprime/react-ui/domain';
|
|
104
|
+
import { Editor } from '@socprime/react-ui/editor';
|
|
105
|
+
import { AreaChartWithGradient, StatisticCard } from '@socprime/react-ui/charts';
|
|
106
|
+
import { AttackFlow } from '@socprime/react-ui/attack-flow';
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Deep imports such as `@socprime/react-ui/dist/ui/Button` are blocked by the `exports` map. This is intentional — it keeps the internal layout of the package free to change without breaking consumers.
|
|
110
|
+
|
|
111
|
+
## Components
|
|
112
|
+
|
|
113
|
+
### Root export
|
|
114
|
+
|
|
115
|
+
**Forms**
|
|
116
|
+
`Field`, `FieldSet`, `FieldGroup`, `FieldLabel`, `FieldTitle`, `FieldDescription`, `FieldContent`, `FieldError`, `FieldLegend`, `FieldSeparator`, `Input`, `InputNumber`, `InputPassword`, `Textarea`, `Checkbox`, `RadioGroup`, `RadioGroupItem`, `Switch`, `Slider`, `Select`, `SelectDefault`, `SelectTrigger`, `SelectContent`, `SelectItem`, `SelectGroup`, `SelectLabel`, `SelectValue`, `SelectSeparator`, `SelectScrollUpButton`, `SelectScrollDownButton`, `MultiSelect`, `SearchInput`, `SearchInputFields`, `Suggestions`, `Label`, `LabelInfo`, `HelperText`
|
|
117
|
+
|
|
118
|
+
**Actions and overlays**
|
|
119
|
+
`Button`, `buttonVariants`, `DeleteButtonConfirm`, `Dialog`, `DialogTrigger`, `DialogContent`, `DialogHeader`, `DialogFooter`, `DialogTitle`, `DialogDescription`, `DialogOverlay`, `DialogPortal`, `DialogClose`, `DefaultDialog`, `ConfirmDeleteDialog`, `DropdownMenu` (with `Trigger`, `Content`, `Item`, `CheckboxItem`, `RadioGroup`, `RadioItem`, `Label`, `Group`, `Separator`, `Shortcut`, `Sub`, `SubTrigger`, `SubContent`, `Portal`), `DropdownsCheckbox`, `DropdownsSelect`, `Tooltip`, `TooltipTrigger`, `TooltipContent`, `TooltipProvider`, `TooltipParent`, `Toaster`
|
|
120
|
+
|
|
121
|
+
**Data display**
|
|
122
|
+
`Table`, `TableHeader`, `TableHead`, `TableBody`, `TableRow`, `TableCell`, `TableFooter`, `TableCaption`, `TableWrap`, `SortableHeader`, `GroupHeaderRow`, `ServerGroupedTableBody`, `SkeletonTable`, `Pagination`, `PaginationWrap`, `PaginationContent`, `PaginationItem`, `PaginationLink`, `PaginationNext`, `PaginationPrevious`, `PaginationEllipsis`, `Badge`, `badgeVariants`, `EmptyState`, `TextTruncate`
|
|
123
|
+
|
|
124
|
+
**Layout and navigation**
|
|
125
|
+
`Aside`, `PageHeader`, `Tabs`, `Accordion`, `AccordionItem`, `AccordionTrigger`, `AccordionContent`, `AccordionSection`, `FolderTreeExpandTrigger`, `ScrollArea`, `ScrollBar`, `Separator`, `TreeGuide`, `TreeRow`
|
|
126
|
+
|
|
127
|
+
**Feedback and state**
|
|
128
|
+
`Spinner`, `SpinnerCustom`, `SpinnerSquare`, `AnimatedDots`, `Skeleton`, `ConditionalContent`
|
|
129
|
+
|
|
130
|
+
**Theming**
|
|
131
|
+
`ThemeToggle`, `applyTheme`, `useDocumentTheme`, `ThemeName`
|
|
132
|
+
|
|
133
|
+
Every component exports its props type under the `<Name>Props` convention — `ButtonProps`, `TableWrapProps`, and so on.
|
|
134
|
+
|
|
135
|
+
### Subpath exports
|
|
136
|
+
|
|
137
|
+
| Entry point | Exports |
|
|
138
|
+
| --- | --- |
|
|
139
|
+
| `/domain` | `Severity`, `CorrelationTimer`, `SyncProcessBar`, `TSeverity` |
|
|
140
|
+
| `/editor` | `Editor`, `EditorProps`, `Theme` |
|
|
141
|
+
| `/charts` | `AreaChartWithGradient`, `StatisticCard`, `AreaChartDataPoint`, `StatisticsGraphData`, `StatisticsGraphDataPoint` |
|
|
142
|
+
| `/attack-flow` | `AttackFlow`, `AttackFlowProps`, `NodeData` |
|
|
143
|
+
| `/preset` | `createStorybookConfig`, `createStorybookPreview`, `StorybookHostOptions` |
|
|
144
|
+
| `/decorators` | `withTheme`, `withRouter`, `applyTheme`, `ThemeName` |
|
|
145
|
+
|
|
146
|
+
## Theme contract
|
|
147
|
+
|
|
148
|
+
This is the part that most often goes wrong on first integration. The library never ships colors of its own — it references Tailwind theme tokens and CSS custom properties by name and expects the host application to define them.
|
|
149
|
+
|
|
150
|
+
You need three things in your global stylesheet:
|
|
151
|
+
|
|
152
|
+
1. **CSS custom properties** for `:root`, `.light` and `.dark`.
|
|
153
|
+
2. **A `@theme inline` block** mapping those properties onto Tailwind color tokens.
|
|
154
|
+
3. **Keyframes, base styles and utilities** used by `Accordion`, `AnimatedDots`, `SyncProcessBar`, `Checkbox` and `TextTruncate`.
|
|
155
|
+
|
|
156
|
+
The `.light` / `.dark` classes are toggled on `<html>` by `applyTheme()` and by the `ThemeToggle` component.
|
|
157
|
+
|
|
158
|
+
<details>
|
|
159
|
+
<summary><strong>Reference theme — copy this into your global stylesheet</strong></summary>
|
|
160
|
+
|
|
161
|
+
```css
|
|
162
|
+
@import 'tailwindcss';
|
|
163
|
+
@source "../node_modules/@socprime/react-ui/**/*.js";
|
|
164
|
+
|
|
165
|
+
@custom-variant dark (&:is(.dark *));
|
|
166
|
+
@custom-variant light (&:is(.light *));
|
|
167
|
+
|
|
168
|
+
:root {
|
|
169
|
+
--font-size: 1rem;
|
|
170
|
+
--font-weight-normal: 400;
|
|
171
|
+
--radius-xs: 0.3rem;
|
|
172
|
+
--radius-s: 0.4rem;
|
|
173
|
+
--radius-sm: 0.5rem;
|
|
174
|
+
|
|
175
|
+
--white: #ffffff;
|
|
176
|
+
--ring: #95c9b4;
|
|
177
|
+
--darkGray: #6b7280;
|
|
178
|
+
|
|
179
|
+
--btn-primary: #4ac18e;
|
|
180
|
+
--btn-primary-hover: #3bac7c;
|
|
181
|
+
--btn-primary-active: #329269;
|
|
182
|
+
--btn-primary-disabled: #333544;
|
|
183
|
+
|
|
184
|
+
--btn-secondary: #3b3d4f;
|
|
185
|
+
--btn-secondary-hover: #50536b;
|
|
186
|
+
--btn-secondary-active: #5b5e7a;
|
|
187
|
+
--btn-secondary-disabled: #333544;
|
|
188
|
+
|
|
189
|
+
--btn-destructive: #ee3523;
|
|
190
|
+
--btn-destructive-hover: #dc2311;
|
|
191
|
+
--btn-destructive-active: #ba1e0e;
|
|
192
|
+
--btn-destructive-disabled: #333544;
|
|
193
|
+
|
|
194
|
+
--border-primary: #95c9b4;
|
|
195
|
+
--border-disabled: #d2d5d8;
|
|
196
|
+
--border-critical: #fd5749;
|
|
197
|
+
--border-critical-disabled: #ffa7a3;
|
|
198
|
+
|
|
199
|
+
--bg-critical-light: #fd5749;
|
|
200
|
+
--red-violet: #c32181;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
.light {
|
|
204
|
+
--btn-secondary: #cfd0d3;
|
|
205
|
+
--tooltip-white: #ffffff;
|
|
206
|
+
--tooltip-black: #000000;
|
|
207
|
+
|
|
208
|
+
--bg-primary: #f9f9f9;
|
|
209
|
+
--bg-secondary: #f9f9f9;
|
|
210
|
+
--bg-success: #4ac18e;
|
|
211
|
+
--bg-warning: #ee9d23;
|
|
212
|
+
--bg-purple: #c27aff;
|
|
213
|
+
--bg-light-blue: #51a2ff;
|
|
214
|
+
--bg-blue: #015bbb;
|
|
215
|
+
--bg-gray-chateau: #99a1af;
|
|
216
|
+
--bg-comet: #54556a;
|
|
217
|
+
--bg-critical: #ee3523;
|
|
218
|
+
--bg-hover: #cfd0d3;
|
|
219
|
+
--bg-yellow: #ffe824;
|
|
220
|
+
|
|
221
|
+
--foreground: #292c3d;
|
|
222
|
+
--border: #cfd0d3;
|
|
223
|
+
--btn-ghost: #cfd0d3;
|
|
224
|
+
--text-subdued: #292c3d;
|
|
225
|
+
--text-default: #1a1e2f;
|
|
226
|
+
--text-dark: #1a1e2f;
|
|
227
|
+
--text-warning: #ee9d23;
|
|
228
|
+
--text-critical: #ee3523;
|
|
229
|
+
--mirisk: #99a1af;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
.dark {
|
|
233
|
+
--btn-secondary: #252838;
|
|
234
|
+
--tooltip-white: #000000;
|
|
235
|
+
--tooltip-black: #ffffff;
|
|
236
|
+
|
|
237
|
+
--bg-black: #ffffff;
|
|
238
|
+
--bg-primary: #1f2232;
|
|
239
|
+
--bg-secondary: #252838;
|
|
240
|
+
--bg-success: #4ac18e;
|
|
241
|
+
--bg-warning: #ee9d23;
|
|
242
|
+
--bg-purple: #c27aff;
|
|
243
|
+
--bg-light-blue: #51a2ff;
|
|
244
|
+
--bg-blue: #015bbb;
|
|
245
|
+
--bg-gray-chateau: #99a1af;
|
|
246
|
+
--bg-comet: #54556a;
|
|
247
|
+
--bg-critical: #ee3523;
|
|
248
|
+
--bg-hover: #3b3d4f;
|
|
249
|
+
--bg-yellow: #ffe824;
|
|
250
|
+
|
|
251
|
+
--foreground: #f9f9f9;
|
|
252
|
+
--border: #3b3d4f;
|
|
253
|
+
--btn-ghost: #3b3d4f;
|
|
254
|
+
--text-subdued: #cfd0d3;
|
|
255
|
+
--text-default: #f9f9f9;
|
|
256
|
+
--text-dark: #1a1e2f;
|
|
257
|
+
--text-warning: #ee9d23;
|
|
258
|
+
--text-critical: #ee3523;
|
|
259
|
+
--silver: #d1d5dc;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
@theme inline {
|
|
263
|
+
--color-primary: var(--bg-primary);
|
|
264
|
+
--color-secondary: var(--bg-secondary);
|
|
265
|
+
--color-foreground: var(--foreground);
|
|
266
|
+
--color-border: var(--border);
|
|
267
|
+
--color-default: var(--text-default);
|
|
268
|
+
--color-subdued: var(--text-subdued);
|
|
269
|
+
--color-dark: var(--text-dark);
|
|
270
|
+
--color-white: var(--white);
|
|
271
|
+
--color-dark-gray: var(--darkGray);
|
|
272
|
+
--color-silver: var(--silver);
|
|
273
|
+
--color-ring: var(--ring);
|
|
274
|
+
--color-hover: var(--bg-hover);
|
|
275
|
+
|
|
276
|
+
--color-btn-primary: var(--btn-primary);
|
|
277
|
+
--color-btn-primary-hover: var(--btn-primary-hover);
|
|
278
|
+
--color-btn-primary-active: var(--btn-primary-active);
|
|
279
|
+
--color-btn-primary-disabled: var(--btn-primary-disabled);
|
|
280
|
+
--color-btn-secondary: var(--btn-secondary);
|
|
281
|
+
--color-btn-secondary-hover: var(--btn-secondary-hover);
|
|
282
|
+
--color-btn-secondary-active: var(--btn-secondary-active);
|
|
283
|
+
--color-btn-secondary-disabled: var(--btn-secondary-disabled);
|
|
284
|
+
--color-btn-destructive: var(--btn-destructive);
|
|
285
|
+
--color-btn-destructive-hover: var(--btn-destructive-hover);
|
|
286
|
+
--color-btn-destructive-active: var(--btn-destructive-active);
|
|
287
|
+
--color-btn-destructive-disabled: var(--btn-destructive-disabled);
|
|
288
|
+
--color-btn-ghost: var(--btn-ghost);
|
|
289
|
+
|
|
290
|
+
--color-success: var(--bg-success);
|
|
291
|
+
--color-warning: var(--bg-warning);
|
|
292
|
+
--color-critical: var(--bg-critical);
|
|
293
|
+
--color-critical-light: var(--bg-critical-light);
|
|
294
|
+
--color-purple: var(--bg-purple);
|
|
295
|
+
--color-light-blue: var(--bg-light-blue);
|
|
296
|
+
--color-blue: var(--bg-blue);
|
|
297
|
+
--color-yellow: var(--bg-yellow);
|
|
298
|
+
--color-gray-chateau: var(--bg-gray-chateau);
|
|
299
|
+
--color-comet: var(--bg-comet);
|
|
300
|
+
--color-red-violet: var(--red-violet);
|
|
301
|
+
--color-tooltip-white: var(--tooltip-white);
|
|
302
|
+
--color-tooltip-black: var(--tooltip-black);
|
|
303
|
+
|
|
304
|
+
--text-3xs: 0.625rem;
|
|
305
|
+
--text-2xs: 0.75rem;
|
|
306
|
+
--text-xs: 0.875rem;
|
|
307
|
+
--text-sm: 1rem;
|
|
308
|
+
--text-m: 1.125rem;
|
|
309
|
+
--text-l: 1.25rem;
|
|
310
|
+
--text-xl: 1.375rem;
|
|
311
|
+
--text-lg: 1.5rem;
|
|
312
|
+
|
|
313
|
+
--animate-accordion-down: accordion-down 0.2s ease-out;
|
|
314
|
+
--animate-accordion-up: accordion-up 0.2s ease-out;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
@layer base {
|
|
318
|
+
html,
|
|
319
|
+
body {
|
|
320
|
+
font-size: var(--font-size);
|
|
321
|
+
font-weight: var(--font-weight-normal);
|
|
322
|
+
color: var(--foreground);
|
|
323
|
+
background-color: var(--bg-primary);
|
|
324
|
+
scrollbar-width: thin;
|
|
325
|
+
scrollbar-color: var(--border) var(--bg-primary);
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
input[type='checkbox'] {
|
|
329
|
+
appearance: none;
|
|
330
|
+
width: 1rem;
|
|
331
|
+
height: 1rem;
|
|
332
|
+
border-width: 1px;
|
|
333
|
+
border-radius: 0.25rem;
|
|
334
|
+
cursor: pointer;
|
|
335
|
+
position: relative;
|
|
336
|
+
flex-shrink: 0;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
input[type='checkbox']:checked::before {
|
|
340
|
+
content: '';
|
|
341
|
+
position: absolute;
|
|
342
|
+
top: 50%;
|
|
343
|
+
left: 50%;
|
|
344
|
+
width: 0.375rem;
|
|
345
|
+
height: 0.625rem;
|
|
346
|
+
border: solid var(--white);
|
|
347
|
+
border-width: 0 2px 2px 0;
|
|
348
|
+
transform: translate(-50%, -60%) rotate(45deg);
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
input[type='checkbox']:focus,
|
|
352
|
+
input[type='checkbox']:focus-visible {
|
|
353
|
+
outline: none;
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
@keyframes accordion-down {
|
|
358
|
+
from { height: 0; opacity: 0; }
|
|
359
|
+
to { height: var(--radix-accordion-content-height); opacity: 1; }
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
@keyframes accordion-up {
|
|
363
|
+
from { height: var(--radix-accordion-content-height); opacity: 1; }
|
|
364
|
+
to { height: 0; opacity: 0; }
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
@keyframes sync-progress {
|
|
368
|
+
0% { transform: translateX(-100%); }
|
|
369
|
+
100% { transform: translateX(350%); }
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
@keyframes dot-loading-1 {
|
|
373
|
+
0%, 100% { opacity: 1; }
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
@keyframes dot-loading-2 {
|
|
377
|
+
0%, 33% { opacity: 0; }
|
|
378
|
+
34%, 99% { opacity: 1; }
|
|
379
|
+
100% { opacity: 0; }
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
@keyframes dot-loading-3 {
|
|
383
|
+
0%, 66% { opacity: 0; }
|
|
384
|
+
67%, 99% { opacity: 1; }
|
|
385
|
+
100% { opacity: 0; }
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
@layer utilities {
|
|
389
|
+
.text-default { color: var(--text-default); }
|
|
390
|
+
.animate-progress {
|
|
391
|
+
animation: sync-progress 2.5s cubic-bezier(0.4, 0, 0.2, 1) infinite;
|
|
392
|
+
will-change: transform;
|
|
393
|
+
}
|
|
394
|
+
.animate-dot-loading-1 { animation: dot-loading-1 1.2s step-end infinite; }
|
|
395
|
+
.animate-dot-loading-2 { animation: dot-loading-2 1.2s step-end infinite; }
|
|
396
|
+
.animate-dot-loading-3 { animation: dot-loading-3 1.2s step-end infinite; }
|
|
397
|
+
.truncate-1 {
|
|
398
|
+
display: -webkit-box;
|
|
399
|
+
-webkit-box-orient: vertical;
|
|
400
|
+
-webkit-line-clamp: 1;
|
|
401
|
+
overflow: hidden;
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
</details>
|
|
407
|
+
|
|
408
|
+
The palette above is the SOC Prime default. Override any custom property to rebrand — the components read tokens only, never hard-coded colors.
|
|
409
|
+
|
|
410
|
+
### Component-level CSS
|
|
411
|
+
|
|
412
|
+
`Button` and `SpinnerSquare` ship a small compiled `.css` file each. They are imported by the components themselves, so no manual CSS import is needed; the package declares `sideEffects` so bundlers keep those imports while still tree-shaking unused components.
|
|
413
|
+
|
|
414
|
+
## Peer dependencies
|
|
415
|
+
|
|
416
|
+
Required for every consumer:
|
|
417
|
+
|
|
418
|
+
```json
|
|
419
|
+
{
|
|
420
|
+
"react": "^19.0.0",
|
|
421
|
+
"react-dom": "^19.0.0",
|
|
422
|
+
"react-router-dom": "^7.0.0",
|
|
423
|
+
"@tanstack/react-table": "^8.21.0"
|
|
424
|
+
}
|
|
425
|
+
```
|
|
426
|
+
|
|
427
|
+
`react-router-dom` is required rather than optional: `Button`, `PageHeader` and `Aside` use React Router internally, and a second copy of the router in the bundle would carry its own context — links rendered by the library would not see your `<BrowserRouter>`.
|
|
428
|
+
|
|
429
|
+
Optional peers, needed only when you import the matching subpath:
|
|
430
|
+
|
|
431
|
+
| Package | Required for |
|
|
432
|
+
| --- | --- |
|
|
433
|
+
| `monaco-editor`, `@monaco-editor/react` | `@socprime/react-ui/editor` |
|
|
434
|
+
| `recharts` | `@socprime/react-ui/charts` |
|
|
435
|
+
| `@xyflow/react`, `dagre` | `@socprime/react-ui/attack-flow` |
|
|
436
|
+
| `@storybook/react-vite`, `vite`, `vite-plugin-svgr` | `@socprime/react-ui/preset`, `@socprime/react-ui/decorators` |
|
|
437
|
+
|
|
438
|
+
Everything else (`@radix-ui/*`, `lucide-react`, `class-variance-authority`, `clsx`, `tailwind-merge`, `motion`, `sonner`) is a regular dependency and installs automatically.
|
|
439
|
+
|
|
440
|
+
## TypeScript
|
|
441
|
+
|
|
442
|
+
Types ship with the package — there is no separate `@types` package. Props types are exported as named type exports next to each component:
|
|
443
|
+
|
|
444
|
+
```tsx
|
|
445
|
+
import { Button, type ButtonProps } from '@socprime/react-ui';
|
|
446
|
+
|
|
447
|
+
type SubmitButtonProps = Omit<ButtonProps, 'variant'> & { pending: boolean };
|
|
448
|
+
```
|
|
449
|
+
|
|
450
|
+
Your `tsconfig.json` must use a resolution mode that understands `exports`:
|
|
451
|
+
|
|
452
|
+
```json
|
|
453
|
+
{
|
|
454
|
+
"compilerOptions": {
|
|
455
|
+
"moduleResolution": "bundler"
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
```
|
|
459
|
+
|
|
460
|
+
With the legacy `"node"` resolution, subpath imports resolve to neither JavaScript nor types.
|
|
461
|
+
|
|
462
|
+
## Bundler notes
|
|
463
|
+
|
|
464
|
+
### Tree shaking
|
|
465
|
+
|
|
466
|
+
`dist/` is built as separate ESM modules rather than one bundle, so importing `{ Button }` from the root export does not pull in `Table` or `Dropdown`. All relative imports are fully specified (`./Button/index.js`), which keeps the output valid for strict resolvers such as Node ESM and webpack 5 with `fullySpecified`.
|
|
467
|
+
|
|
468
|
+
### Monaco Editor in Vite hosts
|
|
469
|
+
|
|
470
|
+
`@socprime/react-ui/editor` registers Monaco workers with `new Worker(new URL(specifier, import.meta.url), { type: 'module' })` rather than the Vite-specific `?worker` suffix. `?worker` is only understood by the full Vite pipeline; during dependency pre-bundling (`optimizeDeps`, which runs through bare esbuild) such imports fail with errors like `Cannot read file: .../ts.worker.js?worker`. The `new URL(...)` form is understood natively by Vite, webpack 5+ and esbuild alike.
|
|
471
|
+
|
|
472
|
+
## Storybook preset
|
|
473
|
+
|
|
474
|
+
If your team maintains its own Storybook on top of this design system, the package provides a config factory and decorators.
|
|
475
|
+
|
|
476
|
+
```ts
|
|
477
|
+
// .storybook/main.ts
|
|
478
|
+
import path from 'node:path';
|
|
479
|
+
import { createStorybookConfig, type StorybookHostOptions } from '@socprime/react-ui/preset';
|
|
480
|
+
|
|
481
|
+
const hostRoot = '/absolute/path/to/your/app';
|
|
482
|
+
|
|
483
|
+
export default createStorybookConfig({
|
|
484
|
+
hostRoot,
|
|
485
|
+
hostSrcDir: path.join(hostRoot, 'src'),
|
|
486
|
+
themeEntry: path.join(hostRoot, 'src/index.scss'),
|
|
487
|
+
packageRoot: path.resolve(import.meta.dirname, '..'),
|
|
488
|
+
appVersion: '1.0.0',
|
|
489
|
+
} satisfies StorybookHostOptions);
|
|
490
|
+
```
|
|
491
|
+
|
|
492
|
+
```tsx
|
|
493
|
+
// .storybook/preview.tsx
|
|
494
|
+
import { createStorybookPreview } from '@socprime/react-ui/preset';
|
|
495
|
+
|
|
496
|
+
import '@storybook-host/theme-entry';
|
|
497
|
+
|
|
498
|
+
export default createStorybookPreview();
|
|
499
|
+
```
|
|
500
|
+
|
|
501
|
+
### `StorybookHostOptions`
|
|
502
|
+
|
|
503
|
+
| Field | Description |
|
|
504
|
+
| --- | --- |
|
|
505
|
+
| `hostRoot` | Absolute path to the host app root. Its `public/` is mounted as static files |
|
|
506
|
+
| `hostSrcDir` | Absolute path to `host/src`, used as a Sass `loadPaths` entry |
|
|
507
|
+
| `themeEntry` | Absolute path to the global theme stylesheet, exposed as the `@storybook-host/theme-entry` alias |
|
|
508
|
+
| `packageRoot?` | Root of **your** package, the one that owns `stories/`. Required when `/preset` is consumed as an installed dependency — otherwise `createStorybookConfig` throws instead of silently finding zero stories |
|
|
509
|
+
| `appVersion?` | Injected into the build as `__APP_VERSION__` |
|
|
510
|
+
| `extraStories?` | Additional story globs, relative to `packageRoot` |
|
|
511
|
+
|
|
512
|
+
Decorators are available separately:
|
|
513
|
+
|
|
514
|
+
```tsx
|
|
515
|
+
import { withTheme, withRouter } from '@socprime/react-ui/decorators';
|
|
516
|
+
```
|
|
517
|
+
|
|
518
|
+
`withTheme` applies the `.light` / `.dark` class and adds a **Theme** toolbar toggle; `withRouter` wraps stories in a `MemoryRouter` so router-aware components work in isolation.
|
|
519
|
+
|
|
520
|
+
## Troubleshooting
|
|
521
|
+
|
|
522
|
+
| Symptom | Cause |
|
|
523
|
+
| --- | --- |
|
|
524
|
+
| Components render completely unstyled | Missing `@source` directive, so Tailwind never generated the library's utilities |
|
|
525
|
+
| Colors are wrong or transparent | The theme custom properties are not defined, or `.light` / `.dark` is not set on `<html>` — call `applyTheme()` |
|
|
526
|
+
| `useHref() may be used only in the context of a <Router>` | `Aside`, `PageHeader` or `Button to=` rendered outside a React Router provider |
|
|
527
|
+
| `Cannot find module '@socprime/react-ui/charts'` in TS | `moduleResolution` is `"node"`; switch to `"bundler"` or `"node16"` |
|
|
528
|
+
| `require() of ES Module` | The package is ESM-only; use `import` or a dynamic `import()` |
|
|
529
|
+
| Toasts never appear | `<Toaster />` is not rendered anywhere in the tree |
|
|
530
|
+
|
|
531
|
+
## Versioning
|
|
532
|
+
|
|
533
|
+
See [CHANGELOG.md](./CHANGELOG.md) for release history and breaking changes.
|
|
534
|
+
|
|
535
|
+
## License
|
|
536
|
+
|
|
537
|
+
MIT
|
package/attack-flow.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { FC } from 'react';
|
|
2
|
+
|
|
3
|
+
interface NodeData {
|
|
4
|
+
content: string;
|
|
5
|
+
color?: string;
|
|
6
|
+
nodeClass?: string;
|
|
7
|
+
nodeId?: string;
|
|
8
|
+
}
|
|
9
|
+
interface IAttackFlow {
|
|
10
|
+
content: string;
|
|
11
|
+
className?: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
declare const AttackFlow: FC<IAttackFlow>;
|
|
15
|
+
|
|
16
|
+
export { AttackFlow, type IAttackFlow as AttackFlowProps, type NodeData };
|
package/charts.d.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import * as React$1 from 'react';
|
|
2
|
+
|
|
3
|
+
interface AreaChartDataPoint {
|
|
4
|
+
name: string;
|
|
5
|
+
value: number;
|
|
6
|
+
}
|
|
7
|
+
interface AreaChartWithGradientProps {
|
|
8
|
+
data: AreaChartDataPoint[];
|
|
9
|
+
color: string;
|
|
10
|
+
height?: number;
|
|
11
|
+
}
|
|
12
|
+
declare const AreaChartWithGradient: React$1.NamedExoticComponent<AreaChartWithGradientProps>;
|
|
13
|
+
|
|
14
|
+
interface StatisticsGraphDataPoint {
|
|
15
|
+
name: string;
|
|
16
|
+
value: number;
|
|
17
|
+
}
|
|
18
|
+
interface StatisticsGraphData {
|
|
19
|
+
name: string;
|
|
20
|
+
activeCount?: number | null;
|
|
21
|
+
totalCount: number;
|
|
22
|
+
points: StatisticsGraphDataPoint[];
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
interface StatisticCardProps {
|
|
26
|
+
title: string;
|
|
27
|
+
color: string;
|
|
28
|
+
data?: StatisticsGraphData;
|
|
29
|
+
}
|
|
30
|
+
declare const StatisticCard: React.FC<StatisticCardProps>;
|
|
31
|
+
|
|
32
|
+
export { type AreaChartDataPoint, AreaChartWithGradient, type AreaChartWithGradientProps, StatisticCard, type StatisticCardProps, type StatisticsGraphData, type StatisticsGraphDataPoint };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { MemoryRouter } from "react-router-dom";
|
|
3
|
+
const withRouter = (Story, context) => {
|
|
4
|
+
const initialPath = context.parameters.initialPath;
|
|
5
|
+
const initialEntries = initialPath ? [initialPath] : ["/"];
|
|
6
|
+
return /* @__PURE__ */ jsx(MemoryRouter, { initialEntries, children: /* @__PURE__ */ jsx(Story, {}) });
|
|
7
|
+
};
|
|
8
|
+
export {
|
|
9
|
+
withRouter
|
|
10
|
+
};
|