@nextlyhq/ui 0.0.2-alpha.37 → 0.0.2-alpha.39

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.
@@ -0,0 +1,80 @@
1
+ declare const uiPreset: {
2
+ theme: {
3
+ extend: {
4
+ colors: {
5
+ border: string;
6
+ input: string;
7
+ ring: string;
8
+ background: string;
9
+ foreground: string;
10
+ primary: {
11
+ DEFAULT: string;
12
+ foreground: string;
13
+ };
14
+ secondary: {
15
+ DEFAULT: string;
16
+ foreground: string;
17
+ };
18
+ destructive: {
19
+ DEFAULT: string;
20
+ solid: string;
21
+ foreground: string;
22
+ };
23
+ success: {
24
+ DEFAULT: string;
25
+ solid: string;
26
+ foreground: string;
27
+ };
28
+ warning: {
29
+ DEFAULT: string;
30
+ foreground: string;
31
+ };
32
+ muted: {
33
+ DEFAULT: string;
34
+ foreground: string;
35
+ };
36
+ accent: {
37
+ DEFAULT: string;
38
+ foreground: string;
39
+ };
40
+ popover: {
41
+ DEFAULT: string;
42
+ foreground: string;
43
+ };
44
+ card: {
45
+ DEFAULT: string;
46
+ foreground: string;
47
+ };
48
+ };
49
+ borderRadius: {
50
+ lg: string;
51
+ md: string;
52
+ sm: string;
53
+ };
54
+ keyframes: {
55
+ "accordion-down": {
56
+ from: {
57
+ height: string;
58
+ };
59
+ to: {
60
+ height: string;
61
+ };
62
+ };
63
+ "accordion-up": {
64
+ from: {
65
+ height: string;
66
+ };
67
+ to: {
68
+ height: string;
69
+ };
70
+ };
71
+ };
72
+ animation: {
73
+ "accordion-down": string;
74
+ "accordion-up": string;
75
+ };
76
+ };
77
+ };
78
+ };
79
+
80
+ export { uiPreset as default, uiPreset };
@@ -0,0 +1,80 @@
1
+ declare const uiPreset: {
2
+ theme: {
3
+ extend: {
4
+ colors: {
5
+ border: string;
6
+ input: string;
7
+ ring: string;
8
+ background: string;
9
+ foreground: string;
10
+ primary: {
11
+ DEFAULT: string;
12
+ foreground: string;
13
+ };
14
+ secondary: {
15
+ DEFAULT: string;
16
+ foreground: string;
17
+ };
18
+ destructive: {
19
+ DEFAULT: string;
20
+ solid: string;
21
+ foreground: string;
22
+ };
23
+ success: {
24
+ DEFAULT: string;
25
+ solid: string;
26
+ foreground: string;
27
+ };
28
+ warning: {
29
+ DEFAULT: string;
30
+ foreground: string;
31
+ };
32
+ muted: {
33
+ DEFAULT: string;
34
+ foreground: string;
35
+ };
36
+ accent: {
37
+ DEFAULT: string;
38
+ foreground: string;
39
+ };
40
+ popover: {
41
+ DEFAULT: string;
42
+ foreground: string;
43
+ };
44
+ card: {
45
+ DEFAULT: string;
46
+ foreground: string;
47
+ };
48
+ };
49
+ borderRadius: {
50
+ lg: string;
51
+ md: string;
52
+ sm: string;
53
+ };
54
+ keyframes: {
55
+ "accordion-down": {
56
+ from: {
57
+ height: string;
58
+ };
59
+ to: {
60
+ height: string;
61
+ };
62
+ };
63
+ "accordion-up": {
64
+ from: {
65
+ height: string;
66
+ };
67
+ to: {
68
+ height: string;
69
+ };
70
+ };
71
+ };
72
+ animation: {
73
+ "accordion-down": string;
74
+ "accordion-up": string;
75
+ };
76
+ };
77
+ };
78
+ };
79
+
80
+ export { uiPreset as default, uiPreset };
@@ -0,0 +1,93 @@
1
+ // src/tailwind-preset.ts
2
+ var statusScale = (base) => ({
3
+ 50: `color-mix(in srgb, var(${base}), white 95%)`,
4
+ 100: `color-mix(in srgb, var(${base}), white 90%)`,
5
+ 200: `color-mix(in srgb, var(${base}), white 70%)`,
6
+ 300: `color-mix(in srgb, var(${base}), white 50%)`,
7
+ 400: `color-mix(in srgb, var(${base}), white 30%)`,
8
+ 500: `var(${base})`,
9
+ 600: `color-mix(in srgb, var(${base}), black 10%)`,
10
+ 700: `color-mix(in srgb, var(${base}), black 30%)`,
11
+ 800: `color-mix(in srgb, var(${base}), black 50%)`,
12
+ 900: `color-mix(in srgb, var(${base}), black 70%)`,
13
+ 950: `color-mix(in srgb, var(${base}), black 85%)`
14
+ });
15
+ var uiPreset = {
16
+ theme: {
17
+ extend: {
18
+ colors: {
19
+ border: "var(--nx-border)",
20
+ input: "var(--nx-input)",
21
+ ring: "var(--nx-ring)",
22
+ background: "var(--nx-background)",
23
+ foreground: "var(--nx-foreground)",
24
+ primary: {
25
+ DEFAULT: "var(--nx-primary)",
26
+ foreground: "var(--nx-primary-foreground)"
27
+ },
28
+ secondary: {
29
+ DEFAULT: "var(--nx-secondary)",
30
+ foreground: "var(--nx-secondary-foreground)"
31
+ },
32
+ destructive: {
33
+ DEFAULT: "var(--nx-destructive)",
34
+ // Saturated fill for solid buttons, distinct from the text-tuned base.
35
+ solid: "var(--nx-destructive-solid)",
36
+ foreground: "var(--nx-destructive-foreground)",
37
+ ...statusScale("--nx-destructive")
38
+ },
39
+ success: {
40
+ DEFAULT: "var(--nx-success)",
41
+ solid: "var(--nx-success-solid)",
42
+ foreground: "var(--nx-success-foreground)",
43
+ ...statusScale("--nx-success")
44
+ },
45
+ warning: {
46
+ DEFAULT: "var(--nx-warning)",
47
+ foreground: "var(--nx-warning-foreground)",
48
+ ...statusScale("--nx-warning")
49
+ },
50
+ muted: {
51
+ DEFAULT: "var(--nx-muted)",
52
+ foreground: "var(--nx-muted-foreground)"
53
+ },
54
+ accent: {
55
+ DEFAULT: "var(--nx-accent)",
56
+ foreground: "var(--nx-accent-foreground)"
57
+ },
58
+ popover: {
59
+ DEFAULT: "var(--nx-popover)",
60
+ foreground: "var(--nx-popover-foreground)"
61
+ },
62
+ card: {
63
+ DEFAULT: "var(--nx-card)",
64
+ foreground: "var(--nx-card-foreground)"
65
+ }
66
+ },
67
+ borderRadius: {
68
+ lg: "var(--radius)",
69
+ md: "calc(var(--radius) - 2px)",
70
+ sm: "calc(var(--radius) - 4px)"
71
+ },
72
+ keyframes: {
73
+ "accordion-down": {
74
+ from: { height: "0" },
75
+ to: { height: "var(--radix-accordion-content-height)" }
76
+ },
77
+ "accordion-up": {
78
+ from: { height: "var(--radix-accordion-content-height)" },
79
+ to: { height: "0" }
80
+ }
81
+ },
82
+ animation: {
83
+ "accordion-down": "accordion-down 0.3s cubic-bezier(0.87, 0, 0.13, 1)",
84
+ "accordion-up": "accordion-up 0.3s cubic-bezier(0.87, 0, 0.13, 1)"
85
+ }
86
+ }
87
+ }
88
+ };
89
+ var tailwind_preset_default = uiPreset;
90
+
91
+ export { tailwind_preset_default as default, uiPreset };
92
+ //# sourceMappingURL=tailwind-preset.mjs.map
93
+ //# sourceMappingURL=tailwind-preset.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/tailwind-preset.ts"],"names":[],"mappings":"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","file":"tailwind-preset.mjs","sourcesContent":["/**\n * Tailwind CSS preset for @nextlyhq/ui components.\n *\n * Defines the CSS custom property contract that all UI components expect.\n * Consumers must provide the actual CSS variable values in their stylesheets.\n *\n * Usage (Tailwind v3, ESM):\n * // tailwind.config.ts\n * import uiPreset from \"@nextlyhq/ui/tailwind-preset\";\n * export default { presets: [uiPreset], ... };\n *\n * Usage (Tailwind v3, CommonJS):\n * // tailwind.config.js\n * const { uiPreset } = require(\"@nextlyhq/ui/tailwind-preset\");\n * module.exports = { presets: [uiPreset], ... };\n *\n * Usage (Tailwind v4 with @config):\n * Consumers define the equivalent @theme tokens in their CSS.\n * This file serves as the reference contract.\n */\n/**\n * The numbered shade scale for a status color, mixed from its base the same way\n * the v4 `@theme` block does, so v3 preset consumers get the same utilities the\n * components emit (`bg-destructive-700`, `bg-success-100 text-success-700`, ...).\n */\nconst statusScale = (base: string): Record<number, string> => ({\n 50: `color-mix(in srgb, var(${base}), white 95%)`,\n 100: `color-mix(in srgb, var(${base}), white 90%)`,\n 200: `color-mix(in srgb, var(${base}), white 70%)`,\n 300: `color-mix(in srgb, var(${base}), white 50%)`,\n 400: `color-mix(in srgb, var(${base}), white 30%)`,\n 500: `var(${base})`,\n 600: `color-mix(in srgb, var(${base}), black 10%)`,\n 700: `color-mix(in srgb, var(${base}), black 30%)`,\n 800: `color-mix(in srgb, var(${base}), black 50%)`,\n 900: `color-mix(in srgb, var(${base}), black 70%)`,\n 950: `color-mix(in srgb, var(${base}), black 85%)`,\n});\n\nconst uiPreset = {\n theme: {\n extend: {\n colors: {\n border: \"var(--nx-border)\",\n input: \"var(--nx-input)\",\n ring: \"var(--nx-ring)\",\n background: \"var(--nx-background)\",\n foreground: \"var(--nx-foreground)\",\n primary: {\n DEFAULT: \"var(--nx-primary)\",\n foreground: \"var(--nx-primary-foreground)\",\n },\n secondary: {\n DEFAULT: \"var(--nx-secondary)\",\n foreground: \"var(--nx-secondary-foreground)\",\n },\n destructive: {\n DEFAULT: \"var(--nx-destructive)\",\n // Saturated fill for solid buttons, distinct from the text-tuned base.\n solid: \"var(--nx-destructive-solid)\",\n foreground: \"var(--nx-destructive-foreground)\",\n ...statusScale(\"--nx-destructive\"),\n },\n success: {\n DEFAULT: \"var(--nx-success)\",\n solid: \"var(--nx-success-solid)\",\n foreground: \"var(--nx-success-foreground)\",\n ...statusScale(\"--nx-success\"),\n },\n warning: {\n DEFAULT: \"var(--nx-warning)\",\n foreground: \"var(--nx-warning-foreground)\",\n ...statusScale(\"--nx-warning\"),\n },\n muted: {\n DEFAULT: \"var(--nx-muted)\",\n foreground: \"var(--nx-muted-foreground)\",\n },\n accent: {\n DEFAULT: \"var(--nx-accent)\",\n foreground: \"var(--nx-accent-foreground)\",\n },\n popover: {\n DEFAULT: \"var(--nx-popover)\",\n foreground: \"var(--nx-popover-foreground)\",\n },\n card: {\n DEFAULT: \"var(--nx-card)\",\n foreground: \"var(--nx-card-foreground)\",\n },\n },\n borderRadius: {\n lg: \"var(--radius)\",\n md: \"calc(var(--radius) - 2px)\",\n sm: \"calc(var(--radius) - 4px)\",\n },\n keyframes: {\n \"accordion-down\": {\n from: { height: \"0\" },\n to: { height: \"var(--radix-accordion-content-height)\" },\n },\n \"accordion-up\": {\n from: { height: \"var(--radix-accordion-content-height)\" },\n to: { height: \"0\" },\n },\n },\n animation: {\n \"accordion-down\": \"accordion-down 0.3s cubic-bezier(0.87, 0, 0.13, 1)\",\n \"accordion-up\": \"accordion-up 0.3s cubic-bezier(0.87, 0, 0.13, 1)\",\n },\n },\n },\n};\n\n// Exported both ways on purpose. CommonJS cannot represent a default-only\n// module without `module.exports =`, which makes the emitted declarations\n// disagree with the runtime shape (attw's FalseExportDefault); a named export\n// alongside it keeps `require()` and `import` consistent and typed.\nexport { uiPreset };\nexport default uiPreset;\n"]}
package/dist/utils.cjs ADDED
@@ -0,0 +1,13 @@
1
+ 'use strict';
2
+
3
+ var clsx = require('clsx');
4
+ var tailwindMerge = require('tailwind-merge');
5
+
6
+ // src/lib/utils.ts
7
+ function cn(...inputs) {
8
+ return tailwindMerge.twMerge(clsx.clsx(inputs));
9
+ }
10
+
11
+ exports.cn = cn;
12
+ //# sourceMappingURL=utils.cjs.map
13
+ //# sourceMappingURL=utils.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/lib/utils.ts"],"names":["twMerge","clsx"],"mappings":";;;;;;AAeO,SAAS,MAAM,MAAA,EAAsB;AAC1C,EAAA,OAAOA,qBAAA,CAAQC,SAAA,CAAK,MAAM,CAAC,CAAA;AAC7B","file":"utils.cjs","sourcesContent":["import { type ClassValue, clsx } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\n/**\n * Utility function to merge class names with Tailwind CSS support.\n *\n * Combines clsx for conditional class names with tailwind-merge\n * to properly handle Tailwind CSS class conflicts.\n *\n * @example\n * ```typescript\n * cn('px-2 py-1', 'px-4') // => 'py-1 px-4'\n * cn('text-muted-foreground', condition && 'text-foreground')\n * ```\n */\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n"]}
@@ -0,0 +1,17 @@
1
+ import { ClassValue } from 'clsx';
2
+
3
+ /**
4
+ * Utility function to merge class names with Tailwind CSS support.
5
+ *
6
+ * Combines clsx for conditional class names with tailwind-merge
7
+ * to properly handle Tailwind CSS class conflicts.
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * cn('px-2 py-1', 'px-4') // => 'py-1 px-4'
12
+ * cn('text-muted-foreground', condition && 'text-foreground')
13
+ * ```
14
+ */
15
+ declare function cn(...inputs: ClassValue[]): string;
16
+
17
+ export { cn };
@@ -0,0 +1,17 @@
1
+ import { ClassValue } from 'clsx';
2
+
3
+ /**
4
+ * Utility function to merge class names with Tailwind CSS support.
5
+ *
6
+ * Combines clsx for conditional class names with tailwind-merge
7
+ * to properly handle Tailwind CSS class conflicts.
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * cn('px-2 py-1', 'px-4') // => 'py-1 px-4'
12
+ * cn('text-muted-foreground', condition && 'text-foreground')
13
+ * ```
14
+ */
15
+ declare function cn(...inputs: ClassValue[]): string;
16
+
17
+ export { cn };
package/dist/utils.mjs ADDED
@@ -0,0 +1,11 @@
1
+ import { clsx } from 'clsx';
2
+ import { twMerge } from 'tailwind-merge';
3
+
4
+ // src/lib/utils.ts
5
+ function cn(...inputs) {
6
+ return twMerge(clsx(inputs));
7
+ }
8
+
9
+ export { cn };
10
+ //# sourceMappingURL=utils.mjs.map
11
+ //# sourceMappingURL=utils.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/lib/utils.ts"],"names":[],"mappings":";;;;AAeO,SAAS,MAAM,MAAA,EAAsB;AAC1C,EAAA,OAAO,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAC,CAAA;AAC7B","file":"utils.mjs","sourcesContent":["import { type ClassValue, clsx } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\n/**\n * Utility function to merge class names with Tailwind CSS support.\n *\n * Combines clsx for conditional class names with tailwind-merge\n * to properly handle Tailwind CSS class conflicts.\n *\n * @example\n * ```typescript\n * cn('px-2 py-1', 'px-4') // => 'py-1 px-4'\n * cn('text-muted-foreground', condition && 'text-foreground')\n * ```\n */\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n"]}
@@ -20,8 +20,8 @@ points:
20
20
  | `@nextlyhq/ui/styles.css` | Pre-compiled bundle (Tailwind + tokens + reset). Zero config. | Standalone UI, or a quick embed with no build wiring. |
