@webx-ui/core 0.0.1

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 webx-ui
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,58 @@
1
+ # @webx-ui/core
2
+
3
+ Vue 3 UI components for admin panels. Every component is styled through
4
+ [`@webx-ui/tokens`](../tokens) CSS variables — no hard-coded colours — and never talks to an API:
5
+ data comes in through props, changes go out through events.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ pnpm add @webx-ui/core @webx-ui/tokens vue
11
+ ```
12
+
13
+ ## Usage
14
+
15
+ Global registration:
16
+
17
+ ```ts
18
+ import { createApp } from 'vue'
19
+ import { WebxUI } from '@webx-ui/core'
20
+ import '@webx-ui/core/style.css'
21
+ import App from './App.vue'
22
+
23
+ createApp(App).use(WebxUI).mount('#app')
24
+ ```
25
+
26
+ Named imports (tree-shakeable):
27
+
28
+ ```vue
29
+ <script setup lang="ts">
30
+ import { WxButton, WxCard, WxInput } from '@webx-ui/core'
31
+ import '@webx-ui/core/style.css'
32
+
33
+ const title = ref('')
34
+ </script>
35
+
36
+ <template>
37
+ <wx-card title="New page">
38
+ <wx-input v-model="title" placeholder="Title" clearable />
39
+ <template #footer>
40
+ <wx-button type="primary">Save</wx-button>
41
+ </template>
42
+ </wx-card>
43
+ </template>
44
+ ```
45
+
46
+ `@webx-ui/core/style.css` already includes the token variables, so importing
47
+ `@webx-ui/tokens/tokens.css` separately is optional.
48
+
49
+ ## Implemented
50
+
51
+ `WxButton`, `WxInput`, `WxCard`. The full component roadmap lives in
52
+ [the docs](https://webx-ui.github.io/webx-ui/guide/roadmap.html).
53
+
54
+ ## Conventions
55
+
56
+ - Components are declared as `WxButton` and used as `<wx-button>` in templates.
57
+ - Classes follow BEM with a `wx-` prefix: `.wx-button`, `.wx-button--primary`, `.wx-button__label`.
58
+ - Each component ships `Component.vue` + `types.ts` + `Component.test.ts` + a docs page.
@@ -0,0 +1,34 @@
1
+ import { ButtonProps } from './types';
2
+ declare function __VLS_template(): {
3
+ attrs: Partial<{}>;
4
+ slots: {
5
+ icon?(_: {}): any;
6
+ default?(_: {}): any;
7
+ };
8
+ refs: {};
9
+ rootEl: any;
10
+ };
11
+ type __VLS_TemplateResult = ReturnType<typeof __VLS_template>;
12
+ declare const __VLS_component: import('vue').DefineComponent<ButtonProps, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
13
+ click: (event: MouseEvent) => any;
14
+ }, string, import('vue').PublicProps, Readonly<ButtonProps> & Readonly<{
15
+ onClick?: ((event: MouseEvent) => any) | undefined;
16
+ }>, {
17
+ type: import('./types').ButtonType;
18
+ variant: import('./types').ButtonVariant;
19
+ size: import('./types').ButtonSize;
20
+ disabled: boolean;
21
+ loading: boolean;
22
+ block: boolean;
23
+ round: boolean;
24
+ href: string;
25
+ target: string;
26
+ nativeType: import('./types').ButtonNativeType;
27
+ }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
28
+ declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_TemplateResult["slots"]>;
29
+ export default _default;
30
+ type __VLS_WithTemplateSlots<T, S> = T & {
31
+ new (): {
32
+ $slots: S;
33
+ };
34
+ };
@@ -0,0 +1,2 @@
1
+ export { default as WxButton } from './Button';
2
+ export type * from './types';
@@ -0,0 +1,25 @@
1
+ export type ButtonType = 'default' | 'primary' | 'success' | 'warning' | 'danger';
2
+ export type ButtonVariant = 'solid' | 'outline' | 'text';
3
+ export type ButtonSize = 'sm' | 'md' | 'lg';
4
+ export type ButtonNativeType = 'button' | 'submit' | 'reset';
5
+ export interface ButtonProps {
6
+ /** Semantic colour of the button. */
7
+ type?: ButtonType;
8
+ /** Visual weight: filled, bordered or borderless. */
9
+ variant?: ButtonVariant;
10
+ size?: ButtonSize;
11
+ disabled?: boolean;
12
+ /** Shows a spinner and blocks interaction. */
13
+ loading?: boolean;
14
+ /** Stretches the button to the full width of its container. */
15
+ block?: boolean;
16
+ round?: boolean;
17
+ /** Renders an `<a>` instead of a `<button>`. */
18
+ href?: string;
19
+ target?: string;
20
+ /** `type` attribute of the underlying `<button>`. */
21
+ nativeType?: ButtonNativeType;
22
+ }
23
+ export interface ButtonEmits {
24
+ click: [event: MouseEvent];
25
+ }
@@ -0,0 +1,26 @@
1
+ import { CardProps } from './types';
2
+ declare function __VLS_template(): {
3
+ attrs: Partial<{}>;
4
+ slots: {
5
+ header?(_: {}): any;
6
+ extra?(_: {}): any;
7
+ default?(_: {}): any;
8
+ footer?(_: {}): any;
9
+ };
10
+ refs: {};
11
+ rootEl: HTMLElement;
12
+ };
13
+ type __VLS_TemplateResult = ReturnType<typeof __VLS_template>;
14
+ declare const __VLS_component: import('vue').DefineComponent<CardProps, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<CardProps> & Readonly<{}>, {
15
+ title: string;
16
+ shadow: import('./types').CardShadow;
17
+ padding: import('./types').CardPadding;
18
+ borderless: boolean;
19
+ }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, HTMLElement>;
20
+ declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_TemplateResult["slots"]>;
21
+ export default _default;
22
+ type __VLS_WithTemplateSlots<T, S> = T & {
23
+ new (): {
24
+ $slots: S;
25
+ };
26
+ };
@@ -0,0 +1,2 @@
1
+ export { default as WxCard } from './Card';
2
+ export type * from './types';
@@ -0,0 +1,12 @@
1
+ export type CardShadow = 'never' | 'hover' | 'always';
2
+ export type CardPadding = 'none' | 'sm' | 'md' | 'lg';
3
+ export interface CardProps {
4
+ /** Header text — ignored when the `header` slot is used. */
5
+ title?: string;
6
+ /** When the card should cast a shadow. */
7
+ shadow?: CardShadow;
8
+ /** Inner padding of the body (and of header/footer). */
9
+ padding?: CardPadding;
10
+ /** Removes the outer border, keeping only the surface colour. */
11
+ borderless?: boolean;
12
+ }
@@ -0,0 +1,58 @@
1
+ import { InputModelValue, InputProps } from './types';
2
+ type __VLS_Props = InputProps;
3
+ type __VLS_PublicProps = {
4
+ modelValue?: InputModelValue;
5
+ } & __VLS_Props;
6
+ declare function __VLS_template(): {
7
+ attrs: Partial<{}>;
8
+ slots: {
9
+ prefix?(_: {}): any;
10
+ suffix?(_: {}): any;
11
+ };
12
+ refs: {
13
+ inputRef: HTMLInputElement;
14
+ };
15
+ rootEl: any;
16
+ };
17
+ type __VLS_TemplateResult = ReturnType<typeof __VLS_template>;
18
+ declare const __VLS_component: import('vue').DefineComponent<__VLS_PublicProps, {
19
+ focus: () => void | undefined;
20
+ blur: () => void | undefined;
21
+ select: () => void | undefined;
22
+ input: import('vue').Ref<HTMLInputElement | null, HTMLInputElement | null>;
23
+ }, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
24
+ input: (value: string) => any;
25
+ change: (value: string) => any;
26
+ focus: (event: FocusEvent) => any;
27
+ blur: (event: FocusEvent) => any;
28
+ clear: () => any;
29
+ "update:modelValue": (value: InputModelValue) => any;
30
+ }, string, import('vue').PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
31
+ onInput?: ((value: string) => any) | undefined;
32
+ onChange?: ((value: string) => any) | undefined;
33
+ onFocus?: ((event: FocusEvent) => any) | undefined;
34
+ onBlur?: ((event: FocusEvent) => any) | undefined;
35
+ onClear?: (() => any) | undefined;
36
+ "onUpdate:modelValue"?: ((value: InputModelValue) => any) | undefined;
37
+ }>, {
38
+ type: import('./types').InputNativeType;
39
+ size: import('./types').InputSize;
40
+ disabled: boolean;
41
+ status: import('./types').InputStatus;
42
+ placeholder: string;
43
+ readonly: boolean;
44
+ clearable: boolean;
45
+ maxlength: number;
46
+ showCount: boolean;
47
+ autocomplete: string;
48
+ ariaLabel: string;
49
+ }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {
50
+ inputRef: HTMLInputElement;
51
+ }, any>;
52
+ declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_TemplateResult["slots"]>;
53
+ export default _default;
54
+ type __VLS_WithTemplateSlots<T, S> = T & {
55
+ new (): {
56
+ $slots: S;
57
+ };
58
+ };
@@ -0,0 +1,2 @@
1
+ export { default as WxInput } from './Input';
2
+ export type * from './types';
@@ -0,0 +1,29 @@
1
+ export type InputSize = 'sm' | 'md' | 'lg';
2
+ export type InputStatus = 'default' | 'success' | 'warning' | 'error';
3
+ export type InputNativeType = 'text' | 'password' | 'email' | 'number' | 'search' | 'tel' | 'url';
4
+ export interface InputProps {
5
+ /** `type` attribute of the underlying `<input>`. */
6
+ type?: InputNativeType;
7
+ size?: InputSize;
8
+ /** Validation state — usually driven by `WxFormItem`. */
9
+ status?: InputStatus;
10
+ placeholder?: string;
11
+ disabled?: boolean;
12
+ readonly?: boolean;
13
+ /** Shows a clear button while the field has a value. */
14
+ clearable?: boolean;
15
+ maxlength?: number;
16
+ /** Renders a `current / max` counter (requires `maxlength`). */
17
+ showCount?: boolean;
18
+ autocomplete?: string;
19
+ /** Accessible label used when the input has no visible `<label>`. */
20
+ ariaLabel?: string;
21
+ }
22
+ export type InputModelValue = string | number | undefined;
23
+ export interface InputEmits {
24
+ input: [value: string];
25
+ change: [value: string];
26
+ focus: [event: FocusEvent];
27
+ blur: [event: FocusEvent];
28
+ clear: [];
29
+ }
@@ -0,0 +1,3 @@
1
+ export * from './Button';
2
+ export * from './Input';
3
+ export * from './Card';
@@ -0,0 +1,2 @@
1
+ export * from './components';
2
+ export { WebxUI, type WebxUiOptions } from './plugin';
package/dist/index.js ADDED
@@ -0,0 +1,253 @@
1
+ import { defineComponent as _, computed as r, openBlock as n, createBlock as D, resolveDynamicComponent as M, mergeProps as $, withCtx as N, createElementBlock as d, renderSlot as p, createCommentVNode as f, useModel as O, ref as g, normalizeClass as k, createElementVNode as m, toDisplayString as B, mergeModels as w, useSlots as T, createTextVNode as j } from "vue";
2
+ const A = {
3
+ key: 0,
4
+ class: "wx-button__spinner",
5
+ "aria-hidden": "true"
6
+ }, P = {
7
+ key: 1,
8
+ class: "wx-button__icon"
9
+ }, E = {
10
+ key: 2,
11
+ class: "wx-button__label"
12
+ }, L = /* @__PURE__ */ _({
13
+ name: "WxButton",
14
+ inheritAttrs: !1,
15
+ __name: "Button",
16
+ props: {
17
+ type: { default: "default" },
18
+ variant: { default: "solid" },
19
+ size: { default: "md" },
20
+ disabled: { type: Boolean, default: !1 },
21
+ loading: { type: Boolean, default: !1 },
22
+ block: { type: Boolean, default: !1 },
23
+ round: { type: Boolean, default: !1 },
24
+ href: { default: void 0 },
25
+ target: { default: void 0 },
26
+ nativeType: { default: "button" }
27
+ },
28
+ emits: ["click"],
29
+ setup(t, { emit: u }) {
30
+ const e = t, a = u, o = r(() => e.disabled || e.loading), l = r(() => e.href ? "a" : "button"), c = r(() => [
31
+ "wx-button",
32
+ `wx-button--${e.type}`,
33
+ `wx-button--${e.variant}`,
34
+ `wx-button--${e.size}`,
35
+ {
36
+ "wx-button--block": e.block,
37
+ "wx-button--round": e.round,
38
+ "wx-button--loading": e.loading,
39
+ "is-disabled": o.value
40
+ }
41
+ ]), v = r(
42
+ () => e.href ? {
43
+ href: o.value ? void 0 : e.href,
44
+ target: e.target,
45
+ role: "button",
46
+ "aria-disabled": o.value ? "true" : void 0,
47
+ tabindex: o.value ? -1 : void 0
48
+ } : {
49
+ type: e.nativeType,
50
+ disabled: o.value
51
+ }
52
+ );
53
+ function x(i) {
54
+ if (o.value) {
55
+ i.preventDefault(), i.stopPropagation();
56
+ return;
57
+ }
58
+ a("click", i);
59
+ }
60
+ return (i, b) => (n(), D(M(l.value), $({ ...v.value, ...i.$attrs }, {
61
+ class: c.value,
62
+ "aria-busy": t.loading || void 0,
63
+ onClick: x
64
+ }), {
65
+ default: N(() => [
66
+ t.loading ? (n(), d("span", A)) : i.$slots.icon ? (n(), d("span", P, [
67
+ p(i.$slots, "icon", {}, void 0, !0)
68
+ ])) : f("", !0),
69
+ i.$slots.default ? (n(), d("span", E, [
70
+ p(i.$slots, "default", {}, void 0, !0)
71
+ ])) : f("", !0)
72
+ ]),
73
+ _: 3
74
+ }, 16, ["class", "aria-busy"]));
75
+ }
76
+ }), y = (t, u) => {
77
+ const e = t.__vccOpts || t;
78
+ for (const [a, o] of u)
79
+ e[a] = o;
80
+ return e;
81
+ }, R = /* @__PURE__ */ y(L, [["__scopeId", "data-v-ab949d1e"]]), F = {
82
+ key: 0,
83
+ class: "wx-input__affix wx-input__affix--prefix"
84
+ }, H = ["type", "value", "placeholder", "disabled", "readonly", "maxlength", "autocomplete", "aria-label", "aria-invalid"], U = {
85
+ key: 2,
86
+ class: "wx-input__count"
87
+ }, q = {
88
+ key: 3,
89
+ class: "wx-input__affix wx-input__affix--suffix"
90
+ }, G = /* @__PURE__ */ _({
91
+ name: "WxInput",
92
+ inheritAttrs: !1,
93
+ __name: "Input",
94
+ props: /* @__PURE__ */ w({
95
+ type: { default: "text" },
96
+ size: { default: "md" },
97
+ status: { default: "default" },
98
+ placeholder: { default: void 0 },
99
+ disabled: { type: Boolean, default: !1 },
100
+ readonly: { type: Boolean, default: !1 },
101
+ clearable: { type: Boolean, default: !1 },
102
+ maxlength: { default: void 0 },
103
+ showCount: { type: Boolean, default: !1 },
104
+ autocomplete: { default: void 0 },
105
+ ariaLabel: { default: void 0 }
106
+ }, {
107
+ modelValue: { default: "" },
108
+ modelModifiers: {}
109
+ }),
110
+ emits: /* @__PURE__ */ w(["input", "change", "focus", "blur", "clear"], ["update:modelValue"]),
111
+ setup(t, { expose: u, emit: e }) {
112
+ const a = t, o = e, l = O(t, "modelValue"), c = g(null), v = g(!1), x = r(() => l.value == null ? "" : String(l.value)), i = r(
113
+ () => a.clearable && !a.disabled && !a.readonly && x.value.length > 0
114
+ ), b = r(
115
+ () => a.showCount && a.maxlength ? `${x.value.length}/${a.maxlength}` : null
116
+ ), C = r(() => [
117
+ "wx-input",
118
+ `wx-input--${a.size}`,
119
+ {
120
+ [`wx-input--${a.status}`]: a.status !== "default",
121
+ "is-focused": v.value,
122
+ "is-disabled": a.disabled,
123
+ "is-readonly": a.readonly
124
+ }
125
+ ]);
126
+ function W(s) {
127
+ const h = s.target.value;
128
+ l.value = h, o("input", h);
129
+ }
130
+ function I(s) {
131
+ o("change", s.target.value);
132
+ }
133
+ function V(s) {
134
+ v.value = !0, o("focus", s);
135
+ }
136
+ function z(s) {
137
+ v.value = !1, o("blur", s);
138
+ }
139
+ function S() {
140
+ l.value = "", o("input", ""), o("change", ""), o("clear"), c.value?.focus();
141
+ }
142
+ return u({
143
+ focus: () => c.value?.focus(),
144
+ blur: () => c.value?.blur(),
145
+ select: () => c.value?.select(),
146
+ input: c
147
+ }), (s, h) => (n(), d("div", {
148
+ class: k(C.value)
149
+ }, [
150
+ s.$slots.prefix ? (n(), d("span", F, [
151
+ p(s.$slots, "prefix", {}, void 0, !0)
152
+ ])) : f("", !0),
153
+ m("input", $({
154
+ ref_key: "inputRef",
155
+ ref: c
156
+ }, s.$attrs, {
157
+ class: "wx-input__inner",
158
+ type: t.type,
159
+ value: x.value,
160
+ placeholder: t.placeholder,
161
+ disabled: t.disabled,
162
+ readonly: t.readonly,
163
+ maxlength: t.maxlength,
164
+ autocomplete: t.autocomplete,
165
+ "aria-label": t.ariaLabel,
166
+ "aria-invalid": t.status === "error" || void 0,
167
+ onInput: W,
168
+ onChange: I,
169
+ onFocus: V,
170
+ onBlur: z
171
+ }), null, 16, H),
172
+ i.value ? (n(), d("button", {
173
+ key: 1,
174
+ class: "wx-input__clear",
175
+ type: "button",
176
+ tabindex: "-1",
177
+ "aria-label": "Clear",
178
+ onClick: S
179
+ }, " ✕ ")) : f("", !0),
180
+ b.value ? (n(), d("span", U, B(b.value), 1)) : f("", !0),
181
+ s.$slots.suffix ? (n(), d("span", q, [
182
+ p(s.$slots, "suffix", {}, void 0, !0)
183
+ ])) : f("", !0)
184
+ ], 2));
185
+ }
186
+ }), J = /* @__PURE__ */ y(G, [["__scopeId", "data-v-962ec44e"]]), K = {
187
+ key: 0,
188
+ class: "wx-card__header"
189
+ }, Q = { class: "wx-card__title" }, X = {
190
+ key: 0,
191
+ class: "wx-card__extra"
192
+ }, Y = { class: "wx-card__body" }, Z = {
193
+ key: 1,
194
+ class: "wx-card__footer"
195
+ }, ee = /* @__PURE__ */ _({
196
+ name: "WxCard",
197
+ __name: "Card",
198
+ props: {
199
+ title: { default: void 0 },
200
+ shadow: { default: "never" },
201
+ padding: { default: "md" },
202
+ borderless: { type: Boolean, default: !1 }
203
+ },
204
+ setup(t) {
205
+ const u = t, e = T(), a = r(() => !!(u.title || e.header || e.extra)), o = r(() => [
206
+ "wx-card",
207
+ `wx-card--shadow-${u.shadow}`,
208
+ `wx-card--padding-${u.padding}`,
209
+ { "wx-card--borderless": u.borderless }
210
+ ]);
211
+ return (l, c) => (n(), d("section", {
212
+ class: k(o.value)
213
+ }, [
214
+ a.value ? (n(), d("header", K, [
215
+ m("div", Q, [
216
+ p(l.$slots, "header", {}, () => [
217
+ j(B(t.title), 1)
218
+ ], !0)
219
+ ]),
220
+ l.$slots.extra ? (n(), d("div", X, [
221
+ p(l.$slots, "extra", {}, void 0, !0)
222
+ ])) : f("", !0)
223
+ ])) : f("", !0),
224
+ m("div", Y, [
225
+ p(l.$slots, "default", {}, void 0, !0)
226
+ ]),
227
+ l.$slots.footer ? (n(), d("footer", Z, [
228
+ p(l.$slots, "footer", {}, void 0, !0)
229
+ ])) : f("", !0)
230
+ ], 2));
231
+ }
232
+ }), te = /* @__PURE__ */ y(ee, [["__scopeId", "data-v-5d02af6e"]]), ae = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
233
+ __proto__: null,
234
+ WxButton: R,
235
+ WxCard: te,
236
+ WxInput: J
237
+ }, Symbol.toStringTag, { value: "Module" })), le = {
238
+ install(t, u = {}) {
239
+ const { prefix: e = "Wx" } = u;
240
+ for (const [a, o] of Object.entries(ae)) {
241
+ if (!a.startsWith("Wx")) continue;
242
+ const l = e === "Wx" ? a : `${e}${a.slice(2)}`;
243
+ t.component(l, o);
244
+ }
245
+ }
246
+ };
247
+ export {
248
+ le as WebxUI,
249
+ R as WxButton,
250
+ te as WxCard,
251
+ J as WxInput
252
+ };
253
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../src/components/Button/Button.vue","../src/components/Input/Input.vue","../src/components/Card/Card.vue","../src/plugin.ts"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport type { ButtonEmits, ButtonProps } from './types'\n\ndefineOptions({ name: 'WxButton', inheritAttrs: false })\n\nconst props = withDefaults(defineProps<ButtonProps>(), {\n type: 'default',\n variant: 'solid',\n size: 'md',\n disabled: false,\n loading: false,\n block: false,\n round: false,\n href: undefined,\n target: undefined,\n nativeType: 'button',\n})\n\nconst emit = defineEmits<ButtonEmits>()\n\nconst isDisabled = computed(() => props.disabled || props.loading)\nconst tag = computed(() => (props.href ? 'a' : 'button'))\n\nconst classes = computed(() => [\n 'wx-button',\n `wx-button--${props.type}`,\n `wx-button--${props.variant}`,\n `wx-button--${props.size}`,\n {\n 'wx-button--block': props.block,\n 'wx-button--round': props.round,\n 'wx-button--loading': props.loading,\n 'is-disabled': isDisabled.value,\n },\n])\n\nconst nativeAttrs = computed(() =>\n props.href\n ? {\n href: isDisabled.value ? undefined : props.href,\n target: props.target,\n role: 'button',\n 'aria-disabled': isDisabled.value ? 'true' : undefined,\n tabindex: isDisabled.value ? -1 : undefined,\n }\n : {\n type: props.nativeType,\n disabled: isDisabled.value,\n },\n)\n\nfunction onClick(event: MouseEvent) {\n if (isDisabled.value) {\n event.preventDefault()\n event.stopPropagation()\n return\n }\n emit('click', event)\n}\n</script>\n\n<template>\n <component\n :is=\"tag\"\n v-bind=\"{ ...nativeAttrs, ...$attrs }\"\n :class=\"classes\"\n :aria-busy=\"loading || undefined\"\n @click=\"onClick\"\n >\n <span v-if=\"loading\" class=\"wx-button__spinner\" aria-hidden=\"true\" />\n <span v-else-if=\"$slots.icon\" class=\"wx-button__icon\">\n <slot name=\"icon\" />\n </span>\n <span v-if=\"$slots.default\" class=\"wx-button__label\">\n <slot />\n </span>\n </component>\n</template>\n\n<style scoped>\n.wx-button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: var(--wx-space-2);\n box-sizing: border-box;\n border: 1px solid transparent;\n border-radius: var(--wx-radius-md);\n font-family: inherit;\n font-weight: var(--wx-font-weight-medium);\n line-height: var(--wx-font-line-height-tight);\n text-decoration: none;\n white-space: nowrap;\n cursor: pointer;\n user-select: none;\n transition:\n background-color var(--wx-duration-fast) var(--wx-easing-standard),\n border-color var(--wx-duration-fast) var(--wx-easing-standard),\n color var(--wx-duration-fast) var(--wx-easing-standard),\n box-shadow var(--wx-duration-fast) var(--wx-easing-standard);\n}\n\n.wx-button:focus-visible {\n outline: none;\n box-shadow: var(--wx-ring-focus);\n}\n\n/* sizes */\n.wx-button--sm {\n height: var(--wx-size-control-sm);\n padding: 0 var(--wx-space-3);\n font-size: var(--wx-font-size-sm);\n}\n\n.wx-button--md {\n height: var(--wx-size-control-md);\n padding: 0 var(--wx-space-5);\n font-size: var(--wx-font-size-md);\n}\n\n.wx-button--lg {\n height: var(--wx-size-control-lg);\n padding: 0 var(--wx-space-7);\n font-size: var(--wx-font-size-lg);\n}\n\n.wx-button--block {\n display: flex;\n width: 100%;\n}\n\n.wx-button--round {\n border-radius: var(--wx-radius-full);\n}\n\n/* solid */\n.wx-button--solid.wx-button--default {\n background: var(--wx-bg-surface);\n border-color: var(--wx-border-strong);\n color: var(--wx-text-default);\n}\n\n.wx-button--solid.wx-button--default:hover:not(.is-disabled) {\n background: var(--wx-bg-muted);\n}\n\n.wx-button--solid.wx-button--primary {\n background: var(--wx-color-primary);\n color: var(--wx-color-primary-contrast);\n}\n\n.wx-button--solid.wx-button--primary:hover:not(.is-disabled) {\n background: var(--wx-color-primary-hover);\n}\n\n.wx-button--solid.wx-button--success {\n background: var(--wx-color-success);\n color: var(--wx-color-primary-contrast);\n}\n\n.wx-button--solid.wx-button--warning {\n background: var(--wx-color-warning);\n color: var(--wx-color-primary-contrast);\n}\n\n.wx-button--solid.wx-button--danger {\n background: var(--wx-color-danger);\n color: var(--wx-color-danger-contrast);\n}\n\n.wx-button--solid.wx-button--danger:hover:not(.is-disabled) {\n background: var(--wx-color-danger-hover);\n}\n\n.wx-button--solid.wx-button--success:hover:not(.is-disabled),\n.wx-button--solid.wx-button--warning:hover:not(.is-disabled) {\n filter: brightness(0.94);\n}\n\n/* outline */\n.wx-button--outline {\n background: transparent;\n border-color: var(--wx-border-strong);\n color: var(--wx-text-default);\n}\n\n.wx-button--outline.wx-button--primary {\n border-color: var(--wx-color-primary);\n color: var(--wx-color-primary);\n}\n\n.wx-button--outline.wx-button--success {\n border-color: var(--wx-color-success);\n color: var(--wx-color-success);\n}\n\n.wx-button--outline.wx-button--warning {\n border-color: var(--wx-color-warning);\n color: var(--wx-color-warning);\n}\n\n.wx-button--outline.wx-button--danger {\n border-color: var(--wx-color-danger);\n color: var(--wx-color-danger);\n}\n\n.wx-button--outline:hover:not(.is-disabled) {\n background: var(--wx-bg-muted);\n}\n\n.wx-button--outline.wx-button--primary:hover:not(.is-disabled) {\n background: var(--wx-color-primary-soft);\n}\n\n.wx-button--outline.wx-button--danger:hover:not(.is-disabled) {\n background: var(--wx-color-danger-soft);\n}\n\n/* text */\n.wx-button--text {\n background: transparent;\n border-color: transparent;\n color: var(--wx-text-default);\n}\n\n.wx-button--text.wx-button--primary {\n color: var(--wx-color-primary);\n}\n\n.wx-button--text.wx-button--danger {\n color: var(--wx-color-danger);\n}\n\n.wx-button--text.wx-button--success {\n color: var(--wx-color-success);\n}\n\n.wx-button--text.wx-button--warning {\n color: var(--wx-color-warning);\n}\n\n.wx-button--text:hover:not(.is-disabled) {\n background: var(--wx-bg-muted);\n}\n\n/* states */\n.wx-button.is-disabled {\n cursor: not-allowed;\n opacity: 0.55;\n}\n\n.wx-button--loading {\n cursor: progress;\n}\n\n.wx-button__spinner {\n width: 1em;\n height: 1em;\n border: 2px solid currentcolor;\n border-right-color: transparent;\n border-radius: var(--wx-radius-full);\n animation: wx-button-spin var(--wx-duration-slow) linear infinite;\n}\n\n.wx-button__icon {\n display: inline-flex;\n align-items: center;\n}\n\n@keyframes wx-button-spin {\n to {\n transform: rotate(360deg);\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .wx-button {\n transition: none;\n }\n\n .wx-button__spinner {\n animation-duration: 2s;\n }\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed, ref } from 'vue'\nimport type { InputEmits, InputModelValue, InputProps } from './types'\n\ndefineOptions({ name: 'WxInput', inheritAttrs: false })\n\nconst props = withDefaults(defineProps<InputProps>(), {\n type: 'text',\n size: 'md',\n status: 'default',\n placeholder: undefined,\n disabled: false,\n readonly: false,\n clearable: false,\n maxlength: undefined,\n showCount: false,\n autocomplete: undefined,\n ariaLabel: undefined,\n})\n\nconst emit = defineEmits<InputEmits>()\n\nconst model = defineModel<InputModelValue>({ default: '' })\n\nconst inputRef = ref<HTMLInputElement | null>(null)\nconst focused = ref(false)\n\nconst currentValue = computed(() => (model.value == null ? '' : String(model.value)))\n\nconst showClear = computed(\n () => props.clearable && !props.disabled && !props.readonly && currentValue.value.length > 0,\n)\n\nconst counter = computed(() =>\n props.showCount && props.maxlength ? `${currentValue.value.length}/${props.maxlength}` : null,\n)\n\nconst classes = computed(() => [\n 'wx-input',\n `wx-input--${props.size}`,\n {\n [`wx-input--${props.status}`]: props.status !== 'default',\n 'is-focused': focused.value,\n 'is-disabled': props.disabled,\n 'is-readonly': props.readonly,\n },\n])\n\nfunction onInput(event: Event) {\n const value = (event.target as HTMLInputElement).value\n model.value = value\n emit('input', value)\n}\n\nfunction onChange(event: Event) {\n emit('change', (event.target as HTMLInputElement).value)\n}\n\nfunction onFocus(event: FocusEvent) {\n focused.value = true\n emit('focus', event)\n}\n\nfunction onBlur(event: FocusEvent) {\n focused.value = false\n emit('blur', event)\n}\n\nfunction clear() {\n model.value = ''\n emit('input', '')\n emit('change', '')\n emit('clear')\n inputRef.value?.focus()\n}\n\ndefineExpose({\n focus: () => inputRef.value?.focus(),\n blur: () => inputRef.value?.blur(),\n select: () => inputRef.value?.select(),\n input: inputRef,\n})\n</script>\n\n<template>\n <div :class=\"classes\">\n <span v-if=\"$slots.prefix\" class=\"wx-input__affix wx-input__affix--prefix\">\n <slot name=\"prefix\" />\n </span>\n\n <input\n ref=\"inputRef\"\n v-bind=\"$attrs\"\n class=\"wx-input__inner\"\n :type=\"type\"\n :value=\"currentValue\"\n :placeholder=\"placeholder\"\n :disabled=\"disabled\"\n :readonly=\"readonly\"\n :maxlength=\"maxlength\"\n :autocomplete=\"autocomplete\"\n :aria-label=\"ariaLabel\"\n :aria-invalid=\"status === 'error' || undefined\"\n @input=\"onInput\"\n @change=\"onChange\"\n @focus=\"onFocus\"\n @blur=\"onBlur\"\n />\n\n <button\n v-if=\"showClear\"\n class=\"wx-input__clear\"\n type=\"button\"\n tabindex=\"-1\"\n aria-label=\"Clear\"\n @click=\"clear\"\n >\n &#10005;\n </button>\n\n <span v-if=\"counter\" class=\"wx-input__count\">{{ counter }}</span>\n\n <span v-if=\"$slots.suffix\" class=\"wx-input__affix wx-input__affix--suffix\">\n <slot name=\"suffix\" />\n </span>\n </div>\n</template>\n\n<style scoped>\n.wx-input {\n display: inline-flex;\n align-items: center;\n gap: var(--wx-space-2);\n box-sizing: border-box;\n width: 100%;\n background: var(--wx-bg-surface);\n border: 1px solid var(--wx-border-default);\n border-radius: var(--wx-radius-md);\n color: var(--wx-text-default);\n transition:\n border-color var(--wx-duration-fast) var(--wx-easing-standard),\n box-shadow var(--wx-duration-fast) var(--wx-easing-standard);\n}\n\n.wx-input:hover:not(.is-disabled) {\n border-color: var(--wx-border-strong);\n}\n\n.wx-input.is-focused {\n border-color: var(--wx-border-focus);\n box-shadow: var(--wx-ring-focus);\n}\n\n.wx-input--sm {\n height: var(--wx-size-control-sm);\n padding: 0 var(--wx-space-3);\n font-size: var(--wx-font-size-sm);\n}\n\n.wx-input--md {\n height: var(--wx-size-control-md);\n padding: 0 var(--wx-space-4);\n font-size: var(--wx-font-size-md);\n}\n\n.wx-input--lg {\n height: var(--wx-size-control-lg);\n padding: 0 var(--wx-space-5);\n font-size: var(--wx-font-size-lg);\n}\n\n.wx-input--error {\n border-color: var(--wx-color-danger);\n}\n\n.wx-input--error.is-focused {\n box-shadow: 0 0 0 3px var(--wx-color-danger-soft);\n}\n\n.wx-input--success {\n border-color: var(--wx-color-success);\n}\n\n.wx-input--warning {\n border-color: var(--wx-color-warning);\n}\n\n.wx-input.is-disabled {\n background: var(--wx-bg-disabled);\n color: var(--wx-text-disabled);\n cursor: not-allowed;\n}\n\n.wx-input__inner {\n flex: 1 1 auto;\n min-width: 0;\n height: 100%;\n padding: 0;\n background: transparent;\n border: none;\n outline: none;\n color: inherit;\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n}\n\n.wx-input__inner::placeholder {\n color: var(--wx-text-muted);\n}\n\n.wx-input__inner:disabled {\n cursor: not-allowed;\n}\n\n.wx-input__affix,\n.wx-input__count {\n display: inline-flex;\n align-items: center;\n flex: 0 0 auto;\n color: var(--wx-text-muted);\n}\n\n.wx-input__count {\n font-size: var(--wx-font-size-xs);\n font-variant-numeric: tabular-nums;\n}\n\n.wx-input__clear {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex: 0 0 auto;\n width: 16px;\n height: 16px;\n padding: 0;\n background: transparent;\n border: none;\n border-radius: var(--wx-radius-full);\n color: var(--wx-text-muted);\n font-size: var(--wx-font-size-xs);\n line-height: 1;\n cursor: pointer;\n}\n\n.wx-input__clear:hover {\n background: var(--wx-bg-muted);\n color: var(--wx-text-default);\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed, useSlots } from 'vue'\nimport type { CardProps } from './types'\n\ndefineOptions({ name: 'WxCard' })\n\nconst props = withDefaults(defineProps<CardProps>(), {\n title: undefined,\n shadow: 'never',\n padding: 'md',\n borderless: false,\n})\n\nconst slots = useSlots()\n\nconst hasHeader = computed(() => Boolean(props.title || slots.header || slots.extra))\n\nconst classes = computed(() => [\n 'wx-card',\n `wx-card--shadow-${props.shadow}`,\n `wx-card--padding-${props.padding}`,\n { 'wx-card--borderless': props.borderless },\n])\n</script>\n\n<template>\n <section :class=\"classes\">\n <header v-if=\"hasHeader\" class=\"wx-card__header\">\n <div class=\"wx-card__title\">\n <slot name=\"header\">{{ title }}</slot>\n </div>\n <div v-if=\"$slots.extra\" class=\"wx-card__extra\">\n <slot name=\"extra\" />\n </div>\n </header>\n\n <div class=\"wx-card__body\">\n <slot />\n </div>\n\n <footer v-if=\"$slots.footer\" class=\"wx-card__footer\">\n <slot name=\"footer\" />\n </footer>\n </section>\n</template>\n\n<style scoped>\n.wx-card {\n display: flex;\n flex-direction: column;\n box-sizing: border-box;\n background: var(--wx-bg-surface);\n border: 1px solid var(--wx-border-default);\n border-radius: var(--wx-radius-lg);\n color: var(--wx-text-default);\n transition: box-shadow var(--wx-duration-normal) var(--wx-easing-standard);\n}\n\n.wx-card--borderless {\n border-color: transparent;\n}\n\n.wx-card--shadow-always {\n box-shadow: var(--wx-shadow-card);\n}\n\n.wx-card--shadow-hover:hover {\n box-shadow: var(--wx-shadow-popover);\n}\n\n.wx-card__header,\n.wx-card__body,\n.wx-card__footer {\n padding: var(--wx-card-padding, var(--wx-space-5));\n}\n\n.wx-card--padding-none {\n --wx-card-padding: 0px;\n}\n\n.wx-card--padding-sm {\n --wx-card-padding: var(--wx-space-3);\n}\n\n.wx-card--padding-md {\n --wx-card-padding: var(--wx-space-5);\n}\n\n.wx-card--padding-lg {\n --wx-card-padding: var(--wx-space-7);\n}\n\n.wx-card__header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--wx-space-4);\n border-bottom: 1px solid var(--wx-border-muted);\n}\n\n.wx-card__title {\n min-width: 0;\n color: var(--wx-text-strong);\n font-size: var(--wx-font-size-lg);\n font-weight: var(--wx-font-weight-semibold);\n line-height: var(--wx-font-line-height-tight);\n}\n\n.wx-card__extra {\n flex: 0 0 auto;\n color: var(--wx-text-muted);\n}\n\n.wx-card__body {\n flex: 1 1 auto;\n}\n\n.wx-card__footer {\n border-top: 1px solid var(--wx-border-muted);\n}\n</style>\n","import type { App, Plugin } from 'vue'\nimport * as components from './components'\n\nexport interface WebxUiOptions {\n /**\n * Prefix used when registering components globally.\n * Components are declared as `WxButton`, so the default keeps that name.\n */\n prefix?: string\n}\n\n/**\n * Registers every component globally:\n *\n * ```ts\n * import { WebxUI } from '@webx-ui/core'\n * import '@webx-ui/core/style.css'\n *\n * app.use(WebxUI)\n * ```\n *\n * Prefer named imports when bundle size matters — they tree-shake.\n */\nexport const WebxUI: Plugin<[WebxUiOptions?]> = {\n install(app: App, options: WebxUiOptions = {}) {\n const { prefix = 'Wx' } = options\n\n for (const [name, component] of Object.entries(components)) {\n if (!name.startsWith('Wx')) continue\n const registeredName = prefix === 'Wx' ? name : `${prefix}${name.slice(2)}`\n app.component(registeredName, component)\n }\n },\n}\n\nexport default WebxUI\n"],"names":["props","__props","emit","__emit","isDisabled","computed","tag","classes","nativeAttrs","onClick","event","_openBlock","_createBlock","_resolveDynamicComponent","_mergeProps","$attrs","_createElementBlock","_hoisted_1","$slots","_hoisted_2","_renderSlot","_ctx","_hoisted_3","model","_useModel","inputRef","ref","focused","currentValue","showClear","counter","onInput","value","onChange","onFocus","onBlur","clear","__expose","_createElementVNode","_toDisplayString","_hoisted_4","slots","useSlots","hasHeader","_hoisted_5","WebxUI","app","options","prefix","name","component","components","registeredName"],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import { Plugin } from 'vue';
2
+ export interface WebxUiOptions {
3
+ /**
4
+ * Prefix used when registering components globally.
5
+ * Components are declared as `WxButton`, so the default keeps that name.
6
+ */
7
+ prefix?: string;
8
+ }
9
+ /**
10
+ * Registers every component globally:
11
+ *
12
+ * ```ts
13
+ * import { WebxUI } from '@webx-ui/core'
14
+ * import '@webx-ui/core/style.css'
15
+ *
16
+ * app.use(WebxUI)
17
+ * ```
18
+ *
19
+ * Prefer named imports when bundle size matters — they tree-shake.
20
+ */
21
+ export declare const WebxUI: Plugin<[WebxUiOptions?]>;
22
+ export default WebxUI;
package/dist/style.css ADDED
@@ -0,0 +1 @@
1
+ :root{color-scheme:light;--wx-color-white: #ffffff;--wx-color-black: #000000;--wx-color-transparent: transparent;--wx-color-gray-50: #f8fafc;--wx-color-gray-100: #f1f5f9;--wx-color-gray-200: #e2e8f0;--wx-color-gray-300: #cbd5e1;--wx-color-gray-400: #94a3b8;--wx-color-gray-500: #64748b;--wx-color-gray-600: #475569;--wx-color-gray-700: #334155;--wx-color-gray-800: #1e293b;--wx-color-gray-900: #0f172a;--wx-color-gray-950: #020617;--wx-color-blue-50: #eff6ff;--wx-color-blue-100: #dbeafe;--wx-color-blue-200: #bfdbfe;--wx-color-blue-300: #93c5fd;--wx-color-blue-400: #60a5fa;--wx-color-blue-500: #3b82f6;--wx-color-blue-600: #2563eb;--wx-color-blue-700: #1d4ed8;--wx-color-blue-800: #1e40af;--wx-color-blue-900: #1e3a8a;--wx-color-green-50: #f0fdf4;--wx-color-green-100: #dcfce7;--wx-color-green-200: #bbf7d0;--wx-color-green-300: #86efac;--wx-color-green-400: #4ade80;--wx-color-green-500: #22c55e;--wx-color-green-600: #16a34a;--wx-color-green-700: #15803d;--wx-color-green-800: #166534;--wx-color-green-900: #14532d;--wx-color-amber-50: #fffbeb;--wx-color-amber-100: #fef3c7;--wx-color-amber-200: #fde68a;--wx-color-amber-300: #fcd34d;--wx-color-amber-400: #fbbf24;--wx-color-amber-500: #f59e0b;--wx-color-amber-600: #d97706;--wx-color-amber-700: #b45309;--wx-color-amber-800: #92400e;--wx-color-amber-900: #78350f;--wx-color-red-50: #fef2f2;--wx-color-red-100: #fee2e2;--wx-color-red-200: #fecaca;--wx-color-red-300: #fca5a5;--wx-color-red-400: #f87171;--wx-color-red-500: #ef4444;--wx-color-red-600: #dc2626;--wx-color-red-700: #b91c1c;--wx-color-red-800: #991b1b;--wx-color-red-900: #7f1d1d;--wx-space-0: 0px;--wx-space-1: 2px;--wx-space-2: 4px;--wx-space-3: 8px;--wx-space-4: 12px;--wx-space-5: 16px;--wx-space-6: 20px;--wx-space-7: 24px;--wx-space-8: 32px;--wx-space-9: 40px;--wx-space-10: 48px;--wx-space-11: 64px;--wx-space-12: 80px;--wx-font-family-sans: Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;--wx-font-family-mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;--wx-font-size-xs: 12px;--wx-font-size-sm: 13px;--wx-font-size-md: 14px;--wx-font-size-lg: 16px;--wx-font-size-xl: 20px;--wx-font-size-2xl: 24px;--wx-font-size-3xl: 30px;--wx-font-weight-regular: 400;--wx-font-weight-medium: 500;--wx-font-weight-semibold: 600;--wx-font-weight-bold: 700;--wx-font-line-height-tight: 1.25;--wx-font-line-height-normal: 1.5;--wx-font-line-height-relaxed: 1.75;--wx-radius-none: 0px;--wx-radius-sm: 4px;--wx-radius-md: 6px;--wx-radius-lg: 10px;--wx-radius-xl: 14px;--wx-radius-full: 9999px;--wx-shadow-none: none;--wx-shadow-sm: 0 1px 2px 0 rgb(15 23 42 / .06);--wx-shadow-md: 0 4px 12px -2px rgb(15 23 42 / .1), 0 2px 4px -2px rgb(15 23 42 / .06);--wx-shadow-lg: 0 12px 32px -8px rgb(15 23 42 / .18), 0 4px 8px -4px rgb(15 23 42 / .08);--wx-size-control-sm: 28px;--wx-size-control-md: 34px;--wx-size-control-lg: 42px;--wx-z-index-base: 0;--wx-z-index-sticky: 800;--wx-z-index-dropdown: 1000;--wx-z-index-overlay: 1100;--wx-z-index-dialog: 1200;--wx-z-index-popover: 1300;--wx-z-index-toast: 1400;--wx-z-index-tooltip: 1500;--wx-duration-fast: .12s;--wx-duration-normal: .2s;--wx-duration-slow: .32s;--wx-easing-standard: cubic-bezier(.2, 0, 0, 1);--wx-color-primary: var(--wx-color-blue-600);--wx-color-primary-hover: var(--wx-color-blue-700);--wx-color-primary-active: var(--wx-color-blue-800);--wx-color-primary-soft: var(--wx-color-blue-50);--wx-color-primary-contrast: var(--wx-color-white);--wx-color-success: var(--wx-color-green-600);--wx-color-success-soft: var(--wx-color-green-50);--wx-color-warning: var(--wx-color-amber-500);--wx-color-warning-soft: var(--wx-color-amber-50);--wx-color-danger: var(--wx-color-red-600);--wx-color-danger-hover: var(--wx-color-red-700);--wx-color-danger-soft: var(--wx-color-red-50);--wx-color-danger-contrast: var(--wx-color-white);--wx-color-info: var(--wx-color-blue-500);--wx-color-info-soft: var(--wx-color-blue-50);--wx-bg-body: var(--wx-color-gray-50);--wx-bg-surface: var(--wx-color-white);--wx-bg-muted: var(--wx-color-gray-100);--wx-bg-subtle: var(--wx-color-gray-50);--wx-bg-inverse: var(--wx-color-gray-900);--wx-bg-disabled: var(--wx-color-gray-100);--wx-bg-overlay: rgb(15 23 42 / .45);--wx-text-default: var(--wx-color-gray-800);--wx-text-strong: var(--wx-color-gray-900);--wx-text-muted: var(--wx-color-gray-500);--wx-text-disabled: var(--wx-color-gray-400);--wx-text-inverse: var(--wx-color-white);--wx-text-link: var(--wx-color-blue-600);--wx-border-default: var(--wx-color-gray-200);--wx-border-strong: var(--wx-color-gray-300);--wx-border-muted: var(--wx-color-gray-100);--wx-border-focus: var(--wx-color-blue-500);--wx-ring-focus: 0 0 0 3px rgb(59 130 246 / .35);--wx-shadow-card: var(--wx-shadow-sm);--wx-shadow-popover: var(--wx-shadow-md);--wx-shadow-dialog: var(--wx-shadow-lg)}[data-theme=dark]{color-scheme:dark;--wx-color-primary: var(--wx-color-blue-500);--wx-color-primary-hover: var(--wx-color-blue-400);--wx-color-primary-active: var(--wx-color-blue-300);--wx-color-primary-soft: rgb(59 130 246 / .16);--wx-color-primary-contrast: var(--wx-color-gray-950);--wx-color-success: var(--wx-color-green-500);--wx-color-success-soft: rgb(34 197 94 / .16);--wx-color-warning: var(--wx-color-amber-400);--wx-color-warning-soft: rgb(245 158 11 / .16);--wx-color-danger: var(--wx-color-red-500);--wx-color-danger-hover: var(--wx-color-red-400);--wx-color-danger-soft: rgb(239 68 68 / .16);--wx-color-danger-contrast: var(--wx-color-gray-950);--wx-color-info: var(--wx-color-blue-400);--wx-color-info-soft: rgb(96 165 250 / .16);--wx-bg-body: var(--wx-color-gray-950);--wx-bg-surface: var(--wx-color-gray-900);--wx-bg-muted: var(--wx-color-gray-800);--wx-bg-subtle: var(--wx-color-gray-800);--wx-bg-inverse: var(--wx-color-gray-100);--wx-bg-disabled: var(--wx-color-gray-800);--wx-bg-overlay: rgb(2 6 23 / .65);--wx-text-default: var(--wx-color-gray-200);--wx-text-strong: var(--wx-color-gray-50);--wx-text-muted: var(--wx-color-gray-400);--wx-text-disabled: var(--wx-color-gray-600);--wx-text-inverse: var(--wx-color-gray-950);--wx-text-link: var(--wx-color-blue-400);--wx-border-default: var(--wx-color-gray-700);--wx-border-strong: var(--wx-color-gray-600);--wx-border-muted: var(--wx-color-gray-800);--wx-border-focus: var(--wx-color-blue-400);--wx-ring-focus: 0 0 0 3px rgb(96 165 250 / .35);--wx-shadow-card: 0 1px 2px 0 rgb(0 0 0 / .4);--wx-shadow-popover: 0 4px 12px -2px rgb(0 0 0 / .5);--wx-shadow-dialog: 0 12px 32px -8px rgb(0 0 0 / .6)}@media(prefers-color-scheme:dark){:root:not([data-theme=light]){color-scheme:dark;--wx-color-primary: var(--wx-color-blue-500);--wx-color-primary-hover: var(--wx-color-blue-400);--wx-color-primary-active: var(--wx-color-blue-300);--wx-color-primary-soft: rgb(59 130 246 / .16);--wx-color-primary-contrast: var(--wx-color-gray-950);--wx-color-success: var(--wx-color-green-500);--wx-color-success-soft: rgb(34 197 94 / .16);--wx-color-warning: var(--wx-color-amber-400);--wx-color-warning-soft: rgb(245 158 11 / .16);--wx-color-danger: var(--wx-color-red-500);--wx-color-danger-hover: var(--wx-color-red-400);--wx-color-danger-soft: rgb(239 68 68 / .16);--wx-color-danger-contrast: var(--wx-color-gray-950);--wx-color-info: var(--wx-color-blue-400);--wx-color-info-soft: rgb(96 165 250 / .16);--wx-bg-body: var(--wx-color-gray-950);--wx-bg-surface: var(--wx-color-gray-900);--wx-bg-muted: var(--wx-color-gray-800);--wx-bg-subtle: var(--wx-color-gray-800);--wx-bg-inverse: var(--wx-color-gray-100);--wx-bg-disabled: var(--wx-color-gray-800);--wx-bg-overlay: rgb(2 6 23 / .65);--wx-text-default: var(--wx-color-gray-200);--wx-text-strong: var(--wx-color-gray-50);--wx-text-muted: var(--wx-color-gray-400);--wx-text-disabled: var(--wx-color-gray-600);--wx-text-inverse: var(--wx-color-gray-950);--wx-text-link: var(--wx-color-blue-400);--wx-border-default: var(--wx-color-gray-700);--wx-border-strong: var(--wx-color-gray-600);--wx-border-muted: var(--wx-color-gray-800);--wx-border-focus: var(--wx-color-blue-400);--wx-ring-focus: 0 0 0 3px rgb(96 165 250 / .35);--wx-shadow-card: 0 1px 2px 0 rgb(0 0 0 / .4);--wx-shadow-popover: 0 4px 12px -2px rgb(0 0 0 / .5);--wx-shadow-dialog: 0 12px 32px -8px rgb(0 0 0 / .6)}}.wx-root,.wx-app{color:var(--wx-text-default);background:var(--wx-bg-body);font-family:var(--wx-font-family-sans);font-size:var(--wx-font-size-md);line-height:var(--wx-font-line-height-normal)}.wx-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}.wx-button[data-v-ab949d1e]{display:inline-flex;align-items:center;justify-content:center;gap:var(--wx-space-2);box-sizing:border-box;border:1px solid transparent;border-radius:var(--wx-radius-md);font-family:inherit;font-weight:var(--wx-font-weight-medium);line-height:var(--wx-font-line-height-tight);text-decoration:none;white-space:nowrap;cursor:pointer;user-select:none;transition:background-color var(--wx-duration-fast) var(--wx-easing-standard),border-color var(--wx-duration-fast) var(--wx-easing-standard),color var(--wx-duration-fast) var(--wx-easing-standard),box-shadow var(--wx-duration-fast) var(--wx-easing-standard)}.wx-button[data-v-ab949d1e]:focus-visible{outline:none;box-shadow:var(--wx-ring-focus)}.wx-button--sm[data-v-ab949d1e]{height:var(--wx-size-control-sm);padding:0 var(--wx-space-3);font-size:var(--wx-font-size-sm)}.wx-button--md[data-v-ab949d1e]{height:var(--wx-size-control-md);padding:0 var(--wx-space-5);font-size:var(--wx-font-size-md)}.wx-button--lg[data-v-ab949d1e]{height:var(--wx-size-control-lg);padding:0 var(--wx-space-7);font-size:var(--wx-font-size-lg)}.wx-button--block[data-v-ab949d1e]{display:flex;width:100%}.wx-button--round[data-v-ab949d1e]{border-radius:var(--wx-radius-full)}.wx-button--solid.wx-button--default[data-v-ab949d1e]{background:var(--wx-bg-surface);border-color:var(--wx-border-strong);color:var(--wx-text-default)}.wx-button--solid.wx-button--default[data-v-ab949d1e]:hover:not(.is-disabled){background:var(--wx-bg-muted)}.wx-button--solid.wx-button--primary[data-v-ab949d1e]{background:var(--wx-color-primary);color:var(--wx-color-primary-contrast)}.wx-button--solid.wx-button--primary[data-v-ab949d1e]:hover:not(.is-disabled){background:var(--wx-color-primary-hover)}.wx-button--solid.wx-button--success[data-v-ab949d1e]{background:var(--wx-color-success);color:var(--wx-color-primary-contrast)}.wx-button--solid.wx-button--warning[data-v-ab949d1e]{background:var(--wx-color-warning);color:var(--wx-color-primary-contrast)}.wx-button--solid.wx-button--danger[data-v-ab949d1e]{background:var(--wx-color-danger);color:var(--wx-color-danger-contrast)}.wx-button--solid.wx-button--danger[data-v-ab949d1e]:hover:not(.is-disabled){background:var(--wx-color-danger-hover)}.wx-button--solid.wx-button--success[data-v-ab949d1e]:hover:not(.is-disabled),.wx-button--solid.wx-button--warning[data-v-ab949d1e]:hover:not(.is-disabled){filter:brightness(.94)}.wx-button--outline[data-v-ab949d1e]{background:transparent;border-color:var(--wx-border-strong);color:var(--wx-text-default)}.wx-button--outline.wx-button--primary[data-v-ab949d1e]{border-color:var(--wx-color-primary);color:var(--wx-color-primary)}.wx-button--outline.wx-button--success[data-v-ab949d1e]{border-color:var(--wx-color-success);color:var(--wx-color-success)}.wx-button--outline.wx-button--warning[data-v-ab949d1e]{border-color:var(--wx-color-warning);color:var(--wx-color-warning)}.wx-button--outline.wx-button--danger[data-v-ab949d1e]{border-color:var(--wx-color-danger);color:var(--wx-color-danger)}.wx-button--outline[data-v-ab949d1e]:hover:not(.is-disabled){background:var(--wx-bg-muted)}.wx-button--outline.wx-button--primary[data-v-ab949d1e]:hover:not(.is-disabled){background:var(--wx-color-primary-soft)}.wx-button--outline.wx-button--danger[data-v-ab949d1e]:hover:not(.is-disabled){background:var(--wx-color-danger-soft)}.wx-button--text[data-v-ab949d1e]{background:transparent;border-color:transparent;color:var(--wx-text-default)}.wx-button--text.wx-button--primary[data-v-ab949d1e]{color:var(--wx-color-primary)}.wx-button--text.wx-button--danger[data-v-ab949d1e]{color:var(--wx-color-danger)}.wx-button--text.wx-button--success[data-v-ab949d1e]{color:var(--wx-color-success)}.wx-button--text.wx-button--warning[data-v-ab949d1e]{color:var(--wx-color-warning)}.wx-button--text[data-v-ab949d1e]:hover:not(.is-disabled){background:var(--wx-bg-muted)}.wx-button.is-disabled[data-v-ab949d1e]{cursor:not-allowed;opacity:.55}.wx-button--loading[data-v-ab949d1e]{cursor:progress}.wx-button__spinner[data-v-ab949d1e]{width:1em;height:1em;border:2px solid currentcolor;border-right-color:transparent;border-radius:var(--wx-radius-full);animation:wx-button-spin-ab949d1e var(--wx-duration-slow) linear infinite}.wx-button__icon[data-v-ab949d1e]{display:inline-flex;align-items:center}@keyframes wx-button-spin-ab949d1e{to{transform:rotate(360deg)}}@media(prefers-reduced-motion:reduce){.wx-button[data-v-ab949d1e]{transition:none}.wx-button__spinner[data-v-ab949d1e]{animation-duration:2s}}.wx-input[data-v-962ec44e]{display:inline-flex;align-items:center;gap:var(--wx-space-2);box-sizing:border-box;width:100%;background:var(--wx-bg-surface);border:1px solid var(--wx-border-default);border-radius:var(--wx-radius-md);color:var(--wx-text-default);transition:border-color var(--wx-duration-fast) var(--wx-easing-standard),box-shadow var(--wx-duration-fast) var(--wx-easing-standard)}.wx-input[data-v-962ec44e]:hover:not(.is-disabled){border-color:var(--wx-border-strong)}.wx-input.is-focused[data-v-962ec44e]{border-color:var(--wx-border-focus);box-shadow:var(--wx-ring-focus)}.wx-input--sm[data-v-962ec44e]{height:var(--wx-size-control-sm);padding:0 var(--wx-space-3);font-size:var(--wx-font-size-sm)}.wx-input--md[data-v-962ec44e]{height:var(--wx-size-control-md);padding:0 var(--wx-space-4);font-size:var(--wx-font-size-md)}.wx-input--lg[data-v-962ec44e]{height:var(--wx-size-control-lg);padding:0 var(--wx-space-5);font-size:var(--wx-font-size-lg)}.wx-input--error[data-v-962ec44e]{border-color:var(--wx-color-danger)}.wx-input--error.is-focused[data-v-962ec44e]{box-shadow:0 0 0 3px var(--wx-color-danger-soft)}.wx-input--success[data-v-962ec44e]{border-color:var(--wx-color-success)}.wx-input--warning[data-v-962ec44e]{border-color:var(--wx-color-warning)}.wx-input.is-disabled[data-v-962ec44e]{background:var(--wx-bg-disabled);color:var(--wx-text-disabled);cursor:not-allowed}.wx-input__inner[data-v-962ec44e]{flex:1 1 auto;min-width:0;height:100%;padding:0;background:transparent;border:none;outline:none;color:inherit;font-family:inherit;font-size:inherit;line-height:inherit}.wx-input__inner[data-v-962ec44e]::placeholder{color:var(--wx-text-muted)}.wx-input__inner[data-v-962ec44e]:disabled{cursor:not-allowed}.wx-input__affix[data-v-962ec44e],.wx-input__count[data-v-962ec44e]{display:inline-flex;align-items:center;flex:0 0 auto;color:var(--wx-text-muted)}.wx-input__count[data-v-962ec44e]{font-size:var(--wx-font-size-xs);font-variant-numeric:tabular-nums}.wx-input__clear[data-v-962ec44e]{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;width:16px;height:16px;padding:0;background:transparent;border:none;border-radius:var(--wx-radius-full);color:var(--wx-text-muted);font-size:var(--wx-font-size-xs);line-height:1;cursor:pointer}.wx-input__clear[data-v-962ec44e]:hover{background:var(--wx-bg-muted);color:var(--wx-text-default)}.wx-card[data-v-5d02af6e]{display:flex;flex-direction:column;box-sizing:border-box;background:var(--wx-bg-surface);border:1px solid var(--wx-border-default);border-radius:var(--wx-radius-lg);color:var(--wx-text-default);transition:box-shadow var(--wx-duration-normal) var(--wx-easing-standard)}.wx-card--borderless[data-v-5d02af6e]{border-color:transparent}.wx-card--shadow-always[data-v-5d02af6e]{box-shadow:var(--wx-shadow-card)}.wx-card--shadow-hover[data-v-5d02af6e]:hover{box-shadow:var(--wx-shadow-popover)}.wx-card__header[data-v-5d02af6e],.wx-card__body[data-v-5d02af6e],.wx-card__footer[data-v-5d02af6e]{padding:var(--wx-card-padding, var(--wx-space-5))}.wx-card--padding-none[data-v-5d02af6e]{--wx-card-padding: 0px}.wx-card--padding-sm[data-v-5d02af6e]{--wx-card-padding: var(--wx-space-3)}.wx-card--padding-md[data-v-5d02af6e]{--wx-card-padding: var(--wx-space-5)}.wx-card--padding-lg[data-v-5d02af6e]{--wx-card-padding: var(--wx-space-7)}.wx-card__header[data-v-5d02af6e]{display:flex;align-items:center;justify-content:space-between;gap:var(--wx-space-4);border-bottom:1px solid var(--wx-border-muted)}.wx-card__title[data-v-5d02af6e]{min-width:0;color:var(--wx-text-strong);font-size:var(--wx-font-size-lg);font-weight:var(--wx-font-weight-semibold);line-height:var(--wx-font-line-height-tight)}.wx-card__extra[data-v-5d02af6e]{flex:0 0 auto;color:var(--wx-text-muted)}.wx-card__body[data-v-5d02af6e]{flex:1 1 auto}.wx-card__footer[data-v-5d02af6e]{border-top:1px solid var(--wx-border-muted)}
package/package.json ADDED
@@ -0,0 +1,63 @@
1
+ {
2
+ "name": "@webx-ui/core",
3
+ "version": "0.0.1",
4
+ "description": "Vue 3 UI components for admin panels, styled entirely with WebX UI design tokens.",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "sideEffects": [
8
+ "*.css"
9
+ ],
10
+ "keywords": [
11
+ "webx-ui",
12
+ "vue",
13
+ "vue3",
14
+ "ui",
15
+ "components",
16
+ "design-system",
17
+ "admin"
18
+ ],
19
+ "repository": {
20
+ "type": "git",
21
+ "url": "git+https://github.com/webx-ui/webx-ui.git",
22
+ "directory": "packages/core"
23
+ },
24
+ "homepage": "https://webx-ui.github.io/webx-ui/components/button.html",
25
+ "publishConfig": {
26
+ "access": "public"
27
+ },
28
+ "files": [
29
+ "dist"
30
+ ],
31
+ "main": "./dist/index.js",
32
+ "module": "./dist/index.js",
33
+ "types": "./dist/index.d.ts",
34
+ "exports": {
35
+ ".": {
36
+ "types": "./dist/index.d.ts",
37
+ "import": "./dist/index.js"
38
+ },
39
+ "./style.css": "./dist/style.css",
40
+ "./dist/style.css": "./dist/style.css",
41
+ "./package.json": "./package.json"
42
+ },
43
+ "peerDependencies": {
44
+ "vue": "^3.5.0"
45
+ },
46
+ "dependencies": {
47
+ "@webx-ui/tokens": "^0.0.1"
48
+ },
49
+ "devDependencies": {
50
+ "@types/node": "^24.10.1",
51
+ "@vitejs/plugin-vue": "^6.0.1",
52
+ "typescript": "^5.9.3",
53
+ "vite": "^7.1.14",
54
+ "vite-plugin-dts": "^4.5.4",
55
+ "vue": "^3.5.24",
56
+ "vue-tsc": "^3.1.3"
57
+ },
58
+ "scripts": {
59
+ "build": "vite build",
60
+ "dev": "vite build --watch",
61
+ "typecheck": "vue-tsc -p tsconfig.json --noEmit"
62
+ }
63
+ }