@nextlyhq/ui 0.0.2-alpha.56 → 0.0.2-alpha.58
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/color.cjs +33 -0
- package/dist/color.cjs.map +1 -1
- package/dist/color.d.cts +84 -1
- package/dist/color.d.ts +84 -1
- package/dist/color.mjs +28 -1
- package/dist/color.mjs.map +1 -1
- package/dist/index.cjs +539 -122
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +167 -20
- package/dist/index.d.ts +167 -20
- package/dist/index.mjs +535 -120
- package/dist/index.mjs.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/styles.scoped.css +1 -1
- package/dist/tailwind-preset.cjs +55 -7
- package/dist/tailwind-preset.cjs.map +1 -1
- package/dist/tailwind-preset.d.cts +37 -1
- package/dist/tailwind-preset.d.ts +37 -1
- package/dist/tailwind-preset.mjs +55 -7
- package/dist/tailwind-preset.mjs.map +1 -1
- package/dist/theme.css +106 -28
- package/docs/plugin-ui-authoring.md +12 -10
- package/package.json +11 -8
|
@@ -6,8 +6,13 @@ declare const uiPreset: {
|
|
|
6
6
|
overlay: string;
|
|
7
7
|
"overlay-soft": string;
|
|
8
8
|
"overlay-strong": string;
|
|
9
|
-
border:
|
|
9
|
+
border: {
|
|
10
|
+
DEFAULT: string;
|
|
11
|
+
subtle: string;
|
|
12
|
+
strong: string;
|
|
13
|
+
};
|
|
10
14
|
input: string;
|
|
15
|
+
"control-border": string;
|
|
11
16
|
ring: string;
|
|
12
17
|
background: string;
|
|
13
18
|
foreground: string;
|
|
@@ -41,6 +46,37 @@ declare const uiPreset: {
|
|
|
41
46
|
DEFAULT: string;
|
|
42
47
|
foreground: string;
|
|
43
48
|
};
|
|
49
|
+
highlight: {
|
|
50
|
+
DEFAULT: string;
|
|
51
|
+
foreground: string;
|
|
52
|
+
};
|
|
53
|
+
code: {
|
|
54
|
+
bg: string;
|
|
55
|
+
fg: string;
|
|
56
|
+
comment: string;
|
|
57
|
+
keyword: string;
|
|
58
|
+
string: string;
|
|
59
|
+
number: string;
|
|
60
|
+
function: string;
|
|
61
|
+
operator: string;
|
|
62
|
+
punctuation: string;
|
|
63
|
+
variable: string;
|
|
64
|
+
tag: string;
|
|
65
|
+
deleted: string;
|
|
66
|
+
inserted: string;
|
|
67
|
+
};
|
|
68
|
+
sidebar: {
|
|
69
|
+
DEFAULT: string;
|
|
70
|
+
background: string;
|
|
71
|
+
foreground: string;
|
|
72
|
+
primary: string;
|
|
73
|
+
"primary-foreground": string;
|
|
74
|
+
accent: string;
|
|
75
|
+
"accent-background": string;
|
|
76
|
+
"accent-foreground": string;
|
|
77
|
+
border: string;
|
|
78
|
+
ring: string;
|
|
79
|
+
};
|
|
44
80
|
popover: {
|
|
45
81
|
DEFAULT: string;
|
|
46
82
|
foreground: string;
|
package/dist/tailwind-preset.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/tailwind-preset.ts
|
|
2
|
-
var
|
|
2
|
+
var tintScale = (base) => ({
|
|
3
3
|
50: `color-mix(in srgb, var(${base}), white 95%)`,
|
|
4
4
|
100: `color-mix(in srgb, var(${base}), white 90%)`,
|
|
5
5
|
200: `color-mix(in srgb, var(${base}), white 70%)`,
|
|
@@ -23,14 +23,24 @@ var uiPreset = {
|
|
|
23
23
|
overlay: "var(--nx-overlay)",
|
|
24
24
|
"overlay-soft": "var(--nx-overlay-soft)",
|
|
25
25
|
"overlay-strong": "var(--nx-overlay-strong)",
|
|
26
|
-
border:
|
|
26
|
+
border: {
|
|
27
|
+
DEFAULT: "var(--nx-border)",
|
|
28
|
+
subtle: "var(--nx-border-subtle)",
|
|
29
|
+
strong: "var(--nx-border-strong)"
|
|
30
|
+
},
|
|
27
31
|
input: "var(--nx-input)",
|
|
32
|
+
// The boundary of a control that draws no fill of its own -- an
|
|
33
|
+
// unchecked checkbox, radio or switch. Separate from `input` because
|
|
34
|
+
// that one is the field border weight, which sits below the 3:1
|
|
35
|
+
// non-text minimum by design.
|
|
36
|
+
"control-border": "var(--nx-control-border)",
|
|
28
37
|
ring: "var(--nx-ring)",
|
|
29
38
|
background: "var(--nx-background)",
|
|
30
39
|
foreground: "var(--nx-foreground)",
|
|
31
40
|
primary: {
|
|
32
41
|
DEFAULT: "var(--nx-primary)",
|
|
33
|
-
foreground: "var(--nx-primary-foreground)"
|
|
42
|
+
foreground: "var(--nx-primary-foreground)",
|
|
43
|
+
...tintScale("--nx-primary")
|
|
34
44
|
},
|
|
35
45
|
secondary: {
|
|
36
46
|
DEFAULT: "var(--nx-secondary)",
|
|
@@ -41,18 +51,18 @@ var uiPreset = {
|
|
|
41
51
|
// Saturated fill for solid buttons, distinct from the text-tuned base.
|
|
42
52
|
solid: "var(--nx-destructive-solid)",
|
|
43
53
|
foreground: "var(--nx-destructive-foreground)",
|
|
44
|
-
...
|
|
54
|
+
...tintScale("--nx-destructive")
|
|
45
55
|
},
|
|
46
56
|
success: {
|
|
47
57
|
DEFAULT: "var(--nx-success)",
|
|
48
58
|
solid: "var(--nx-success-solid)",
|
|
49
59
|
foreground: "var(--nx-success-foreground)",
|
|
50
|
-
...
|
|
60
|
+
...tintScale("--nx-success")
|
|
51
61
|
},
|
|
52
62
|
warning: {
|
|
53
63
|
DEFAULT: "var(--nx-warning)",
|
|
54
64
|
foreground: "var(--nx-warning-foreground)",
|
|
55
|
-
...
|
|
65
|
+
...tintScale("--nx-warning")
|
|
56
66
|
},
|
|
57
67
|
muted: {
|
|
58
68
|
DEFAULT: "var(--nx-muted)",
|
|
@@ -60,7 +70,45 @@ var uiPreset = {
|
|
|
60
70
|
},
|
|
61
71
|
accent: {
|
|
62
72
|
DEFAULT: "var(--nx-accent)",
|
|
63
|
-
foreground: "var(--nx-accent-foreground)"
|
|
73
|
+
foreground: "var(--nx-accent-foreground)",
|
|
74
|
+
...tintScale("--nx-accent")
|
|
75
|
+
},
|
|
76
|
+
// The editor's highlight mark, and the syntax colors, so authored
|
|
77
|
+
// content and code blocks theme like everything else.
|
|
78
|
+
highlight: {
|
|
79
|
+
DEFAULT: "var(--nx-highlight)",
|
|
80
|
+
foreground: "var(--nx-highlight-foreground)"
|
|
81
|
+
},
|
|
82
|
+
code: {
|
|
83
|
+
bg: "var(--nx-code-bg)",
|
|
84
|
+
fg: "var(--nx-code-fg)",
|
|
85
|
+
comment: "var(--nx-code-comment)",
|
|
86
|
+
keyword: "var(--nx-code-keyword)",
|
|
87
|
+
string: "var(--nx-code-string)",
|
|
88
|
+
number: "var(--nx-code-number)",
|
|
89
|
+
function: "var(--nx-code-function)",
|
|
90
|
+
operator: "var(--nx-code-operator)",
|
|
91
|
+
punctuation: "var(--nx-code-punctuation)",
|
|
92
|
+
variable: "var(--nx-code-variable)",
|
|
93
|
+
tag: "var(--nx-code-tag)",
|
|
94
|
+
deleted: "var(--nx-code-deleted)",
|
|
95
|
+
inserted: "var(--nx-code-inserted)"
|
|
96
|
+
},
|
|
97
|
+
// `sidebar` and `sidebar-background` are the same value under two
|
|
98
|
+
// names, and `sidebar-accent` and `sidebar-accent-background` likewise.
|
|
99
|
+
// Both pairs exist in the v4 block and both spellings are in use, so
|
|
100
|
+
// dropping either here would leave a live utility generating nothing.
|
|
101
|
+
sidebar: {
|
|
102
|
+
DEFAULT: "var(--nx-sidebar-background)",
|
|
103
|
+
background: "var(--nx-sidebar-background)",
|
|
104
|
+
foreground: "var(--nx-sidebar-foreground)",
|
|
105
|
+
primary: "var(--nx-sidebar-primary)",
|
|
106
|
+
"primary-foreground": "var(--nx-sidebar-primary-foreground)",
|
|
107
|
+
accent: "var(--nx-sidebar-accent)",
|
|
108
|
+
"accent-background": "var(--nx-sidebar-accent)",
|
|
109
|
+
"accent-foreground": "var(--nx-sidebar-accent-foreground)",
|
|
110
|
+
border: "var(--nx-sidebar-border)",
|
|
111
|
+
ring: "var(--nx-sidebar-ring)"
|
|
64
112
|
},
|
|
65
113
|
popover: {
|
|
66
114
|
DEFAULT: "var(--nx-popover)",
|
|
@@ -1 +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\n/** @experimental */\nconst uiPreset = {\n theme: {\n extend: {\n colors: {\n // The modal scrim. Mapped here as well as in the v4 `@theme` block,\n // because this preset is the documented Tailwind v3 path and reads\n // none of that: without these two, `bg-overlay` generates no rule at\n // all and every backdrop is transparent rather than merely unthemed.\n overlay: \"var(--nx-overlay)\",\n \"overlay-soft\": \"var(--nx-overlay-soft)\",\n \"overlay-strong\": \"var(--nx-overlay-strong)\",\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"]}
|
|
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 color, mixed from its base the same way the v4\n * `@theme` block does, so v3 preset consumers get the same utilities the\n * components emit (`bg-destructive-700`, `bg-primary-500`, `border-primary-300`).\n *\n * Named for the derivation rather than for one caller: the status colors, the\n * primary and the accent all use it, and `@theme` derives all five identically.\n */\nconst tintScale = (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\n/** @experimental */\nconst uiPreset = {\n theme: {\n extend: {\n colors: {\n // The modal scrim. Mapped here as well as in the v4 `@theme` block,\n // because this preset is the documented Tailwind v3 path and reads\n // none of that: without these two, `bg-overlay` generates no rule at\n // all and every backdrop is transparent rather than merely unthemed.\n overlay: \"var(--nx-overlay)\",\n \"overlay-soft\": \"var(--nx-overlay-soft)\",\n \"overlay-strong\": \"var(--nx-overlay-strong)\",\n border: {\n DEFAULT: \"var(--nx-border)\",\n subtle: \"var(--nx-border-subtle)\",\n strong: \"var(--nx-border-strong)\",\n },\n input: \"var(--nx-input)\",\n // The boundary of a control that draws no fill of its own -- an\n // unchecked checkbox, radio or switch. Separate from `input` because\n // that one is the field border weight, which sits below the 3:1\n // non-text minimum by design.\n \"control-border\": \"var(--nx-control-border)\",\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 ...tintScale(\"--nx-primary\"),\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 ...tintScale(\"--nx-destructive\"),\n },\n success: {\n DEFAULT: \"var(--nx-success)\",\n solid: \"var(--nx-success-solid)\",\n foreground: \"var(--nx-success-foreground)\",\n ...tintScale(\"--nx-success\"),\n },\n warning: {\n DEFAULT: \"var(--nx-warning)\",\n foreground: \"var(--nx-warning-foreground)\",\n ...tintScale(\"--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 ...tintScale(\"--nx-accent\"),\n },\n // The editor's highlight mark, and the syntax colors, so authored\n // content and code blocks theme like everything else.\n highlight: {\n DEFAULT: \"var(--nx-highlight)\",\n foreground: \"var(--nx-highlight-foreground)\",\n },\n code: {\n bg: \"var(--nx-code-bg)\",\n fg: \"var(--nx-code-fg)\",\n comment: \"var(--nx-code-comment)\",\n keyword: \"var(--nx-code-keyword)\",\n string: \"var(--nx-code-string)\",\n number: \"var(--nx-code-number)\",\n function: \"var(--nx-code-function)\",\n operator: \"var(--nx-code-operator)\",\n punctuation: \"var(--nx-code-punctuation)\",\n variable: \"var(--nx-code-variable)\",\n tag: \"var(--nx-code-tag)\",\n deleted: \"var(--nx-code-deleted)\",\n inserted: \"var(--nx-code-inserted)\",\n },\n // `sidebar` and `sidebar-background` are the same value under two\n // names, and `sidebar-accent` and `sidebar-accent-background` likewise.\n // Both pairs exist in the v4 block and both spellings are in use, so\n // dropping either here would leave a live utility generating nothing.\n sidebar: {\n DEFAULT: \"var(--nx-sidebar-background)\",\n background: \"var(--nx-sidebar-background)\",\n foreground: \"var(--nx-sidebar-foreground)\",\n primary: \"var(--nx-sidebar-primary)\",\n \"primary-foreground\": \"var(--nx-sidebar-primary-foreground)\",\n accent: \"var(--nx-sidebar-accent)\",\n \"accent-background\": \"var(--nx-sidebar-accent)\",\n \"accent-foreground\": \"var(--nx-sidebar-accent-foreground)\",\n border: \"var(--nx-sidebar-border)\",\n ring: \"var(--nx-sidebar-ring)\",\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/theme.css
CHANGED
|
@@ -139,6 +139,7 @@
|
|
|
139
139
|
--color-border-subtle: var(--nx-border-subtle);
|
|
140
140
|
--color-border-strong: var(--nx-border-strong);
|
|
141
141
|
--color-input: var(--nx-input);
|
|
142
|
+
--color-control-border: var(--nx-control-border);
|
|
142
143
|
--color-ring: var(--nx-ring);
|
|
143
144
|
--color-background: var(--nx-background);
|
|
144
145
|
--color-foreground: var(--nx-foreground);
|
|
@@ -418,16 +419,18 @@
|
|
|
418
419
|
* rounded-xl / rounded-2xl are NOT tiers of this knob. `tailwind-preset.ts`
|
|
419
420
|
* exports only lg/md/sm, so a plugin using the preset gets Tailwind's fixed
|
|
420
421
|
* 0.75rem / 1rem for them, detached from --radius; and the definitions below
|
|
421
|
-
*
|
|
422
|
-
*
|
|
423
|
-
*
|
|
422
|
+
* ADD to the knob rather than subtracting, so they always sit rounder than
|
|
423
|
+
* the container tier and drift further as the knob grows. Nothing in the repo
|
|
424
|
+
* uses them. Treat them as off-contract and pick from sm/md/lg.
|
|
424
425
|
*
|
|
425
|
-
*
|
|
426
|
-
*
|
|
427
|
-
*
|
|
428
|
-
*
|
|
429
|
-
*
|
|
430
|
-
*
|
|
426
|
+
* At the shipped 0.5rem the three tiers are 4px, 6px and 8px. All positive,
|
|
427
|
+
* which matters: `sm` and `md` SUBTRACT from the knob, so a knob under 4px
|
|
428
|
+
* makes them negative. They still render square, because border-radius clamps
|
|
429
|
+
* a negative length to 0 at used-value time — but the token keeps its
|
|
430
|
+
* negative value, so reading `--radius-sm` for a padding, an inset, or
|
|
431
|
+
* through getComputedStyle yields -4px rather than 0. Anything consuming a
|
|
432
|
+
* step as a LENGTH rather than as a corner must clamp it itself, and that
|
|
433
|
+
* obligation returns the moment someone dials the knob back down.
|
|
431
434
|
*
|
|
432
435
|
* A site that genuinely must stay square keeps `rounded-none` WITH an inline
|
|
433
436
|
* comment saying why — overlapped-border strips, full-bleed fills inside an
|
|
@@ -519,11 +522,34 @@
|
|
|
519
522
|
* and it shadows the real weight utility rather than adding to it.
|
|
520
523
|
* ============================================ */
|
|
521
524
|
@theme {
|
|
522
|
-
|
|
525
|
+
/* The host app supplies the face through the variable; the family name is the
|
|
526
|
+
* var()'s own FALLBACK ARGUMENT, covering a host that installed the font
|
|
527
|
+
* without `next/font`, and the generic stack after it covers a host that did
|
|
528
|
+
* neither. Naming only the family would resolve to nothing under `next/font`,
|
|
529
|
+
* which self-hosts the face and exposes it ONLY as a variable -- a bare
|
|
530
|
+
* "Geist" there silently falls through to the system sans.
|
|
531
|
+
*
|
|
532
|
+
* The fallback has to sit INSIDE the parentheses. A family listed after the
|
|
533
|
+
* closing `)` is not reached when the variable is undefined: an unresolved
|
|
534
|
+
* `var()` with no fallback makes the whole declaration invalid at
|
|
535
|
+
* computed-value time, which for an inherited property like font-family means
|
|
536
|
+
* the element inherits its parent's face and the entire stack is discarded.
|
|
537
|
+
* The comma list looks like a fallback chain and is not one, so a host that
|
|
538
|
+
* skipped the variable rendered in whatever the page already used rather than
|
|
539
|
+
* in the generic sans this stack names.
|
|
540
|
+
*
|
|
541
|
+
* These are declared in a non-inline `@theme`, so they are emitted into
|
|
542
|
+
* `:root` and substitution happens THERE, not on the consuming element. A
|
|
543
|
+
* host must expose the variable at or above that scope -- `next/font`'s
|
|
544
|
+
* generated class belongs on `<html>`. On `<body>` the variable is invisible
|
|
545
|
+
* to this declaration no matter how it is spelled. */
|
|
546
|
+
--font-sans:
|
|
547
|
+
var(--font-geist, Geist), ui-sans-serif, system-ui, -apple-system,
|
|
548
|
+
"Segoe UI", sans-serif;
|
|
523
549
|
--font-serif: ui-serif, Georgia, Cambria, "Times New Roman", Times, serif;
|
|
524
550
|
--font-mono:
|
|
525
|
-
ui-monospace, SFMono-Regular, Menlo,
|
|
526
|
-
"Courier New", monospace;
|
|
551
|
+
var(--font-geist-mono, "Geist Mono"), ui-monospace, SFMono-Regular, Menlo,
|
|
552
|
+
Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
|
527
553
|
|
|
528
554
|
/* Body text, captions */
|
|
529
555
|
--font-weight-normal: 400;
|
|
@@ -733,9 +759,12 @@
|
|
|
733
759
|
* light enough to read as text on the page is too light for white text, so
|
|
734
760
|
* success splits the fill and destructive flips its ink to black instead.
|
|
735
761
|
* The on-color token is what varies, not just the fill. */
|
|
736
|
-
/*
|
|
737
|
-
|
|
738
|
-
|
|
762
|
+
/* red-500 itself, the reference palette's red. It is lighter than the 4.5:1
|
|
763
|
+
* text minimum allows; darkening it to pass reads as a different colour, and
|
|
764
|
+
* the palette is built around this one. `contrast/accepted.ts` records the
|
|
765
|
+
* affected pairings with their measured ratios. */
|
|
766
|
+
--nx-destructive: oklch(0.63 0.19 23.03);
|
|
767
|
+
--nx-destructive-solid: oklch(0.63 0.19 23.03);
|
|
739
768
|
--nx-destructive-foreground: oklch(1 0 0);
|
|
740
769
|
/* white */
|
|
741
770
|
/* Darkened from green-600; renders as #00852c, ~4.8:1 as text on white. */
|
|
@@ -803,10 +832,33 @@
|
|
|
803
832
|
--nx-overlay-soft: oklch(0 0 0 / 0.4);
|
|
804
833
|
--nx-border-subtle: color-mix(in srgb, oklch(0.92 0 0), transparent 60%);
|
|
805
834
|
--nx-border: oklch(0.92 0 0);
|
|
806
|
-
/*
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
835
|
+
/* These two sit BELOW the WCAG 1.4.11 3:1 minimum for a control boundary,
|
|
836
|
+
* deliberately, to keep the light border weight the palette is designed
|
|
837
|
+
* around. `contrast/accepted.ts` records each affected pairing with its
|
|
838
|
+
* measured ratio and is what keeps that visible rather than silent; the
|
|
839
|
+
* contrast suite reads that list, so neither token can drift further without
|
|
840
|
+
* failing. */
|
|
841
|
+
--nx-border-strong: color-mix(in srgb, oklch(0.92 0 0), black 25%);
|
|
842
|
+
--nx-input: oklch(0.94 0 0);
|
|
843
|
+
/* The boundary of a control that has NOTHING ELSE to identify it.
|
|
844
|
+
*
|
|
845
|
+
* A text field at --nx-input is identifiable without its edge: it carries a
|
|
846
|
+
* label, a placeholder, a value, and a focus ring the moment it is used. An
|
|
847
|
+
* unchecked checkbox or radio is only the box. Its border is not decoration
|
|
848
|
+
* around the control, it IS the control, so 1.4.11's 3:1 applies with nothing
|
|
849
|
+
* to fall back on -- and at the reference palette's border weight the box is
|
|
850
|
+
* effectively invisible.
|
|
851
|
+
*
|
|
852
|
+
* These were one token, which is why the reference weight could not be taken
|
|
853
|
+
* without losing the checkbox. They are two questions -- "how heavy is a field
|
|
854
|
+
* edge" and "can this control be seen at all" -- and they only shared an
|
|
855
|
+
* answer by accident. Splitting them is what lets the field borders match the
|
|
856
|
+
* reference while the controls stay identifiable.
|
|
857
|
+
*
|
|
858
|
+
* Solved to the LIGHTEST value that still clears 3:1 with the margin the
|
|
859
|
+
* contrast suite requires, against the darkest surface a control lands on, so
|
|
860
|
+
* it sits as close to the reference weight as the criterion permits. */
|
|
861
|
+
--nx-control-border: oklch(0.62 0 0);
|
|
810
862
|
--nx-ring: var(--nx-primary);
|
|
811
863
|
|
|
812
864
|
/* The base colour of the elevation ramp (--shadow-sm..xl, -inner-subtle,
|
|
@@ -825,7 +877,10 @@
|
|
|
825
877
|
/* red-500 */
|
|
826
878
|
|
|
827
879
|
/* Design tokens */
|
|
828
|
-
|
|
880
|
+
/* The one corner knob. Every tier below derives from it, so this single
|
|
881
|
+
* declaration re-rounds the whole admin and a plugin built against the
|
|
882
|
+
* published preset re-rounds with it. */
|
|
883
|
+
--radius: 0.5rem;
|
|
829
884
|
|
|
830
885
|
/* Control sizing — derived from a single height knob so control density
|
|
831
886
|
* scales from one place. Steps map to the control size variants:
|
|
@@ -843,19 +898,35 @@
|
|
|
843
898
|
/* Sidebar specific colors - using Slate scale */
|
|
844
899
|
--nx-sidebar-background: oklch(0.99 0 0);
|
|
845
900
|
/* flat with the content surface; nav is separated by borders, not fill */
|
|
846
|
-
/* Resting nav ink
|
|
847
|
-
*
|
|
848
|
-
*
|
|
849
|
-
*
|
|
850
|
-
|
|
901
|
+
/* Resting and active nav ink are the same value in light mode: nav labels sit
|
|
902
|
+
* at body-text weight rather than a step back from it, which is the reference
|
|
903
|
+
* palette's arrangement.
|
|
904
|
+
*
|
|
905
|
+
* So the active row is marked by its FILL (--nx-sidebar-accent) TOGETHER WITH
|
|
906
|
+
* a font-weight change, and the pair is load-bearing rather than decorative.
|
|
907
|
+
* The fill alone is about 1.11:1, far under the 3:1 WCAG 1.4.11 asks of
|
|
908
|
+
* information identifying a component's state, and there is no exemption for
|
|
909
|
+
* a large filled region -- that is 1.4.3, and it is about text. The weight
|
|
910
|
+
* change is what satisfies the criterion, being a difference that is not a
|
|
911
|
+
* colour and so carries no ratio at all.
|
|
912
|
+
*
|
|
913
|
+
* Removing `data-[active=true]:font-medium` from the sidebar menu buttons
|
|
914
|
+
* therefore leaves the nav with no conforming active state, and
|
|
915
|
+
* `contrast/__tests__/sidebar-ink-hierarchy.test.ts` fails per variant if
|
|
916
|
+
* either loses it.
|
|
917
|
+
*
|
|
918
|
+
* Dark mode keeps the two-step ink relationship instead, where a near-white
|
|
919
|
+
* active ink on a dark row is what separates the states. */
|
|
920
|
+
--nx-sidebar-foreground: oklch(0 0 0);
|
|
851
921
|
--nx-sidebar-primary: oklch(0 0 0);
|
|
852
922
|
--nx-sidebar-primary-foreground: oklch(1 0 0);
|
|
853
923
|
/* slate-50 */
|
|
854
924
|
--nx-sidebar-accent: oklch(0.94 0 0);
|
|
855
925
|
/* slate-100 */
|
|
856
926
|
--nx-sidebar-accent-foreground: oklch(0 0 0);
|
|
857
|
-
/*
|
|
858
|
-
|
|
927
|
+
/* Below the 3:1 boundary minimum, deliberately, to match the border weight of
|
|
928
|
+
* the rest of the palette. Recorded in `contrast/accepted.ts`. */
|
|
929
|
+
--nx-sidebar-border: oklch(0.94 0 0);
|
|
859
930
|
--nx-sidebar-ring: var(--nx-primary);
|
|
860
931
|
|
|
861
932
|
/* Data table specific colors */
|
|
@@ -930,7 +1001,11 @@
|
|
|
930
1001
|
--nx-destructive-foreground: oklch(0 0 0);
|
|
931
1002
|
/* Lightened green so it reads as text at WCAG 4.5:1 on the dark page and on
|
|
932
1003
|
* the lighter popover surface (was 4.17:1 on the page, 4.29:1 on a popover). */
|
|
933
|
-
--nx-
|
|
1004
|
+
/* Lightened a step so success ink clears 4.5:1 on --nx-muted with the margin
|
|
1005
|
+
* the suite requires. Muted is the binding surface here, being the lightest
|
|
1006
|
+
* of the dark surfaces this ink lands on; against card or page it was never
|
|
1007
|
+
* close. */
|
|
1008
|
+
--nx-success: oklch(0.61 0.1921 149.58);
|
|
934
1009
|
/* Darker green fill so white on-color button text clears 4.5:1. */
|
|
935
1010
|
--nx-success-solid: oklch(0.5225 0.1921 149.58);
|
|
936
1011
|
--nx-success-foreground: oklch(1 0 0);
|
|
@@ -982,6 +1057,9 @@
|
|
|
982
1057
|
/* Brightened so the field border clears WCAG 3:1 on the lighter popover
|
|
983
1058
|
* surface as well as the page and card (was 1.73:1 on a popover). */
|
|
984
1059
|
--nx-input: oklch(0.5445 0 0);
|
|
1060
|
+
/* Dark mode never gave up the boundary minimum, so the control border simply
|
|
1061
|
+
tracks the field border here and the split costs nothing. */
|
|
1062
|
+
--nx-control-border: oklch(0.5445 0 0);
|
|
985
1063
|
--nx-ring: var(--nx-primary);
|
|
986
1064
|
|
|
987
1065
|
/* Black in dark mode too: the ramp reads as depth against the deep surfaces
|
|
@@ -88,8 +88,8 @@ Do not hardcode hex, `rgb()`, `rgba()`, or named colors. The only literals allow
|
|
|
88
88
|
|
|
89
89
|
### Corner radius: pick a tier, never a value
|
|
90
90
|
|
|
91
|
-
The admin ships
|
|
92
|
-
knob, so an operator who sets `--radius:
|
|
91
|
+
The admin ships rounded today (`--radius: 0.5rem`), and the whole scale derives from that
|
|
92
|
+
one knob, so an operator who sets `--radius: 0` squares every surface at once. Your plugin
|
|
93
93
|
keeps up with that only if it picks a **tier by element category** rather than writing a
|
|
94
94
|
length. Hardcoding a corner — `rounded-none` just as much as `rounded-[6px]` or
|
|
95
95
|
`border-radius: 4px` — pins your UI at that value and opts it out of the knob.
|
|
@@ -113,14 +113,16 @@ Four consequences worth internalising:
|
|
|
113
113
|
- **`rounded-xl` and `rounded-2xl` are not tiers of this knob.** The preset exports only
|
|
114
114
|
`lg`, `md` and `sm`, so a plugin built against it gets Tailwind's fixed `0.75rem` /
|
|
115
115
|
`1rem` for those two, detached from `--radius`. Inside the admin's own build they are
|
|
116
|
-
defined, but as `--radius + 4px` and `--radius + 8px`, so at the shipped `--radius: 0`
|
|
117
|
-
they resolve to `
|
|
118
|
-
`sm` / `md` / `lg`.
|
|
119
|
-
-
|
|
120
|
-
and
|
|
121
|
-
`
|
|
122
|
-
|
|
123
|
-
|
|
116
|
+
defined, but as `--radius + 4px` and `--radius + 8px`, so at the shipped `--radius: 0.5rem`
|
|
117
|
+
they resolve to `12px` and `16px` — rounder than the container tier, and drifting further
|
|
118
|
+
as the knob grows. Pick from `sm` / `md` / `lg`.
|
|
119
|
+
- **A low knob drives the lower steps negative.** At the shipped `0.5rem` the three tiers
|
|
120
|
+
are `4px`, `6px` and `8px`, all positive. But `sm` and `md` SUBTRACT from the knob, so
|
|
121
|
+
anything under `4px` — `--radius: 0` most obviously — computes them to `-4px` and `-2px`.
|
|
122
|
+
They _render_ square only because `border-radius` clamps a negative length to `0` at
|
|
123
|
+
used-value time. The token keeps its negative value, so reading a step for padding, for an
|
|
124
|
+
inset, or through `getComputedStyle` gives you `-4px`, not `0`. Clamp it yourself if you
|
|
125
|
+
consume a step as a length rather than as a corner.
|
|
124
126
|
- **A rounded container must handle full-bleed children.** If a child paints a background
|
|
125
127
|
all the way to the container's edge (a tinted footer, a sticky header, a hover row), give
|
|
126
128
|
the container `overflow-hidden` or give the child a matching corner with
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nextlyhq/ui",
|
|
3
|
-
"version": "0.0.2-alpha.
|
|
3
|
+
"version": "0.0.2-alpha.58",
|
|
4
4
|
"description": "Nextly UI — Reusable React component library for Nextly plugins and custom admin UIs",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"keywords": [
|
|
@@ -65,10 +65,11 @@
|
|
|
65
65
|
],
|
|
66
66
|
"files": [
|
|
67
67
|
"dist",
|
|
68
|
-
"docs"
|
|
68
|
+
"docs",
|
|
69
|
+
"!dist/metafile-*.json"
|
|
69
70
|
],
|
|
70
71
|
"engines": {
|
|
71
|
-
"node": "
|
|
72
|
+
"node": "^20.19.0 || ^22.12.0 || >=24.0.0"
|
|
72
73
|
},
|
|
73
74
|
"peerDependencies": {
|
|
74
75
|
"lucide-react": ">=0.400.0",
|
|
@@ -94,12 +95,14 @@
|
|
|
94
95
|
"rimraf": "^6.1.3",
|
|
95
96
|
"tailwindcss": "^4.3.2",
|
|
96
97
|
"tsup": "^8.5.0",
|
|
98
|
+
"tsx": "^4.20.5",
|
|
97
99
|
"typescript": "^5.9.3",
|
|
98
100
|
"vite-tsconfig-paths": "^5.1.4",
|
|
99
101
|
"vitest": "^4.1.0",
|
|
100
|
-
"@nextlyhq/
|
|
101
|
-
"@nextlyhq/
|
|
102
|
-
"@nextlyhq/
|
|
102
|
+
"@nextlyhq/admin-css": "0.0.2-alpha.58",
|
|
103
|
+
"@nextlyhq/eslint-config": "0.0.2-alpha.58",
|
|
104
|
+
"@nextlyhq/module-specifiers": "0.0.2-alpha.58",
|
|
105
|
+
"@nextlyhq/tsconfig": "0.0.2-alpha.58"
|
|
103
106
|
},
|
|
104
107
|
"dependencies": {
|
|
105
108
|
"@radix-ui/react-accordion": "^1.2.12",
|
|
@@ -145,9 +148,9 @@
|
|
|
145
148
|
"author": "Nextly <contact@nextlyhq.com> (https://nextlyhq.com)",
|
|
146
149
|
"scripts": {
|
|
147
150
|
"build": "pnpm build:js && node scripts/build-css.mjs",
|
|
148
|
-
"build:js": "rimraf dist && tsup && tsup --config tsup.server-safe.config.ts &&
|
|
151
|
+
"build:js": "rimraf dist && tsup && tsup --config tsup.server-safe.config.ts && tsx scripts/check-client-directive.ts && tsx scripts/check-server-safe-artifacts.ts",
|
|
149
152
|
"build:css": "node scripts/build-css.mjs",
|
|
150
|
-
"dev": "
|
|
153
|
+
"dev": "node scripts/dev.mjs",
|
|
151
154
|
"check-types": "tsc --noEmit && tsc --noEmit -p tsconfig.tests.json",
|
|
152
155
|
"lint": "eslint . --max-warnings 0",
|
|
153
156
|
"lint:fix": "eslint . --fix",
|