@refinn/core-ui 0.1.0

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/README.md ADDED
@@ -0,0 +1,36 @@
1
+ This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app).
2
+
3
+ ## Getting Started
4
+
5
+ First, run the development server:
6
+
7
+ ```bash
8
+ npm run dev
9
+ # or
10
+ yarn dev
11
+ # or
12
+ pnpm dev
13
+ # or
14
+ bun dev
15
+ ```
16
+
17
+ Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
18
+
19
+ You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
20
+
21
+ This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel.
22
+
23
+ ## Learn More
24
+
25
+ To learn more about Next.js, take a look at the following resources:
26
+
27
+ - [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
28
+ - [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
29
+
30
+ You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome!
31
+
32
+ ## Deploy on Vercel
33
+
34
+ The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
35
+
36
+ Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details.
@@ -0,0 +1,27 @@
1
+ import * as react from 'react';
2
+ import { ButtonHTMLAttributes, ReactNode, InputHTMLAttributes } from 'react';
3
+
4
+ type ButtonVariant = 'primary' | 'secondary' | 'tertiary' | 'contrast' | 'transparent';
5
+ type ButtonSize = 'small' | 'medium' | 'large' | 'extra-large';
6
+ interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
7
+ variant?: ButtonVariant;
8
+ size?: ButtonSize;
9
+ rounded?: boolean;
10
+ loading?: boolean;
11
+ startIcon?: ReactNode;
12
+ endIcon?: ReactNode;
13
+ }
14
+ declare const Button: react.ForwardRefExoticComponent<ButtonProps & react.RefAttributes<HTMLButtonElement>>;
15
+
16
+ type CheckboxSize = 'small' | 'medium';
17
+ interface CheckboxProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'size' | 'type'> {
18
+ size?: CheckboxSize;
19
+ label?: ReactNode;
20
+ description?: ReactNode;
21
+ indeterminate?: boolean;
22
+ error?: boolean;
23
+ contrast?: boolean;
24
+ }
25
+ declare const Checkbox: react.ForwardRefExoticComponent<CheckboxProps & react.RefAttributes<HTMLInputElement>>;
26
+
27
+ export { Button, type ButtonProps, Checkbox, type CheckboxProps };
@@ -0,0 +1,27 @@
1
+ import * as react from 'react';
2
+ import { ButtonHTMLAttributes, ReactNode, InputHTMLAttributes } from 'react';
3
+
4
+ type ButtonVariant = 'primary' | 'secondary' | 'tertiary' | 'contrast' | 'transparent';
5
+ type ButtonSize = 'small' | 'medium' | 'large' | 'extra-large';
6
+ interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
7
+ variant?: ButtonVariant;
8
+ size?: ButtonSize;
9
+ rounded?: boolean;
10
+ loading?: boolean;
11
+ startIcon?: ReactNode;
12
+ endIcon?: ReactNode;
13
+ }
14
+ declare const Button: react.ForwardRefExoticComponent<ButtonProps & react.RefAttributes<HTMLButtonElement>>;
15
+
16
+ type CheckboxSize = 'small' | 'medium';
17
+ interface CheckboxProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'size' | 'type'> {
18
+ size?: CheckboxSize;
19
+ label?: ReactNode;
20
+ description?: ReactNode;
21
+ indeterminate?: boolean;
22
+ error?: boolean;
23
+ contrast?: boolean;
24
+ }
25
+ declare const Checkbox: react.ForwardRefExoticComponent<CheckboxProps & react.RefAttributes<HTMLInputElement>>;
26
+
27
+ export { Button, type ButtonProps, Checkbox, type CheckboxProps };
package/dist/index.js ADDED
@@ -0,0 +1,313 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __defProps = Object.defineProperties;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
10
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
11
+ var __spreadValues = (a, b) => {
12
+ for (var prop in b || (b = {}))
13
+ if (__hasOwnProp.call(b, prop))
14
+ __defNormalProp(a, prop, b[prop]);
15
+ if (__getOwnPropSymbols)
16
+ for (var prop of __getOwnPropSymbols(b)) {
17
+ if (__propIsEnum.call(b, prop))
18
+ __defNormalProp(a, prop, b[prop]);
19
+ }
20
+ return a;
21
+ };
22
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
23
+ var __objRest = (source, exclude) => {
24
+ var target = {};
25
+ for (var prop in source)
26
+ if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
27
+ target[prop] = source[prop];
28
+ if (source != null && __getOwnPropSymbols)
29
+ for (var prop of __getOwnPropSymbols(source)) {
30
+ if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
31
+ target[prop] = source[prop];
32
+ }
33
+ return target;
34
+ };
35
+ var __export = (target, all) => {
36
+ for (var name in all)
37
+ __defProp(target, name, { get: all[name], enumerable: true });
38
+ };
39
+ var __copyProps = (to, from, except, desc) => {
40
+ if (from && typeof from === "object" || typeof from === "function") {
41
+ for (let key of __getOwnPropNames(from))
42
+ if (!__hasOwnProp.call(to, key) && key !== except)
43
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
44
+ }
45
+ return to;
46
+ };
47
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
48
+
49
+ // src/components/index.ts
50
+ var index_exports = {};
51
+ __export(index_exports, {
52
+ Button: () => Button,
53
+ Checkbox: () => Checkbox
54
+ });
55
+ module.exports = __toCommonJS(index_exports);
56
+
57
+ // src/components/Button/Button.tsx
58
+ var import_react = require("react");
59
+ var import_jsx_runtime = require("react/jsx-runtime");
60
+ var variantClasses = {
61
+ primary: [
62
+ "bg-btn-primary text-btn-primary-text",
63
+ "hover:bg-btn-primary-hover",
64
+ "active:bg-btn-primary-active",
65
+ "focus-visible:ring-2 focus-visible:ring-btn-primary-ring focus-visible:ring-offset-2",
66
+ "disabled:bg-btn-primary-disabled disabled:text-btn-primary-text-disabled"
67
+ ].join(" "),
68
+ secondary: [
69
+ "bg-btn-secondary text-btn-secondary-text",
70
+ "hover:bg-btn-secondary-hover",
71
+ "active:bg-btn-secondary-active",
72
+ "focus-visible:ring-2 focus-visible:ring-btn-secondary-ring focus-visible:ring-offset-2",
73
+ "disabled:bg-btn-secondary-disabled disabled:text-btn-secondary-text-disabled"
74
+ ].join(" "),
75
+ tertiary: [
76
+ "bg-btn-tertiary text-btn-tertiary-text",
77
+ "hover:bg-btn-tertiary-hover",
78
+ "active:bg-btn-tertiary-active",
79
+ "focus-visible:ring-2 focus-visible:ring-btn-tertiary-ring focus-visible:ring-offset-2",
80
+ "disabled:bg-btn-tertiary-disabled disabled:text-btn-tertiary-text-disabled"
81
+ ].join(" "),
82
+ contrast: [
83
+ "bg-btn-contrast text-btn-contrast-text",
84
+ "hover:bg-btn-contrast-hover",
85
+ "active:bg-btn-contrast-active",
86
+ "focus-visible:ring-2 focus-visible:ring-btn-contrast-ring focus-visible:ring-offset-2",
87
+ "disabled:bg-btn-contrast-disabled disabled:text-btn-contrast-text-disabled"
88
+ ].join(" "),
89
+ transparent: [
90
+ "bg-btn-transparent text-btn-transparent-text",
91
+ "hover:bg-btn-transparent-hover",
92
+ "active:bg-btn-transparent-active",
93
+ "focus-visible:ring-2 focus-visible:ring-btn-transparent-ring focus-visible:ring-offset-2",
94
+ "disabled:bg-btn-transparent-disabled disabled:text-btn-transparent-text-disabled"
95
+ ].join(" ")
96
+ };
97
+ var sizeClasses = {
98
+ small: "h-8 px-3 text-sm gap-1",
99
+ medium: "h-10 px-4 text-sm gap-1.5",
100
+ large: "h-12 px-5 text-base gap-2",
101
+ "extra-large": "h-14 px-6 text-lg gap-2"
102
+ };
103
+ function Spinner({ className }) {
104
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
105
+ "svg",
106
+ {
107
+ className,
108
+ width: "1em",
109
+ height: "1em",
110
+ viewBox: "0 0 20 20",
111
+ fill: "none",
112
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
113
+ "path",
114
+ {
115
+ d: "M10 2.5a7.5 7.5 0 1 0 7.5 7.5",
116
+ stroke: "currentColor",
117
+ strokeWidth: "2",
118
+ strokeLinecap: "round"
119
+ }
120
+ )
121
+ }
122
+ );
123
+ }
124
+ var Button = (0, import_react.forwardRef)(
125
+ (_a, ref) => {
126
+ var _b = _a, {
127
+ variant = "primary",
128
+ size = "medium",
129
+ rounded = false,
130
+ loading = false,
131
+ disabled = false,
132
+ startIcon,
133
+ endIcon,
134
+ children,
135
+ className = ""
136
+ } = _b, rest = __objRest(_b, [
137
+ "variant",
138
+ "size",
139
+ "rounded",
140
+ "loading",
141
+ "disabled",
142
+ "startIcon",
143
+ "endIcon",
144
+ "children",
145
+ "className"
146
+ ]);
147
+ const isDisabled = disabled || loading;
148
+ const classes = [
149
+ "inline-flex items-center justify-center font-medium font-sans",
150
+ "transition-colors duration-150",
151
+ "outline-none",
152
+ "disabled:cursor-not-allowed",
153
+ sizeClasses[size],
154
+ variantClasses[variant],
155
+ rounded ? "rounded-full" : "rounded-lg",
156
+ className
157
+ ].filter(Boolean).join(" ");
158
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
159
+ "button",
160
+ __spreadProps(__spreadValues({
161
+ ref,
162
+ disabled: isDisabled,
163
+ className: classes
164
+ }, rest), {
165
+ children: [
166
+ loading ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Spinner, { className: "animate-spin" }) : startIcon,
167
+ children,
168
+ !loading && endIcon
169
+ ]
170
+ })
171
+ );
172
+ }
173
+ );
174
+ Button.displayName = "Button";
175
+
176
+ // src/components/Checkbox/Checkbox.tsx
177
+ var import_react2 = require("react");
178
+ var import_jsx_runtime2 = require("react/jsx-runtime");
179
+ var sizeClasses2 = {
180
+ small: {
181
+ box: "h-4 w-4",
182
+ icon: "h-3 w-3",
183
+ label: "text-sm leading-5",
184
+ description: "text-xs leading-4",
185
+ gap: "gap-2"
186
+ },
187
+ medium: {
188
+ box: "h-5 w-5",
189
+ icon: "h-3.5 w-3.5",
190
+ label: "text-base leading-6",
191
+ description: "text-sm leading-5",
192
+ gap: "gap-2.5"
193
+ }
194
+ };
195
+ function CheckIcon({ className }) {
196
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { className, viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
197
+ "path",
198
+ {
199
+ d: "M13.333 4.667 6 12l-3.333-3.333",
200
+ stroke: "currentColor",
201
+ strokeWidth: "2",
202
+ strokeLinecap: "round",
203
+ strokeLinejoin: "round"
204
+ }
205
+ ) });
206
+ }
207
+ function IndeterminateIcon({ className }) {
208
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { className, viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
209
+ "path",
210
+ {
211
+ d: "M3.333 8h9.334",
212
+ stroke: "currentColor",
213
+ strokeWidth: "2",
214
+ strokeLinecap: "round"
215
+ }
216
+ ) });
217
+ }
218
+ var Checkbox = (0, import_react2.forwardRef)(
219
+ (_a, ref) => {
220
+ var _b = _a, {
221
+ size = "medium",
222
+ label,
223
+ description,
224
+ indeterminate = false,
225
+ error = false,
226
+ contrast = false,
227
+ checked,
228
+ defaultChecked,
229
+ disabled = false,
230
+ className = "",
231
+ id
232
+ } = _b, rest = __objRest(_b, [
233
+ "size",
234
+ "label",
235
+ "description",
236
+ "indeterminate",
237
+ "error",
238
+ "contrast",
239
+ "checked",
240
+ "defaultChecked",
241
+ "disabled",
242
+ "className",
243
+ "id"
244
+ ]);
245
+ const reactId = (0, import_react2.useId)();
246
+ const inputId = id != null ? id : reactId;
247
+ const sz = sizeClasses2[size];
248
+ const isActive = checked || indeterminate;
249
+ const boxBase = [
250
+ "relative inline-flex items-center justify-center shrink-0",
251
+ "rounded",
252
+ "border",
253
+ "transition-colors duration-150",
254
+ sz.box
255
+ ].join(" ");
256
+ let boxState;
257
+ if (disabled) {
258
+ boxState = isActive ? "bg-checkbox-disabled-checked-bg border-checkbox-disabled-border text-checkbox-disabled-icon" : "bg-checkbox-disabled-bg border-checkbox-disabled-border";
259
+ } else if (contrast) {
260
+ boxState = isActive ? "bg-checkbox-contrast-checked-bg border-checkbox-contrast-checked-bg text-checkbox-contrast-checked-icon" : "bg-checkbox-contrast-bg border-checkbox-contrast-border text-transparent";
261
+ } else if (error) {
262
+ boxState = isActive ? "bg-checkbox-checked-bg border-checkbox-error-border text-checkbox-checked-icon" : "bg-checkbox-error-bg border-checkbox-error-border text-transparent";
263
+ } else if (isActive) {
264
+ boxState = "bg-checkbox-checked-bg border-checkbox-checked-border text-checkbox-checked-icon";
265
+ } else {
266
+ boxState = "bg-checkbox-bg border-checkbox-border text-transparent hover:border-checkbox-hover-border";
267
+ }
268
+ const ringColor = error ? "peer-focus-visible:ring-checkbox-error-ring" : contrast ? "peer-focus-visible:ring-checkbox-contrast-ring" : "peer-focus-visible:ring-checkbox-ring";
269
+ const ringClasses = `peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 ${ringColor}`;
270
+ const labelColor = disabled ? "text-checkbox-label-disabled" : contrast ? "text-checkbox-contrast-label" : error ? "text-checkbox-label-error" : "text-checkbox-label";
271
+ const descriptionColor = disabled ? "text-checkbox-label-disabled" : contrast ? "text-checkbox-contrast-description" : "text-checkbox-description";
272
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
273
+ "label",
274
+ {
275
+ htmlFor: inputId,
276
+ className: [
277
+ "inline-flex items-start font-sans",
278
+ sz.gap,
279
+ disabled ? "cursor-not-allowed" : "cursor-pointer",
280
+ className
281
+ ].filter(Boolean).join(" "),
282
+ children: [
283
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "relative inline-flex", children: [
284
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
285
+ "input",
286
+ __spreadValues({
287
+ ref,
288
+ id: inputId,
289
+ type: "checkbox",
290
+ checked,
291
+ defaultChecked,
292
+ disabled,
293
+ "aria-checked": indeterminate ? "mixed" : checked,
294
+ className: "peer absolute inset-0 h-full w-full cursor-[inherit] opacity-0"
295
+ }, rest)
296
+ ),
297
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: [boxBase, boxState, ringClasses].join(" "), children: indeterminate ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(IndeterminateIcon, { className: sz.icon }) : checked ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(CheckIcon, { className: sz.icon }) : null })
298
+ ] }),
299
+ (label || description) && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "flex flex-col", children: [
300
+ label && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: `${sz.label} font-medium ${labelColor}`, children: label }),
301
+ description && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: `${sz.description} ${descriptionColor}`, children: description })
302
+ ] })
303
+ ]
304
+ }
305
+ );
306
+ }
307
+ );
308
+ Checkbox.displayName = "Checkbox";
309
+ // Annotate the CommonJS export names for ESM import in node:
310
+ 0 && (module.exports = {
311
+ Button,
312
+ Checkbox
313
+ });
package/dist/index.mjs ADDED
@@ -0,0 +1,291 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __defProps = Object.defineProperties;
3
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
4
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
7
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
8
+ var __spreadValues = (a, b) => {
9
+ for (var prop in b || (b = {}))
10
+ if (__hasOwnProp.call(b, prop))
11
+ __defNormalProp(a, prop, b[prop]);
12
+ if (__getOwnPropSymbols)
13
+ for (var prop of __getOwnPropSymbols(b)) {
14
+ if (__propIsEnum.call(b, prop))
15
+ __defNormalProp(a, prop, b[prop]);
16
+ }
17
+ return a;
18
+ };
19
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
20
+ var __objRest = (source, exclude) => {
21
+ var target = {};
22
+ for (var prop in source)
23
+ if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
24
+ target[prop] = source[prop];
25
+ if (source != null && __getOwnPropSymbols)
26
+ for (var prop of __getOwnPropSymbols(source)) {
27
+ if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
28
+ target[prop] = source[prop];
29
+ }
30
+ return target;
31
+ };
32
+
33
+ // src/components/Button/Button.tsx
34
+ import { forwardRef } from "react";
35
+ import { jsx, jsxs } from "react/jsx-runtime";
36
+ var variantClasses = {
37
+ primary: [
38
+ "bg-btn-primary text-btn-primary-text",
39
+ "hover:bg-btn-primary-hover",
40
+ "active:bg-btn-primary-active",
41
+ "focus-visible:ring-2 focus-visible:ring-btn-primary-ring focus-visible:ring-offset-2",
42
+ "disabled:bg-btn-primary-disabled disabled:text-btn-primary-text-disabled"
43
+ ].join(" "),
44
+ secondary: [
45
+ "bg-btn-secondary text-btn-secondary-text",
46
+ "hover:bg-btn-secondary-hover",
47
+ "active:bg-btn-secondary-active",
48
+ "focus-visible:ring-2 focus-visible:ring-btn-secondary-ring focus-visible:ring-offset-2",
49
+ "disabled:bg-btn-secondary-disabled disabled:text-btn-secondary-text-disabled"
50
+ ].join(" "),
51
+ tertiary: [
52
+ "bg-btn-tertiary text-btn-tertiary-text",
53
+ "hover:bg-btn-tertiary-hover",
54
+ "active:bg-btn-tertiary-active",
55
+ "focus-visible:ring-2 focus-visible:ring-btn-tertiary-ring focus-visible:ring-offset-2",
56
+ "disabled:bg-btn-tertiary-disabled disabled:text-btn-tertiary-text-disabled"
57
+ ].join(" "),
58
+ contrast: [
59
+ "bg-btn-contrast text-btn-contrast-text",
60
+ "hover:bg-btn-contrast-hover",
61
+ "active:bg-btn-contrast-active",
62
+ "focus-visible:ring-2 focus-visible:ring-btn-contrast-ring focus-visible:ring-offset-2",
63
+ "disabled:bg-btn-contrast-disabled disabled:text-btn-contrast-text-disabled"
64
+ ].join(" "),
65
+ transparent: [
66
+ "bg-btn-transparent text-btn-transparent-text",
67
+ "hover:bg-btn-transparent-hover",
68
+ "active:bg-btn-transparent-active",
69
+ "focus-visible:ring-2 focus-visible:ring-btn-transparent-ring focus-visible:ring-offset-2",
70
+ "disabled:bg-btn-transparent-disabled disabled:text-btn-transparent-text-disabled"
71
+ ].join(" ")
72
+ };
73
+ var sizeClasses = {
74
+ small: "h-8 px-3 text-sm gap-1",
75
+ medium: "h-10 px-4 text-sm gap-1.5",
76
+ large: "h-12 px-5 text-base gap-2",
77
+ "extra-large": "h-14 px-6 text-lg gap-2"
78
+ };
79
+ function Spinner({ className }) {
80
+ return /* @__PURE__ */ jsx(
81
+ "svg",
82
+ {
83
+ className,
84
+ width: "1em",
85
+ height: "1em",
86
+ viewBox: "0 0 20 20",
87
+ fill: "none",
88
+ children: /* @__PURE__ */ jsx(
89
+ "path",
90
+ {
91
+ d: "M10 2.5a7.5 7.5 0 1 0 7.5 7.5",
92
+ stroke: "currentColor",
93
+ strokeWidth: "2",
94
+ strokeLinecap: "round"
95
+ }
96
+ )
97
+ }
98
+ );
99
+ }
100
+ var Button = forwardRef(
101
+ (_a, ref) => {
102
+ var _b = _a, {
103
+ variant = "primary",
104
+ size = "medium",
105
+ rounded = false,
106
+ loading = false,
107
+ disabled = false,
108
+ startIcon,
109
+ endIcon,
110
+ children,
111
+ className = ""
112
+ } = _b, rest = __objRest(_b, [
113
+ "variant",
114
+ "size",
115
+ "rounded",
116
+ "loading",
117
+ "disabled",
118
+ "startIcon",
119
+ "endIcon",
120
+ "children",
121
+ "className"
122
+ ]);
123
+ const isDisabled = disabled || loading;
124
+ const classes = [
125
+ "inline-flex items-center justify-center font-medium font-sans",
126
+ "transition-colors duration-150",
127
+ "outline-none",
128
+ "disabled:cursor-not-allowed",
129
+ sizeClasses[size],
130
+ variantClasses[variant],
131
+ rounded ? "rounded-full" : "rounded-lg",
132
+ className
133
+ ].filter(Boolean).join(" ");
134
+ return /* @__PURE__ */ jsxs(
135
+ "button",
136
+ __spreadProps(__spreadValues({
137
+ ref,
138
+ disabled: isDisabled,
139
+ className: classes
140
+ }, rest), {
141
+ children: [
142
+ loading ? /* @__PURE__ */ jsx(Spinner, { className: "animate-spin" }) : startIcon,
143
+ children,
144
+ !loading && endIcon
145
+ ]
146
+ })
147
+ );
148
+ }
149
+ );
150
+ Button.displayName = "Button";
151
+
152
+ // src/components/Checkbox/Checkbox.tsx
153
+ import {
154
+ forwardRef as forwardRef2,
155
+ useId
156
+ } from "react";
157
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
158
+ var sizeClasses2 = {
159
+ small: {
160
+ box: "h-4 w-4",
161
+ icon: "h-3 w-3",
162
+ label: "text-sm leading-5",
163
+ description: "text-xs leading-4",
164
+ gap: "gap-2"
165
+ },
166
+ medium: {
167
+ box: "h-5 w-5",
168
+ icon: "h-3.5 w-3.5",
169
+ label: "text-base leading-6",
170
+ description: "text-sm leading-5",
171
+ gap: "gap-2.5"
172
+ }
173
+ };
174
+ function CheckIcon({ className }) {
175
+ return /* @__PURE__ */ jsx2("svg", { className, viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx2(
176
+ "path",
177
+ {
178
+ d: "M13.333 4.667 6 12l-3.333-3.333",
179
+ stroke: "currentColor",
180
+ strokeWidth: "2",
181
+ strokeLinecap: "round",
182
+ strokeLinejoin: "round"
183
+ }
184
+ ) });
185
+ }
186
+ function IndeterminateIcon({ className }) {
187
+ return /* @__PURE__ */ jsx2("svg", { className, viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx2(
188
+ "path",
189
+ {
190
+ d: "M3.333 8h9.334",
191
+ stroke: "currentColor",
192
+ strokeWidth: "2",
193
+ strokeLinecap: "round"
194
+ }
195
+ ) });
196
+ }
197
+ var Checkbox = forwardRef2(
198
+ (_a, ref) => {
199
+ var _b = _a, {
200
+ size = "medium",
201
+ label,
202
+ description,
203
+ indeterminate = false,
204
+ error = false,
205
+ contrast = false,
206
+ checked,
207
+ defaultChecked,
208
+ disabled = false,
209
+ className = "",
210
+ id
211
+ } = _b, rest = __objRest(_b, [
212
+ "size",
213
+ "label",
214
+ "description",
215
+ "indeterminate",
216
+ "error",
217
+ "contrast",
218
+ "checked",
219
+ "defaultChecked",
220
+ "disabled",
221
+ "className",
222
+ "id"
223
+ ]);
224
+ const reactId = useId();
225
+ const inputId = id != null ? id : reactId;
226
+ const sz = sizeClasses2[size];
227
+ const isActive = checked || indeterminate;
228
+ const boxBase = [
229
+ "relative inline-flex items-center justify-center shrink-0",
230
+ "rounded",
231
+ "border",
232
+ "transition-colors duration-150",
233
+ sz.box
234
+ ].join(" ");
235
+ let boxState;
236
+ if (disabled) {
237
+ boxState = isActive ? "bg-checkbox-disabled-checked-bg border-checkbox-disabled-border text-checkbox-disabled-icon" : "bg-checkbox-disabled-bg border-checkbox-disabled-border";
238
+ } else if (contrast) {
239
+ boxState = isActive ? "bg-checkbox-contrast-checked-bg border-checkbox-contrast-checked-bg text-checkbox-contrast-checked-icon" : "bg-checkbox-contrast-bg border-checkbox-contrast-border text-transparent";
240
+ } else if (error) {
241
+ boxState = isActive ? "bg-checkbox-checked-bg border-checkbox-error-border text-checkbox-checked-icon" : "bg-checkbox-error-bg border-checkbox-error-border text-transparent";
242
+ } else if (isActive) {
243
+ boxState = "bg-checkbox-checked-bg border-checkbox-checked-border text-checkbox-checked-icon";
244
+ } else {
245
+ boxState = "bg-checkbox-bg border-checkbox-border text-transparent hover:border-checkbox-hover-border";
246
+ }
247
+ const ringColor = error ? "peer-focus-visible:ring-checkbox-error-ring" : contrast ? "peer-focus-visible:ring-checkbox-contrast-ring" : "peer-focus-visible:ring-checkbox-ring";
248
+ const ringClasses = `peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 ${ringColor}`;
249
+ const labelColor = disabled ? "text-checkbox-label-disabled" : contrast ? "text-checkbox-contrast-label" : error ? "text-checkbox-label-error" : "text-checkbox-label";
250
+ const descriptionColor = disabled ? "text-checkbox-label-disabled" : contrast ? "text-checkbox-contrast-description" : "text-checkbox-description";
251
+ return /* @__PURE__ */ jsxs2(
252
+ "label",
253
+ {
254
+ htmlFor: inputId,
255
+ className: [
256
+ "inline-flex items-start font-sans",
257
+ sz.gap,
258
+ disabled ? "cursor-not-allowed" : "cursor-pointer",
259
+ className
260
+ ].filter(Boolean).join(" "),
261
+ children: [
262
+ /* @__PURE__ */ jsxs2("span", { className: "relative inline-flex", children: [
263
+ /* @__PURE__ */ jsx2(
264
+ "input",
265
+ __spreadValues({
266
+ ref,
267
+ id: inputId,
268
+ type: "checkbox",
269
+ checked,
270
+ defaultChecked,
271
+ disabled,
272
+ "aria-checked": indeterminate ? "mixed" : checked,
273
+ className: "peer absolute inset-0 h-full w-full cursor-[inherit] opacity-0"
274
+ }, rest)
275
+ ),
276
+ /* @__PURE__ */ jsx2("span", { className: [boxBase, boxState, ringClasses].join(" "), children: indeterminate ? /* @__PURE__ */ jsx2(IndeterminateIcon, { className: sz.icon }) : checked ? /* @__PURE__ */ jsx2(CheckIcon, { className: sz.icon }) : null })
277
+ ] }),
278
+ (label || description) && /* @__PURE__ */ jsxs2("span", { className: "flex flex-col", children: [
279
+ label && /* @__PURE__ */ jsx2("span", { className: `${sz.label} font-medium ${labelColor}`, children: label }),
280
+ description && /* @__PURE__ */ jsx2("span", { className: `${sz.description} ${descriptionColor}`, children: description })
281
+ ] })
282
+ ]
283
+ }
284
+ );
285
+ }
286
+ );
287
+ Checkbox.displayName = "Checkbox";
288
+ export {
289
+ Button,
290
+ Checkbox
291
+ };
package/dist/theme.css ADDED
@@ -0,0 +1,483 @@
1
+ /*
2
+ * Refinn Design System — Tailwind v4 Theme Preset
3
+ *
4
+ * Usage in consumer project:
5
+ * @import "core-ui-xpo/theme.css";
6
+ */
7
+
8
+ @theme {
9
+ /* ========================================
10
+ * Fonts
11
+ * ======================================== */
12
+ --font-sans: 'IBM Plex Sans Thai', sans-serif;
13
+ --font-looped: 'IBM Plex Sans Thai Looped', sans-serif;
14
+
15
+ /* ========================================
16
+ * Colors — Primitives
17
+ * ======================================== */
18
+
19
+ /* White */
20
+ --color-white-10: rgba(255, 255, 255, 0.1);
21
+ --color-white-20: rgba(255, 255, 255, 0.2);
22
+ --color-white-30: rgba(255, 255, 255, 0.3);
23
+ --color-white-40: rgba(255, 255, 255, 0.4);
24
+ --color-white-65: rgba(255, 255, 255, 0.65);
25
+ --color-white-80: rgba(255, 255, 255, 0.8);
26
+ --color-white-85: rgba(255, 255, 255, 0.85);
27
+ --color-white-90: rgba(255, 255, 255, 0.9);
28
+ --color-white-100: #ffffff;
29
+
30
+ /* Black */
31
+ --color-black-0: rgba(0, 0, 0, 0);
32
+ --color-black-5: rgba(0, 0, 0, 0.05);
33
+ --color-black-10: rgba(0, 0, 0, 0.1);
34
+ --color-black-20: rgba(0, 0, 0, 0.2);
35
+ --color-black-30: rgba(0, 0, 0, 0.3);
36
+ --color-black-50: rgba(0, 0, 0, 0.5);
37
+ --color-black-100: #000000;
38
+
39
+ /* Vanilla */
40
+ --color-vanilla-100: #fff6ec;
41
+
42
+ /* Gray */
43
+ --color-gray-50: #f9fafb;
44
+ --color-gray-100: #f3f4f6;
45
+ --color-gray-200: #e5e7eb;
46
+ --color-gray-300: #d1d5db;
47
+ --color-gray-400: #9ca3af;
48
+ --color-gray-500: #6b7280;
49
+ --color-gray-600: #4b5563;
50
+ --color-gray-700: #374151;
51
+ --color-gray-800: #1f2937;
52
+ --color-gray-900: #111827;
53
+ --color-gray-950: #030712;
54
+
55
+ /* Red */
56
+ --color-red-50: #fef2f2;
57
+ --color-red-100: #fee2e2;
58
+ --color-red-200: #fecaca;
59
+ --color-red-300: #fca5a5;
60
+ --color-red-400: #f87171;
61
+ --color-red-500: #ef4444;
62
+ --color-red-600: #dc2626;
63
+ --color-red-700: #b91c1c;
64
+ --color-red-800: #991b1b;
65
+ --color-red-900: #7f1d1d;
66
+ --color-red-950: #450a0a;
67
+
68
+ /* Orange */
69
+ --color-orange-50: #fff7ed;
70
+ --color-orange-100: #ffedd5;
71
+ --color-orange-200: #fed7aa;
72
+ --color-orange-300: #fdba74;
73
+ --color-orange-400: #fb923c;
74
+ --color-orange-500: #f97316;
75
+ --color-orange-600: #ea580c;
76
+ --color-orange-700: #c2410c;
77
+ --color-orange-800: #9a3412;
78
+ --color-orange-900: #7c2d12;
79
+ --color-orange-950: #431407;
80
+
81
+ /* Amber */
82
+ --color-amber-50: #fffbeb;
83
+ --color-amber-100: #fef3c7;
84
+ --color-amber-200: #fde68a;
85
+ --color-amber-300: #fcd34d;
86
+ --color-amber-400: #fbbf24;
87
+ --color-amber-500: #f59e0b;
88
+ --color-amber-600: #d97706;
89
+ --color-amber-700: #b45309;
90
+ --color-amber-800: #92400e;
91
+ --color-amber-900: #78350f;
92
+ --color-amber-950: #451a03;
93
+
94
+ /* Yellow */
95
+ --color-yellow-50: #fefce8;
96
+ --color-yellow-100: #fef9c3;
97
+ --color-yellow-200: #fef08a;
98
+ --color-yellow-300: #fde047;
99
+ --color-yellow-400: #facc15;
100
+ --color-yellow-500: #eab308;
101
+ --color-yellow-600: #ca8a04;
102
+ --color-yellow-700: #a16207;
103
+ --color-yellow-800: #854d0e;
104
+ --color-yellow-900: #713f12;
105
+ --color-yellow-950: #422006;
106
+
107
+ /* Green */
108
+ --color-green-50: #f0fdf4;
109
+ --color-green-100: #dcfce7;
110
+ --color-green-200: #bbf7d0;
111
+ --color-green-300: #86efac;
112
+ --color-green-400: #4ade80;
113
+ --color-green-500: #22c55e;
114
+ --color-green-600: #16a34a;
115
+ --color-green-700: #15803d;
116
+ --color-green-800: #166534;
117
+ --color-green-900: #14532d;
118
+ --color-green-950: #052e16;
119
+
120
+ /* Cyan */
121
+ --color-cyan-50: #ecfeff;
122
+ --color-cyan-100: #cffafe;
123
+ --color-cyan-200: #a5f3fc;
124
+ --color-cyan-300: #67e8f9;
125
+ --color-cyan-400: #22d3ee;
126
+ --color-cyan-500: #06b6d4;
127
+ --color-cyan-600: #0891b2;
128
+ --color-cyan-700: #0e7490;
129
+ --color-cyan-800: #155e75;
130
+ --color-cyan-900: #164e63;
131
+ --color-cyan-950: #083344;
132
+
133
+ /* Mint */
134
+ --color-mint-50: #eefffc;
135
+ --color-mint-100: #c6fff6;
136
+ --color-mint-200: #8effef;
137
+ --color-mint-300: #4dfbe6;
138
+ --color-mint-400: #19e8d5;
139
+ --color-mint-500: #00d9c9;
140
+ --color-mint-600: #00a49c;
141
+ --color-mint-700: #02837e;
142
+ --color-mint-800: #086764;
143
+ --color-mint-900: #0c5553;
144
+ --color-mint-950: #003334;
145
+
146
+ /* Blue */
147
+ --color-blue-50: #f0f9ff;
148
+ --color-blue-100: #e0f3fe;
149
+ --color-blue-200: #bae7fd;
150
+ --color-blue-300: #7cd6fd;
151
+ --color-blue-400: #37c1f9;
152
+ --color-blue-500: #0daaea;
153
+ --color-blue-600: #0193d7;
154
+ --color-blue-700: #026da2;
155
+ --color-blue-800: #065c86;
156
+ --color-blue-900: #0b4c6f;
157
+ --color-blue-950: #083049;
158
+
159
+ /* Sky */
160
+ --color-sky-50: #f0f9ff;
161
+ --color-sky-100: #e0f2fe;
162
+ --color-sky-200: #bae6fd;
163
+ --color-sky-300: #7dd3fc;
164
+ --color-sky-400: #38bdf8;
165
+ --color-sky-500: #0ea5e9;
166
+ --color-sky-600: #0284c7;
167
+ --color-sky-700: #0369a1;
168
+ --color-sky-800: #075985;
169
+ --color-sky-900: #0c4a6e;
170
+ --color-sky-950: #082f49;
171
+
172
+ /* Ocean */
173
+ --color-ocean-50: #eff6ff;
174
+ --color-ocean-100: #dbeafe;
175
+ --color-ocean-200: #bfdbfe;
176
+ --color-ocean-300: #93c5fd;
177
+ --color-ocean-400: #60a5fa;
178
+ --color-ocean-500: #3b82f6;
179
+ --color-ocean-600: #2563eb;
180
+ --color-ocean-700: #1d4ed8;
181
+ --color-ocean-800: #1e40af;
182
+ --color-ocean-900: #1e3a8a;
183
+ --color-ocean-950: #172554;
184
+
185
+ /* Indigo */
186
+ --color-indigo-50: #eef2ff;
187
+ --color-indigo-100: #e0e7ff;
188
+ --color-indigo-200: #c7d2fe;
189
+ --color-indigo-300: #a5b4fc;
190
+ --color-indigo-400: #818cf8;
191
+ --color-indigo-500: #6366f1;
192
+ --color-indigo-600: #4f46e5;
193
+ --color-indigo-700: #4338ca;
194
+ --color-indigo-800: #3730a3;
195
+ --color-indigo-900: #312e81;
196
+ --color-indigo-950: #1e1b4b;
197
+
198
+ /* Violet */
199
+ --color-violet-50: #f5f3ff;
200
+ --color-violet-100: #ede9fe;
201
+ --color-violet-200: #ddd6fe;
202
+ --color-violet-300: #c4b5fd;
203
+ --color-violet-400: #a78bfa;
204
+ --color-violet-500: #8b5cf6;
205
+ --color-violet-600: #7c3aed;
206
+ --color-violet-700: #6d28d9;
207
+ --color-violet-800: #5b21b6;
208
+ --color-violet-900: #4c1d95;
209
+ --color-violet-950: #2e1065;
210
+
211
+ /* Purple */
212
+ --color-purple-50: #faf5ff;
213
+ --color-purple-100: #f3e8ff;
214
+ --color-purple-200: #e9d5ff;
215
+ --color-purple-300: #d8b4fe;
216
+ --color-purple-400: #c084fc;
217
+ --color-purple-500: #a855f7;
218
+ --color-purple-600: #9333ea;
219
+ --color-purple-700: #7e22ce;
220
+ --color-purple-800: #6b21a8;
221
+ --color-purple-900: #581c87;
222
+ --color-purple-950: #3b0764;
223
+
224
+ /* Pink */
225
+ --color-pink-50: #fdf2f8;
226
+ --color-pink-100: #fce7f3;
227
+ --color-pink-200: #fbcfe8;
228
+ --color-pink-300: #f9a8d4;
229
+ --color-pink-400: #f472b6;
230
+ --color-pink-500: #ec4899;
231
+ --color-pink-600: #db2777;
232
+ --color-pink-700: #be185d;
233
+ --color-pink-800: #9d174d;
234
+ --color-pink-900: #831843;
235
+ --color-pink-950: #500724;
236
+
237
+ /* Rose */
238
+ --color-rose-50: #fff1f2;
239
+ --color-rose-100: #ffe4e6;
240
+ --color-rose-200: #fecdd3;
241
+ --color-rose-300: #fda4af;
242
+ --color-rose-400: #fb7185;
243
+ --color-rose-500: #f43f5e;
244
+ --color-rose-600: #e11d48;
245
+ --color-rose-700: #be123c;
246
+ --color-rose-800: #9f1239;
247
+ --color-rose-900: #881337;
248
+ --color-rose-950: #4c0519;
249
+
250
+ /* Strawberry */
251
+ --color-strawberry-50: #fef3f2;
252
+ --color-strawberry-100: #ffe3e1;
253
+ --color-strawberry-200: #ffcdc9;
254
+ --color-strawberry-300: #fea9a3;
255
+ --color-strawberry-400: #fc776d;
256
+ --color-strawberry-500: #f34336;
257
+ --color-strawberry-600: #e12e21;
258
+ --color-strawberry-700: #bd2318;
259
+ --color-strawberry-800: #9c2118;
260
+ --color-strawberry-900: #82211a;
261
+ --color-strawberry-950: #470c08;
262
+
263
+ /* Sherbet */
264
+ --color-sherbet-50: #fef4ee;
265
+ --color-sherbet-100: #fce5d8;
266
+ --color-sherbet-200: #f8c7b0;
267
+ --color-sherbet-300: #f4a07d;
268
+ --color-sherbet-400: #ed6238;
269
+ --color-sherbet-500: #ea4b25;
270
+ --color-sherbet-600: #db331b;
271
+ --color-sherbet-700: #b62418;
272
+ --color-sherbet-800: #911e1b;
273
+ --color-sherbet-900: #751c19;
274
+ --color-sherbet-950: #3f0b0b;
275
+
276
+ /* Pumpkin */
277
+ --color-pumpkin-50: #fff7eb;
278
+ --color-pumpkin-100: #ffeac6;
279
+ --color-pumpkin-200: #ffd188;
280
+ --color-pumpkin-300: #ffb44a;
281
+ --color-pumpkin-400: #ff9d2b;
282
+ --color-pumpkin-500: #f97307;
283
+ --color-pumpkin-600: #dd4f02;
284
+ --color-pumpkin-700: #b73306;
285
+ --color-pumpkin-800: #94260c;
286
+ --color-pumpkin-900: #7a200d;
287
+ --color-pumpkin-950: #460e02;
288
+
289
+ /* Avocado */
290
+ --color-avocado-50: #ebfef4;
291
+ --color-avocado-100: #d0fbe3;
292
+ --color-avocado-200: #a4f6cc;
293
+ --color-avocado-300: #6aebb2;
294
+ --color-avocado-400: #2fd892;
295
+ --color-avocado-500: #0abf7a;
296
+ --color-avocado-600: #00af70;
297
+ --color-avocado-700: #007c53;
298
+ --color-avocado-800: #036242;
299
+ --color-avocado-900: #045038;
300
+ --color-avocado-950: #012d21;
301
+
302
+ /* Bubblegum */
303
+ --color-bubblegum-50: #edf6ff;
304
+ --color-bubblegum-100: #deefff;
305
+ --color-bubblegum-200: #c3e1ff;
306
+ --color-bubblegum-300: #9fcbff;
307
+ --color-bubblegum-400: #79abff;
308
+ --color-bubblegum-500: #598afb;
309
+ --color-bubblegum-600: #4c71f1;
310
+ --color-bubblegum-700: #2e50d4;
311
+ --color-bubblegum-800: #2845ab;
312
+ --color-bubblegum-900: #283f87;
313
+ --color-bubblegum-950: #18244e;
314
+
315
+ /* ========================================
316
+ * Colors — Semantic
317
+ * ======================================== */
318
+
319
+ /* Background */
320
+ --color-bg-primary: #ffffff;
321
+ --color-bg-inverse: #111827;
322
+ --color-bg-secondary: #f9fafb;
323
+ --color-bg-tertiary: #f3f4f6;
324
+ --color-bg-disabled: #f3f4f6;
325
+
326
+ /* Text */
327
+ --color-text-primary: #111827;
328
+ --color-text-secondary: #4b5563;
329
+ --color-text-tertiary: #6b7280;
330
+ --color-text-disabled: #9ca3af;
331
+ --color-text-inverse: #ffffff;
332
+
333
+ /* Border */
334
+ --color-border-enabled: #d1d5db;
335
+ --color-border-subtle: #e5e7eb;
336
+ --color-border-strong: #9ca3af;
337
+ --color-border-focus: #0daaea;
338
+ --color-border-divider: #f9fafb;
339
+
340
+ /* Accent */
341
+ --color-accent-brand: #0193d7;
342
+ --color-accent-brand-bold: #083049;
343
+ --color-accent-brand-subtle: #e0f3fe;
344
+ --color-accent-brand-minimal: #f0f9ff;
345
+ --color-accent-success: #16a34a;
346
+ --color-accent-success-subtle: #dcfce7;
347
+ --color-accent-success-minimal: #f0fdf4;
348
+ --color-accent-warning: #f59e0b;
349
+ --color-accent-warning-subtle: #fef3c7;
350
+ --color-accent-warning-minimal: #fffbeb;
351
+ --color-accent-danger: #ef4444;
352
+ --color-accent-danger-subtle: #fee2e2;
353
+ --color-accent-danger-minimal: #fef2f2;
354
+ --color-accent-info: #3b82f6;
355
+ --color-accent-info-subtle: #dbeafe;
356
+ --color-accent-info-minimal: #eff6ff;
357
+
358
+ /* ========================================
359
+ * Button
360
+ * ========================================
361
+ * All values reference primitive color vars above.
362
+ * To rebrand: swap the var() references below.
363
+ * e.g. change primary from blue → green:
364
+ * --color-btn-primary: var(--color-green-600);
365
+ * --color-btn-primary-hover: var(--color-green-700);
366
+ * --color-btn-primary-active: var(--color-green-800);
367
+ * --color-btn-primary-ring: var(--color-green-500);
368
+ * --color-btn-contrast-text: var(--color-green-600);
369
+ * ======================================== */
370
+
371
+ /* Primary — from buttonTokens.primary → colors.blue */
372
+ --color-btn-primary: var(--color-blue-600);
373
+ --color-btn-primary-hover: var(--color-blue-700);
374
+ --color-btn-primary-active: var(--color-blue-800);
375
+ --color-btn-primary-disabled: var(--color-gray-100);
376
+ --color-btn-primary-text: var(--color-white-100);
377
+ --color-btn-primary-text-disabled: var(--color-gray-400);
378
+ --color-btn-primary-ring: var(--color-blue-500);
379
+
380
+ /* Secondary — from buttonTokens.secondary → colors.gray */
381
+ --color-btn-secondary: var(--color-gray-100);
382
+ --color-btn-secondary-hover: var(--color-gray-200);
383
+ --color-btn-secondary-active: var(--color-gray-300);
384
+ --color-btn-secondary-disabled: var(--color-gray-100);
385
+ --color-btn-secondary-text: var(--color-gray-900);
386
+ --color-btn-secondary-text-disabled: var(--color-gray-400);
387
+ --color-btn-secondary-ring: var(--color-blue-500);
388
+
389
+ /* Tertiary — from buttonTokens.tertiary → colors.gray */
390
+ --color-btn-tertiary: transparent;
391
+ --color-btn-tertiary-hover: var(--color-gray-200);
392
+ --color-btn-tertiary-active: var(--color-gray-300);
393
+ --color-btn-tertiary-disabled: var(--color-gray-100);
394
+ --color-btn-tertiary-text: var(--color-gray-900);
395
+ --color-btn-tertiary-text-disabled: var(--color-gray-400);
396
+ --color-btn-tertiary-ring: var(--color-blue-500);
397
+
398
+ /* Contrast — from buttonTokens.contrast → colors.white */
399
+ --color-btn-contrast: var(--color-white-100);
400
+ --color-btn-contrast-hover: var(--color-white-90);
401
+ --color-btn-contrast-active: var(--color-white-80);
402
+ --color-btn-contrast-disabled: var(--color-gray-50);
403
+ --color-btn-contrast-text: var(--color-blue-600);
404
+ --color-btn-contrast-text-disabled: var(--color-gray-400);
405
+ --color-btn-contrast-ring: var(--color-white-100);
406
+
407
+ /* Transparent — from buttonTokens.transparent → colors.white/black */
408
+ --color-btn-transparent: transparent;
409
+ --color-btn-transparent-hover: var(--color-white-20);
410
+ --color-btn-transparent-active: var(--color-white-30);
411
+ --color-btn-transparent-disabled: transparent;
412
+ --color-btn-transparent-text: var(--color-white-100);
413
+ --color-btn-transparent-text-disabled: var(--color-white-40);
414
+ --color-btn-transparent-ring: var(--color-white-100);
415
+
416
+ /* ========================================
417
+ * Checkbox
418
+ * ========================================
419
+ * To rebrand: swap the var() references below.
420
+ * ======================================== */
421
+
422
+ /* Default (unchecked) */
423
+ --color-checkbox-bg: var(--color-white-100);
424
+ --color-checkbox-border: var(--color-gray-400);
425
+ --color-checkbox-hover-border: var(--color-blue-600);
426
+
427
+ /* Checked / Intermediate */
428
+ --color-checkbox-checked-bg: var(--color-blue-600);
429
+ --color-checkbox-checked-border: var(--color-blue-600);
430
+ --color-checkbox-checked-icon: var(--color-white-100);
431
+
432
+ /* Focus ring */
433
+ --color-checkbox-ring: var(--color-blue-500);
434
+
435
+ /* Disabled */
436
+ --color-checkbox-disabled-bg: var(--color-gray-100);
437
+ --color-checkbox-disabled-border: var(--color-gray-300);
438
+ --color-checkbox-disabled-checked-bg: var(--color-gray-300);
439
+ --color-checkbox-disabled-icon: var(--color-gray-400);
440
+
441
+ /* Error */
442
+ --color-checkbox-error-border: var(--color-red-500);
443
+ --color-checkbox-error-bg: var(--color-white-100);
444
+ --color-checkbox-error-ring: var(--color-red-400);
445
+
446
+ /* Label / description */
447
+ --color-checkbox-label: var(--color-gray-900);
448
+ --color-checkbox-description: var(--color-gray-500);
449
+ --color-checkbox-label-disabled: var(--color-gray-400);
450
+ --color-checkbox-label-error: var(--color-red-600);
451
+
452
+ /* Contrast (on dark bg) */
453
+ --color-checkbox-contrast-bg: transparent;
454
+ --color-checkbox-contrast-border: var(--color-white-65);
455
+ --color-checkbox-contrast-checked-bg: var(--color-white-100);
456
+ --color-checkbox-contrast-checked-icon: var(--color-blue-700);
457
+ --color-checkbox-contrast-label: var(--color-white-100);
458
+ --color-checkbox-contrast-description: var(--color-white-65);
459
+ --color-checkbox-contrast-ring: var(--color-white-100);
460
+
461
+ /* ========================================
462
+ * Border Radius
463
+ * ======================================== */
464
+ --radius-none: 0px;
465
+ --radius-sm: 2px;
466
+ --radius-DEFAULT: 4px;
467
+ --radius-md: 6px;
468
+ --radius-lg: 8px;
469
+ --radius-xl: 12px;
470
+ --radius-2xl: 16px;
471
+ --radius-3xl: 24px;
472
+ --radius-4xl: 32px;
473
+ --radius-full: 9999px;
474
+
475
+ /* ========================================
476
+ * Box Shadow
477
+ * ======================================== */
478
+ --shadow-small: 0px 1px 2px 0px rgba(17, 24, 39, 0.05);
479
+ --shadow-base: 0px 1px 3px 0px rgba(17, 24, 39, 0.1), 0px 1px 2px -1px rgba(17, 24, 39, 0.1);
480
+ --shadow-medium: 0px 4px 6px -1px rgba(17, 24, 39, 0.1), 0px 2px 4px -2px rgba(17, 24, 39, 0.1);
481
+ --shadow-large: 0px 10px 16px -3px rgba(17, 24, 39, 0.1), 0px 4px 6px -4px rgba(17, 24, 39, 0.1);
482
+ --shadow-xl: 0px 20px 24px -5px rgba(17, 24, 39, 0.1), 0px 8px 10px -6px rgba(17, 24, 39, 0.1);
483
+ }
package/package.json ADDED
@@ -0,0 +1,62 @@
1
+ {
2
+ "name": "@refinn/core-ui",
3
+ "version": "0.1.0",
4
+ "description": "Refinn Design System — UI components + Tailwind v4 theme preset",
5
+ "main": "./dist/index.cjs",
6
+ "module": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js",
12
+ "require": "./dist/index.cjs"
13
+ },
14
+ "./theme.css": "./dist/theme.css"
15
+ },
16
+ "files": [
17
+ "dist"
18
+ ],
19
+ "sideEffects": false,
20
+ "scripts": {
21
+ "dev": "next dev",
22
+ "build": "next build",
23
+ "build:lib": "tsup",
24
+ "start": "next start",
25
+ "lint": "eslint",
26
+ "storybook": "storybook dev -p 6006",
27
+ "build-storybook": "storybook build"
28
+ },
29
+ "peerDependencies": {
30
+ "react": ">=18",
31
+ "react-dom": ">=18"
32
+ },
33
+ "dependencies": {
34
+ "next": "16.2.2",
35
+ "react": "19.2.4",
36
+ "react-dom": "19.2.4"
37
+ },
38
+ "devDependencies": {
39
+ "@chromatic-com/storybook": "^5.1.1",
40
+ "@storybook/addon-a11y": "^10.3.5",
41
+ "@storybook/addon-docs": "^10.3.5",
42
+ "@storybook/addon-onboarding": "^10.3.5",
43
+ "@storybook/addon-vitest": "^10.3.5",
44
+ "@storybook/nextjs-vite": "^10.3.5",
45
+ "@tailwindcss/postcss": "^4",
46
+ "@types/node": "^20",
47
+ "@types/react": "^19",
48
+ "@types/react-dom": "^19",
49
+ "@vitest/browser-playwright": "^4.1.3",
50
+ "@vitest/coverage-v8": "^4.1.3",
51
+ "eslint": "^9",
52
+ "eslint-config-next": "16.2.2",
53
+ "eslint-plugin-storybook": "^10.3.5",
54
+ "playwright": "^1.59.1",
55
+ "storybook": "^10.3.5",
56
+ "tailwindcss": "^4",
57
+ "tsup": "^8.5.1",
58
+ "typescript": "^5",
59
+ "vite": "^8.0.7",
60
+ "vitest": "^4.1.3"
61
+ }
62
+ }