21
21
 
22
22
  **Inside a Nextly admin plugin you usually need neither.** The admin already loads
23
- `@nextlyhq/admin/style.css`, which defines every token scoped to `.adminapp` (and
24
- `.adminapp.dark` for dark mode). Plugin admin views render inside that scope, so the tokens
23
+ `@nextlyhq/admin/style.css`, which defines every token scoped to `.nextly-admin` (and
24
+ `.nextly-admin.dark` for dark mode). Plugin admin views render inside that scope, so the tokens
25
25
  are already on the page. Your plugin CSS should **consume** those tokens, never redefine
26
26
  them.
27
27
 
@@ -36,52 +36,52 @@ Tokens are **complete color values** (OKLCH). Reference them directly:
36
36
 
37
37
  ```css
38
38
  .my-panel {
39
- background: var(--card);
40
- color: var(--foreground);
41
- border: 1px solid var(--border);
39
+ background: var(--nx-card);
40
+ color: var(--nx-foreground);
41
+ border: 1px solid var(--nx-border);
42
42
  border-radius: var(--radius);
43
43
  }
44
44
  ```
45
45
 
46
46
  ### Never wrap a token in `hsl()` / `rgb()`
47
47
 
48
- Older Nextly builds stored tokens as bare HSL channels (`--primary: 221 83% 53%`) and code
49
- wrapped them: `hsl(var(--primary))`. **That convention is gone.** Tokens are now full colors
50
- (`--primary: oklch(0 0 0)`), so `hsl(var(--primary))` becomes `hsl(oklch(0 0 0))`, which is
48
+ Older Nextly builds stored tokens as bare HSL channels (`--nx-primary: 221 83% 53%`) and code
49
+ wrapped them: `hsl(var(--nx-primary))`. **That convention is gone.** Tokens are now full colors
50
+ (`--nx-primary: oklch(0 0 0)`), so `hsl(var(--nx-primary))` becomes `hsl(oklch(0 0 0))`, which is
51
51
  invalid CSS — the browser drops the declaration and your element loses its color. Always:
