@torch-ui/solid 0.1.3

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 (118) hide show
  1. package/README.md +166 -0
  2. package/package.json +67 -0
  3. package/src/components/actions/Button.tsx +612 -0
  4. package/src/components/actions/ButtonGroup.tsx +728 -0
  5. package/src/components/actions/Copy.tsx +98 -0
  6. package/src/components/actions/DarkModeToggle.tsx +80 -0
  7. package/src/components/actions/Link.tsx +37 -0
  8. package/src/components/actions/index.ts +19 -0
  9. package/src/components/actions/useCopyToClipboard.ts +90 -0
  10. package/src/components/charts/Chart.tsx +331 -0
  11. package/src/components/charts/Sparkline.tsx +156 -0
  12. package/src/components/charts/index.ts +13 -0
  13. package/src/components/data-display/Avatar.tsx +208 -0
  14. package/src/components/data-display/AvatarGroup.tsx +228 -0
  15. package/src/components/data-display/Badge.tsx +70 -0
  16. package/src/components/data-display/Carousel.tsx +214 -0
  17. package/src/components/data-display/ColorSwatch.tsx +56 -0
  18. package/src/components/data-display/DataTable.tsx +886 -0
  19. package/src/components/data-display/EmptyState.tsx +61 -0
  20. package/src/components/data-display/Image.tsx +277 -0
  21. package/src/components/data-display/Kbd.tsx +114 -0
  22. package/src/components/data-display/Persona.tsx +78 -0
  23. package/src/components/data-display/StatCard.tsx +338 -0
  24. package/src/components/data-display/Table.tsx +147 -0
  25. package/src/components/data-display/Tag.tsx +91 -0
  26. package/src/components/data-display/Timeline.tsx +200 -0
  27. package/src/components/data-display/TreeView.tsx +172 -0
  28. package/src/components/data-display/Video.tsx +95 -0
  29. package/src/components/data-display/avatar-utils.ts +32 -0
  30. package/src/components/data-display/index.ts +81 -0
  31. package/src/components/feedback/Loading.tsx +159 -0
  32. package/src/components/feedback/Progress.tsx +321 -0
  33. package/src/components/feedback/Skeleton.tsx +62 -0
  34. package/src/components/feedback/SkeletonBlocks.tsx +222 -0
  35. package/src/components/feedback/Toast.tsx +648 -0
  36. package/src/components/feedback/index.ts +44 -0
  37. package/src/components/feedback/password/PasswordStrengthIndicator.tsx +232 -0
  38. package/src/components/feedback/password/password-strength.ts +115 -0
  39. package/src/components/feedback/password/password-validation-data.ts +66 -0
  40. package/src/components/feedback/password/password-validation.ts +93 -0
  41. package/src/components/forms/Autocomplete.tsx +268 -0
  42. package/src/components/forms/Checkbox.tsx +155 -0
  43. package/src/components/forms/CodeInput.tsx +237 -0
  44. package/src/components/forms/ColorPicker/ColorPicker.tsx +469 -0
  45. package/src/components/forms/ColorPicker/color-utils.ts +75 -0
  46. package/src/components/forms/ColorPicker/index.ts +2 -0
  47. package/src/components/forms/DatePicker.tsx +516 -0
  48. package/src/components/forms/DateRangePicker.tsx +464 -0
  49. package/src/components/forms/FieldPicker.tsx +64 -0
  50. package/src/components/forms/FileUpload.tsx +614 -0
  51. package/src/components/forms/FilterBuilder/FilterGroupBlock.ts +6 -0
  52. package/src/components/forms/FilterBuilder.tsx +16 -0
  53. package/src/components/forms/FilterRuleRow.tsx +68 -0
  54. package/src/components/forms/Input.tsx +200 -0
  55. package/src/components/forms/MultiSelect.tsx +361 -0
  56. package/src/components/forms/NumberField.tsx +145 -0
  57. package/src/components/forms/RadioGroup.tsx +135 -0
  58. package/src/components/forms/RelativeDateDefaultInput.tsx +62 -0
  59. package/src/components/forms/ReorderableList.tsx +163 -0
  60. package/src/components/forms/Select.tsx +268 -0
  61. package/src/components/forms/Slider.tsx +260 -0
  62. package/src/components/forms/Switch.tsx +135 -0
  63. package/src/components/forms/TextArea.tsx +202 -0
  64. package/src/components/forms/ViewCustomizer.tsx +44 -0
  65. package/src/components/forms/index.ts +43 -0
  66. package/src/components/layout/Accordion.tsx +110 -0
  67. package/src/components/layout/Alert.tsx +156 -0
  68. package/src/components/layout/BlockQuote.tsx +70 -0
  69. package/src/components/layout/Card.tsx +166 -0
  70. package/src/components/layout/CodeBlock/CodeBlock.tsx +477 -0
  71. package/src/components/layout/CodeBlock/code-block-tokens.css +104 -0
  72. package/src/components/layout/CodeBlock/prism.ts +81 -0
  73. package/src/components/layout/Collapsible.tsx +84 -0
  74. package/src/components/layout/Container.tsx +55 -0
  75. package/src/components/layout/Divider.tsx +64 -0
  76. package/src/components/layout/Form.tsx +39 -0
  77. package/src/components/layout/FormActions.tsx +50 -0
  78. package/src/components/layout/Grid.tsx +53 -0
  79. package/src/components/layout/PageHeading.tsx +46 -0
  80. package/src/components/layout/PromptWithAction.tsx +49 -0
  81. package/src/components/layout/Section.tsx +60 -0
  82. package/src/components/layout/TablePanel.tsx +24 -0
  83. package/src/components/layout/TableView/TableView.tsx +1018 -0
  84. package/src/components/layout/TableView/index.ts +3 -0
  85. package/src/components/layout/TableView/types.ts +51 -0
  86. package/src/components/layout/WizardStep.tsx +40 -0
  87. package/src/components/layout/WizardStepper.tsx +173 -0
  88. package/src/components/layout/index.ts +96 -0
  89. package/src/components/navigation/Breadcrumbs.tsx +66 -0
  90. package/src/components/navigation/DropdownMenu.tsx +86 -0
  91. package/src/components/navigation/MegaMenu.tsx +480 -0
  92. package/src/components/navigation/NavigationMenu.tsx +305 -0
  93. package/src/components/navigation/Pagination.tsx +298 -0
  94. package/src/components/navigation/Sidebar.tsx +280 -0
  95. package/src/components/navigation/Tabs.tsx +122 -0
  96. package/src/components/navigation/ViewSwitcher.tsx +314 -0
  97. package/src/components/navigation/index.ts +66 -0
  98. package/src/components/overlays/AlertDialog.tsx +174 -0
  99. package/src/components/overlays/ContextMenu.tsx +65 -0
  100. package/src/components/overlays/Dialog.tsx +279 -0
  101. package/src/components/overlays/Drawer.tsx +370 -0
  102. package/src/components/overlays/HoverCard.tsx +107 -0
  103. package/src/components/overlays/Popover.tsx +73 -0
  104. package/src/components/overlays/Tooltip.tsx +31 -0
  105. package/src/components/overlays/index.ts +71 -0
  106. package/src/components/typography/Code.tsx +72 -0
  107. package/src/components/typography/Icon.tsx +36 -0
  108. package/src/components/typography/index.ts +10 -0
  109. package/src/env.d.ts +9 -0
  110. package/src/index.ts +13 -0
  111. package/src/styles/theme.css +226 -0
  112. package/src/types/avatar-types.ts +11 -0
  113. package/src/types/filter-types.ts +35 -0
  114. package/src/utilities/classNames.ts +6 -0
  115. package/src/utilities/componentSize.ts +46 -0
  116. package/src/utilities/i18n.tsx +60 -0
  117. package/src/utilities/mergeRefs.ts +12 -0
  118. package/src/utilities/relativeDateDefault.ts +14 -0
