@mesob/ui 0.2.0 → 0.2.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 (78) hide show
  1. package/dist/components/alert-dialog.js +10 -10
  2. package/dist/components/alert-dialog.js.map +1 -1
  3. package/dist/components/alert.js +1 -1
  4. package/dist/components/alert.js.map +1 -1
  5. package/dist/components/animated-tabs.js +1 -1
  6. package/dist/components/animated-tabs.js.map +1 -1
  7. package/dist/components/app-header-actions.js +68 -53
  8. package/dist/components/app-header-actions.js.map +1 -1
  9. package/dist/components/app-sidebar.js +33 -28
  10. package/dist/components/app-sidebar.js.map +1 -1
  11. package/dist/components/button-group.js +1 -1
  12. package/dist/components/button-group.js.map +1 -1
  13. package/dist/components/button.d.ts +6 -3
  14. package/dist/components/button.js +15 -7
  15. package/dist/components/button.js.map +1 -1
  16. package/dist/components/calendar.js +15 -7
  17. package/dist/components/calendar.js.map +1 -1
  18. package/dist/components/card.js +1 -1
  19. package/dist/components/card.js.map +1 -1
  20. package/dist/components/carousel.js +18 -10
  21. package/dist/components/carousel.js.map +1 -1
  22. package/dist/components/command.js +5 -5
  23. package/dist/components/command.js.map +1 -1
  24. package/dist/components/context-menu.js +2 -2
  25. package/dist/components/context-menu.js.map +1 -1
  26. package/dist/components/data-table/index.js +129 -120
  27. package/dist/components/data-table/index.js.map +1 -1
  28. package/dist/components/dialog.js +2 -2
  29. package/dist/components/dialog.js.map +1 -1
  30. package/dist/components/drawer.js +2 -2
  31. package/dist/components/drawer.js.map +1 -1
  32. package/dist/components/dropdown-menu.js +2 -2
  33. package/dist/components/dropdown-menu.js.map +1 -1
  34. package/dist/components/entity/index.js +138 -133
  35. package/dist/components/entity/index.js.map +1 -1
  36. package/dist/components/hover-card.js +1 -1
  37. package/dist/components/hover-card.js.map +1 -1
  38. package/dist/components/input-group.js +15 -7
  39. package/dist/components/input-group.js.map +1 -1
  40. package/dist/components/item.d.ts +1 -1
  41. package/dist/components/menubar.js +3 -3
  42. package/dist/components/menubar.js.map +1 -1
  43. package/dist/components/navigation-menu.js +1 -1
  44. package/dist/components/navigation-menu.js.map +1 -1
  45. package/dist/components/page/index.js +24 -16
  46. package/dist/components/page/index.js.map +1 -1
  47. package/dist/components/pagination.js +10 -10
  48. package/dist/components/pagination.js.map +1 -1
  49. package/dist/components/popover.js +1 -1
  50. package/dist/components/popover.js.map +1 -1
  51. package/dist/components/section/index.js +19 -11
  52. package/dist/components/section/index.js.map +1 -1
  53. package/dist/components/select.js +1 -1
  54. package/dist/components/select.js.map +1 -1
  55. package/dist/components/sheet.js +2 -2
  56. package/dist/components/sheet.js.map +1 -1
  57. package/dist/components/shell.js +44 -31
  58. package/dist/components/shell.js.map +1 -1
  59. package/dist/components/sidebar-context.d.ts +19 -0
  60. package/dist/components/sidebar-context.js +17 -0
  61. package/dist/components/sidebar-context.js.map +1 -0
  62. package/dist/components/sidebar.d.ts +2 -15
  63. package/dist/components/sidebar.js +51 -38
  64. package/dist/components/sidebar.js.map +1 -1
  65. package/dist/components/spotlight-search.js +38 -30
  66. package/dist/components/spotlight-search.js.map +1 -1
  67. package/dist/components/theme-toggle.js +17 -9
  68. package/dist/components/theme-toggle.js.map +1 -1
  69. package/dist/hooks/use-translation.js +3 -2
  70. package/dist/hooks/use-translation.js.map +1 -1
  71. package/dist/index.d.ts +1 -0
  72. package/dist/index.js +94 -1
  73. package/dist/index.js.map +1 -1
  74. package/dist/lib/theme-schema.d.ts +21 -0
  75. package/dist/lib/theme-schema.js +95 -0
  76. package/dist/lib/theme-schema.js.map +1 -0
  77. package/package.json +2 -5
  78. package/src/styles/globals.css +0 -130