52
52
 
53
53
  ```css
54
54
  /* ✗ wrong — produces hsl(oklch(...)), silently dropped */
55
- color: hsl(var(--foreground));
55
+ color: hsl(var(--nx-foreground));
56
56
 
57
57
  /* ✓ right */
58
- color: var(--foreground);
58
+ color: var(--nx-foreground);
59
59
  ```
60
60
 
61
61
  ### Alpha / transparency
62
62
 
63
- You can no longer do `hsl(var(--primary) / 0.1)`. Use `color-mix`:
63
+ You can no longer do `hsl(var(--nx-primary) / 0.1)`. Use `color-mix`:
64
64
 
65
65
  ```css
66
66
  /* 10% primary over transparent */
67
- background: color-mix(in srgb, var(--primary) 10%, transparent);
67
+ background: color-mix(in srgb, var(--nx-primary) 10%, transparent);
68
68
 
69
69
  /* a subtle hover tint from the foreground */
70
- background: color-mix(in srgb, var(--foreground) 6%, transparent);
70
+ background: color-mix(in srgb, var(--nx-foreground) 6%, transparent);
71
71
  ```
72
72
 
73
73
  ### The tokens you may use
74
74
 
75
- Colors: `--background` / `--foreground`, `--card` / `--card-foreground`,
76
- `--popover` / `--popover-foreground`, `--primary` / `--primary-foreground`,
77
- `--secondary` / `--secondary-foreground`, `--muted` / `--muted-foreground`,
78
- `--accent` / `--accent-foreground`, `--destructive`, `--success`, `--warning`,
79
- `--border`, `--border-strong`, `--input`, `--ring`,
80
- `--sidebar-background` and the `--sidebar-*` family.
75
+ Colors: `--nx-background` / `--nx-foreground`, `--nx-card` / `--nx-card-foreground`,
76
+ `--nx-popover` / `--nx-popover-foreground`, `--nx-primary` / `--nx-primary-foreground`,
77
+ `--nx-secondary` / `--nx-secondary-foreground`, `--nx-muted` / `--nx-muted-foreground`,
78
+ `--nx-accent` / `--nx-accent-foreground`, `--nx-destructive`, `--nx-success`, `--nx-warning`,
79
+ `--nx-border`, `--nx-border-strong`, `--nx-input`, `--nx-ring`,
80
+ `--nx-sidebar-background` and the `--nx-sidebar-*` family.
81
81
 
