@zvoove/unity-ui 2.23.1 → 2.24.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/bin/cli.js +5629 -0
- package/{bin/commands/skills.mjs → dist/bin/generate-skills.js} +621 -688
- package/dist/llms.txt +74 -34
- package/dist/theme.css +54 -0
- package/dist/unity-ui.cjs.js +1 -1
- package/dist/unity-ui.css +1 -1
- package/dist/unity-ui.d.ts +127 -9
- package/dist/unity-ui.es.js +308 -298
- package/package.json +16 -14
- package/bin/cli.mjs +0 -49
- package/bin/commands/config.mjs +0 -68
- package/bin/commands/create.mjs +0 -163
- package/bin/commands/init.mjs +0 -158
- package/bin/commands/rules.mjs +0 -100
- package/bin/generate-skills.mjs +0 -32
- /package/{bin → dist/bin}/templates/component.tsx +0 -0
- /package/{bin → dist/bin}/templates/doc.mdx +0 -0
- /package/{bin → dist/bin}/templates/index.ts +0 -0
- /package/{bin → dist/bin}/templates/stories.tsx +0 -0
- /package/{bin → dist/bin}/templates/styled.ts +0 -0
- /package/{bin → dist/bin}/templates/test.tsx +0 -0
- /package/{bin → dist/bin}/templates/types.ts +0 -0
package/dist/llms.txt
CHANGED
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
> This file describes all available components in the Unity UI design system.
|
|
4
4
|
> When building UIs, use ONLY these components. Do NOT create custom components for functionality already provided here.
|
|
5
5
|
|
|
6
|
+
**Styling exports from this library:** Do **not** pass `className` or `style` to Unity UI components (for example `Stack`, `Grid`, `Button`, `Card`, `Typography`). They are already styled via their public props and design tokens. Use token-based Tailwind classes only on **native HTML elements** (for example a wrapping `div` or `section`) when you need extra positioning or chrome that has no matching component prop.
|
|
7
|
+
|
|
6
8
|
## Setup
|
|
7
9
|
|
|
8
10
|
Install:
|
|
@@ -53,18 +55,23 @@ Values cascade upward — setting `mobile` applies to all larger breakpoints unt
|
|
|
53
55
|
|
|
54
56
|
### Stack
|
|
55
57
|
**Primary layout component.** Use Stack for ALL layout needs — arranging children in rows or columns with consistent spacing. Do NOT use Card or raw divs for layout.
|
|
58
|
+
|
|
59
|
+
**Default `align` is `baseline`** — always set it explicitly when you need centering, stretching, or any other alignment. Never assume items are centered without `align="center"`.
|
|
60
|
+
|
|
61
|
+
**Dividers need `width="100%"` on the Stack** — without it the divider may not reach the edges.
|
|
62
|
+
|
|
56
63
|
```tsx
|
|
57
64
|
import { Stack } from '@zvoove/unity-ui';
|
|
58
65
|
|
|
59
66
|
<Stack
|
|
60
67
|
direction="column" // ResponsiveType<'row' | 'row-reverse' | 'column' | 'column-reverse'>
|
|
61
68
|
gap="md" // ResponsiveType<SpacingKeys> - none|xs2|xs|sm|md|lg|xl|xl2|xl3|xl4|xl5|xl6|xl7
|
|
62
|
-
align="center" // ResponsiveType<AlignItems> - default: 'baseline'
|
|
69
|
+
align="center" // ResponsiveType<AlignItems> - default: 'baseline' — set explicitly every time
|
|
63
70
|
justify="space-between" // ResponsiveType<JustifyContent>
|
|
64
71
|
wrap="wrap" // ResponsiveType<FlexWrap>
|
|
65
72
|
padding="md" // ResponsiveType<Padding>
|
|
66
73
|
margin="none" // ResponsiveType<Margin>
|
|
67
|
-
width="100%" // ResponsiveType<number | string>
|
|
74
|
+
width="100%" // ResponsiveType<number | string> — required when Stack contains a Divider
|
|
68
75
|
height="auto" // ResponsiveType<number | string>
|
|
69
76
|
minWidth, maxWidth, minHeight, maxHeight // ResponsiveType<number | string>
|
|
70
77
|
>
|
|
@@ -74,18 +81,25 @@ import { Stack } from '@zvoove/unity-ui';
|
|
|
74
81
|
|
|
75
82
|
Common patterns:
|
|
76
83
|
```tsx
|
|
84
|
+
// Row with icon + label — must set align="center" or they baseline-align
|
|
85
|
+
<Stack direction="row" gap="sm" align="center">
|
|
86
|
+
<Icon name="info" />
|
|
87
|
+
<Typography variant="body" size="medium">Label</Typography>
|
|
88
|
+
</Stack>
|
|
89
|
+
|
|
90
|
+
// Divider spanning full width — Stack must have width="100%"
|
|
91
|
+
<Stack direction="column" gap="md" width="100%">
|
|
92
|
+
<Typography variant="title" size="large">Title</Typography>
|
|
93
|
+
<Divider />
|
|
94
|
+
<Typography variant="body" size="medium">Content</Typography>
|
|
95
|
+
</Stack>
|
|
96
|
+
|
|
77
97
|
// Page layout — stacks vertically on mobile, horizontally on tablet+
|
|
78
98
|
<Stack direction={{ mobile: 'column', tablet: 'row' }} gap="lg">
|
|
79
99
|
<Sidebar />
|
|
80
100
|
<MainContent />
|
|
81
101
|
</Stack>
|
|
82
102
|
|
|
83
|
-
// Form fields in a row
|
|
84
|
-
<Stack direction="row" gap="md" align="flex-end">
|
|
85
|
-
<TextField label="First name" name="first" />
|
|
86
|
-
<TextField label="Last name" name="last" />
|
|
87
|
-
</Stack>
|
|
88
|
-
|
|
89
103
|
// Action bar — right-aligned buttons
|
|
90
104
|
<Stack direction="row" gap="sm" justify="flex-end">
|
|
91
105
|
<Button variant="outlined">Cancel</Button>
|
|
@@ -790,9 +804,9 @@ import { Breadcrumbs } from '@zvoove/unity-ui';
|
|
|
790
804
|
```
|
|
791
805
|
|
|
792
806
|
### SideNavigation
|
|
793
|
-
Collapsible sidebar navigation with user area
|
|
807
|
+
Collapsible sidebar navigation with user area, optional **root** mid-sections, and optional **sub-menu panels** (`parentId` + arbitrary `content`).
|
|
794
808
|
```tsx
|
|
795
|
-
import { SideNavigation, type MidSection } from '@zvoove/unity-ui';
|
|
809
|
+
import { MidSectionMenus, SideNavigation, type MidSection, type SubMenuLayer } from '@zvoove/unity-ui';
|
|
796
810
|
|
|
797
811
|
<SideNavigation
|
|
798
812
|
menuItems={[ // ListMenuItem[] (required)
|
|
@@ -802,16 +816,14 @@ import { SideNavigation, type MidSection } from '@zvoove/unity-ui';
|
|
|
802
816
|
utilityItems={[ // ListMenuItem[]
|
|
803
817
|
{ id: 'settings', label: 'Einstellungen', icon: 'settings', href: '/settings' },
|
|
804
818
|
]}
|
|
805
|
-
midSections={[ // MidSection[] —
|
|
806
|
-
{
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
items: [{ id: 'p1', label: 'Pinned item', href: '#' }],
|
|
810
|
-
},
|
|
819
|
+
midSections={[ // MidSection[] — root column only; sub-panel lists go in `subMenus[].content`
|
|
820
|
+
{ title: 'ANGEPINNT', replaceWithIconOnClose: 'pin', items: [{ id: 'p1', label: 'Pinned item', href: '#' }] },
|
|
821
|
+
]}
|
|
822
|
+
subMenus={[ // SubMenuLayer[] — matching menu rows get chevron-right endContent; shell renders back row (Tag = parent label) + spacer; body is your ReactNode (e.g. ListMenu from an MFE)
|
|
811
823
|
{
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
824
|
+
parentId: 'users', // must match an item id in menuItems, utilityItems, or midSections
|
|
825
|
+
backLabel: 'Hauptmenü', // optional (default: 'Hauptmenü')
|
|
826
|
+
content: <MidSectionMenus sections={...} open={open} variant={variant} />,
|
|
815
827
|
},
|
|
816
828
|
]}
|
|
817
829
|
userArea={{ // UserAreaProps — user info at the bottom
|
|
@@ -826,22 +838,42 @@ import { SideNavigation, type MidSection } from '@zvoove/unity-ui';
|
|
|
826
838
|
name: <MyWordmark />, // shown when expanded (fades in/out)
|
|
827
839
|
}}
|
|
828
840
|
hideUserAreaInMobile={true} // boolean (default: true) — hides user area on mobile
|
|
829
|
-
activeItem="home" // string
|
|
841
|
+
activeItem="home" // string — root id, or `parentId` / `parentId.*` to open a sub panel (segment after dot is app-defined)
|
|
830
842
|
variant="default" // 'default' | 'compact'
|
|
831
843
|
open={true} // boolean
|
|
832
844
|
onToggleOpen={handleToggle} // (open: boolean) => void
|
|
833
|
-
|
|
845
|
+
onActiveItemChange={setId} // (activeItem: string) => void — root/utility/parentId when opening a layer; not for `__back__` or clicks inside `content`
|
|
846
|
+
onItemClick={handleClick} // (item: ListMenuItem) => void — root, utility, sub parent, back row (`__back__`); not clicks inside `content`
|
|
834
847
|
linkComponent={Link} // React.ElementType
|
|
835
848
|
/>
|
|
836
849
|
```
|
|
837
850
|
|
|
851
|
+
### MidSectionMenus
|
|
852
|
+
Renders the same **mid-section** blocks as `SideNavigation`’s `midSections` (titles, dividers, `ListMenu`, `replaceWithIconOnClose` hover menus when collapsed on desktop). **Inner lists are always `ListMenu` `variant="compact"`** (fixed; not configurable). Prop **`variant`** only matches the parent sidebar **rail width** (`default` vs `compact` open/closed widths), not row density. Uses **`useBreakpoint()`** internally (`isSmallerThan('tablet')` for mobile). Use in `subMenus[].content` with the same **`open`** / **`variant`** as the parent shell.
|
|
853
|
+
```tsx
|
|
854
|
+
import { MidSectionMenus, type MidSection } from '@zvoove/unity-ui';
|
|
855
|
+
|
|
856
|
+
<MidSectionMenus
|
|
857
|
+
sections={[ // MidSection[]
|
|
858
|
+
{ title: 'ANGEPINNT', replaceWithIconOnClose: 'pin', items: [/* ListMenuItem[] */] },
|
|
859
|
+
]}
|
|
860
|
+
open={true} // boolean — sidebar expanded
|
|
861
|
+
variant="default" // 'default' | 'compact' — shell width only; lists stay compact
|
|
862
|
+
activeItem="x" // string | undefined
|
|
863
|
+
onItemClick={handleClick} // (item: ListMenuItem) => void
|
|
864
|
+
linkComponent={Link} // optional, default 'a'
|
|
865
|
+
/>
|
|
866
|
+
```
|
|
867
|
+
|
|
838
868
|
### ListMenu
|
|
839
869
|
Standalone vertical menu with icon + label items. Used internally by SideNavigation, available standalone.
|
|
870
|
+
|
|
871
|
+
**`items`:** either a flat `ListMenuItem[]` **or** sectioned `ListMenuSection[]` (`{ title?, items: ListMenuItem[] }[]`). Mutually exclusive — do not mix row objects and section objects in one array. Empty `[]` is treated as flat. Optional `title` per section is **uppercase** (`label` / `small` / `on-surface-variant`); omit it or use whitespace-only to hide the header (e.g. first section untitled). Titles collapse when `open` is `false`. Use `isListMenuSections(items)` for the same runtime check the component uses.
|
|
840
872
|
```tsx
|
|
841
|
-
import { ListMenu, type ListMenuItem } from '@zvoove/unity-ui';
|
|
873
|
+
import { ListMenu, type ListMenuItem, type ListMenuSection, isListMenuSections } from '@zvoove/unity-ui';
|
|
842
874
|
|
|
843
875
|
<ListMenu
|
|
844
|
-
items={[ // ListMenuItem[] (required)
|
|
876
|
+
items={[ // ListMenuItem[] | ListMenuSection[] (required)
|
|
845
877
|
{ id: 'home', label: 'Startseite', icon: 'home', href: '/' },
|
|
846
878
|
{ id: 'chat', label: 'Chat title', href: '#',
|
|
847
879
|
endContent: <Icon name="pin" size="xs" />, // extra content on the right
|
|
@@ -849,6 +881,11 @@ import { ListMenu, type ListMenuItem } from '@zvoove/unity-ui';
|
|
|
849
881
|
},
|
|
850
882
|
{ id: 'spacer', label: '', isSpacer: true }, // renders a 16px vertical spacer
|
|
851
883
|
]}
|
|
884
|
+
// Sectioned example (separate usage — not mixed with flat rows):
|
|
885
|
+
// items={[
|
|
886
|
+
// { title: 'Gruppe', items: [{ id: 'a', label: 'A', href: '#' }] },
|
|
887
|
+
// { items: [{ id: 'b', label: 'B', href: '#' }] },
|
|
888
|
+
// ]}
|
|
852
889
|
activeItem="home" // string
|
|
853
890
|
open={true} // boolean — shows/hides labels with animation
|
|
854
891
|
variant="default" // 'default' | 'compact'
|
|
@@ -1537,14 +1574,17 @@ function ContactForm() {
|
|
|
1537
1574
|
## RULES FOR AI AGENTS
|
|
1538
1575
|
|
|
1539
1576
|
1. **Always import from `@zvoove/unity-ui`** - never recreate components that exist in this library
|
|
1540
|
-
2. **
|
|
1541
|
-
3. **
|
|
1542
|
-
4. **
|
|
1543
|
-
5. **Use
|
|
1544
|
-
6. **Use
|
|
1545
|
-
7. **Use
|
|
1546
|
-
8. **Use
|
|
1547
|
-
9. **Use
|
|
1548
|
-
10. **Use
|
|
1549
|
-
11. **
|
|
1550
|
-
12. **
|
|
1577
|
+
2. **NEVER pass `className` or `style` to ANY Unity UI component** — components are not customizable via className/style; use their props API exclusively. For layout or chrome not covered by a prop, wrap in a native HTML element (`div`, `section`, etc.) and apply design-token Tailwind utilities there
|
|
1578
|
+
3. **Use Stack and Grid for layout** - do not use Card, div, or CSS for layout. Stack is for rows/columns, Grid is for multi-column layouts
|
|
1579
|
+
4. **Card is a visual container, NOT a layout tool** - Card provides background, elevation, and border. Wrap layout content in Stack/Grid INSIDE a Card. Never use Card to arrange items
|
|
1580
|
+
5. **Use Typography for all text** - never use raw `<p>`, `<h1>`, `<span>` etc.
|
|
1581
|
+
6. **Use the spacing scale** for gap/padding/margin - never use arbitrary pixel values
|
|
1582
|
+
7. **Use Button variants** appropriately - primary actions: `filled`, secondary: `outlined`, destructive: `negative`, success: `positive`
|
|
1583
|
+
8. **Use TextField/Select/Checkbox/Radio for forms** - never create custom form inputs
|
|
1584
|
+
9. **Use Dialog for modals, Sheet for panels** - never create custom overlays
|
|
1585
|
+
10. **Use Snackbar for notifications** - never create custom toast systems
|
|
1586
|
+
11. **Use responsive props** when the UI should adapt to screen sizes. Values cascade up from smallest breakpoint. Common pattern: `{{ mobile: 'column', tablet: 'row' }}`
|
|
1587
|
+
12. **Card, Dialog, Sheet padding can be "none"** - use `padding="none"` for edge-to-edge content like images, tables, or dividers inside these components
|
|
1588
|
+
13. **Icons use semantic names** as strings (e.g., `"search"`, `"delete"`, `"edit"`) - never import Phosphor icon components directly
|
|
1589
|
+
14. **Stack `align` defaults to `baseline`** — always set `align` explicitly when you need centering (`align="center"`), stretching, or any other alignment. Never assume items are centered without it
|
|
1590
|
+
15. **Stack containing a Divider needs `width="100%"`** — without it the divider will not span the full width of the container
|
package/dist/theme.css
CHANGED
|
@@ -139,6 +139,7 @@
|
|
|
139
139
|
--color-primary-70: #9aa4ff;
|
|
140
140
|
--color-primary-80: #bdc2ff;
|
|
141
141
|
--color-primary-90: #dfe0ff;
|
|
142
|
+
--color-primary-92: #eeeff7;
|
|
142
143
|
--color-primary-95: #eff0ff;
|
|
143
144
|
--color-primary-99: #fbfbff;
|
|
144
145
|
--color-primary-100: #ffffff;
|
|
@@ -285,6 +286,9 @@
|
|
|
285
286
|
--color-on-primary-container: var(--color-primary-10);
|
|
286
287
|
--color-secondary-container: var(--color-secondary-90);
|
|
287
288
|
--color-on-secondary-container: var(--color-secondary-10);
|
|
289
|
+
--color-container-neutral: var(--color-neutral-variant-95);
|
|
290
|
+
--color-container-neutral-hover: var(--color-neutral-variant-92);
|
|
291
|
+
--color-on-container-neutral: var(--color-neutral-variant-10);
|
|
288
292
|
--color-tertiary-container: var(--color-tertiary-90);
|
|
289
293
|
--color-tertiary-container-hover: var(--color-tertiary-80);
|
|
290
294
|
--color-tertiary-container-active: var(--color-tertiary-70);
|
|
@@ -508,6 +512,9 @@
|
|
|
508
512
|
--color-on-primary-container: var(--color-primary-90);
|
|
509
513
|
--color-secondary-container: var(--color-secondary-30);
|
|
510
514
|
--color-on-secondary-container: var(--color-secondary-90);
|
|
515
|
+
--color-container-neutral: var(--color-neutral-variant-10);
|
|
516
|
+
--color-container-neutral-hover: var(--color-neutral-variant-15);
|
|
517
|
+
--color-on-container-neutral: var(--color-neutral-variant-95);
|
|
511
518
|
--color-tertiary-container: var(--color-tertiary-30);
|
|
512
519
|
--color-tertiary-container-hover: var(--color-tertiary-40);
|
|
513
520
|
--color-tertiary-container-active: var(--color-tertiary-50);
|
|
@@ -612,6 +619,53 @@
|
|
|
612
619
|
display: none; /* Chrome, Safari */
|
|
613
620
|
}
|
|
614
621
|
}
|
|
622
|
+
|
|
623
|
+
.scrollbar-overlay {
|
|
624
|
+
/* Firefox — thin bar, transparent until hover/scroll */
|
|
625
|
+
scrollbar-width: thin;
|
|
626
|
+
scrollbar-color: transparent transparent;
|
|
627
|
+
|
|
628
|
+
/* Chrome / Edge / Safari */
|
|
629
|
+
&::-webkit-scrollbar {
|
|
630
|
+
width: 6px;
|
|
631
|
+
height: 6px;
|
|
632
|
+
background: transparent;
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
&::-webkit-scrollbar-thumb {
|
|
636
|
+
background: transparent;
|
|
637
|
+
border-radius: 9999px;
|
|
638
|
+
transition: background 0.2s ease;
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
/* Visible on hover */
|
|
642
|
+
&:hover {
|
|
643
|
+
scrollbar-color: color-mix(
|
|
644
|
+
in srgb,
|
|
645
|
+
var(--color-on-surface) 30%,
|
|
646
|
+
transparent
|
|
647
|
+
)
|
|
648
|
+
transparent;
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
&:hover::-webkit-scrollbar-thumb {
|
|
652
|
+
background: color-mix(in srgb, var(--color-on-surface) 30%, transparent);
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
/* Visible while actively scrolling (toggled by JS scroll listener) */
|
|
656
|
+
&[data-scrolling='true'] {
|
|
657
|
+
scrollbar-color: color-mix(
|
|
658
|
+
in srgb,
|
|
659
|
+
var(--color-on-surface) 30%,
|
|
660
|
+
transparent
|
|
661
|
+
)
|
|
662
|
+
transparent;
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
&[data-scrolling='true']::-webkit-scrollbar-thumb {
|
|
666
|
+
background: color-mix(in srgb, var(--color-on-surface) 30%, transparent);
|
|
667
|
+
}
|
|
668
|
+
}
|
|
615
669
|
.prevent-select {
|
|
616
670
|
-webkit-user-select: none; /* Safari */
|
|
617
671
|
-ms-user-select: none; /* IE 10 and IE 11 */
|