@neuralytics/alpine-ds 0.2.3 → 0.2.5

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/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @neuralytics/alpine-ds
2
2
 
3
+ ## 0.2.5
4
+
5
+ ### Patch Changes
6
+
7
+ - 8964133: Add `type` prop to `AlpineButton` (defaults to `button`) and fix content to always be centered.
8
+
9
+ ## 0.2.4
10
+
11
+ ### Patch Changes
12
+
13
+ - 34c4f8a: Clean up the package README: add prerequisites, move the Colors section here, and remove the dead Histoire playground link.
14
+
3
15
  ## 0.2.3
4
16
 
5
17
  ### Patch Changes
package/README.md CHANGED
@@ -4,15 +4,22 @@
4
4
 
5
5
  ## Documentation
6
6
 
7
- Component playground (Histoire): -
8
-
9
7
  Changelog: [CHANGELOG.md](./CHANGELOG.md)
10
8
 
9
+ Component playground (Histoire): not published yet.
10
+
11
+ For monorepo-level docs (setup, architecture, contribution workflow), see the [repository README](https://github.com/neuralytics/alpine-design-system#readme).
12
+
11
13
  ## Components already available
12
14
 
13
15
  - `AlpineButton`
14
16
  - `AlpineIcon`
15
17
 
18
+ ## Prerequisites
19
+
20
+ - `vue` ^3.5.25
21
+ - `tailwindcss` ^4.1.17
22
+
16
23
  ## Integration
17
24
 
18
25
  1. Install the package: `pnpm add @neuralytics/alpine-ds`
@@ -78,4 +85,18 @@ This only affects the primary button's text (not disabled or loading states) and
78
85
  import { AlpineButton } from "@neuralytics/alpine-ds"
79
86
  ```
80
87
 
81
- For monorepo-level docs, see the [repository README](https://github.com/neuralytics/alpine-design-system#readme).
88
+ ## Colors
89
+
90
+ The Design System uses the following Tailwind colors:
91
+
92
+ - `gray` (aliased to Tailwind's `neutral` scale)
93
+ - `red`
94
+ - `yellow` (aliased to Tailwind's `amber` scale)
95
+ - `green`
96
+ - `blue`
97
+ - `accent` (required)
98
+
99
+ These are the only colors available: any other Tailwind color utility (e.g. `bg-purple-500`) will not generate any CSS.
100
+
101
+ Note that all colors use 10 shades: `50`, `100`, `200`, ..., `900`.
102
+ `accent` must be provided by the consumer via `setAccentColorTheme` (see step 6 of [Integration](#integration)); the other colors already have a default value.
@@ -0,0 +1,70 @@
1
+ export declare const buttonStyle: import('tailwind-variants').TVReturnType<{
2
+ iconPosition: {
3
+ left: string;
4
+ right: string;
5
+ };
6
+ design: {
7
+ primary: string;
8
+ secondary: string;
9
+ invisible: string;
10
+ };
11
+ isDisabled: {
12
+ true: string;
13
+ };
14
+ isLoading: {
15
+ true: string;
16
+ };
17
+ isDanger: {
18
+ true: string;
19
+ };
20
+ hasLabel: {
21
+ true: string;
22
+ false: string;
23
+ };
24
+ }, undefined, "rounded-lg flex items-center justify-center gap-2 font-medium transition-all max-w-full border", {
25
+ iconPosition: {
26
+ left: string;
27
+ right: string;
28
+ };
29
+ design: {
30
+ primary: string;
31
+ secondary: string;
32
+ invisible: string;
33
+ };
34
+ isDisabled: {
35
+ true: string;
36
+ };
37
+ isLoading: {
38
+ true: string;
39
+ };
40
+ isDanger: {
41
+ true: string;
42
+ };
43
+ hasLabel: {
44
+ true: string;
45
+ false: string;
46
+ };
47
+ }, undefined, import('tailwind-variants').TVReturnType<{
48
+ iconPosition: {
49
+ left: string;
50
+ right: string;
51
+ };
52
+ design: {
53
+ primary: string;
54
+ secondary: string;
55
+ invisible: string;
56
+ };
57
+ isDisabled: {
58
+ true: string;
59
+ };
60
+ isLoading: {
61
+ true: string;
62
+ };
63
+ isDanger: {
64
+ true: string;
65
+ };
66
+ hasLabel: {
67
+ true: string;
68
+ false: string;
69
+ };
70
+ }, undefined, "rounded-lg flex items-center justify-center gap-2 font-medium transition-all max-w-full border", unknown, unknown, undefined>>;
@@ -1,4 +1,6 @@
1
1
  export declare const buttonDesigns: readonly ["primary", "secondary", "invisible"];
2
2
  export declare const buttonIconPositions: readonly ["left", "right"];
3
+ export declare const buttonTypes: readonly ["button", "submit", "reset"];
3
4
  export type ButtonDesign = typeof buttonDesigns[number];
4
5
  export type ButtonIconPosition = typeof buttonIconPositions[number];
6
+ export type ButtonType = typeof buttonTypes[number];
@@ -1,4 +1,4 @@
1
- import { ButtonDesign as ButtonDesignType, ButtonIconPosition as ButtonIconPositionType } from './Button.types';
1
+ import { ButtonDesign as ButtonDesignType, ButtonIconPosition as ButtonIconPositionType, ButtonType as ButtonTypeType } from './Button.types';
2
2
  export interface ButtonProps {
3
3
  label?: string | null;
4
4
  icon?: string | null;
@@ -7,13 +7,15 @@ export interface ButtonProps {
7
7
  isDisabled?: boolean;
8
8
  isDanger?: boolean;
9
9
  iconPosition?: ButtonIconPositionType;
10
+ type?: ButtonTypeType;
10
11
  }
11
12
  declare const _default: import('vue').DefineComponent<ButtonProps, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<ButtonProps> & Readonly<{}>, {
12
13
  icon: string | null;
13
14
  isLoading: boolean;
15
+ type: ButtonTypeType;
14
16
  design: ButtonDesignType;
15
- isDisabled: boolean;
16
17
  isDanger: boolean;
18
+ isDisabled: boolean;
17
19
  iconPosition: ButtonIconPositionType;
18
20
  }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, HTMLButtonElement>;
19
21
  export default _default;
package/dist/index.mjs CHANGED
@@ -1,6 +1,7 @@
1
- import { defineComponent as w, ref as B, computed as y, createElementBlock as p, openBlock as l, normalizeClass as L, unref as f, createBlock as k, createCommentVNode as m, toDisplayString as S } from "vue";
1
+ import { defineComponent as w, ref as _, computed as p, createElementBlock as y, openBlock as l, normalizeClass as L, unref as m, createBlock as k, createCommentVNode as f, toDisplayString as A } from "vue";
2
2
  import { tv as D } from "tailwind-variants";
3
- const H = ["xs", "sm", "md", "lg", "xl", "2xl"], P = /* @__PURE__ */ w({
3
+ const q = ["xs", "sm", "md", "lg", "xl", "2xl"], S = /* @__PURE__ */ w({
4
+ name: "AlpineIcon",
4
5
  __name: "Icon",
5
6
  props: {
6
7
  icon: {},
@@ -9,7 +10,7 @@ const H = ["xs", "sm", "md", "lg", "xl", "2xl"], P = /* @__PURE__ */ w({
9
10
  isLoading: { type: Boolean, default: !1 }
10
11
  },
11
12
  setup(t) {
12
- const e = t, o = D({
13
+ const e = t, a = D({
13
14
  variants: {
14
15
  size: {
15
16
  xs: "size-3",
@@ -20,145 +21,148 @@ const H = ["xs", "sm", "md", "lg", "xl", "2xl"], P = /* @__PURE__ */ w({
20
21
  "2xl": "size-8"
21
22
  }
22
23
  }
23
- }), n = B(!1), s = y(() => e.isLoading ? "i-line-md-loading-twotone-loop" : e.hoverIcon && n.value ? e.hoverIcon : e.icon);
24
- return (r, a) => (l(), p("span", {
25
- class: L([s.value, f(o)({ size: t.size })]),
26
- onMouseover: a[0] || (a[0] = (i) => n.value = !0),
27
- onMouseleave: a[1] || (a[1] = (i) => n.value = !1)
24
+ }), s = _(!1), n = p(() => e.isLoading ? "i-line-md-loading-twotone-loop" : e.hoverIcon && s.value ? e.hoverIcon : e.icon);
25
+ return (r, o) => (l(), y("span", {
26
+ class: L([n.value, m(a)({ size: t.size })]),
27
+ onMouseover: o[0] || (o[0] = (i) => s.value = !0),
28
+ onMouseleave: o[1] || (o[1] = (i) => s.value = !1)
28
29
  }, null, 34));
29
30
  }
30
- }), T = ["primary", "secondary", "invisible"], $ = ["left", "right"], A = ["aria-label", "disabled"], C = {
31
+ }), T = D({
32
+ base: "rounded-lg flex items-center justify-center gap-2 font-medium transition-all max-w-full border",
33
+ variants: {
34
+ iconPosition: {
35
+ left: "flex-row",
36
+ right: "flex-row-reverse"
37
+ },
38
+ design: {
39
+ primary: "h-9 bg-accent-500 border-transparent shadow-xs hover:shadow hover:brightness-110 active:bg-accent-600 active:shadow-none active:brightness-100 text-button-text-color",
40
+ secondary: "h-9 bg-white border-gray-200 text-gray-900 shadow-xs hover:shadow active:shadow-inner",
41
+ invisible: "h-7 bg-transparent hover:bg-gray-100 active:bg-gray-200 text-gray-900 border-transparent underline"
42
+ },
43
+ isDisabled: {
44
+ true: "cursor-not-allowed hover:brightness-100 shadow-none"
45
+ },
46
+ isLoading: {
47
+ true: "cursor-wait hover:brightness-100 shadow-none"
48
+ },
49
+ isDanger: {
50
+ true: ""
51
+ },
52
+ hasLabel: {
53
+ true: "w-auto",
54
+ false: "px-0"
55
+ }
56
+ },
57
+ compoundVariants: [
58
+ // Has Label
59
+ {
60
+ hasLabel: !0,
61
+ design: "primary",
62
+ class: "px-3"
63
+ },
64
+ {
65
+ hasLabel: !0,
66
+ design: "secondary",
67
+ class: "px-3"
68
+ },
69
+ {
70
+ hasLabel: !0,
71
+ design: "invisible",
72
+ class: "px-2"
73
+ },
74
+ {
75
+ hasLabel: !1,
76
+ design: "primary",
77
+ class: "size-9"
78
+ },
79
+ {
80
+ hasLabel: !1,
81
+ design: "secondary",
82
+ class: "size-9"
83
+ },
84
+ {
85
+ hasLabel: !1,
86
+ design: "invisible",
87
+ class: "size-7"
88
+ },
89
+ // Danger
90
+ {
91
+ design: "primary",
92
+ isDanger: !0,
93
+ class: "bg-red-600 text-white active:bg-red-700"
94
+ },
95
+ {
96
+ design: "secondary",
97
+ isDanger: !0,
98
+ class: "bg-white text-red-600"
99
+ },
100
+ {
101
+ design: "invisible",
102
+ isDanger: !0,
103
+ class: "text-red-600 hover:bg-red-100 active:bg-red-200"
104
+ },
105
+ // Disabled
106
+ {
107
+ design: "primary",
108
+ isDisabled: !0,
109
+ class: "bg-gray-200 text-gray-500 hover:bg-gray-200 active:bg-gray-200 hover:shadow-none active:shadow-none"
110
+ },
111
+ {
112
+ design: "secondary",
113
+ isDisabled: !0,
114
+ class: "bg-gray-50 text-gray-500 hover:bg-gray-50 active:bg-gray-50 hover:shadow-none active:shadow-none"
115
+ },
116
+ {
117
+ design: "invisible",
118
+ isDisabled: !0,
119
+ class: "bg-transparent text-gray-500 hover:bg-transparent active:bg-transparent hover:text-gray-500 hover:shadow-none active:shadow-none"
120
+ },
121
+ // Loading
122
+ {
123
+ design: "primary",
124
+ isLoading: !0,
125
+ class: "bg-gray-200 text-gray-500 hover:bg-gray-200 active:bg-gray-200 hover:shadow-none active:shadow-none"
126
+ },
127
+ {
128
+ design: "secondary",
129
+ isLoading: !0,
130
+ class: "bg-gray-50 text-gray-500 hover:bg-gray-50 active:bg-gray-50 hover:shadow-none active:shadow-none"
131
+ },
132
+ {
133
+ design: "invisible",
134
+ isLoading: !0,
135
+ class: "bg-transparent text-gray-500 hover:bg-transparent active:bg-transparent hover:text-gray-500 hover:shadow-none active:shadow-none"
136
+ },
137
+ // Default
138
+ {
139
+ isLoading: !1,
140
+ isDisabled: !1,
141
+ class: "cursor-pointer"
142
+ }
143
+ ]
144
+ }), P = ["primary", "secondary", "invisible"], $ = ["left", "right"], C = ["button", "submit", "reset"], R = ["type", "aria-label", "disabled"], O = {
31
145
  key: 1,
32
- class: "flex-1 text-left truncate"
33
- }, V = /* @__PURE__ */ w({
146
+ class: "min-w-0 truncate"
147
+ }, G = /* @__PURE__ */ w({
148
+ name: "AlpineButton",
34
149
  __name: "Button",
35
150
  props: {
36
151
  label: {},
37
152
  icon: { default: null },
38
- design: { default: T[0] },
153
+ design: { default: P[0] },
39
154
  isLoading: { type: Boolean, default: !1 },
40
155
  isDisabled: { type: Boolean, default: !1 },
41
156
  isDanger: { type: Boolean, default: !1 },
42
- iconPosition: { default: $[0] }
157
+ iconPosition: { default: $[0] },
158
+ type: { default: C[0] }
43
159
  },
44
160
  setup(t) {
45
- const e = t, o = D({
46
- base: "rounded-lg flex items-center gap-2 font-medium transition-all max-w-full border",
47
- variants: {
48
- iconPosition: {
49
- left: "flex-row",
50
- right: "flex-row-reverse"
51
- },
52
- design: {
53
- primary: "h-9 bg-accent-500 border-transparent shadow-xs hover:shadow hover:brightness-110 active:bg-accent-600 active:shadow-none active:brightness-100 text-button-text-color",
54
- secondary: "h-9 bg-white border-gray-200 text-gray-900 shadow-xs hover:shadow active:shadow-inner",
55
- invisible: "h-7 bg-transparent hover:bg-gray-100 active:bg-gray-200 text-gray-900 border-transparent underline"
56
- },
57
- isDisabled: {
58
- true: "cursor-not-allowed hover:brightness-100 shadow-none"
59
- },
60
- isLoading: {
61
- true: "cursor-wait hover:brightness-100 shadow-none"
62
- },
63
- isDanger: {
64
- true: ""
65
- },
66
- hasLabel: {
67
- true: "w-auto",
68
- false: "px-0 justify-center"
69
- }
70
- },
71
- compoundVariants: [
72
- // Has Label
73
- {
74
- hasLabel: !0,
75
- design: "primary",
76
- class: "px-3"
77
- },
78
- {
79
- hasLabel: !0,
80
- design: "secondary",
81
- class: "px-3"
82
- },
83
- {
84
- hasLabel: !0,
85
- design: "invisible",
86
- class: "px-2"
87
- },
88
- {
89
- hasLabel: !1,
90
- design: "primary",
91
- class: "size-9"
92
- },
93
- {
94
- hasLabel: !1,
95
- design: "secondary",
96
- class: "size-9"
97
- },
98
- {
99
- hasLabel: !1,
100
- design: "invisible",
101
- class: "size-7"
102
- },
103
- // Danger
104
- {
105
- design: "primary",
106
- isDanger: !0,
107
- class: "bg-red-600 text-white active:bg-red-700"
108
- },
109
- {
110
- design: "secondary",
111
- isDanger: !0,
112
- class: "bg-white text-red-600"
113
- },
114
- {
115
- design: "invisible",
116
- isDanger: !0,
117
- class: "text-red-600 hover:bg-red-100 active:bg-red-200"
118
- },
119
- // Disabled
120
- {
121
- design: "primary",
122
- isDisabled: !0,
123
- class: "bg-gray-200 text-gray-500 hover:bg-gray-200 active:bg-gray-200 hover:shadow-none active:shadow-none"
124
- },
125
- {
126
- design: "secondary",
127
- isDisabled: !0,
128
- class: "bg-gray-50 text-gray-500 hover:bg-gray-50 active:bg-gray-50 hover:shadow-none active:shadow-none"
129
- },
130
- {
131
- design: "invisible",
132
- isDisabled: !0,
133
- class: "bg-transparent text-gray-500 hover:bg-transparent active:bg-transparent hover:text-gray-500 hover:shadow-none active:shadow-none"
134
- },
135
- // Loading
136
- {
137
- design: "primary",
138
- isLoading: !0,
139
- class: "bg-gray-200 text-gray-500 hover:bg-gray-200 active:bg-gray-200 hover:shadow-none active:shadow-none"
140
- },
141
- {
142
- design: "secondary",
143
- isLoading: !0,
144
- class: "bg-gray-50 text-gray-500 hover:bg-gray-50 active:bg-gray-50 hover:shadow-none active:shadow-none"
145
- },
146
- {
147
- design: "invisible",
148
- isLoading: !0,
149
- class: "bg-transparent text-gray-500 hover:bg-transparent active:bg-transparent hover:text-gray-500 hover:shadow-none active:shadow-none"
150
- },
151
- // Default
152
- {
153
- isLoading: !1,
154
- isDisabled: !1,
155
- class: "cursor-pointer"
156
- }
157
- ]
158
- }), n = y(() => e.isLoading ? "i-line-md-loading-twotone-loop" : e.icon), s = y(() => !e.icon && !e.label ? "-" : e.label);
159
- return (r, a) => (l(), p("button", {
161
+ const e = t, a = p(() => e.isLoading ? "i-line-md-loading-twotone-loop" : e.icon), s = p(() => !e.icon && !e.label ? "-" : e.label);
162
+ return (n, r) => (l(), y("button", {
163
+ type: e.type,
160
164
  "aria-label": e.label ?? e.icon ?? "Button without label or icon",
161
- class: L(f(o)({
165
+ class: L(m(T)({
162
166
  design: e.design,
163
167
  iconPosition: e.iconPosition,
164
168
  isLoading: e.isLoading,
@@ -168,17 +172,17 @@ const H = ["xs", "sm", "md", "lg", "xl", "2xl"], P = /* @__PURE__ */ w({
168
172
  })),
169
173
  disabled: e.isDisabled || e.isLoading
170
174
  }, [
171
- n.value ? (l(), k(f(P), {
175
+ a.value ? (l(), k(m(S), {
172
176
  key: 0,
173
177
  "aria-hidden": !0,
174
- icon: n.value,
178
+ icon: a.value,
175
179
  class: "shrink-0"
176
- }, null, 8, ["icon"])) : m("", !0),
177
- s.value ? (l(), p("span", C, S(s.value), 1)) : m("", !0)
178
- ], 10, A));
180
+ }, null, 8, ["icon"])) : f("", !0),
181
+ s.value ? (l(), y("span", O, A(s.value), 1)) : f("", !0)
182
+ ], 10, R));
179
183
  }
180
184
  });
181
- function R(t) {
185
+ function N(t) {
182
186
  const e = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(t);
183
187
  return e ? {
184
188
  r: Number.parseInt(e[1], 16),
@@ -190,10 +194,10 @@ function v(t) {
190
194
  const e = t / 255;
191
195
  return e <= 0.04045 ? e / 12.92 : ((e + 0.055) / 1.055) ** 2.4;
192
196
  }
193
- function O(t) {
194
- const { r: e, g: o, b: n } = R(t), s = v(e), r = v(o), a = v(n), i = 0.4122214708 * s + 0.5363325363 * r + 0.0514459929 * a, z = 0.2119034982 * s + 0.6806995451 * r + 0.1073969566 * a, I = 0.0883024619 * s + 0.2817188376 * r + 0.6299787005 * a, c = Math.cbrt(i), d = Math.cbrt(z), g = Math.cbrt(I), M = 0.2104542553 * c + 0.793617785 * d - 0.0040720468 * g, u = 1.9779984951 * c - 2.428592205 * d + 0.4505937099 * g, b = 0.0259040371 * c + 0.7827717662 * d - 0.808675766 * g, _ = Math.sqrt(u * u + b * b);
197
+ function E(t) {
198
+ const { r: e, g: a, b: s } = N(t), n = v(e), r = v(a), o = v(s), i = 0.4122214708 * n + 0.5363325363 * r + 0.0514459929 * o, I = 0.2119034982 * n + 0.6806995451 * r + 0.1073969566 * o, z = 0.0883024619 * n + 0.2817188376 * r + 0.6299787005 * o, c = Math.cbrt(i), d = Math.cbrt(I), g = Math.cbrt(z), B = 0.2104542553 * c + 0.793617785 * d - 0.0040720468 * g, u = 1.9779984951 * c - 2.428592205 * d + 0.4505937099 * g, b = 0.0259040371 * c + 0.7827717662 * d - 0.808675766 * g, M = Math.sqrt(u * u + b * b);
195
199
  let h = Math.atan2(b, u) * 180 / Math.PI;
196
- return h < 0 && (h += 360), { lightness: M, chroma: _, hue: h };
200
+ return h < 0 && (h += 360), { lightness: B, chroma: M, hue: h };
197
201
  }
198
202
  const x = {
199
203
  50: 1.4208,
@@ -206,7 +210,7 @@ const x = {
206
210
  700: 0.754,
207
211
  800: 0.6501,
208
212
  900: 0.5749
209
- }, N = {
213
+ }, j = {
210
214
  50: 0.0549,
211
215
  100: 0.135,
212
216
  200: 0.262,
@@ -218,27 +222,27 @@ const x = {
218
222
  800: 0.747,
219
223
  900: 0.595
220
224
  };
221
- function E(t) {
222
- const { lightness: e, chroma: o, hue: n } = O(t), s = {};
225
+ function F(t) {
226
+ const { lightness: e, chroma: a, hue: s } = E(t), n = {};
223
227
  for (const r of Object.keys(x)) {
224
- const a = Math.min(1, Math.max(0, e * x[r])), i = Math.max(0, o * N[r]);
225
- s[`--color-accent-${r}`] = `oklch(${(a * 100).toFixed(1)}% ${i.toFixed(3)} ${n.toFixed(1)})`;
228
+ const o = Math.min(1, Math.max(0, e * x[r])), i = Math.max(0, a * j[r]);
229
+ n[`--color-accent-${r}`] = `oklch(${(o * 100).toFixed(1)}% ${i.toFixed(3)} ${s.toFixed(1)})`;
226
230
  }
227
- return s;
231
+ return n;
228
232
  }
229
- function q(t) {
230
- const e = E(t), o = document.documentElement;
231
- for (const [n, s] of Object.entries(e))
232
- o.style.setProperty(n, s);
233
+ function J(t) {
234
+ const e = F(t), a = document.documentElement;
235
+ for (const [s, n] of Object.entries(e))
236
+ a.style.setProperty(s, n);
233
237
  }
234
- function G(t) {
238
+ function K(t) {
235
239
  document.documentElement.style.setProperty("--button-text-color", t);
236
240
  }
237
241
  export {
238
- V as AlpineButton,
239
- P as AlpineIcon,
240
- E as generateAccentScale,
241
- H as iconSizes,
242
- q as setAccentColorTheme,
243
- G as setButtonTextColor
242
+ G as AlpineButton,
243
+ S as AlpineIcon,
244
+ F as generateAccentScale,
245
+ q as iconSizes,
246
+ J as setAccentColorTheme,
247
+ K as setButtonTextColor
244
248
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@neuralytics/alpine-ds",
3
3
  "type": "module",
4
- "version": "0.2.3",
4
+ "version": "0.2.5",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -29,12 +29,6 @@
29
29
  "engines": {
30
30
  "node": ">=24"
31
31
  },
32
- "scripts": {
33
- "build": "vite build",
34
- "test": "vitest run",
35
- "test:watch": "vitest",
36
- "typecheck": "vue-tsc -p tsconfig.app.json --noEmit"
37
- },
38
32
  "peerDependencies": {
39
33
  "tailwindcss": "^4.1.17",
40
34
  "vue": "^3.5.25"
@@ -58,5 +52,11 @@
58
52
  "vitest": "^4.0.14",
59
53
  "vue": "^3.5.25",
60
54
  "vue-tsc": "^3.1.5"
55
+ },
56
+ "scripts": {
57
+ "build": "vite build",
58
+ "test": "vitest run",
59
+ "test:watch": "vitest",
60
+ "typecheck": "vue-tsc -p tsconfig.app.json --noEmit"
61
61
  }
62
- }
62
+ }