82
82
  Sizing: `--radius` (the system is square — this is `0`; always route corner radius through
83
- it so a future rounding is one edit), and the control-height scale `--control-height`,
84
- `--control-height-sm`, `--control-height-md`, `--control-height-lg` for anything that should
83
+ it so a future rounding is one edit), and the control-height scale `--nx-control-height`,
84
+ `--nx-control-height-sm`, `--nx-control-height-md`, `--nx-control-height-lg` for anything that should
85
85
  line up with admin inputs and buttons.
86
86
 
87
87
  Do not hardcode hex, `rgb()`, `rgba()`, or named colors. The only literals allowed are
@@ -96,7 +96,7 @@ a stylesheet. They are already token-driven, accessible, and dark-mode-correct.
96
96
 
97
97
  ```tsx
98
98
  import { Button, Input, Select, Switch, Badge } from "@nextlyhq/ui";
99
- import { cn } from "@nextlyhq/ui";
99
+ import { cn } from "@nextlyhq/ui/utils";
100
100
 
101
101
  <Button variant="outline" size="sm">Add field</Button>
102
102
  <Input placeholder="Form name" />
@@ -114,13 +114,13 @@ control). When you write it, it must obey the token contract in section 2 and be
114
114
 
115
115
  ## 4. Dark mode is automatic — don't fight it
116
116
 
117
- The admin flips every token under `.adminapp.dark`. If you only ever reference tokens, your
117
+ The admin flips every token under `.nextly-admin.dark`. If you only ever reference tokens, your
118
118
  UI switches with it and you never write a dark rule.
119
119
 
120
120
  - **Never** hardcode a light or dark color.
121
121
  - **Never** gate admin theming on `@media (prefers-color-scheme: dark)` — admin dark mode is
122
- class-based (`.dark` / `.adminapp.dark`), independent of the OS. A media query makes your
123
- UI ignore the admin's own theme toggle. Use Tailwind's `dark:` variant or `.adminapp.dark`
122
+ class-based (`.dark` / `.nextly-admin.dark`), independent of the OS. A media query makes your
123
+ UI ignore the admin's own theme toggle. Use Tailwind's `dark:` variant or `.nextly-admin.dark`
124
124
  descendant selectors if you truly need a mode-specific tweak.
125
125
 
126
126
  ---
@@ -169,7 +169,7 @@ allowlist in the script with a one-line reason — don't silence the whole check
169
169
 
170
170
  - [ ] Colors come from `var(--token)` — no `hsl()`/`rgb()` wrappers, no hardcoded values.
171
171
  - [ ] Alpha uses `color-mix(in srgb, var(--token) N%, transparent)`.
172
- - [ ] Corner radius routes through `var(--radius)`; control heights use `--control-height*`.
172
+ - [ ] Corner radius routes through `var(--radius)`; control heights use `--nx-control-height*`.
173
173
  - [ ] New UI uses `@nextlyhq/ui` components + Tailwind utilities where practical.
174
174
  - [ ] No `@media (prefers-color-scheme)`; dark mode inherited from the admin.
175
175
  - [ ] Class names are prefixed/scoped; no bare element selectors.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nextlyhq/ui",
3
- "version": "0.0.2-alpha.37",
3
+ "version": "0.0.2-alpha.39",
4
4
  "description": "Nextly UI — Reusable React component library for Nextly plugins and custom admin UIs",
5
5
  "license": "MIT",
6
6
  "keywords": [
@@ -17,13 +17,42 @@
17
17
  "types": "dist/index.d.ts",
18
18
  "exports": {
19
19
  ".": {
20
- "types": "./dist/index.d.ts",
21
- "import": "./dist/index.mjs",
22
- "require": "./dist/index.cjs"
20
+ "import": {
21
+ "types": "./dist/index.d.ts",
22
+ "default": "./dist/index.mjs"
23
+ },
24
+ "require": {
25
+ "types": "./dist/index.d.cts",
26
+ "default": "./dist/index.cjs"
27
+ }
28
+ },
29
+ "./tailwind-preset": {
30
+ "import": {
31
+ "types": "./dist/tailwind-preset.d.ts",
32
+ "default": "./dist/tailwind-preset.mjs"
33
+ },
34
+ "require": {
35
+ "types": "./dist/tailwind-preset.d.cts",
36
+ "default": "./dist/tailwind-preset.cjs"
37
+ }
38
+ },
39
+ "./utils": {
40
+ "import": {
41
+ "types": "./dist/utils.d.ts",
42
+ "default": "./dist/utils.mjs"
43
+ },
44
+ "require": {
45
+ "types": "./dist/utils.d.cts",
46
+ "default": "./dist/utils.cjs"
47
+ }
23
48
  },
24
49
  "./theme.css": "./dist/theme.css",
25
- "./styles.css": "./dist/styles.css"
50
+ "./styles.css": "./dist/styles.css",
51
+ "./styles.scoped.css": "./dist/styles.scoped.css"
26
52
  },
53
+ "sideEffects": [
54
+ "**/*.css"
55
+ ],
27
56
  "files": [
28
57
  "dist",
29
58
  "docs"
@@ -51,13 +80,15 @@
51
80
  "postcss": "^8.5.6",
52
81
  "react": "19.2.0",
53
82
  "react-dom": "19.2.0",
83
+ "rimraf": "^6.1.3",
54
84
  "tailwindcss": "^4.3.2",
55
85
  "tsup": "^8.5.0",
56
86
  "typescript": "^5.9.3",
57
87
  "vite-tsconfig-paths": "^5.1.4",
58
88
  "vitest": "^4.1.0",
59
- "@nextlyhq/eslint-config": "0.0.2-alpha.37",
60
- "@nextlyhq/tsconfig": "0.0.2-alpha.37"
89
+ "@nextlyhq/admin-css": "0.0.2-alpha.39",
90
+ "@nextlyhq/tsconfig": "0.0.2-alpha.39",
91
+ "@nextlyhq/eslint-config": "0.0.2-alpha.39"
61
92
  },
62
93
  "dependencies": {
63
94
  "@radix-ui/react-accordion": "^1.2.12",
@@ -98,10 +129,10 @@
98
129
  },
99
130
  "author": "Nextly <contact@nextlyhq.com> (https://nextlyhq.com)",
100
131
  "scripts": {
101
- "build": "tsup && node scripts/build-css.mjs",
102
- "build:js": "tsup",
132
+ "build": "pnpm build:js && node scripts/build-css.mjs",
133
+ "build:js": "rimraf dist && tsup && tsup --config tsup.server-safe.config.ts && node scripts/check-client-directive.mjs",
103
134
  "build:css": "node scripts/build-css.mjs",
104
- "dev": "tsup --watch",
135
+ "dev": "tsup --watch & tsup --config tsup.server-safe.config.ts --watch & wait",
105
136
  "check-types": "tsc --noEmit",
106
137
  "lint": "eslint . --max-warnings 0",
107
138
  "lint:fix": "eslint . --fix",