@@ -10,18 +10,18 @@ function cn(...inputs) {
10
10
  // src/components/button.tsx
11
11
  import { Slot } from "@radix-ui/react-slot";
12
12
  import { cva } from "class-variance-authority";
13
- import { jsx } from "react/jsx-runtime";
13
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
14
14
  var buttonVariants = cva(
15
15
  "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
16
16
  {
17
17
  variants: {
18
18
  variant: {
19
- default: "bg-primary text-primary-foreground hover:bg-primary/90",
20
- destructive: "bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
21
- outline: "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50",
22
- secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
19
+ default: "bg-primary text-primary-foreground hover:bg-primary-600 dark:hover:bg-primary-400",
20
+ destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40",
21
+ outline: "border border-input bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50",
22
+ secondary: "bg-secondary text-secondary-foreground hover:bg-secondary-600 dark:hover:bg-secondary-400",
23
23
  ghost: "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
24
- link: "text-primary underline-offset-4 hover:underline"
24
+ link: "text-primary underline-offset-4 hover:text-primary-600 dark:hover:text-primary-400 hover:underline"
25
25
  },
26
26
  size: {
27
27
  default: "h-9 px-4 py-2 has-[>svg]:px-3",
@@ -43,6 +43,9 @@ function Button({
43
43
  variant,
44
44
  size,
45
45
  asChild = false,
46
+ leftIcon,
47
+ rightIcon,
48
+ children,
46
49
  ...props
47
50
  }) {
48
51
  const Comp = asChild ? Slot : "button";
@@ -51,7 +54,12 @@ function Button({
51
54
  {
52
55
  "data-slot": "button",
53
56
  className: cn(buttonVariants({ variant, size, className })),
54
- ...props
57
+ ...props,
58
+ children: asChild ? children : /* @__PURE__ */ jsxs(Fragment, { children: [
59
+ leftIcon,
60
+ children,
61
+ rightIcon
62
+ ] })
55
63
  }
56
64
  );
57
65
  }
@@ -59,11 +67,11 @@ function Button({
59
67
  // src/components/theme-toggle.tsx
60
68
  import { IconMoon, IconSun } from "@tabler/icons-react";
61
69
  import { useTheme } from "next-themes";
62
- import { jsx as jsx2, jsxs } from "react/jsx-runtime";
70
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
63
71
  function ThemeToggle({ className }) {
64
72
  const { resolvedTheme, setTheme, theme } = useTheme();
65
73
  const isDark = (theme ?? resolvedTheme) === "dark";
66
- return /* @__PURE__ */ jsxs(
74
+ return /* @__PURE__ */ jsxs2(
67
75
  Button,
68
76
  {
69
77
  type: "button",
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/lib/utils.ts","../../src/components/button.tsx","../../src/components/theme-toggle.tsx"],"sourcesContent":["import { type ClassValue, clsx } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","import { cn } from '@mesob/ui/lib/utils';\nimport { Slot } from '@radix-ui/react-slot';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport type * as React from 'react';\n\nconst buttonVariants = cva(\n \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive\",\n {\n variants: {\n variant: {\n default: 'bg-primary text-primary-foreground hover:bg-primary/90',\n destructive:\n 'bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60',\n outline:\n 'border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50',\n secondary:\n 'bg-secondary text-secondary-foreground hover:bg-secondary/80',\n ghost:\n 'hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50',\n link: 'text-primary underline-offset-4 hover:underline',\n },\n size: {\n default: 'h-9 px-4 py-2 has-[>svg]:px-3',\n sm: 'h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5',\n lg: 'h-10 rounded-md px-6 has-[>svg]:px-4',\n icon: 'size-9',\n 'icon-sm': 'size-8',\n 'icon-lg': 'size-10',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'default',\n },\n },\n);\n\nfunction Button({\n className,\n variant,\n size,\n asChild = false,\n ...props\n}: React.ComponentProps<'button'> &\n VariantProps<typeof buttonVariants> & {\n asChild?: boolean;\n }) {\n const Comp = asChild ? Slot : 'button';\n\n return (\n <Comp\n data-slot=\"button\"\n className={cn(buttonVariants({ variant, size, className }))}\n {...props}\n />\n );\n}\n\nexport { Button, buttonVariants };\n","'use client';\n\nimport { Button } from '@mesob/ui/components/button';\nimport { cn } from '@mesob/ui/lib/utils';\nimport { IconMoon, IconSun } from '@tabler/icons-react';\nimport { useTheme } from 'next-themes';\n\ntype ThemeToggleProps = {\n className?: string;\n};\n\nexport function ThemeToggle({ className }: ThemeToggleProps) {\n const { resolvedTheme, setTheme, theme } = useTheme();\n const isDark = (theme ?? resolvedTheme) === 'dark';\n\n return (\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"icon\"\n aria-label=\"Toggle theme\"\n className={cn('relative', className)}\n onClick={() => setTheme(isDark ? 'light' : 'dark')}\n >\n <IconSun className=\"h-4 w-4 rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0\" />\n <IconMoon className=\"absolute h-4 w-4 rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100\" />\n <span className=\"sr-only\">Toggle theme</span>\n </Button>\n );\n}\n"],"mappings":";;;AAAA,SAA0B,YAAY;AACtC,SAAS,eAAe;AAEjB,SAAS,MAAM,QAAsB;AAC1C,SAAO,QAAQ,KAAK,MAAM,CAAC;AAC7B;;;ACJA,SAAS,YAAY;AACrB,SAAS,WAA8B;AAgDnC;AA7CJ,IAAM,iBAAiB;AAAA,EACrB;AAAA,EACA;AAAA,IACE,UAAU;AAAA,MACR,SAAS;AAAA,QACP,SAAS;AAAA,QACT,aACE;AAAA,QACF,SACE;AAAA,QACF,WACE;AAAA,QACF,OACE;AAAA,QACF,MAAM;AAAA,MACR;AAAA,MACA,MAAM;AAAA,QACJ,SAAS;AAAA,QACT,IAAI;AAAA,QACJ,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,WAAW;AAAA,QACX,WAAW;AAAA,MACb;AAAA,IACF;AAAA,IACA,iBAAiB;AAAA,MACf,SAAS;AAAA,MACT,MAAM;AAAA,IACR;AAAA,EACF;AACF;AAEA,SAAS,OAAO;AAAA,EACd;AAAA,EACA;AAAA,EACA;AAAA,EACA,UAAU;AAAA,EACV,GAAG;AACL,GAGK;AACH,QAAM,OAAO,UAAU,OAAO;AAE9B,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW,GAAG,eAAe,EAAE,SAAS,MAAM,UAAU,CAAC,CAAC;AAAA,MACzD,GAAG;AAAA;AAAA,EACN;AAEJ;;;ACpDA,SAAS,UAAU,eAAe;AAClC,SAAS,gBAAgB;AAWrB,SAQE,OAAAA,MARF;AALG,SAAS,YAAY,EAAE,UAAU,GAAqB;AAC3D,QAAM,EAAE,eAAe,UAAU,MAAM,IAAI,SAAS;AACpD,QAAM,UAAU,SAAS,mBAAmB;AAE5C,SACE;AAAA,IAAC;AAAA;AAAA,MACC,MAAK;AAAA,MACL,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,cAAW;AAAA,MACX,WAAW,GAAG,YAAY,SAAS;AAAA,MACnC,SAAS,MAAM,SAAS,SAAS,UAAU,MAAM;AAAA,MAEjD;AAAA,wBAAAA,KAAC,WAAQ,WAAU,0EAAyE;AAAA,QAC5F,gBAAAA,KAAC,YAAS,WAAU,kFAAiF;AAAA,QACrG,gBAAAA,KAAC,UAAK,WAAU,WAAU,0BAAY;AAAA;AAAA;AAAA,EACxC;AAEJ;","names":["jsx"]}
1
+ {"version":3,"sources":["../../src/lib/utils.ts","../../src/components/button.tsx","../../src/components/theme-toggle.tsx"],"sourcesContent":["import { type ClassValue, clsx } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","import { cn } from '@mesob/ui/lib/utils';\nimport { Slot } from '@radix-ui/react-slot';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport type * as React from 'react';\n\nconst buttonVariants = cva(\n \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive\",\n {\n variants: {\n variant: {\n default:\n 'bg-primary text-primary-foreground hover:bg-primary-600 dark:hover:bg-primary-400',\n destructive:\n 'bg-destructive text-destructive-foreground hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40',\n outline:\n 'border border-input bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50',\n secondary:\n 'bg-secondary text-secondary-foreground hover:bg-secondary-600 dark:hover:bg-secondary-400',\n ghost:\n 'hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50',\n link: 'text-primary underline-offset-4 hover:text-primary-600 dark:hover:text-primary-400 hover:underline',\n },\n size: {\n default: 'h-9 px-4 py-2 has-[>svg]:px-3',\n sm: 'h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5',\n lg: 'h-10 rounded-md px-6 has-[>svg]:px-4',\n icon: 'size-9',\n 'icon-sm': 'size-8',\n 'icon-lg': 'size-10',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'default',\n },\n },\n);\n\ntype ButtonProps = React.ComponentProps<'button'> &\n VariantProps<typeof buttonVariants> & {\n asChild?: boolean;\n leftIcon?: React.ReactNode;\n rightIcon?: React.ReactNode;\n };\n\nfunction Button({\n className,\n variant,\n size,\n asChild = false,\n leftIcon,\n rightIcon,\n children,\n ...props\n}: ButtonProps) {\n const Comp = asChild ? Slot : 'button';\n\n return (\n <Comp\n data-slot=\"button\"\n className={cn(buttonVariants({ variant, size, className }))}\n {...props}\n >\n {asChild ? (\n children\n ) : (\n <>\n {leftIcon}\n {children}\n {rightIcon}\n </>\n )}\n </Comp>\n );\n}\n\nexport { Button, buttonVariants };\n","'use client';\n\nimport { Button } from '@mesob/ui/components/button';\nimport { cn } from '@mesob/ui/lib/utils';\nimport { IconMoon, IconSun } from '@tabler/icons-react';\nimport { useTheme } from 'next-themes';\n\ntype ThemeToggleProps = {\n className?: string;\n};\n\nexport function ThemeToggle({ className }: ThemeToggleProps) {\n const { resolvedTheme, setTheme, theme } = useTheme();\n const isDark = (theme ?? resolvedTheme) === 'dark';\n\n return (\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"icon\"\n aria-label=\"Toggle theme\"\n className={cn('relative', className)}\n onClick={() => setTheme(isDark ? 'light' : 'dark')}\n >\n <IconSun className=\"h-4 w-4 rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0\" />\n <IconMoon className=\"absolute h-4 w-4 rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100\" />\n <span className=\"sr-only\">Toggle theme</span>\n </Button>\n );\n}\n"],"mappings":";;;AAAA,SAA0B,YAAY;AACtC,SAAS,eAAe;AAEjB,SAAS,MAAM,QAAsB;AAC1C,SAAO,QAAQ,KAAK,MAAM,CAAC;AAC7B;;;ACJA,SAAS,YAAY;AACrB,SAAS,WAA8B;AAwDnC,SAQI,UARJ,KAQI,YARJ;AArDJ,IAAM,iBAAiB;AAAA,EACrB;AAAA,EACA;AAAA,IACE,UAAU;AAAA,MACR,SAAS;AAAA,QACP,SACE;AAAA,QACF,aACE;AAAA,QACF,SACE;AAAA,QACF,WACE;AAAA,QACF,OACE;AAAA,QACF,MAAM;AAAA,MACR;AAAA,MACA,MAAM;AAAA,QACJ,SAAS;AAAA,QACT,IAAI;AAAA,QACJ,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,WAAW;AAAA,QACX,WAAW;AAAA,MACb;AAAA,IACF;AAAA,IACA,iBAAiB;AAAA,MACf,SAAS;AAAA,MACT,MAAM;AAAA,IACR;AAAA,EACF;AACF;AASA,SAAS,OAAO;AAAA,EACd;AAAA,EACA;AAAA,EACA;AAAA,EACA,UAAU;AAAA,EACV;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAAgB;AACd,QAAM,OAAO,UAAU,OAAO;AAE9B,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW,GAAG,eAAe,EAAE,SAAS,MAAM,UAAU,CAAC,CAAC;AAAA,MACzD,GAAG;AAAA,MAEH,oBACC,WAEA,iCACG;AAAA;AAAA,QACA;AAAA,QACA;AAAA,SACH;AAAA;AAAA,EAEJ;AAEJ;;;ACtEA,SAAS,UAAU,eAAe;AAClC,SAAS,gBAAgB;AAWrB,SAQE,OAAAA,MARF,QAAAC,aAAA;AALG,SAAS,YAAY,EAAE,UAAU,GAAqB;AAC3D,QAAM,EAAE,eAAe,UAAU,MAAM,IAAI,SAAS;AACpD,QAAM,UAAU,SAAS,mBAAmB;AAE5C,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC,MAAK;AAAA,MACL,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,cAAW;AAAA,MACX,WAAW,GAAG,YAAY,SAAS;AAAA,MACnC,SAAS,MAAM,SAAS,SAAS,UAAU,MAAM;AAAA,MAEjD;AAAA,wBAAAD,KAAC,WAAQ,WAAU,0EAAyE;AAAA,QAC5F,gBAAAA,KAAC,YAAS,WAAU,kFAAiF;AAAA,QACrG,gBAAAA,KAAC,UAAK,WAAU,WAAU,0BAAY;AAAA;AAAA;AAAA,EACxC;AAEJ;","names":["jsx","jsxs"]}
@@ -29,8 +29,9 @@ function useTranslation(namespace) {
29
29
  const mesob = useMesob();
30
30
  const nextIntlT = useTranslations(namespace);
31
31
  return useMemo2(() => {
32
- if (mesob?.t) {
33
- return (key, params) => mesob.t(namespace ? `${namespace}.${key}` : key, params);
32
+ const t = mesob?.t;
33
+ if (t) {
34
+ return (key, params) => t(namespace ? `${namespace}.${key}` : key, params);
34
35
  }
35
36
  return nextIntlT;
36
37
  }, [mesob?.t, namespace, nextIntlT]);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/hooks/use-translation.ts","../../src/lib/utils.ts","../../src/components/tooltip.tsx","../../src/components/mesob-context.tsx"],"sourcesContent":["'use client';\n\nimport { useTranslations } from 'next-intl';\nimport { useMemo } from 'react';\nimport { useMesob } from '../components/mesob-context';\n\nexport function useTranslation(namespace?: string) {\n const mesob = useMesob();\n const nextIntlT = useTranslations(namespace);\n\n return useMemo(() => {\n if (mesob?.t) {\n return (key: string, params?: Record<string, string | number>) =>\n mesob.t!(namespace ? `${namespace}.${key}` : key, params);\n }\n return nextIntlT;\n }, [mesob?.t, namespace, nextIntlT]);\n}\n","import { type ClassValue, clsx } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","'use client';\n\nimport { cn } from '@mesob/ui/lib/utils';\nimport * as TooltipPrimitive from '@radix-ui/react-tooltip';\nimport type * as React from 'react';\n\nfunction TooltipProvider({\n delayDuration = 0,\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Provider>) {\n return (\n <TooltipPrimitive.Provider\n data-slot=\"tooltip-provider\"\n delayDuration={delayDuration}\n {...props}\n />\n );\n}\n\nfunction Tooltip({\n children,\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Root>) {\n return (\n <TooltipPrimitive.Root data-slot=\"tooltip\" {...props}>\n {children}\n </TooltipPrimitive.Root>\n );\n}\n\nfunction TooltipTrigger({\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Trigger>) {\n return <TooltipPrimitive.Trigger data-slot=\"tooltip-trigger\" {...props} />;\n}\n\nfunction TooltipContent({\n className,\n sideOffset = 0,\n children,\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Content>) {\n return (\n <TooltipPrimitive.Portal>\n <TooltipPrimitive.Content\n data-slot=\"tooltip-content\"\n sideOffset={sideOffset}\n className={cn(\n 'bg-foreground text-background animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-fit origin-(--radix-tooltip-content-transform-origin) rounded-md px-3 py-1.5 text-xs text-balance',\n className,\n )}\n {...props}\n >\n {children}\n <TooltipPrimitive.Arrow className=\"bg-foreground fill-foreground z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px]\" />\n </TooltipPrimitive.Content>\n </TooltipPrimitive.Portal>\n );\n}\n\nexport { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider };\n","'use client';\n\nimport { TooltipProvider } from '@mesob/ui/components/tooltip';\nimport {\n type ComponentType,\n createContext,\n type ReactNode,\n useContext,\n useMemo,\n} from 'react';\n\nexport type MesobLinkProps = {\n href: string;\n children: ReactNode;\n className?: string;\n onClick?: () => void;\n};\n\nexport type Router = {\n push: (href: string) => void;\n replace: (href: string) => void;\n back: () => void;\n forward: () => void;\n refresh: () => void;\n prefetch: (href: string) => void;\n};\n\nexport type MesobContextValue = {\n linkComponent?: ComponentType<MesobLinkProps>;\n t?: (key: string, params?: Record<string, string | number>) => string;\n router?: Router;\n};\n\nconst MesobContext = createContext<MesobContextValue | null>(null);\n\nexport type MesobProviderProps = {\n children: ReactNode;\n linkComponent?: ComponentType<MesobLinkProps>;\n /** Hook that returns the app's t function (e.g. from next-intl useTranslations()). */\n useTranslation?: () => (\n key: string,\n params?: Record<string, string | number>,\n ) => string;\n /** Hook that returns the app's router (e.g. from next-intl useRouter()). */\n useRouter?: () => Router;\n};\n\nexport function MesobProvider({\n children,\n linkComponent,\n useTranslation,\n useRouter,\n}: MesobProviderProps) {\n const t = useTranslation?.();\n const router = useRouter?.();\n const value = useMemo<MesobContextValue>(\n () => ({ linkComponent, t: t ?? undefined, router: router ?? undefined }),\n [linkComponent, t, router],\n );\n return (\n <MesobContext.Provider value={value}>\n <TooltipProvider delayDuration={0}>{children}</TooltipProvider>\n </MesobContext.Provider>\n );\n}\n\nexport function useMesob(): MesobContextValue | null {\n return useContext(MesobContext);\n}\n"],"mappings":";;;AAEA,SAAS,uBAAuB;AAChC,SAAS,WAAAA,gBAAe;;;ACHxB,SAA0B,YAAY;AACtC,SAAS,eAAe;;;ACExB,YAAY,sBAAsB;AAQ9B,cAiCE,YAjCF;;;ACRJ;AAAA,EAEE;AAAA,EAEA;AAAA,EACA;AAAA,OACK;AAoDD,gBAAAC,YAAA;AA5BN,IAAM,eAAe,cAAwC,IAAI;AAiC1D,SAAS,WAAqC;AACnD,SAAO,WAAW,YAAY;AAChC;;;AH9DO,SAAS,eAAe,WAAoB;AACjD,QAAM,QAAQ,SAAS;AACvB,QAAM,YAAY,gBAAgB,SAAS;AAE3C,SAAOC,SAAQ,MAAM;AACnB,QAAI,OAAO,GAAG;AACZ,aAAO,CAAC,KAAa,WACnB,MAAM,EAAG,YAAY,GAAG,SAAS,IAAI,GAAG,KAAK,KAAK,MAAM;AAAA,IAC5D;AACA,WAAO;AAAA,EACT,GAAG,CAAC,OAAO,GAAG,WAAW,SAAS,CAAC;AACrC;","names":["useMemo","jsx","useMemo"]}
1
+ {"version":3,"sources":["../../src/hooks/use-translation.ts","../../src/lib/utils.ts","../../src/components/tooltip.tsx","../../src/components/mesob-context.tsx"],"sourcesContent":["'use client';\n\nimport { useTranslations } from 'next-intl';\nimport { useMemo } from 'react';\nimport { useMesob } from '../components/mesob-context';\n\nexport function useTranslation(namespace?: string) {\n const mesob = useMesob();\n const nextIntlT = useTranslations(namespace);\n\n return useMemo(() => {\n const t = mesob?.t;\n if (t) {\n return (key: string, params?: Record<string, string | number>) =>\n t(namespace ? `${namespace}.${key}` : key, params);\n }\n return nextIntlT;\n }, [mesob?.t, namespace, nextIntlT]);\n}\n","import { type ClassValue, clsx } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","'use client';\n\nimport { cn } from '@mesob/ui/lib/utils';\nimport * as TooltipPrimitive from '@radix-ui/react-tooltip';\nimport type * as React from 'react';\n\nfunction TooltipProvider({\n delayDuration = 0,\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Provider>) {\n return (\n <TooltipPrimitive.Provider\n data-slot=\"tooltip-provider\"\n delayDuration={delayDuration}\n {...props}\n />\n );\n}\n\nfunction Tooltip({\n children,\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Root>) {\n return (\n <TooltipPrimitive.Root data-slot=\"tooltip\" {...props}>\n {children}\n </TooltipPrimitive.Root>\n );\n}\n\nfunction TooltipTrigger({\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Trigger>) {\n return <TooltipPrimitive.Trigger data-slot=\"tooltip-trigger\" {...props} />;\n}\n\nfunction TooltipContent({\n className,\n sideOffset = 0,\n children,\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Content>) {\n return (\n <TooltipPrimitive.Portal>\n <TooltipPrimitive.Content\n data-slot=\"tooltip-content\"\n sideOffset={sideOffset}\n className={cn(\n 'bg-foreground text-background animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-fit origin-(--radix-tooltip-content-transform-origin) rounded-md px-3 py-1.5 text-xs text-balance',\n className,\n )}\n {...props}\n >\n {children}\n <TooltipPrimitive.Arrow className=\"bg-foreground fill-foreground z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px]\" />\n </TooltipPrimitive.Content>\n </TooltipPrimitive.Portal>\n );\n}\n\nexport { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider };\n","'use client';\n\nimport { TooltipProvider } from '@mesob/ui/components/tooltip';\nimport {\n type ComponentType,\n createContext,\n type ReactNode,\n useContext,\n useMemo,\n} from 'react';\n\nexport type MesobLinkProps = {\n href: string;\n children: ReactNode;\n className?: string;\n onClick?: () => void;\n};\n\nexport type Router = {\n push: (href: string) => void;\n replace: (href: string) => void;\n back: () => void;\n forward: () => void;\n refresh: () => void;\n prefetch: (href: string) => void;\n};\n\nexport type MesobContextValue = {\n linkComponent?: ComponentType<MesobLinkProps>;\n t?: (key: string, params?: Record<string, string | number>) => string;\n router?: Router;\n};\n\nconst MesobContext = createContext<MesobContextValue | null>(null);\n\nexport type MesobProviderProps = {\n children: ReactNode;\n linkComponent?: ComponentType<MesobLinkProps>;\n /** Hook that returns the app's t function (e.g. from next-intl useTranslations()). */\n useTranslation?: () => (\n key: string,\n params?: Record<string, string | number>,\n ) => string;\n /** Hook that returns the app's router (e.g. from next-intl useRouter()). */\n useRouter?: () => Router;\n};\n\nexport function MesobProvider({\n children,\n linkComponent,\n useTranslation,\n useRouter,\n}: MesobProviderProps) {\n const t = useTranslation?.();\n const router = useRouter?.();\n const value = useMemo<MesobContextValue>(\n () => ({ linkComponent, t: t ?? undefined, router: router ?? undefined }),\n [linkComponent, t, router],\n );\n return (\n <MesobContext.Provider value={value}>\n <TooltipProvider delayDuration={0}>{children}</TooltipProvider>\n </MesobContext.Provider>\n );\n}\n\nexport function useMesob(): MesobContextValue | null {\n return useContext(MesobContext);\n}\n"],"mappings":";;;AAEA,SAAS,uBAAuB;AAChC,SAAS,WAAAA,gBAAe;;;ACHxB,SAA0B,YAAY;AACtC,SAAS,eAAe;;;ACExB,YAAY,sBAAsB;AAQ9B,cAiCE,YAjCF;;;ACRJ;AAAA,EAEE;AAAA,EAEA;AAAA,EACA;AAAA,OACK;AAoDD,gBAAAC,YAAA;AA5BN,IAAM,eAAe,cAAwC,IAAI;AAiC1D,SAAS,WAAqC;AACnD,SAAO,WAAW,YAAY;AAChC;;;AH9DO,SAAS,eAAe,WAAoB;AACjD,QAAM,QAAQ,SAAS;AACvB,QAAM,YAAY,gBAAgB,SAAS;AAE3C,SAAOC,SAAQ,MAAM;AACnB,UAAM,IAAI,OAAO;AACjB,QAAI,GAAG;AACL,aAAO,CAAC,KAAa,WACnB,EAAE,YAAY,GAAG,SAAS,IAAI,GAAG,KAAK,KAAK,MAAM;AAAA,IACrD;AACA,WAAO;AAAA,EACT,GAAG,CAAC,OAAO,GAAG,WAAW,SAAS,CAAC;AACrC;","names":["useMemo","jsx","useMemo"]}
package/dist/index.d.ts CHANGED
@@ -1,2 +1,3 @@
1
+ export { REQUIRED_THEME_VARS, THEME_VAR_NAMES, ThemeValidation, ThemeVarName, validateTheme } from './lib/theme-schema.js';
1
2
  export { cn } from './lib/utils.js';
2
3
  import 'clsx';
package/dist/index.js CHANGED
@@ -1,3 +1,93 @@
1
+ // src/lib/theme-schema.ts
2
+ var SHADE_KEYS = [
3
+ 50,
4
+ 100,
5
+ 200,
6
+ 300,
7
+ 400,
8
+ 500,
9
+ 600,
10
+ 700,
11
+ 800,
12
+ 900,
13
+ 950
14
+ ];
15
+ var THEME_VAR_NAMES = [
16
+ "--background",
17
+ "--foreground",
18
+ "--card",
19
+ "--card-foreground",
20
+ "--popover",
21
+ "--popover-foreground",
22
+ "--primary",
23
+ "--primary-foreground",
24
+ ...SHADE_KEYS.map((s) => `--primary-${s}`),
25
+ "--secondary",
26
+ "--secondary-foreground",
27
+ ...SHADE_KEYS.map((s) => `--secondary-${s}`),
28
+ "--accent",
29
+ "--accent-foreground",
30
+ ...SHADE_KEYS.map((s) => `--accent-${s}`),
31
+ "--muted",
32
+ "--muted-foreground",
33
+ "--destructive",
34
+ "--destructive-foreground",
35
+ "--border",
36
+ "--input",
37
+ "--ring",
38
+ "--chart-1",
39
+ "--chart-2",
40
+ "--chart-3",
41
+ "--chart-4",
42
+ "--chart-5",
43
+ "--radius",
44
+ "--spacing",
45
+ "--sidebar",
46
+ "--sidebar-foreground",
47
+ "--sidebar-primary",
48
+ "--sidebar-primary-foreground",
49
+ "--sidebar-accent",
50
+ "--sidebar-accent-foreground",
51
+ "--sidebar-active",
52
+ "--sidebar-border",
53
+ "--sidebar-ring",
54
+ "--overlay"
55
+ ];
56
+ var THEME_VAR_SET = new Set(THEME_VAR_NAMES);
57
+ var REQUIRED_THEME_VARS = [
58
+ "--primary",
59
+ "--primary-foreground",
60
+ ...SHADE_KEYS.map((s) => `--primary-${s}`),
61
+ "--secondary",
62
+ "--secondary-foreground",
63
+ ...SHADE_KEYS.map((s) => `--secondary-${s}`),
64
+ "--accent",
65
+ "--accent-foreground",
66
+ ...SHADE_KEYS.map((s) => `--accent-${s}`),
67
+ "--radius",
68
+ "--spacing"
69
+ ];
70
+ function validateTheme(theme) {
71
+ const keys = new Set(Object.keys(theme));
72
+ const unknown = [];
73
+ const missing = [];
74
+ for (const key of keys) {
75
+ if (!THEME_VAR_SET.has(key)) {
76
+ unknown.push(key);
77
+ }
78
+ }
79
+ for (const key of REQUIRED_THEME_VARS) {
80
+ if (!keys.has(key)) {
81
+ missing.push(key);
82
+ }
83
+ }
84
+ return {
85
+ valid: unknown.length === 0 && missing.length === 0,
86
+ unknown,
87
+ missing
88
+ };
89
+ }
90
+
1
91
  // src/lib/utils.ts
2
92
  import { clsx } from "clsx";
3
93
  import { twMerge } from "tailwind-merge";
@@ -5,6 +95,9 @@ function cn(...inputs) {
5
95
  return twMerge(clsx(inputs));
6
96
  }
7
97
  export {
8
- cn
98
+ REQUIRED_THEME_VARS,
99
+ THEME_VAR_NAMES,
100
+ cn,
101
+ validateTheme
9
102
  };
10
103
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/lib/utils.ts"],"sourcesContent":["import { type ClassValue, clsx } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n"],"mappings":";AAAA,SAA0B,YAAY;AACtC,SAAS,eAAe;AAEjB,SAAS,MAAM,QAAsB;AAC1C,SAAO,QAAQ,KAAK,MAAM,CAAC;AAC7B;","names":[]}
1
+ {"version":3,"sources":["../src/lib/theme-schema.ts","../src/lib/utils.ts"],"sourcesContent":["/**\n * Canonical theme variable names for consumer theme (theme.css or generateTheme).\n * UI components depend on these CSS vars; consumer defines them.\n */\n\nconst SHADE_KEYS = [\n 50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 950,\n] as const;\n\nexport const THEME_VAR_NAMES = [\n '--background',\n '--foreground',\n '--card',\n '--card-foreground',\n '--popover',\n '--popover-foreground',\n '--primary',\n '--primary-foreground',\n ...SHADE_KEYS.map((s) => `--primary-${s}`),\n '--secondary',\n '--secondary-foreground',\n ...SHADE_KEYS.map((s) => `--secondary-${s}`),\n '--accent',\n '--accent-foreground',\n ...SHADE_KEYS.map((s) => `--accent-${s}`),\n '--muted',\n '--muted-foreground',\n '--destructive',\n '--destructive-foreground',\n '--border',\n '--input',\n '--ring',\n '--chart-1',\n '--chart-2',\n '--chart-3',\n '--chart-4',\n '--chart-5',\n '--radius',\n '--spacing',\n '--sidebar',\n '--sidebar-foreground',\n '--sidebar-primary',\n '--sidebar-primary-foreground',\n '--sidebar-accent',\n '--sidebar-accent-foreground',\n '--sidebar-active',\n '--sidebar-border',\n '--sidebar-ring',\n '--overlay',\n] as const;\n\nexport type ThemeVarName = (typeof THEME_VAR_NAMES)[number];\n\nconst THEME_VAR_SET = new Set<string>(THEME_VAR_NAMES);\n\n/** Vars that a minimal theme (e.g. generateTheme) should provide for primary/secondary/accent. */\nexport const REQUIRED_THEME_VARS: readonly string[] = [\n '--primary',\n '--primary-foreground',\n ...SHADE_KEYS.map((s) => `--primary-${s}`),\n '--secondary',\n '--secondary-foreground',\n ...SHADE_KEYS.map((s) => `--secondary-${s}`),\n '--accent',\n '--accent-foreground',\n ...SHADE_KEYS.map((s) => `--accent-${s}`),\n '--radius',\n '--spacing',\n];\n\nexport type ThemeValidation = {\n valid: boolean;\n unknown: string[];\n missing: string[];\n};\n\n/**\n * Validates a theme object against the consumer theme contract.\n * - unknown: keys not in THEME_VAR_NAMES (typos / unsupported).\n * - missing: required vars absent (for full theme override).\n */\nexport function validateTheme(theme: Record<string, string>): ThemeValidation {\n const keys = new Set(Object.keys(theme));\n const unknown: string[] = [];\n const missing: string[] = [];\n\n for (const key of keys) {\n if (!THEME_VAR_SET.has(key)) {\n unknown.push(key);\n }\n }\n for (const key of REQUIRED_THEME_VARS) {\n if (!keys.has(key)) {\n missing.push(key);\n }\n }\n\n return {\n valid: unknown.length === 0 && missing.length === 0,\n unknown,\n missing,\n };\n}\n","import { type ClassValue, clsx } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n"],"mappings":";AAKA,IAAM,aAAa;AAAA,EACjB;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AACnD;AAEO,IAAM,kBAAkB;AAAA,EAC7B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG,WAAW,IAAI,CAAC,MAAM,aAAa,CAAC,EAAE;AAAA,EACzC;AAAA,EACA;AAAA,EACA,GAAG,WAAW,IAAI,CAAC,MAAM,eAAe,CAAC,EAAE;AAAA,EAC3C;AAAA,EACA;AAAA,EACA,GAAG,WAAW,IAAI,CAAC,MAAM,YAAY,CAAC,EAAE;AAAA,EACxC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAIA,IAAM,gBAAgB,IAAI,IAAY,eAAe;AAG9C,IAAM,sBAAyC;AAAA,EACpD;AAAA,EACA;AAAA,EACA,GAAG,WAAW,IAAI,CAAC,MAAM,aAAa,CAAC,EAAE;AAAA,EACzC;AAAA,EACA;AAAA,EACA,GAAG,WAAW,IAAI,CAAC,MAAM,eAAe,CAAC,EAAE;AAAA,EAC3C;AAAA,EACA;AAAA,EACA,GAAG,WAAW,IAAI,CAAC,MAAM,YAAY,CAAC,EAAE;AAAA,EACxC;AAAA,EACA;AACF;AAaO,SAAS,cAAc,OAAgD;AAC5E,QAAM,OAAO,IAAI,IAAI,OAAO,KAAK,KAAK,CAAC;AACvC,QAAM,UAAoB,CAAC;AAC3B,QAAM,UAAoB,CAAC;AAE3B,aAAW,OAAO,MAAM;AACtB,QAAI,CAAC,cAAc,IAAI,GAAG,GAAG;AAC3B,cAAQ,KAAK,GAAG;AAAA,IAClB;AAAA,EACF;AACA,aAAW,OAAO,qBAAqB;AACrC,QAAI,CAAC,KAAK,IAAI,GAAG,GAAG;AAClB,cAAQ,KAAK,GAAG;AAAA,IAClB;AAAA,EACF;AAEA,SAAO;AAAA,IACL,OAAO,QAAQ,WAAW,KAAK,QAAQ,WAAW;AAAA,IAClD;AAAA,IACA;AAAA,EACF;AACF;;;ACtGA,SAA0B,YAAY;AACtC,SAAS,eAAe;AAEjB,SAAS,MAAM,QAAsB;AAC1C,SAAO,QAAQ,KAAK,MAAM,CAAC;AAC7B;","names":[]}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Canonical theme variable names for consumer theme (theme.css or generateTheme).
3
+ * UI components depend on these CSS vars; consumer defines them.
4
+ */
5
+ declare const THEME_VAR_NAMES: readonly ["--background", "--foreground", "--card", "--card-foreground", "--popover", "--popover-foreground", "--primary", "--primary-foreground", ...string[], "--muted", "--muted-foreground", "--destructive", "--destructive-foreground", "--border", "--input", "--ring", "--chart-1", "--chart-2", "--chart-3", "--chart-4", "--chart-5", "--radius", "--spacing", "--sidebar", "--sidebar-foreground", "--sidebar-primary", "--sidebar-primary-foreground", "--sidebar-accent", "--sidebar-accent-foreground", "--sidebar-active", "--sidebar-border", "--sidebar-ring", "--overlay"];
6
+ type ThemeVarName = (typeof THEME_VAR_NAMES)[number];
7
+ /** Vars that a minimal theme (e.g. generateTheme) should provide for primary/secondary/accent. */
8
+ declare const REQUIRED_THEME_VARS: readonly string[];
9
+ type ThemeValidation = {
10
+ valid: boolean;
11
+ unknown: string[];
12
+ missing: string[];
13
+ };
14
+ /**
15
+ * Validates a theme object against the consumer theme contract.
16
+ * - unknown: keys not in THEME_VAR_NAMES (typos / unsupported).
17
+ * - missing: required vars absent (for full theme override).
18
+ */
19
+ declare function validateTheme(theme: Record<string, string>): ThemeValidation;
20
+
21
+ export { REQUIRED_THEME_VARS, THEME_VAR_NAMES, type ThemeValidation, type ThemeVarName, validateTheme };
@@ -0,0 +1,95 @@
1
+ // src/lib/theme-schema.ts
2
+ var SHADE_KEYS = [
3
+ 50,
4
+ 100,
5
+ 200,
6
+ 300,
7
+ 400,
8
+ 500,
9
+ 600,
10
+ 700,
11
+ 800,
12
+ 900,
13
+ 950
14
+ ];
15
+ var THEME_VAR_NAMES = [
16
+ "--background",
17
+ "--foreground",
18
+ "--card",
19
+ "--card-foreground",
20
+ "--popover",
21
+ "--popover-foreground",
22
+ "--primary",
23
+ "--primary-foreground",
24
+ ...SHADE_KEYS.map((s) => `--primary-${s}`),
25
+ "--secondary",
26
+ "--secondary-foreground",
27
+ ...SHADE_KEYS.map((s) => `--secondary-${s}`),
28
+ "--accent",
29
+ "--accent-foreground",
30
+ ...SHADE_KEYS.map((s) => `--accent-${s}`),
31
+ "--muted",
32
+ "--muted-foreground",
33
+ "--destructive",
34
+ "--destructive-foreground",
35
+ "--border",
36
+ "--input",
37
+ "--ring",
38
+ "--chart-1",
39
+ "--chart-2",
40
+ "--chart-3",
41
+ "--chart-4",
42
+ "--chart-5",
43
+ "--radius",
44
+ "--spacing",
45
+ "--sidebar",
46
+ "--sidebar-foreground",
47
+ "--sidebar-primary",
48
+ "--sidebar-primary-foreground",
49
+ "--sidebar-accent",
50
+ "--sidebar-accent-foreground",
51
+ "--sidebar-active",
52
+ "--sidebar-border",
53
+ "--sidebar-ring",
54
+ "--overlay"
55
+ ];
56
+ var THEME_VAR_SET = new Set(THEME_VAR_NAMES);
57
+ var REQUIRED_THEME_VARS = [
58
+ "--primary",
59
+ "--primary-foreground",
60
+ ...SHADE_KEYS.map((s) => `--primary-${s}`),
61
+ "--secondary",
62
+ "--secondary-foreground",
63
+ ...SHADE_KEYS.map((s) => `--secondary-${s}`),
64
+ "--accent",
65
+ "--accent-foreground",
66
+ ...SHADE_KEYS.map((s) => `--accent-${s}`),
67
+ "--radius",
68
+ "--spacing"
69
+ ];
70
+ function validateTheme(theme) {
71
+ const keys = new Set(Object.keys(theme));
72
+ const unknown = [];
73
+ const missing = [];
74
+ for (const key of keys) {
75
+ if (!THEME_VAR_SET.has(key)) {
76
+ unknown.push(key);
77
+ }
78
+ }
79
+ for (const key of REQUIRED_THEME_VARS) {
80
+ if (!keys.has(key)) {
81
+ missing.push(key);
82
+ }
83
+ }
84
+ return {
85
+ valid: unknown.length === 0 && missing.length === 0,
86
+ unknown,
87
+ missing
88
+ };
89
+ }
90
+ export {
91
+ REQUIRED_THEME_VARS,
92
+ THEME_VAR_NAMES,
93
+ validateTheme
94
+ };
95
+ //# sourceMappingURL=theme-schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/lib/theme-schema.ts"],"sourcesContent":["/**\n * Canonical theme variable names for consumer theme (theme.css or generateTheme).\n * UI components depend on these CSS vars; consumer defines them.\n */\n\nconst SHADE_KEYS = [\n 50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 950,\n] as const;\n\nexport const THEME_VAR_NAMES = [\n '--background',\n '--foreground',\n '--card',\n '--card-foreground',\n '--popover',\n '--popover-foreground',\n '--primary',\n '--primary-foreground',\n ...SHADE_KEYS.map((s) => `--primary-${s}`),\n '--secondary',\n '--secondary-foreground',\n ...SHADE_KEYS.map((s) => `--secondary-${s}`),\n '--accent',\n '--accent-foreground',\n ...SHADE_KEYS.map((s) => `--accent-${s}`),\n '--muted',\n '--muted-foreground',\n '--destructive',\n '--destructive-foreground',\n '--border',\n '--input',\n '--ring',\n '--chart-1',\n '--chart-2',\n '--chart-3',\n '--chart-4',\n '--chart-5',\n '--radius',\n '--spacing',\n '--sidebar',\n '--sidebar-foreground',\n '--sidebar-primary',\n '--sidebar-primary-foreground',\n '--sidebar-accent',\n '--sidebar-accent-foreground',\n '--sidebar-active',\n '--sidebar-border',\n '--sidebar-ring',\n '--overlay',\n] as const;\n\nexport type ThemeVarName = (typeof THEME_VAR_NAMES)[number];\n\nconst THEME_VAR_SET = new Set<string>(THEME_VAR_NAMES);\n\n/** Vars that a minimal theme (e.g. generateTheme) should provide for primary/secondary/accent. */\nexport const REQUIRED_THEME_VARS: readonly string[] = [\n '--primary',\n '--primary-foreground',\n ...SHADE_KEYS.map((s) => `--primary-${s}`),\n '--secondary',\n '--secondary-foreground',\n ...SHADE_KEYS.map((s) => `--secondary-${s}`),\n '--accent',\n '--accent-foreground',\n ...SHADE_KEYS.map((s) => `--accent-${s}`),\n '--radius',\n '--spacing',\n];\n\nexport type ThemeValidation = {\n valid: boolean;\n unknown: string[];\n missing: string[];\n};\n\n/**\n * Validates a theme object against the consumer theme contract.\n * - unknown: keys not in THEME_VAR_NAMES (typos / unsupported).\n * - missing: required vars absent (for full theme override).\n */\nexport function validateTheme(theme: Record<string, string>): ThemeValidation {\n const keys = new Set(Object.keys(theme));\n const unknown: string[] = [];\n const missing: string[] = [];\n\n for (const key of keys) {\n if (!THEME_VAR_SET.has(key)) {\n unknown.push(key);\n }\n }\n for (const key of REQUIRED_THEME_VARS) {\n if (!keys.has(key)) {\n missing.push(key);\n }\n }\n\n return {\n valid: unknown.length === 0 && missing.length === 0,\n unknown,\n missing,\n };\n}\n"],"mappings":";AAKA,IAAM,aAAa;AAAA,EACjB;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AACnD;AAEO,IAAM,kBAAkB;AAAA,EAC7B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG,WAAW,IAAI,CAAC,MAAM,aAAa,CAAC,EAAE;AAAA,EACzC;AAAA,EACA;AAAA,EACA,GAAG,WAAW,IAAI,CAAC,MAAM,eAAe,CAAC,EAAE;AAAA,EAC3C;AAAA,EACA;AAAA,EACA,GAAG,WAAW,IAAI,CAAC,MAAM,YAAY,CAAC,EAAE;AAAA,EACxC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAIA,IAAM,gBAAgB,IAAI,IAAY,eAAe;AAG9C,IAAM,sBAAyC;AAAA,EACpD;AAAA,EACA;AAAA,EACA,GAAG,WAAW,IAAI,CAAC,MAAM,aAAa,CAAC,EAAE;AAAA,EACzC;AAAA,EACA;AAAA,EACA,GAAG,WAAW,IAAI,CAAC,MAAM,eAAe,CAAC,EAAE;AAAA,EAC3C;AAAA,EACA;AAAA,EACA,GAAG,WAAW,IAAI,CAAC,MAAM,YAAY,CAAC,EAAE;AAAA,EACxC;AAAA,EACA;AACF;AAaO,SAAS,cAAc,OAAgD;AAC5E,QAAM,OAAO,IAAI,IAAI,OAAO,KAAK,KAAK,CAAC;AACvC,QAAM,UAAoB,CAAC;AAC3B,QAAM,UAAoB,CAAC;AAE3B,aAAW,OAAO,MAAM;AACtB,QAAI,CAAC,cAAc,IAAI,GAAG,GAAG;AAC3B,cAAQ,KAAK,GAAG;AAAA,IAClB;AAAA,EACF;AACA,aAAW,OAAO,qBAAqB;AACrC,QAAI,CAAC,KAAK,IAAI,GAAG,GAAG;AAClB,cAAQ,KAAK,GAAG;AAAA,IAClB;AAAA,EACF;AAEA,SAAO;AAAA,IACL,OAAO,QAAQ,WAAW,KAAK,QAAQ,WAAW;AAAA,IAClD;AAAA,IACA;AAAA,EACF;AACF;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mesob/ui",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",
@@ -10,8 +10,6 @@
10
10
  "types": "./dist/index.d.ts",
11
11
  "default": "./dist/index.js"
12
12
  },
13
- "./globals.css": "./src/styles/globals.css",
14
- "./styles/globals.css": "./src/styles/globals.css",
15
13
  "./postcss.config": "./postcss.config.mjs",
16
14
  "./lib/*": {
17
15
  "types": "./dist/lib/*.d.ts",
@@ -43,8 +41,7 @@
43
41
  }
44
42
  },
45
43
  "files": [
46
- "dist",
47
- "src/styles"
44
+ "dist"
48
45
  ],
49
46
  "dependencies": {
50
47
  "@hookform/resolvers": "^5.2.2",
@@ -1,130 +0,0 @@
1
- @import "tailwindcss";
2
- @import "tw-animate-css";
3
- @source "../../../../apps/**/*.{ts,tsx}";
4
- @source "../../../../demos/**/*.{ts,tsx}";
5
- @source "../**/*.{ts,tsx}";
6
- @source "../../../auth-react/src/**/*.{ts,tsx}";
7
-
8
- @custom-variant dark (&:is(.dark *));
9
-
10
- :root {
11
- --background: oklch(1 0 0);
12
- --foreground: oklch(0.145 0 0);
13
- --card: oklch(1 0 0);
14
- --card-foreground: oklch(0.145 0 0);
15
- --popover: oklch(1 0 0);
16
- --popover-foreground: oklch(0.145 0 0);
17
- --primary: oklch(0.205 0 0);
18
- --primary-foreground: oklch(0.985 0 0);
19
- --secondary: oklch(0.97 0 0);
20
- --secondary-foreground: oklch(0.205 0 0);
21
- --muted: oklch(0.97 0 0);
22
- --muted-foreground: oklch(0.556 0 0);
23
- --accent: oklch(0.97 0 0);
24
- --accent-foreground: oklch(0.205 0 0);
25
- --destructive: oklch(0.577 0.245 27.325);
26
- --destructive-foreground: oklch(0.577 0.245 27.325);
27
- --border: oklch(0.922 0 0);
28
- --input: oklch(0.922 0 0);
29
- --ring: oklch(0.708 0 0);
30
- --chart-1: oklch(0.646 0.222 41.116);
31
- --chart-2: oklch(0.6 0.118 184.704);
32
- --chart-3: oklch(0.398 0.07 227.392);
33
- --chart-4: oklch(0.828 0.189 84.429);
34
- --chart-5: oklch(0.769 0.188 70.08);
35
- --radius: 0.625rem;
36
- --sidebar: oklch(0.985 0 0);
37
- --sidebar-foreground: oklch(0.145 0 0);
38
- --sidebar-primary: oklch(0.205 0 0);
39
- --sidebar-primary-foreground: oklch(0.985 0 0);
40
- --sidebar-accent: oklch(0.97 0 0);
41
- --sidebar-accent-foreground: oklch(0.205 0 0);
42
- --sidebar-active: oklch(0.94 0.04 250);
43
- --sidebar-border: oklch(0.922 0 0);
44
- --sidebar-ring: oklch(0.708 0 0);
45
- }
46
-
47
- .dark {
48
- --background: oklch(0.145 0 0);
49
- --foreground: oklch(0.985 0 0);
50
- --card: oklch(0.145 0 0);
51
- --card-foreground: oklch(0.985 0 0);
52
- --popover: oklch(0.145 0 0);
53
- --popover-foreground: oklch(0.985 0 0);
54
- --primary: oklch(0.985 0 0);
55
- --primary-foreground: oklch(0.205 0 0);
56
- --secondary: oklch(0.269 0 0);
57
- --secondary-foreground: oklch(0.985 0 0);
58
- --muted: oklch(0.269 0 0);
59
- --muted-foreground: oklch(0.708 0 0);
60
- --accent: oklch(0.269 0 0);
61
- --accent-foreground: oklch(0.985 0 0);
62
- --destructive: oklch(0.396 0.141 25.723);
63
- --destructive-foreground: oklch(0.637 0.237 25.331);
64
- --border: oklch(0.269 0 0);
65
- --input: oklch(0.269 0 0);
66
- --ring: oklch(0.556 0 0);
67
- --chart-1: oklch(0.488 0.243 264.376);
68
- --chart-2: oklch(0.696 0.17 162.48);
69
- --chart-3: oklch(0.769 0.188 70.08);
70
- --chart-4: oklch(0.627 0.265 303.9);
71
- --chart-5: oklch(0.645 0.246 16.439);
72
- --sidebar: oklch(0.205 0 0);
73
- --sidebar-foreground: oklch(0.985 0 0);
74
- --sidebar-primary: oklch(0.488 0.243 264.376);
75
- --sidebar-primary-foreground: oklch(0.985 0 0);
76
- --sidebar-accent: oklch(0.269 0 0);
77
- --sidebar-accent-foreground: oklch(0.985 0 0);
78
- --sidebar-active: oklch(0.28 0.06 264);
79
- --sidebar-border: oklch(0.269 0 0);
80
- --sidebar-ring: oklch(0.439 0 0);
81
- }
82
-
83
- @theme inline {
84
- --color-background: var(--background);
85
- --color-foreground: var(--foreground);
86
- --color-card: var(--card);
87
- --color-card-foreground: var(--card-foreground);
88
- --color-popover: var(--popover);
89
- --color-popover-foreground: var(--popover-foreground);
90
- --color-primary: var(--primary);
91
- --color-primary-foreground: var(--primary-foreground);
92
- --color-secondary: var(--secondary);
93
- --color-secondary-foreground: var(--secondary-foreground);
94
- --color-muted: var(--muted);
95
- --color-muted-foreground: var(--muted-foreground);
96
- --color-accent: var(--accent);
97
- --color-accent-foreground: var(--accent-foreground);
98
- --color-destructive: var(--destructive);
99
- --color-destructive-foreground: var(--destructive-foreground);
100
- --color-border: var(--border);
101
- --color-input: var(--input);
102
- --color-ring: var(--ring);
103
- --color-chart-1: var(--chart-1);
104
- --color-chart-2: var(--chart-2);
105
- --color-chart-3: var(--chart-3);
106
- --color-chart-4: var(--chart-4);
107
- --color-chart-5: var(--chart-5);
108
- --radius-sm: calc(var(--radius) - 4px);
109
- --radius-md: calc(var(--radius) - 2px);
110
- --radius-lg: var(--radius);
111
- --radius-xl: calc(var(--radius) + 4px);
112
- --color-sidebar: var(--sidebar);
113
- --color-sidebar-foreground: var(--sidebar-foreground);
114
- --color-sidebar-primary: var(--sidebar-primary);
115
- --color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
116
- --color-sidebar-accent: var(--sidebar-accent);
117
- --color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
118
- --color-sidebar-active: var(--sidebar-active);
119
- --color-sidebar-border: var(--sidebar-border);
120
- --color-sidebar-ring: var(--sidebar-ring);
121
- }
122
-
123
- @layer base {
124
- * {
125
- @apply border-border outline-ring/50;
126
- }
127
- body {
128
- @apply bg-background text-foreground;
129
- }
130
- }