@@ -0,0 +1,107 @@
1
+ import { type JSX, splitProps } from 'solid-js'
2
+ import { HoverCard as KobalteHoverCard, type HoverCardRootProps as KobalteHoverCardRootProps, type HoverCardContentProps as KobalteHoverCardContentProps } from '@kobalte/core/hover-card'
3
+ import { cn } from '../../utilities/classNames'
4
+
5
+ const SIDES = ['top', 'bottom', 'left', 'right'] as const
6
+ const ALIGNMENTS = ['start', 'center', 'end'] as const
7
+
8
+ export type HoverCardSide = (typeof SIDES)[number]
9
+ export type HoverCardAlign = (typeof ALIGNMENTS)[number]
10
+ type NonCenterAlign = Exclude<HoverCardAlign, 'center'>
11
+ type DerivedPlacement = HoverCardSide | `${HoverCardSide}-${NonCenterAlign}`
12
+ export type HoverCardPlacement = DerivedPlacement
13
+
14
+ export interface HoverCardRootProps extends Omit<KobalteHoverCardRootProps, 'placement'> {
15
+ /** Side of the trigger the card appears on. Default 'bottom'. */
16
+ side?: HoverCardSide
17
+ /** Alignment relative to the trigger. Default 'center'. */
18
+ align?: HoverCardAlign
19
+ /** Override placement directly. If not provided, derived from side + align. */
20
+ placement?: HoverCardPlacement
21
+ }
22
+
23
+ export function HoverCardRoot(props: HoverCardRootProps) {
24
+ const [local, others] = splitProps(props, ['align', 'side', 'placement'])
25
+
26
+ const side = () => local.side ?? 'bottom'
27
+ const align = () => local.align ?? 'center'
28
+
29
+ const placement = (): HoverCardPlacement => {
30
+ if (local.placement) return local.placement
31
+ const s = side()
32
+ const a = align()
33
+ return a === 'center' ? s : `${s}-${a}`
34
+ }
35
+
36
+ return (
37
+ <KobalteHoverCard
38
+ {...others}
39
+ placement={placement()}
40
+ />
41
+ )
42
+ }
43
+
44
+ export const HoverCardTrigger = KobalteHoverCard.Trigger
45
+ export const HoverCardPortal = KobalteHoverCard.Portal
46
+ export const HoverCardArrow = KobalteHoverCard.Arrow
47
+
48
+ export interface HoverCardContentProps extends KobalteHoverCardContentProps {
49
+ class?: string
50
+ children?: JSX.Element
51
+ /** Show an arrow pointing to the trigger. Default false. */
52
+ showArrow?: boolean
53
+ }
54
+
55
+ export function HoverCardContent(props: HoverCardContentProps) {
56
+ const [local, others] = splitProps(props, ['class', 'children', 'showArrow'])
57
+ return (
58
+ <KobalteHoverCard.Portal>
59
+ <KobalteHoverCard.Content
60
+ class={cn(
61
+ 'z-50 min-w-[220px] max-w-sm rounded-xl border border-surface-border bg-surface-raised shadow-lg',
62
+ 'data-[expanded]:animate-in data-[closed]:animate-out',
63
+ 'data-[expanded]:fade-in-0 data-[closed]:fade-out-0',
64
+ 'data-[expanded]:zoom-in-95 data-[closed]:zoom-out-95',
65
+ 'data-[side=top]:slide-in-from-bottom-2 data-[side=bottom]:slide-in-from-top-2',
66
+ 'data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2',
67
+ local.class,
68
+ )}
69
+ {...others}
70
+ >
71
+ {local.children}
72
+ {local.showArrow && (
73
+ <KobalteHoverCard.Arrow class="fill-surface-raised stroke-surface-border" />
74
+ )}
75
+ </KobalteHoverCard.Content>
76
+ </KobalteHoverCard.Portal>
77
+ )
78
+ }
79
+
80
+ /** Convenience sub-components for structured card content */
81
+ export function HoverCardHeader(props: { class?: string; children: JSX.Element }) {
82
+ return (
83
+ <div class={cn('px-4 pt-4 pb-2', props.class)}>
84
+ {props.children}
85
+ </div>
86
+ )
87
+ }
88
+
89
+ export function HoverCardBody(props: { class?: string; children: JSX.Element }) {
90
+ return (
91
+ <div class={cn('px-4 py-3', props.class)}>
92
+ {props.children}
93
+ </div>
94
+ )
95
+ }
96
+
97
+ export function HoverCardFooter(props: { class?: string; children: JSX.Element }) {
98
+ return (
99
+ <div class={cn('px-4 pb-4 pt-2 border-t border-surface-border', props.class)}>
100
+ {props.children}
101
+ </div>
102
+ )
103
+ }
104
+
105
+ export function HoverCardSeparator(props: { class?: string }) {
106
+ return <div class={cn('h-px bg-surface-border', props.class)} />
107
+ }
@@ -0,0 +1,73 @@
1
+ import { type JSX, splitProps } from 'solid-js'
2
+ import { Popover as KobaltePopover, type PopoverRootProps as KobaltePopoverRootProps, type PopoverContentProps as KobaltePopoverContentProps } from '@kobalte/core/popover'
3
+ import { cn } from '../../utilities/classNames'
4
+
5
+ const SIDES = ['top', 'bottom', 'left', 'right'] as const
6
+ const ALIGNMENTS = ['start', 'center', 'end'] as const
7
+
8
+ export type PopoverSide = (typeof SIDES)[number]
9
+ export type PopoverAlign = (typeof ALIGNMENTS)[number]
10
+ type NonCenterAlign = Exclude<PopoverAlign, 'center'>
11
+ type DerivedPlacement = PopoverSide | `${PopoverSide}-${NonCenterAlign}`
12
+
13
+ // Valid placement combinations derived from SIDES and ALIGNMENTS
14
+ export type PopoverPlacement = DerivedPlacement
15
+
16
+ export interface PopoverRootProps extends Omit<KobaltePopoverRootProps, 'placement'> {
17
+ /** Horizontal alignment relative to trigger. Use 'end' to right-align panel to trigger. Ignored if placement is set. */
18
+ align?: PopoverAlign
19
+ /** Side of the trigger the panel appears on. Ignored if placement is set. Default 'bottom'. */
20
+ side?: PopoverSide
21
+ /** Override placement. If not provided, derived from side + align. */
22
+ placement?: PopoverPlacement
23
+ }
24
+
25
+ /** Root with align/side support; placement is derived as side + align (e.g. bottom-end). */
26
+ export function PopoverRoot(props: PopoverRootProps) {
27
+ const [local, others] = splitProps(props, ['align', 'side', 'placement'])
28
+
29
+ const side = () => local.side ?? 'bottom'
30
+ const align = () => local.align ?? 'center'
31
+
32
+ const placement = (): PopoverPlacement => {
33
+ if (local.placement) return local.placement
34
+ const s = side()
35
+ const a = align()
36
+ return a === 'center' ? s : `${s}-${a}`
37
+ }
38
+
39
+ return (
40
+ <KobaltePopover
41
+ {...others}
42
+ placement={placement()}
43
+ />
44
+ )
45
+ }
46
+
47
+ export const PopoverTrigger = KobaltePopover.Trigger
48
+ export const PopoverAnchor = KobaltePopover.Anchor
49
+ export const PopoverPortal = KobaltePopover.Portal
50
+ export const PopoverContentPrimitive = KobaltePopover.Content
51
+ export const PopoverArrow = KobaltePopover.Arrow
52
+
53
+ export interface PopoverContentProps extends KobaltePopoverContentProps {
54
+ class?: string
55
+ children?: JSX.Element
56
+ }
57
+
58
+ export function PopoverContent(props: PopoverContentProps) {
59
+ const [local, others] = splitProps(props, ['class', 'children'])
60
+ return (
61
+ <KobaltePopover.Portal>
62
+ <KobaltePopover.Content
63
+ class={cn(
64
+ 'z-50 min-w-[180px] rounded-lg border border-surface-border bg-surface-raised p-2 shadow-lg',
65
+ local.class
66
+ )}
67
+ {...others}
68
+ >
69
+ {local.children}
70
+ </KobaltePopover.Content>
71
+ </KobaltePopover.Portal>
72
+ )
73
+ }
@@ -0,0 +1,31 @@
1
+ import { type JSX, splitProps } from 'solid-js'
2
+ import { Tooltip as KobalteTooltip, type TooltipContentProps as KobalteTooltipContentProps } from '@kobalte/core/tooltip'
3
+ import { cn } from '../../utilities/classNames'
4
+
5
+ export const TooltipRoot = KobalteTooltip
6
+ export const TooltipTrigger = KobalteTooltip.Trigger
7
+ export const TooltipPortal = KobalteTooltip.Portal
8
+ export const TooltipContentPrimitive = KobalteTooltip.Content
9
+ export const TooltipArrow = KobalteTooltip.Arrow
10
+
11
+ export interface TooltipContentProps extends KobalteTooltipContentProps {
12
+ class?: string
13
+ children?: JSX.Element
14
+ }
15
+
16
+ export function TooltipContent(props: TooltipContentProps) {
17
+ const [local, others] = splitProps(props, ['class', 'children'])
18
+ return (
19
+ <KobalteTooltip.Portal>
20
+ <KobalteTooltip.Content
21
+ class={cn(
22
+ 'z-50 max-w-xs rounded-md border border-ink-200 bg-ink-900 px-3 py-2 text-sm text-white shadow-md',
23
+ local.class
24
+ )}
25
+ {...others}
26
+ >
27
+ {local.children}
28
+ </KobalteTooltip.Content>
29
+ </KobalteTooltip.Portal>
30
+ )
31
+ }
@@ -0,0 +1,71 @@
1
+ /** Overlays: AlertDialog, Dialog, Drawer, Popover, Tooltip, ContextMenu, HoverCard */
2
+ export { AlertDialog, type AlertDialogProps } from './AlertDialog'
3
+
4
+ export {
5
+ Dialog,
6
+ type DialogProps,
7
+ type DialogSize,
8
+ type DialogOverlayAnimation,
9
+ type DialogPanelAnimation,
10
+ } from './Dialog'
11
+
12
+ export {
13
+ Drawer,
14
+ type DrawerProps,
15
+ type DrawerSize,
16
+ type DrawerSide,
17
+ type DrawerOffset,
18
+ type DrawerActionsPosition,
19
+ } from './Drawer'
20
+
21
+ export {
22
+ TooltipRoot,
23
+ TooltipTrigger,
24
+ TooltipPortal,
25
+ TooltipContentPrimitive,
26
+ TooltipArrow,
27
+ TooltipContent,
28
+ type TooltipContentProps,
29
+ } from './Tooltip'
30
+
31
+ export {
32
+ PopoverRoot,
33
+ PopoverTrigger,
34
+ PopoverAnchor,
35
+ PopoverPortal,
36
+ PopoverContentPrimitive,
37
+ PopoverArrow,
38
+ PopoverContent,
39
+ type PopoverContentProps,
40
+ type PopoverRootProps,
41
+ type PopoverSide,
42
+ type PopoverAlign,
43
+ } from './Popover'
44
+
45
+ export {
46
+ ContextMenuRoot,
47
+ ContextMenuTrigger,
48
+ ContextMenuContent,
49
+ ContextMenuItem,
50
+ ContextMenuSeparator,
51
+ type ContextMenuContentProps,
52
+ type ContextMenuItemProps,
53
+ type ContextMenuSeparatorProps,
54
+ } from './ContextMenu'
55
+
56
+ export {
57
+ HoverCardRoot,
58
+ HoverCardTrigger,
59
+ HoverCardPortal,
60
+ HoverCardArrow,
61
+ HoverCardContent,
62
+ HoverCardHeader,
63
+ HoverCardBody,
64
+ HoverCardFooter,
65
+ HoverCardSeparator,
66
+ type HoverCardRootProps,
67
+ type HoverCardContentProps,
68
+ type HoverCardSide,
69
+ type HoverCardAlign,
70
+ type HoverCardPlacement,
71
+ } from './HoverCard'
@@ -0,0 +1,72 @@
1
+ import { type JSX, Show, splitProps } from 'solid-js'
2
+ import { Copy } from '../actions'
3
+ import { cn } from '../../utilities/classNames'
4
+
5
+ type InlineProps = JSX.HTMLAttributes<HTMLElement> & { block?: false }
6
+ type BlockProps = JSX.HTMLAttributes<HTMLDivElement> & { block: true }
7
+
8
+ type Copyable = { copyable: true; text: string }
9
+ type NotCopyable = { copyable?: false; text?: string }
10
+
11
+ type BaseProps = {
12
+ /** Inline or single-line code. */
13
+ children?: JSX.Element
14
+ /** Optional class. */
15
+ class?: string
16
+ } & (Copyable | NotCopyable)
17
+
18
+ export type CodeProps = (InlineProps | BlockProps) & BaseProps
19
+
20
+ /**
21
+ * Inline or single-line code. Use for variable names, commands, or short snippets in text.
22
+ * Set block to get a one-line block with optional copy button.
23
+ */
24
+ export function Code(props: CodeProps) {
25
+ // mx-0.5: intentional horizontal spacing so inline code doesn't touch adjacent text.
26
+ const inlineClass =
27
+ 'rounded bg-surface-overlay px-2 py-1 text-[0.9em] font-mono text-ink-800 mx-0.5'
28
+
29
+ const blockClass =
30
+ 'flex items-center gap-2 rounded-lg border border-surface-border bg-surface-base px-3 py-2 text-sm font-mono text-ink-800'
31
+
32
+ if (props.block) {
33
+ const [local, divProps] = splitProps(props, [
34
+ 'children',
35
+ 'block',
36
+ 'copyable',
37
+ 'text',
38
+ 'class',
39
+ ])
40
+
41
+ const copyText = () => (local.text ?? '').trim()
42
+
43
+ return (
44
+ <div
45
+ class={cn('w-full relative', blockClass, local.copyable && 'pr-12', local.class)}
46
+ {...divProps}
47
+ >
48
+ <code class="flex-1 min-w-0 truncate block">{local.children}</code>
49
+
50
+ <Show when={local.copyable && copyText()}>
51
+ <div class="absolute right-2 top-1/2 -translate-y-1/2 shrink-0">
52
+ <Copy text={copyText()} display="icon-only" variant="ghost" size="xs" />
53
+ </div>
54
+ </Show>
55
+ </div>
56
+ )
57
+ }
58
+
59
+ const [local, codeProps] = splitProps(props, [
60
+ 'children',
61
+ 'block',
62
+ 'copyable',
63
+ 'text',
64
+ 'class',
65
+ ])
66
+
67
+ return (
68
+ <code class={cn(inlineClass, local.class)} {...codeProps}>
69
+ {local.children}
70
+ </code>
71
+ )
72
+ }
@@ -0,0 +1,36 @@
1
+ import { type JSX, splitProps } from 'solid-js'
2
+ import { cn } from '../../utilities/classNames'
3
+
4
+ export interface IconProps extends Omit<JSX.ImgHTMLAttributes<HTMLImageElement>, 'children' | 'width' | 'height'> {
5
+ /** Image URL (local path or CDN). */
6
+ src: string
7
+ /** Size in pixels (sets both width and height). Default: 16. */
8
+ size?: number
9
+ }
10
+
11
+ /**
12
+ * Renders a custom icon image with consistent sizing and styling.
13
+ * Point src at a local asset or CDN URL.
14
+ *
15
+ * Decorative by default (`alt=""`, `aria-hidden="true"`). To make the icon
16
+ * meaningful to screen readers, pass both `alt="description"` and
17
+ * `aria-hidden="false"` — the spread overrides both defaults.
18
+ *
19
+ * <Icon src="/images/icons/solid.svg" size={20} />
20
+ */
21
+ export function Icon(props: IconProps) {
22
+ const [local, others] = splitProps(props, ['src', 'size', 'class'])
23
+ const size = () => local.size ?? 16
24
+
25
+ return (
26
+ <img
27
+ alt=""
28
+ aria-hidden="true"
29
+ src={local.src}
30
+ width={size()}
31
+ height={size()}
32
+ class={cn('inline-block shrink-0', local.class)}
33
+ {...others}
34
+ />
35
+ )
36
+ }
@@ -0,0 +1,10 @@
1
+ /** Typography: Block Quote, Code (sidebar-aligned entry point) */
2
+ export { BlockQuote } from '../layout/BlockQuote'
3
+ export type { BlockQuoteProps, BlockQuoteJustify } from '../layout/BlockQuote'
4
+
5
+ export { Code } from './Code'
6
+ export type { CodeProps } from './Code'
7
+
8
+ export { Icon } from './Icon'
9
+ export type { IconProps } from './Icon'
10
+
package/src/env.d.ts ADDED
@@ -0,0 +1,9 @@
1
+ interface ImportMetaEnv {
2
+ readonly DEV: boolean
3
+ readonly PROD: boolean
4
+ readonly MODE: string
5
+ }
6
+
7
+ interface ImportMeta {
8
+ readonly env: ImportMetaEnv
9
+ }
package/src/index.ts ADDED
@@ -0,0 +1,13 @@
1
+ export * from './components/data-display'
2
+ export * from './components/actions'
3
+ export * from './components/forms'
4
+ export * from './components/feedback'
5
+ export * from './components/layout'
6
+ export * from './components/navigation'
7
+ export * from './components/overlays'
8
+ export * from './components/typography'
9
+ export * from './components/charts'
10
+ export { cn } from './utilities/classNames'
11
+ export { mergeRefs } from './utilities/mergeRefs'
12
+ export { AppI18nProvider, useAppLocale } from './utilities/i18n'
13
+ export { type ComponentSize, inputSizeConfig } from './utilities/componentSize'
@@ -0,0 +1,226 @@
1
+ @variant dark (&:where(.dark, .dark *));
2
+
3
+ @theme {
4
+ /* Surface */
5
+ --color-surface-base: var(--surface-base);
6
+ --color-surface-raised: var(--surface-raised);
7
+ --color-surface-overlay: var(--surface-overlay);
8
+ --color-surface-dim: var(--surface-dim);
9
+ --color-surface-border: var(--surface-border);
10
+
11
+ /* Ink */
12
+ --color-ink-50: var(--ink-50);
13
+ --color-ink-100: var(--ink-100);
14
+ --color-ink-200: var(--ink-200);
15
+ --color-ink-300: var(--ink-300);
16
+ --color-ink-400: var(--ink-400);
17
+ --color-ink-500: var(--ink-500);
18
+ --color-ink-600: var(--ink-600);
19
+ --color-ink-700: var(--ink-700);
20
+ --color-ink-800: var(--ink-800);
21
+ --color-ink-850: var(--ink-850);
22
+ --color-ink-900: var(--ink-900);
23
+ --color-ink-950: var(--ink-950);
24
+
25
+ /* Primary */
26
+ --color-primary-50: var(--primary-50);
27
+ --color-primary-100: var(--primary-100);
28
+ --color-primary-200: var(--primary-200);
29
+ --color-primary-300: var(--primary-300);
30
+ --color-primary-400: var(--primary-400);
31
+ --color-primary-500: var(--primary-500);
32
+ --color-primary-600: var(--primary-600);
33
+ --color-primary-700: var(--primary-700);
34
+ --color-primary-800: var(--primary-800);
35
+ --color-primary-900: var(--primary-900);
36
+ --color-primary-950: var(--primary-950);
37
+
38
+ /* Success */
39
+ --color-success-50: var(--success-50);
40
+ --color-success-100: var(--success-100);
41
+ --color-success-200: var(--success-200);
42
+ --color-success-300: var(--success-300);
43
+ --color-success-400: var(--success-400);
44
+ --color-success-500: var(--success-500);
45
+ --color-success-600: var(--success-600);
46
+ --color-success-700: var(--success-700);
47
+ --color-success-800: var(--success-800);
48
+ --color-success-900: var(--success-900);
49
+ --color-success-950: var(--success-950);
50
+
51
+ /* Warning */
52
+ --color-warning-50: var(--warning-50);
53
+ --color-warning-100: var(--warning-100);
54
+ --color-warning-200: var(--warning-200);
55
+ --color-warning-300: var(--warning-300);
56
+ --color-warning-400: var(--warning-400);
57
+ --color-warning-500: var(--warning-500);
58
+ --color-warning-600: var(--warning-600);
59
+ --color-warning-700: var(--warning-700);
60
+ --color-warning-800: var(--warning-800);
61
+ --color-warning-900: var(--warning-900);
62
+ --color-warning-950: var(--warning-950);
63
+
64
+ /* Danger */
65
+ --color-danger-50: var(--danger-50);
66
+ --color-danger-100: var(--danger-100);
67
+ --color-danger-200: var(--danger-200);
68
+ --color-danger-300: var(--danger-300);
69
+ --color-danger-400: var(--danger-400);
70
+ --color-danger-500: var(--danger-500);
71
+ --color-danger-600: var(--danger-600);
72
+ --color-danger-700: var(--danger-700);
73
+ --color-danger-800: var(--danger-800);
74
+ --color-danger-900: var(--danger-900);
75
+ --color-danger-950: var(--danger-950);
76
+
77
+ /* Info */
78
+ --color-info-50: var(--info-50);
79
+ --color-info-100: var(--info-100);
80
+ --color-info-200: var(--info-200);
81
+ --color-info-300: var(--info-300);
82
+ --color-info-400: var(--info-400);
83
+ --color-info-500: var(--info-500);
84
+ --color-info-600: var(--info-600);
85
+ --color-info-700: var(--info-700);
86
+ --color-info-800: var(--info-800);
87
+ --color-info-900: var(--info-900);
88
+ --color-info-950: var(--info-950);
89
+ }
90
+
91
+ /* ─────────────────────────────────────────────────────────────
92
+ USER CONFIGURATION
93
+ These are the only variables you need to change to retheme
94
+ the entire design system.
95
+ ───────────────────────────────────────────────────────────── */
96
+ :root {
97
+ --ink-light: #18181c;
98
+ --ink-dark: #f0f0f2;
99
+ --surface-light: #fafafa;
100
+ --surface-dark: #0f1112;
101
+
102
+ --primary: #ff7547;
103
+ --success: #0dcd51;
104
+ --warning: #e6ba05;
105
+ --danger: #f12828;
106
+ --info: #10b3f4;
107
+ }
108
+
109
+ /* ─────────────────────────────────────────────────────────────
110
+ LIGHT MODE
111
+ ───────────────────────────────────────────────────────────── */
112
+ :root {
113
+ /* Surface — derived from --surface-light */
114
+ --surface-base: var(--surface-light);
115
+ --surface-raised: color-mix(in oklch, white 100%, var(--surface-light));
116
+ --surface-overlay: color-mix(in oklch, black 3%, var(--surface-light));
117
+ --surface-dim: color-mix(in oklch, black 8%, var(--surface-light));
118
+ --surface-border: color-mix(in oklch, black 8%, var(--surface-light));
119
+
120
+ /* Ink — derived from --ink-light, anchored at ink-900 */
121
+ --ink-50: color-mix(in oklch, white 95%, var(--ink-light));
122
+ --ink-100: color-mix(in oklch, white 85%, var(--ink-light));
123
+ --ink-200: color-mix(in oklch, white 70%, var(--ink-light));
124
+ --ink-300: color-mix(in oklch, white 55%, var(--ink-light));
125
+ --ink-400: color-mix(in oklch, white 40%, var(--ink-light));
126
+ --ink-500: color-mix(in oklch, white 25%, var(--ink-light));
127
+ --ink-600: color-mix(in oklch, white 15%, var(--ink-light));
128
+ --ink-700: color-mix(in oklch, white 10%, var(--ink-light));
129
+ --ink-800: color-mix(in oklch, white 5%, var(--ink-light));
130
+ --ink-850: color-mix(in oklch, white 2%, var(--ink-light));
131
+ --ink-900: var(--ink-light);
132
+ --ink-950: color-mix(in oklch, black 30%, var(--ink-light));
133
+
134
+ /* Primary — derived from --primary, anchored at 500
135
+ Light: 20% steps toward white
136
+ Dark: 8 / 18 / 30 / 44 / 52% toward black */
137
+ --primary-50: color-mix(in oklch, white 90%, var(--primary));
138
+ --primary-100: color-mix(in oklch, white 80%, var(--primary));
139
+ --primary-200: color-mix(in oklch, white 60%, var(--primary));
140
+ --primary-300: color-mix(in oklch, white 40%, var(--primary));
141
+ --primary-400: color-mix(in oklch, white 20%, var(--primary));
142
+ --primary-500: var(--primary);
143
+ --primary-600: color-mix(in oklch, black 8%, var(--primary));
144
+ --primary-700: color-mix(in oklch, black 18%, var(--primary));
145
+ --primary-800: color-mix(in oklch, black 30%, var(--primary));
146
+ --primary-900: color-mix(in oklch, black 44%, var(--primary));
147
+ --primary-950: color-mix(in oklch, black 52%, var(--primary));
148
+
149
+ /* Success */
150
+ --success-50: color-mix(in oklch, white 90%, var(--success));
151
+ --success-100: color-mix(in oklch, white 80%, var(--success));
152
+ --success-200: color-mix(in oklch, white 60%, var(--success));
153
+ --success-300: color-mix(in oklch, white 40%, var(--success));
154
+ --success-400: color-mix(in oklch, white 20%, var(--success));
155
+ --success-500: var(--success);
156
+ --success-600: color-mix(in oklch, black 8%, var(--success));
157
+ --success-700: color-mix(in oklch, black 18%, var(--success));
158
+ --success-800: color-mix(in oklch, black 30%, var(--success));
159
+ --success-900: color-mix(in oklch, black 44%, var(--success));
160
+ --success-950: color-mix(in oklch, black 52%, var(--success));
161
+
162
+ /* Warning */
163
+ --warning-50: color-mix(in oklch, white 90%, var(--warning));
164
+ --warning-100: color-mix(in oklch, white 80%, var(--warning));
165
+ --warning-200: color-mix(in oklch, white 60%, var(--warning));
166
+ --warning-300: color-mix(in oklch, white 40%, var(--warning));
167
+ --warning-400: color-mix(in oklch, white 20%, var(--warning));
168
+ --warning-500: var(--warning);
169
+ --warning-600: color-mix(in oklch, black 8%, var(--warning));
170
+ --warning-700: color-mix(in oklch, black 18%, var(--warning));
171
+ --warning-800: color-mix(in oklch, black 30%, var(--warning));
172
+ --warning-900: color-mix(in oklch, black 44%, var(--warning));
173
+ --warning-950: color-mix(in oklch, black 52%, var(--warning));
174
+
175
+ /* Danger */
176
+ --danger-50: color-mix(in oklch, white 90%, var(--danger));
177
+ --danger-100: color-mix(in oklch, white 80%, var(--danger));
178
+ --danger-200: color-mix(in oklch, white 60%, var(--danger));
179
+ --danger-300: color-mix(in oklch, white 40%, var(--danger));
180
+ --danger-400: color-mix(in oklch, white 20%, var(--danger));
181
+ --danger-500: var(--danger);
182
+ --danger-600: color-mix(in oklch, black 8%, var(--danger));
183
+ --danger-700: color-mix(in oklch, black 18%, var(--danger));
184
+ --danger-800: color-mix(in oklch, black 30%, var(--danger));
185
+ --danger-900: color-mix(in oklch, black 44%, var(--danger));
186
+ --danger-950: color-mix(in oklch, black 52%, var(--danger));
187
+
188
+ /* Info */
189
+ --info-50: color-mix(in oklch, white 90%, var(--info));
190
+ --info-100: color-mix(in oklch, white 80%, var(--info));
191
+ --info-200: color-mix(in oklch, white 60%, var(--info));
192
+ --info-300: color-mix(in oklch, white 40%, var(--info));
193
+ --info-400: color-mix(in oklch, white 20%, var(--info));
194
+ --info-500: var(--info);
195
+ --info-600: color-mix(in oklch, black 8%, var(--info));
196
+ --info-700: color-mix(in oklch, black 18%, var(--info));
197
+ --info-800: color-mix(in oklch, black 30%, var(--info));
198
+ --info-900: color-mix(in oklch, black 44%, var(--info));
199
+ --info-950: color-mix(in oklch, black 52%, var(--info));
200
+ }
201
+
202
+ /* ─────────────────────────────────────────────────────────────
203
+ DARK MODE
204
+ ───────────────────────────────────────────────────────────── */
205
+ .dark {
206
+ /* Surface — derived from --surface-dark */
207
+ --surface-base: var(--surface-dark);
208
+ --surface-raised: color-mix(in oklch, white 6%, var(--surface-dark));
209
+ --surface-overlay: color-mix(in oklch, white 9%, var(--surface-dark));
210
+ --surface-dim: color-mix(in oklch, white 22%, var(--surface-dark));
211
+ --surface-border: color-mix(in oklch, white 22%, var(--surface-dark));
212
+
213
+ /* Ink — derived from --ink-dark, anchored at ink-900 (inverted: 900 = lightest) */
214
+ --ink-50: color-mix(in oklch, black 90%, var(--ink-dark));
215
+ --ink-100: color-mix(in oklch, black 80%, var(--ink-dark));
216
+ --ink-200: color-mix(in oklch, black 60%, var(--ink-dark));
217
+ --ink-300: color-mix(in oklch, black 40%, var(--ink-dark));
218
+ --ink-400: color-mix(in oklch, black 20%, var(--ink-dark));
219
+ --ink-500: color-mix(in oklch, black 5%, var(--ink-dark));
220
+ --ink-600: color-mix(in oklch, white 5%, var(--ink-dark));
221
+ --ink-700: color-mix(in oklch, white 15%, var(--ink-dark));
222
+ --ink-800: color-mix(in oklch, white 25%, var(--ink-dark));
223
+ --ink-850: color-mix(in oklch, white 35%, var(--ink-dark));
224
+ --ink-900: var(--ink-dark);
225
+ --ink-950: color-mix(in oklch, white 30%, var(--ink-dark));
226
+ }
@@ -0,0 +1,11 @@
1
+ export type AvatarShape = 'circle' | 'rounded' | 'square'
2
+
3
+ export type AvatarColor =
4
+ | 'neutral'
5
+ | 'primary'
6
+ | 'success'
7
+ | 'warning'
8
+ | 'danger'
9
+ | 'info'
10
+
11
+ export type SizeKey = 'sm' | 'md' | 'lg'