@dalexto/lexsys-registry 0.1.0 → 0.1.2
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/index.js +12 -3
- package/package.json +2 -2
- package/templates/blocks/AuthForm/AuthForm.tsx +2 -2
- package/templates/blocks/AuthForm/AuthForm.types.ts +3 -3
- package/templates/blocks/CommandPalette/CommandPalette.tsx +4 -4
- package/templates/blocks/CommandPalette/CommandPalette.types.ts +2 -2
- package/templates/blocks/DataTable/DataTable.tsx +2 -2
- package/templates/blocks/DataTable/DataTable.types.ts +2 -2
- package/templates/blocks/FilterToolbar/FilterToolbar.tsx +4 -4
- package/templates/blocks/FilterToolbar/FilterToolbar.types.ts +4 -4
- package/templates/blocks/FormField/FormField.tsx +1 -1
- package/templates/blocks/FormField/FormField.types.ts +1 -1
- package/templates/blocks/PageHeader/PageHeader.tsx +2 -2
- package/templates/blocks/PageHeader/PageHeader.types.ts +2 -2
- package/templates/blocks/SettingsPanel/SettingsPanel.tsx +1 -1
- package/templates/blocks/SettingsPanel/SettingsPanel.types.ts +1 -1
- package/templates/blocks/Sidebar/Sidebar.tsx +935 -22
- package/templates/blocks/Sidebar/Sidebar.types.ts +155 -1
- package/templates/blocks/Sidebar/Sidebar.utils.ts +34 -0
- package/templates/blocks/Sidebar/Sidebar.variants.ts +310 -17
- package/templates/blocks/StatsCard/StatsCard.tsx +1 -1
- package/templates/blocks/StatsCard/StatsCard.types.ts +1 -1
- package/templates/styles/theme.css +9 -1
- package/templates/styles/tokens.css +34 -1
- package/templates/templates/SettingsPageLayout/SettingsPageLayout.tsx +2 -2
- package/templates/templates/SettingsPageLayout/SettingsPageLayout.types.ts +2 -2
|
@@ -12,12 +12,49 @@ import type {
|
|
|
12
12
|
ReactNode,
|
|
13
13
|
Ref,
|
|
14
14
|
} from "react"
|
|
15
|
-
import type {
|
|
15
|
+
import type { Collapsible as BaseCollapsible } from "@base-ui/react/collapsible"
|
|
16
|
+
import type { BadgeProps } from "@/components/primitives/Badge/Badge.types"
|
|
17
|
+
import type { ButtonProps } from "@/components/primitives/Button/Button.types"
|
|
18
|
+
import type {
|
|
19
|
+
CollapsiblePanelProps,
|
|
20
|
+
CollapsibleProps,
|
|
21
|
+
} from "@/components/primitives/Collapsible/Collapsible.types"
|
|
22
|
+
import type { InputProps } from "@/components/primitives/Input/Input.types"
|
|
23
|
+
import type { SeparatorProps } from "@/components/primitives/Separator/Separator.types"
|
|
24
|
+
|
|
25
|
+
export type SidebarCollapsible = "none" | "icon" | "offcanvas"
|
|
26
|
+
export type SidebarSide = "left" | "right"
|
|
27
|
+
|
|
28
|
+
export interface SidebarProviderProps {
|
|
29
|
+
children?: ReactNode
|
|
30
|
+
defaultOpen?: boolean
|
|
31
|
+
open?: boolean
|
|
32
|
+
onOpenChange?: (open: boolean) => void
|
|
33
|
+
defaultCollapsed?: boolean
|
|
34
|
+
collapsed?: boolean
|
|
35
|
+
onCollapsedChange?: (collapsed: boolean) => void
|
|
36
|
+
collapsible?: SidebarCollapsible
|
|
37
|
+
side?: SidebarSide
|
|
38
|
+
persistKey?: string
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export interface SidebarContextValue {
|
|
42
|
+
open: boolean
|
|
43
|
+
setOpen: (open: boolean) => void
|
|
44
|
+
collapsed: boolean
|
|
45
|
+
setCollapsed: (collapsed: boolean) => void
|
|
46
|
+
toggleSidebar: () => void
|
|
47
|
+
isMobile: boolean
|
|
48
|
+
collapsible: SidebarCollapsible
|
|
49
|
+
side: SidebarSide
|
|
50
|
+
}
|
|
16
51
|
|
|
17
52
|
export interface SidebarProps extends HTMLAttributes<HTMLElement> {
|
|
18
53
|
ref?: Ref<HTMLElement>
|
|
19
54
|
className?: string
|
|
20
55
|
children?: ReactNode
|
|
56
|
+
collapsible?: SidebarCollapsible
|
|
57
|
+
side?: SidebarSide
|
|
21
58
|
}
|
|
22
59
|
|
|
23
60
|
export interface SidebarHeaderProps extends HTMLAttributes<HTMLDivElement> {
|
|
@@ -56,6 +93,22 @@ export interface SidebarGroupContentProps extends HTMLAttributes<HTMLDivElement>
|
|
|
56
93
|
children?: ReactNode
|
|
57
94
|
}
|
|
58
95
|
|
|
96
|
+
export type SidebarGroupCollapsibleProps = Omit<CollapsibleProps, "variant">
|
|
97
|
+
|
|
98
|
+
export interface SidebarGroupCollapsibleTriggerProps extends Omit<
|
|
99
|
+
BaseCollapsible.Trigger.Props,
|
|
100
|
+
"className"
|
|
101
|
+
> {
|
|
102
|
+
ref?: Ref<HTMLButtonElement>
|
|
103
|
+
className?: string
|
|
104
|
+
children?: ReactNode
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export interface SidebarGroupCollapsiblePanelProps extends CollapsiblePanelProps {
|
|
108
|
+
ref?: Ref<HTMLDivElement>
|
|
109
|
+
className?: string
|
|
110
|
+
}
|
|
111
|
+
|
|
59
112
|
export interface SidebarListProps extends HTMLAttributes<HTMLUListElement> {
|
|
60
113
|
ref?: Ref<HTMLUListElement>
|
|
61
114
|
className?: string
|
|
@@ -66,11 +119,19 @@ export interface SidebarItemProps extends LiHTMLAttributes<HTMLLIElement> {
|
|
|
66
119
|
ref?: Ref<HTMLLIElement>
|
|
67
120
|
className?: string
|
|
68
121
|
children?: ReactNode
|
|
122
|
+
/** Disables row interaction; inherited by child nav item parts unless overridden. */
|
|
123
|
+
disabled?: boolean
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export interface SidebarNavActiveOptions {
|
|
127
|
+
/** When true, only an exact pathname match is active. Defaults to `true`. */
|
|
128
|
+
end?: boolean
|
|
69
129
|
}
|
|
70
130
|
|
|
71
131
|
export interface SidebarItemLinkProps extends AnchorHTMLAttributes<HTMLAnchorElement> {
|
|
72
132
|
ref?: Ref<HTMLAnchorElement>
|
|
73
133
|
active?: boolean
|
|
134
|
+
disabled?: boolean
|
|
74
135
|
className?: string
|
|
75
136
|
children?: ReactNode
|
|
76
137
|
}
|
|
@@ -78,17 +139,110 @@ export interface SidebarItemLinkProps extends AnchorHTMLAttributes<HTMLAnchorEle
|
|
|
78
139
|
export interface SidebarItemButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
|
|
79
140
|
ref?: Ref<HTMLButtonElement>
|
|
80
141
|
active?: boolean
|
|
142
|
+
disabled?: boolean
|
|
81
143
|
className?: string
|
|
82
144
|
children?: ReactNode
|
|
83
145
|
}
|
|
84
146
|
|
|
147
|
+
export type SidebarInputProps = InputProps
|
|
148
|
+
|
|
149
|
+
export type SidebarSeparatorProps = SeparatorProps
|
|
150
|
+
|
|
151
|
+
export interface SidebarItemSkeletonProps extends HTMLAttributes<HTMLDivElement> {
|
|
152
|
+
ref?: Ref<HTMLDivElement>
|
|
153
|
+
className?: string
|
|
154
|
+
/** Renders an icon-sized pulse block. Defaults to `true`. */
|
|
155
|
+
showIcon?: boolean
|
|
156
|
+
/** Indented skeleton for nested `SidebarSubList` rows. */
|
|
157
|
+
indent?: boolean
|
|
158
|
+
}
|
|
159
|
+
|
|
85
160
|
export interface SidebarTriggerProps extends Omit<ButtonProps, "type"> {
|
|
86
161
|
ref?: Ref<HTMLButtonElement>
|
|
87
162
|
children?: ReactNode
|
|
88
163
|
}
|
|
89
164
|
|
|
165
|
+
export interface SidebarCollapseTriggerProps extends Omit<ButtonProps, "type"> {
|
|
166
|
+
ref?: Ref<HTMLButtonElement>
|
|
167
|
+
children?: ReactNode
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
export interface SidebarRailProps extends ButtonHTMLAttributes<HTMLButtonElement> {
|
|
171
|
+
ref?: Ref<HTMLButtonElement>
|
|
172
|
+
className?: string
|
|
173
|
+
}
|
|
174
|
+
|
|
90
175
|
export interface SidebarMobileHeaderProps extends HTMLAttributes<HTMLDivElement> {
|
|
91
176
|
ref?: Ref<HTMLDivElement>
|
|
92
177
|
className?: string
|
|
93
178
|
children?: ReactNode
|
|
94
179
|
}
|
|
180
|
+
|
|
181
|
+
export interface SidebarExpandableProps extends HTMLAttributes<HTMLSpanElement> {
|
|
182
|
+
ref?: Ref<HTMLSpanElement>
|
|
183
|
+
className?: string
|
|
184
|
+
children?: ReactNode
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
export interface SidebarItemBadgeProps extends BadgeProps {
|
|
188
|
+
/**
|
|
189
|
+
* Force dot indicator instead of the count badge.
|
|
190
|
+
* Defaults to dot when the sidebar is icon-collapsed on desktop.
|
|
191
|
+
*/
|
|
192
|
+
dot?: boolean
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
export interface SidebarItemIconProps extends HTMLAttributes<HTMLSpanElement> {
|
|
196
|
+
ref?: Ref<HTMLSpanElement>
|
|
197
|
+
className?: string
|
|
198
|
+
children?: ReactNode
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
export interface SidebarItemActionProps extends Omit<
|
|
202
|
+
ButtonProps,
|
|
203
|
+
"type" | "variant" | "size"
|
|
204
|
+
> {
|
|
205
|
+
ref?: Ref<HTMLButtonElement>
|
|
206
|
+
showOnHover?: boolean
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
export interface SidebarItemShortcutProps extends HTMLAttributes<HTMLElement> {
|
|
210
|
+
ref?: Ref<HTMLElement>
|
|
211
|
+
className?: string
|
|
212
|
+
children?: ReactNode
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
export interface SidebarGroupActionProps extends Omit<
|
|
216
|
+
ButtonProps,
|
|
217
|
+
"type" | "variant" | "size"
|
|
218
|
+
> {
|
|
219
|
+
ref?: Ref<HTMLButtonElement>
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
export interface SidebarSubListProps extends HTMLAttributes<HTMLUListElement> {
|
|
223
|
+
ref?: Ref<HTMLUListElement>
|
|
224
|
+
className?: string
|
|
225
|
+
children?: ReactNode
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
export interface SidebarSubItemLinkProps extends AnchorHTMLAttributes<HTMLAnchorElement> {
|
|
229
|
+
ref?: Ref<HTMLAnchorElement>
|
|
230
|
+
active?: boolean
|
|
231
|
+
disabled?: boolean
|
|
232
|
+
className?: string
|
|
233
|
+
children?: ReactNode
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
export interface SidebarSubItemButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
|
|
237
|
+
ref?: Ref<HTMLButtonElement>
|
|
238
|
+
active?: boolean
|
|
239
|
+
disabled?: boolean
|
|
240
|
+
className?: string
|
|
241
|
+
children?: ReactNode
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
export interface SidebarShellOptions {
|
|
245
|
+
collapsed?: boolean
|
|
246
|
+
collapsible?: SidebarCollapsible
|
|
247
|
+
side?: SidebarSide
|
|
248
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { SidebarNavActiveOptions } from "./Sidebar.types.js"
|
|
2
|
+
|
|
3
|
+
const stripSidebarNavPath = (value: string): string => {
|
|
4
|
+
const withoutQuery = value.split(/[?#]/u)[0] ?? value
|
|
5
|
+
const withLeadingSlash = withoutQuery.startsWith("/")
|
|
6
|
+
? withoutQuery
|
|
7
|
+
: `/${withoutQuery}`
|
|
8
|
+
|
|
9
|
+
if (withLeadingSlash.length > 1 && withLeadingSlash.endsWith("/")) {
|
|
10
|
+
return withLeadingSlash.slice(0, -1)
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
return withLeadingSlash
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Router-agnostic matcher for Sidebar `active` props.
|
|
18
|
+
* Mirrors React Router `NavLink` `end` semantics without a router dependency.
|
|
19
|
+
*/
|
|
20
|
+
export const isSidebarNavActive = (
|
|
21
|
+
pathname: string,
|
|
22
|
+
href: string,
|
|
23
|
+
options: SidebarNavActiveOptions = {},
|
|
24
|
+
): boolean => {
|
|
25
|
+
const path = stripSidebarNavPath(pathname)
|
|
26
|
+
const target = stripSidebarNavPath(href)
|
|
27
|
+
const end = options.end ?? true
|
|
28
|
+
|
|
29
|
+
if (end) {
|
|
30
|
+
return path === target
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return path === target || path.startsWith(`${target}/`)
|
|
34
|
+
}
|
|
@@ -4,16 +4,100 @@
|
|
|
4
4
|
* Variant classes for the Sidebar block.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
import { disabledStateClasses } from "@/lib/utils"
|
|
8
|
+
import type { BadgeVariant } from "@/components/primitives/Badge/Badge.types"
|
|
9
|
+
import type { SidebarShellOptions } from "./Sidebar.types"
|
|
10
|
+
|
|
11
|
+
export const sidebarRootClasses = ({
|
|
12
|
+
collapsed = false,
|
|
13
|
+
collapsible = "none",
|
|
14
|
+
side = "left",
|
|
15
|
+
}: SidebarShellOptions = {}): string => {
|
|
16
|
+
const classes = [
|
|
17
|
+
"group/sidebar lex-sidebar w-full shrink-0 md:h-full md:w-auto",
|
|
18
|
+
]
|
|
19
|
+
|
|
20
|
+
if (collapsible !== "none" && collapsed) {
|
|
21
|
+
classes.push("lex-sidebar--collapsed")
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (collapsible === "offcanvas" && collapsed) {
|
|
25
|
+
classes.push("lex-sidebar--offcanvas")
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (side === "right") {
|
|
29
|
+
classes.push("lex-sidebar--right")
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return classes.join(" ")
|
|
9
33
|
}
|
|
10
34
|
|
|
11
|
-
export const
|
|
12
|
-
return "
|
|
35
|
+
export const sidebarCollapsedItemClasses = (): string => {
|
|
36
|
+
return "md:group-data-[collapsed=true]/sidebar:justify-center md:group-data-[collapsed=true]/sidebar:px-2"
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export const sidebarCollapsedGroupLabelClasses = (): string => {
|
|
40
|
+
return "md:group-data-[collapsed=true]/sidebar:hidden"
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export const sidebarExpandableClasses = (): string => {
|
|
44
|
+
return [
|
|
45
|
+
"sidebar-expandable transition-[opacity,width] duration-(--lex-sidebar-transition-duration) ease-(--lex-sidebar-transition-easing)",
|
|
46
|
+
"md:group-data-[collapsed=true]/sidebar:hidden",
|
|
47
|
+
].join(" ")
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export const sidebarCollapsedBrandClasses = (): string => {
|
|
51
|
+
return "md:group-data-[collapsed=true]/sidebar:justify-center"
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export const sidebarCollapsedFooterClasses = (): string => {
|
|
55
|
+
return "md:group-data-[collapsed=true]/sidebar:justify-center"
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export const sidebarDesktopClasses = ({
|
|
59
|
+
collapsed = false,
|
|
60
|
+
collapsible = "none",
|
|
61
|
+
side = "left",
|
|
62
|
+
}: SidebarShellOptions = {}): string => {
|
|
63
|
+
const classes = [
|
|
64
|
+
"lex-sidebar__desktop hidden h-full shrink-0 bg-[var(--lex-color-background-subtle)] md:flex md:flex-col",
|
|
65
|
+
"overflow-hidden transition-[width,transform] duration-(--lex-sidebar-transition-duration) ease-(--lex-sidebar-transition-easing) motion-reduce:transition-none",
|
|
66
|
+
side === "right"
|
|
67
|
+
? "border-s border-[var(--lex-border-default)]"
|
|
68
|
+
: "border-e border-[var(--lex-border-default)]",
|
|
69
|
+
]
|
|
70
|
+
|
|
71
|
+
if (collapsible === "icon" && collapsed) {
|
|
72
|
+
classes.push("w-(--lex-sidebar-width-collapsed)")
|
|
73
|
+
} else if (collapsible === "offcanvas" && collapsed) {
|
|
74
|
+
classes.push(
|
|
75
|
+
"w-(--lex-sidebar-width-default)",
|
|
76
|
+
side === "right"
|
|
77
|
+
? "translate-x-full rtl:-translate-x-full"
|
|
78
|
+
: "-translate-x-full rtl:translate-x-full",
|
|
79
|
+
)
|
|
80
|
+
} else {
|
|
81
|
+
classes.push("w-(--lex-sidebar-width-default)")
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return classes.join(" ")
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export const sidebarRailClasses = ({
|
|
88
|
+
side = "left",
|
|
89
|
+
}: SidebarShellOptions = {}): string => {
|
|
90
|
+
return [
|
|
91
|
+
"lex-sidebar__rail absolute inset-y-0 hidden w-4 md:block",
|
|
92
|
+
side === "right" ? "-start-2" : "-end-2",
|
|
93
|
+
"cursor-pointer border-0 bg-transparent p-0 outline-none",
|
|
94
|
+
"after:absolute after:inset-y-0 after:w-px after:bg-[var(--lex-border-default)]",
|
|
95
|
+
side === "right" ? "after:start-2" : "after:end-2",
|
|
96
|
+
].join(" ")
|
|
13
97
|
}
|
|
14
98
|
|
|
15
99
|
export const sidebarMobileHeaderClasses = (): string => {
|
|
16
|
-
return "lex-sidebar__mobile-header min-w-0 flex-1"
|
|
100
|
+
return "lex-sidebar__mobile-header flex min-w-0 flex-1 items-center gap-3"
|
|
17
101
|
}
|
|
18
102
|
|
|
19
103
|
export const sidebarBrandClasses = (): string => {
|
|
@@ -24,34 +108,216 @@ export const sidebarNavClasses = (): string => {
|
|
|
24
108
|
return "lex-sidebar__nav min-h-0 flex-1 p-[var(--lex-space-2)]"
|
|
25
109
|
}
|
|
26
110
|
|
|
111
|
+
export const sidebarInputClasses = (): string => {
|
|
112
|
+
return [
|
|
113
|
+
"lex-sidebar__input w-full",
|
|
114
|
+
"md:group-data-[collapsed=true]/sidebar:hidden",
|
|
115
|
+
].join(" ")
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export const sidebarSeparatorClasses = (): string => {
|
|
119
|
+
return [
|
|
120
|
+
"lex-sidebar__separator",
|
|
121
|
+
"mx-[var(--lex-space-2)] w-auto",
|
|
122
|
+
"my-[var(--lex-space-1)]",
|
|
123
|
+
].join(" ")
|
|
124
|
+
}
|
|
125
|
+
|
|
27
126
|
export const sidebarNavListClasses = (): string => {
|
|
28
127
|
return "lex-sidebar__list m-0 flex list-none flex-col gap-[var(--lex-space-1)] p-0"
|
|
29
128
|
}
|
|
30
129
|
|
|
31
|
-
export const
|
|
130
|
+
export const sidebarItemClasses = (): string => {
|
|
131
|
+
return [
|
|
132
|
+
"lex-sidebar__row group/sidebar-row relative flex items-center",
|
|
133
|
+
"[&>:first-child]:min-w-0 [&>:first-child]:flex-1",
|
|
134
|
+
"has-[.lex-sidebar__item-action]:[&>:first-child]:pe-8",
|
|
135
|
+
].join(" ")
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
export const sidebarItemIconClasses = (): string => {
|
|
139
|
+
return [
|
|
140
|
+
"lex-sidebar__item-icon flex size-(--lex-sidebar-item-icon-size) shrink-0 items-center justify-center",
|
|
141
|
+
"[&_svg]:size-full",
|
|
142
|
+
].join(" ")
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
export const sidebarItemActionClasses = (showOnHover = true): string => {
|
|
146
|
+
const classes = [
|
|
147
|
+
"lex-sidebar__item-action absolute top-1/2 end-1 -translate-y-1/2",
|
|
148
|
+
"md:group-data-[collapsed=true]/sidebar:hidden",
|
|
149
|
+
]
|
|
150
|
+
|
|
151
|
+
if (showOnHover) {
|
|
152
|
+
classes.push(
|
|
153
|
+
"opacity-0 transition-opacity duration-(--lex-sidebar-transition-duration) ease-(--lex-sidebar-transition-easing)",
|
|
154
|
+
"group-hover/sidebar-row:opacity-100 focus-visible:opacity-100",
|
|
155
|
+
)
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
return classes.join(" ")
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
export const sidebarItemShortcutClasses = (): string => {
|
|
162
|
+
return [
|
|
163
|
+
"lex-sidebar__item-shortcut ms-auto shrink-0",
|
|
164
|
+
"rounded-(--lex-sidebar-item-radius) border border-[var(--lex-border-default)]",
|
|
165
|
+
"px-(--lex-space-control-x-xs) py-(--lex-space-control-y-xs)",
|
|
166
|
+
"text-(length:--lex-sidebar-item-font-size) font-(--lex-sidebar-item-font-weight)",
|
|
167
|
+
"leading-(--lex-sidebar-item-font-line-height) text-(--lex-sidebar-item-foreground)",
|
|
168
|
+
"md:group-data-[collapsed=true]/sidebar:hidden",
|
|
169
|
+
].join(" ")
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
export const sidebarGroupActionClasses = (): string => {
|
|
173
|
+
return [
|
|
174
|
+
"lex-sidebar__group-action shrink-0",
|
|
175
|
+
"md:group-data-[collapsed=true]/sidebar:hidden",
|
|
176
|
+
].join(" ")
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
export const sidebarItemBadgeClasses = (): string => {
|
|
180
|
+
return [
|
|
181
|
+
"lex-sidebar__item-badge shrink-0",
|
|
182
|
+
"max-w-(--lex-sidebar-item-badge-max-width) truncate",
|
|
183
|
+
"md:group-data-[collapsed=true]/sidebar:absolute md:group-data-[collapsed=true]/sidebar:top-1",
|
|
184
|
+
"md:group-data-[collapsed=true]/sidebar:end-1 md:group-data-[collapsed=true]/sidebar:max-w-none",
|
|
185
|
+
].join(" ")
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
export const sidebarItemBadgeCollapsedClasses = (): string => {
|
|
189
|
+
return [
|
|
190
|
+
"md:group-data-[collapsed=true]/sidebar:h-2 md:group-data-[collapsed=true]/sidebar:min-h-2",
|
|
191
|
+
"md:group-data-[collapsed=true]/sidebar:w-2 md:group-data-[collapsed=true]/sidebar:min-w-2",
|
|
192
|
+
"md:group-data-[collapsed=true]/sidebar:px-0",
|
|
193
|
+
"md:group-data-[collapsed=true]/sidebar:text-[0px] md:group-data-[collapsed=true]/sidebar:leading-(--lex-badge-font-line-height)",
|
|
194
|
+
].join(" ")
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
export const sidebarItemBadgeLabelClasses = (): string => {
|
|
198
|
+
return "md:group-data-[collapsed=true]/sidebar:sr-only"
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
const sidebarItemBadgeDotVariantClasses: Record<BadgeVariant, string> = {
|
|
202
|
+
neutral: "bg-(--lex-badge-neutral-foreground)",
|
|
203
|
+
primary: "bg-(--lex-badge-primary-background)",
|
|
204
|
+
success: "bg-(--lex-color-feedback-success-foreground)",
|
|
205
|
+
warning: "bg-(--lex-color-feedback-warning-foreground)",
|
|
206
|
+
danger: "bg-(--lex-badge-danger-background)",
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
export const sidebarItemBadgeDotClasses = (
|
|
210
|
+
variant: BadgeVariant = "neutral",
|
|
211
|
+
): string => {
|
|
212
|
+
return [
|
|
213
|
+
"size-2 rounded-full border-0 p-0",
|
|
214
|
+
sidebarItemBadgeDotVariantClasses[variant],
|
|
215
|
+
].join(" ")
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
export const sidebarSubListClasses = (): string => {
|
|
219
|
+
return [
|
|
220
|
+
"lex-sidebar__sub-list m-0 flex list-none flex-col gap-[var(--lex-space-1)] p-0",
|
|
221
|
+
"ms-[calc(var(--lex-sidebar-item-padding-x)+(var(--lex-sidebar-item-icon-size)/2))]",
|
|
222
|
+
"border-s border-[var(--lex-border-default)] ps-(--lex-sidebar-item-sub-indent)",
|
|
223
|
+
"md:group-data-[collapsed=true]/sidebar:hidden",
|
|
224
|
+
].join(" ")
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
export const sidebarSubNavItemClasses = (
|
|
228
|
+
active?: boolean,
|
|
229
|
+
disabled?: boolean,
|
|
230
|
+
): string => {
|
|
231
|
+
const base = sidebarNavItemClasses(active, disabled)
|
|
232
|
+
|
|
233
|
+
return [
|
|
234
|
+
base,
|
|
235
|
+
"ps-[calc(var(--lex-sidebar-item-padding-x)+var(--lex-sidebar-item-sub-indent))]",
|
|
236
|
+
].join(" ")
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
const sidebarNavItemActiveAccentClasses = (): string => {
|
|
240
|
+
return [
|
|
241
|
+
"before:absolute before:inset-y-1 before:w-(--lex-sidebar-item-accent-width)",
|
|
242
|
+
"before:rounded-full before:bg-(--lex-sidebar-item-accent-color) before:content-['']",
|
|
243
|
+
"before:start-0 group-data-[side=right]/sidebar:before:start-auto",
|
|
244
|
+
"group-data-[side=right]/sidebar:before:end-0",
|
|
245
|
+
].join(" ")
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
export const sidebarNavItemClasses = (
|
|
249
|
+
active?: boolean,
|
|
250
|
+
disabled?: boolean,
|
|
251
|
+
): string => {
|
|
32
252
|
const base = [
|
|
33
253
|
"lex-sidebar__item",
|
|
34
|
-
"flex w-
|
|
35
|
-
"
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
"
|
|
40
|
-
"focus-visible:ring-
|
|
254
|
+
"relative flex min-w-0 flex-1 items-center gap-(--lex-sidebar-item-gap)",
|
|
255
|
+
"rounded-(--lex-sidebar-item-radius)",
|
|
256
|
+
"px-(--lex-sidebar-item-padding-x) py-(--lex-sidebar-item-padding-y)",
|
|
257
|
+
"text-(length:--lex-sidebar-item-font-size) font-(--lex-sidebar-item-font-weight)",
|
|
258
|
+
"leading-(--lex-sidebar-item-font-line-height)",
|
|
259
|
+
"no-underline outline-none transition-colors duration-(--lex-sidebar-transition-duration) ease-(--lex-sidebar-transition-easing)",
|
|
260
|
+
"focus-visible:ring-(length:--lex-sidebar-item-focus-ring-width) focus-visible:ring-(--lex-sidebar-item-focus-ring-color)",
|
|
261
|
+
"focus-visible:ring-offset-(length:--lex-sidebar-item-focus-ring-offset) focus-visible:ring-offset-(--lex-sidebar-item-focus-ring-offset-color)",
|
|
41
262
|
].join(" ")
|
|
42
263
|
|
|
264
|
+
if (disabled) {
|
|
265
|
+
return [
|
|
266
|
+
base,
|
|
267
|
+
disabledStateClasses,
|
|
268
|
+
"cursor-not-allowed text-(--lex-color-text-disabled)",
|
|
269
|
+
"hover:bg-transparent hover:text-(--lex-color-text-disabled)",
|
|
270
|
+
"data-[disabled]:text-(--lex-color-text-disabled)",
|
|
271
|
+
].join(" ")
|
|
272
|
+
}
|
|
273
|
+
|
|
43
274
|
if (active) {
|
|
44
275
|
return [
|
|
45
276
|
base,
|
|
46
277
|
"lex-sidebar__item--active",
|
|
47
|
-
"bg-(--lex-
|
|
48
|
-
"
|
|
278
|
+
"bg-(--lex-sidebar-item-background-active) text-(--lex-sidebar-item-foreground-active)",
|
|
279
|
+
"font-(--lex-sidebar-item-font-weight-active)",
|
|
280
|
+
sidebarNavItemActiveAccentClasses(),
|
|
281
|
+
"hover:bg-(--lex-sidebar-item-background-active) hover:text-(--lex-sidebar-item-foreground-active)",
|
|
49
282
|
].join(" ")
|
|
50
283
|
}
|
|
51
284
|
|
|
52
285
|
return [
|
|
53
286
|
base,
|
|
54
|
-
"
|
|
287
|
+
"text-(--lex-sidebar-item-foreground)",
|
|
288
|
+
"hover:bg-(--lex-sidebar-item-background-hover) hover:text-(--lex-color-text-primary)",
|
|
289
|
+
].join(" ")
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
export const sidebarItemSkeletonClasses = (indent = false): string => {
|
|
293
|
+
const classes = [
|
|
294
|
+
"lex-sidebar__item-skeleton flex w-full min-w-0 flex-1 items-center gap-(--lex-sidebar-item-gap)",
|
|
295
|
+
"rounded-(--lex-sidebar-item-radius)",
|
|
296
|
+
"px-(--lex-sidebar-item-padding-x) py-(--lex-sidebar-item-padding-y)",
|
|
297
|
+
sidebarCollapsedItemClasses(),
|
|
298
|
+
]
|
|
299
|
+
|
|
300
|
+
if (indent) {
|
|
301
|
+
classes.push(
|
|
302
|
+
"ps-[calc(var(--lex-sidebar-item-padding-x)+var(--lex-sidebar-item-sub-indent))]",
|
|
303
|
+
)
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
return classes.join(" ")
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
export const sidebarItemSkeletonIconClasses = (): string => {
|
|
310
|
+
return [
|
|
311
|
+
"lex-sidebar__item-skeleton-icon size-(--lex-sidebar-item-icon-size) shrink-0",
|
|
312
|
+
"rounded-(--lex-sidebar-item-radius) animate-pulse bg-(--lex-color-background-subtle)",
|
|
313
|
+
].join(" ")
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
export const sidebarItemSkeletonLabelClasses = (): string => {
|
|
317
|
+
return [
|
|
318
|
+
"lex-sidebar__item-skeleton-label h-[1em] min-w-0 flex-1",
|
|
319
|
+
"rounded-(--lex-sidebar-item-radius) animate-pulse bg-(--lex-color-background-subtle)",
|
|
320
|
+
"md:group-data-[collapsed=true]/sidebar:hidden",
|
|
55
321
|
].join(" ")
|
|
56
322
|
}
|
|
57
323
|
|
|
@@ -72,9 +338,36 @@ export const sidebarGroupClasses = (): string => {
|
|
|
72
338
|
}
|
|
73
339
|
|
|
74
340
|
export const sidebarGroupLabelClasses = (): string => {
|
|
75
|
-
return
|
|
341
|
+
return [
|
|
342
|
+
"lex-sidebar__group-label flex items-center justify-between gap-[var(--lex-space-2)]",
|
|
343
|
+
"px-[var(--lex-space-3)] py-[var(--lex-space-1)]",
|
|
344
|
+
"text-(length:--lex-menu-group-label-font-size) font-(--lex-menu-group-label-font-weight)",
|
|
345
|
+
"leading-(--lex-menu-group-label-font-line-height) text-(--lex-menu-group-label-foreground)",
|
|
346
|
+
].join(" ")
|
|
76
347
|
}
|
|
77
348
|
|
|
78
349
|
export const sidebarGroupContentClasses = (): string => {
|
|
79
350
|
return "lex-sidebar__group-content flex flex-col gap-[var(--lex-space-1)]"
|
|
80
351
|
}
|
|
352
|
+
|
|
353
|
+
export const sidebarGroupCollapsibleClasses = (): string => {
|
|
354
|
+
return "group/sidebar-group-collapsible lex-sidebar__group-collapsible"
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
export const sidebarGroupCollapsibleTriggerClasses = (): string => {
|
|
358
|
+
return [
|
|
359
|
+
"lex-sidebar__group-collapsible-trigger",
|
|
360
|
+
"flex min-w-0 flex-1 items-center gap-[var(--lex-space-2)] text-left outline-none",
|
|
361
|
+
"text-(length:--lex-menu-group-label-font-size) font-(--lex-menu-group-label-font-weight)",
|
|
362
|
+
"leading-(--lex-menu-group-label-font-line-height) text-(--lex-menu-group-label-foreground)",
|
|
363
|
+
"transition-colors duration-(--lex-sidebar-transition-duration) ease-(--lex-sidebar-transition-easing)",
|
|
364
|
+
"hover:text-(--lex-menu-group-label-foreground)",
|
|
365
|
+
"focus-visible:ring-(length:--lex-focus-ring-width) focus-visible:ring-inset focus-visible:ring-(--lex-focus-ring-color)",
|
|
366
|
+
"[&>svg]:ms-auto [&>svg]:size-4 [&>svg]:shrink-0 [&>svg]:transition-transform",
|
|
367
|
+
"group-data-[panel-open]/sidebar-group-collapsible:[&>svg]:rotate-180",
|
|
368
|
+
].join(" ")
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
export const sidebarGroupCollapsiblePanelClasses = (): string => {
|
|
372
|
+
return "lex-sidebar__group-collapsible-panel p-0"
|
|
373
|
+
}
|
|
@@ -12,7 +12,7 @@ import type {
|
|
|
12
12
|
CardHeaderProps,
|
|
13
13
|
CardProps,
|
|
14
14
|
CardTitleProps,
|
|
15
|
-
} from "@/components/primitives/Card"
|
|
15
|
+
} from "@/components/primitives/Card/Card.types"
|
|
16
16
|
|
|
17
17
|
export interface StatsCardProps extends Omit<CardProps, "children"> {
|
|
18
18
|
ref?: Ref<HTMLDivElement>
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Generated by @dalexto/lexsys-tokens.
|
|
5
5
|
* Manual changes will be overwritten.
|
|
6
|
-
* Last generated: 2026-06-
|
|
6
|
+
* Last generated: 2026-06-06T23:24:29.234Z
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
:root {
|
|
@@ -100,12 +100,20 @@
|
|
|
100
100
|
--spacing-twix-overlay-list-max-height: var(--lex-size-overlay-list-max-height);
|
|
101
101
|
--spacing-twix-overlay-viewport-max-height: var(--lex-size-overlay-viewport-max-height);
|
|
102
102
|
--spacing-twix-sidebar-width: var(--lex-size-sidebar-width);
|
|
103
|
+
--spacing-twix-sidebar-width-collapsed: var(--lex-size-sidebar-width-collapsed);
|
|
103
104
|
--spacing-twix-command-palette-list-max-height: var(--lex-size-command-palette-list-max-height);
|
|
104
105
|
--duration-twix-control: var(--lex-duration-control);
|
|
105
106
|
--duration-twix-surface: var(--lex-duration-surface);
|
|
107
|
+
--duration-twix-overlay-enter: var(--lex-duration-overlay-enter);
|
|
108
|
+
--duration-twix-overlay-exit: var(--lex-duration-overlay-exit);
|
|
109
|
+
--duration-twix-layout: var(--lex-duration-layout);
|
|
106
110
|
--ease-twix-control: var(--lex-easing-control);
|
|
107
111
|
--ease-twix-surface: var(--lex-easing-surface);
|
|
112
|
+
--ease-twix-ease-in: var(--lex-easing-ease-in);
|
|
113
|
+
--ease-twix-ease-out: var(--lex-easing-ease-out);
|
|
114
|
+
--ease-twix-layout: var(--lex-easing-layout);
|
|
108
115
|
--twix-motion-offset-entry-y: var(--lex-motion-offset-entry-y);
|
|
116
|
+
--twix-motion-offset-slide-panel: var(--lex-motion-offset-slide-panel);
|
|
109
117
|
--text-twix-family-sans: var(--lex-typography-family-sans);
|
|
110
118
|
--text-twix-family-serif: var(--lex-typography-family-serif);
|
|
111
119
|
--text-twix-family-mono: var(--lex-typography-family-mono);
|