@dalexto/lexsys-registry 0.1.1 → 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.
Files changed (26) hide show
  1. package/dist/index.js +12 -3
  2. package/package.json +2 -2
  3. package/templates/blocks/AuthForm/AuthForm.tsx +2 -2
  4. package/templates/blocks/AuthForm/AuthForm.types.ts +3 -3
  5. package/templates/blocks/CommandPalette/CommandPalette.tsx +4 -4
  6. package/templates/blocks/CommandPalette/CommandPalette.types.ts +2 -2
  7. package/templates/blocks/DataTable/DataTable.tsx +2 -2
  8. package/templates/blocks/DataTable/DataTable.types.ts +2 -2
  9. package/templates/blocks/FilterToolbar/FilterToolbar.tsx +4 -4
  10. package/templates/blocks/FilterToolbar/FilterToolbar.types.ts +4 -4
  11. package/templates/blocks/FormField/FormField.tsx +1 -1
  12. package/templates/blocks/FormField/FormField.types.ts +1 -1
  13. package/templates/blocks/PageHeader/PageHeader.tsx +2 -2
  14. package/templates/blocks/PageHeader/PageHeader.types.ts +2 -2
  15. package/templates/blocks/SettingsPanel/SettingsPanel.tsx +1 -1
  16. package/templates/blocks/SettingsPanel/SettingsPanel.types.ts +1 -1
  17. package/templates/blocks/Sidebar/Sidebar.tsx +935 -22
  18. package/templates/blocks/Sidebar/Sidebar.types.ts +155 -1
  19. package/templates/blocks/Sidebar/Sidebar.utils.ts +34 -0
  20. package/templates/blocks/Sidebar/Sidebar.variants.ts +310 -17
  21. package/templates/blocks/StatsCard/StatsCard.tsx +1 -1
  22. package/templates/blocks/StatsCard/StatsCard.types.ts +1 -1
  23. package/templates/styles/theme.css +9 -1
  24. package/templates/styles/tokens.css +34 -1
  25. package/templates/templates/SettingsPageLayout/SettingsPageLayout.tsx +2 -2
  26. 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 { ButtonProps } from "@/components/primitives/Button"
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
- export const sidebarRootClasses = (): string => {
8
- return "lex-sidebar w-full shrink-0 md:h-full md:w-auto"
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 sidebarDesktopClasses = (): string => {
12
- return "lex-sidebar__desktop hidden h-full w-[var(--lex-size-sidebar-width,16rem)] shrink-0 border-r border-[var(--lex-border-default)] bg-[var(--lex-color-background-subtle)] md:flex md:flex-col"
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 sidebarNavItemClasses = (active?: boolean): string => {
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-full items-center rounded-(--lex-menu-item-radius)",
35
- "px-(--lex-menu-item-padding-x) py-(--lex-menu-item-padding-y)",
36
- "text-(length:--lex-menu-item-font-size) font-(--lex-menu-item-font-weight)",
37
- "leading-(--lex-menu-item-font-line-height) text-(--lex-menu-item-foreground)",
38
- "no-underline outline-none transition-colors",
39
- "focus-visible:ring-(length:--lex-menu-item-focus-ring-width) focus-visible:ring-(--lex-menu-item-focus-ring-color)",
40
- "focus-visible:ring-offset-(length:--lex-menu-item-focus-ring-offset) focus-visible:ring-offset-(--lex-menu-item-focus-ring-offset-color)",
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-menu-item-checked-background) text-(--lex-menu-item-checked-foreground)",
48
- "hover:bg-(--lex-action-primary-hover) hover:text-(--lex-menu-item-checked-foreground)",
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
- "hover:bg-(--lex-action-secondary-hover) hover:text-(--lex-color-text-primary)",
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 "lex-sidebar__group-label px-[var(--lex-space-3)] py-[var(--lex-space-1)] text-(length:--lex-menu-group-label-font-size) font-(--lex-menu-group-label-font-weight) leading-(--lex-menu-group-label-font-line-height) text-(--lex-menu-group-label-foreground)"
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
+ }
@@ -11,7 +11,7 @@ import {
11
11
  CardFooter,
12
12
  CardHeader,
13
13
  CardTitle,
14
- } from "@/components/primitives/Card"
14
+ } from "@/components/primitives/Card/Card"
15
15
  import type {
16
16
  StatsCardContentProps,
17
17
  StatsCardDescriptionProps,
@@ -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-06T12:57:40.698Z
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);