UNPKG

7.css-vue

Version:

Vue3 component library for recreating Windows 7 UI

1,233 lines (1,232 loc) 27.3 kB
import { defineComponent as o, createVNode as n, mergeProps as b, computed as d, Fragment as Y, ref as p, onMounted as q, onUnmounted as F, nextTick as G, useSlots as E, Teleport as R, Transition as U, createTextVNode as T, isVNode as K } from "vue"; import './main.css';const Z = /* @__PURE__ */ o({ name: "WinBalloon", props: { top: { type: Boolean, default: !1 }, bottom: { type: Boolean, default: !1 }, left: { type: Boolean, default: !1 }, right: { type: Boolean, default: !1 }, caption: { type: String, default: null } }, setup(e, { slots: t }) { return () => n("div", { role: "tooltip", class: ["winui-balloon", { "is-bottom": e.bottom, "is-top": e.top, "is-left": e.left, "is-right": e.right }] }, [t.default ? t.default() : e.caption]); } }), O = /* @__PURE__ */ o({ name: "WinButton", inheritAttrs: !1, props: { text: String, to: String, href: String, target: String, role: String, onClick: Function }, setup(e, { slots: t, attrs: u }) { const i = e.href ? "a" : "button"; return () => n(i, b(u, { class: "winui-button", href: e.href, target: e.target, role: e.role, onClick: e.onClick }), { default: () => [t.prepend && t.prepend(), t.default ? t.default() : e.text, t.append && t.append()] }); } }), P = /* @__PURE__ */ o({ name: "WinCheckbox", props: { disabled: { type: Boolean, default: !1 }, falseValue: { type: [Array, Boolean, Number, String, Object], default: void 0 }, modelValue: { type: [Array, Boolean, Number, String, Object], default: !1 }, name: { type: String, required: !0 }, label: { type: String, default: null }, trueValue: { type: [Array, Boolean, Number, String, Object], default: void 0 }, value: { type: [Array, Boolean, Number, String, Object], default: !0 } }, emits: ["update:model-value"], setup(e, { slots: t, emit: u }) { const i = d(() => `${e.name}-checkbox`), a = d(() => e.trueValue === void 0 ? e.value : e.trueValue), l = d(() => e.falseValue === void 0 ? !1 : e.falseValue), r = d(() => Array.isArray(e.modelValue) ? e.modelValue?.includes(a.value) : a.value === e.modelValue); function s() { if (e.disabled) return; if (!Array.isArray(e.modelValue)) { u("update:model-value", r.value ? l.value : a.value); return; } if (r.value) { u("update:model-value", e.modelValue.filter((m) => m !== a.value)); return; } u("update:model-value", [...e.modelValue, a.value]); } return () => n("div", { class: "winui-checkbox", onClick: (c) => { c.preventDefault(), s(); } }, [n("input", { id: i.value, name: e.name, disabled: e.disabled, type: "checkbox", checked: r.value }, null), n("label", { for: i.value }, [t.label ? t.label() : e.label])]); } }), Q = { monitor: "M21,16H3V4H21M21,2H3C1.89,2 1,2.89 1,4V16A2,2 0 0,0 3,18H10V20H8V22H16V20H14V18H21A2,2 0 0,0 23,16V4C23,2.89 22.1,2 21,2Z" }, C = /* @__PURE__ */ o({ name: "WinIcon", props: { icon: { type: String, required: !0 }, size: { type: [String, Number], default: 24 } }, setup(e) { return () => n("span", { class: "winui-icon" }, [n("svg", { viewBox: "0 0 24 24", xmlns: "http://www.w3.org/2000/svg", width: `${e.size}px`, height: `${e.size}px` }, [n("path", { d: Q[e.icon] }, null)])]); } }); let J = 0; function $() { return `${++J}`; } function k() { return { width: window.innerWidth, height: window.innerHeight }; } function D(e, t, u) { return Math.min(Math.max(e, t), u); } const ee = /* @__PURE__ */ o({ name: "WinCollapse", props: { open: { type: Boolean, default: !1 }, title: { type: String, required: !0 }, prependIcon: { type: String, default: null }, children: { type: Array, default: () => [] } }, emits: ["update:open"], setup(e, { slots: t, emit: u }) { const i = `winui-collapse-${$()}`, a = d({ get() { return e.open; }, set(r) { u("update:open", r); } }), l = /* @__PURE__ */ o({ name: "WinCollapse", props: { title: { type: String, required: !0 }, prependIcon: { type: String, default: null }, children: { type: Array, default: () => [] } }, setup(r) { return () => n("li", null, [r.children && r.children.length > 0 ? n(l, { title: r.title, prependIcon: r.prependIcon, children: r.children }, null) : n("span", null, [r.title])]); } }); return () => n("details", { id: i, class: "winui-collapse", open: a.value, onToggle: () => { a.value = !a.value; } }, [n("summary", { class: "collapse-title" }, [t.title ? t.title() : n(Y, null, [e.prependIcon && n(C, { icon: e.prependIcon, size: "16" }, null), n("span", null, [e.title])])]), t.default ? t.default() : e.children && e.children.length > 0 && n("ul", null, [e.children.map((r) => n(l, { key: r.id, title: r.title, prependIcon: r.prependIcon, children: r.children }, null))])]); } }); function te(e, t, u, i) { const a = p(Number(t.defaultX) || 0), l = p(Number(t.defaultY) || 0), r = p(!1); let s = 0, c = 0, m = null, g = null; const v = []; function W() { const f = (h) => _(h), y = () => I(); document.addEventListener("mousemove", f, { passive: !1 }), document.addEventListener("mouseup", y), v.push(() => { document.removeEventListener("mousemove", f), document.removeEventListener("mouseup", y); }); } function V() { v.forEach((f) => f()), v.length = 0; } function N() { const { width: f, height: y } = k(), h = m?.getBoundingClientRect(), x = h?.width || 300, w = h?.height || 200; return { minX: 0, minY: 0, maxX: f - x, maxY: y - w }; } function S(f, y) { const { minX: h, minY: x, maxX: w, maxY: B } = N(); return { x: D(f, h, w), y: D(y, x, B) }; } function I() { r.value && (V(), r.value = !1, g && (g.style.cursor = "grab")); } function _(f) { if (!r.value || u?.value || i?.value) return; f.preventDefault(); const y = s - f.clientX, h = c - f.clientY; s = f.clientX, c = f.clientY; const x = a.value - y, w = l.value - h, B = S(x, w); a.value = B.x, l.value = B.y; } function A(f) { u?.value || i?.value || (f.preventDefault(), s = f.clientX, c = f.clientY, r.value = !0, g && (g.style.cursor = "grabbing"), W()); } async function H() { if (t.draggable) { await G(); try { if (m = document.getElementById(e), g = document.getElementById(`${e}-header`), !m) { console.warn(`[Draggable] Element with id "${e}" not found`); return; } if (!g) { console.warn(`[Draggable] Header element with id "${e}-header" not found`); return; } g.addEventListener("mousedown", A), v.push(() => { g && g.removeEventListener("mousedown", A); }); } catch (f) { console.error("[Draggable] Initialization failed:", f); } } } function M() { V(), g && g.removeEventListener("mousedown", A); } return q(H), F(M), { dragging: r, offsetX: a, offsetY: l, cleanup: M }; } const z = 35, ne = 900, L = /* @__PURE__ */ o({ name: "WinWindow", props: { active: { type: Boolean, default: !1 }, title: { type: String, default: "Window" }, width: { type: String, default: "auto" }, height: { type: String, default: "auto" }, color: { type: String, default: "#4580c4" }, hasScrollbar: { type: Boolean, default: !1 }, hasStatus: { type: Boolean, default: !1 }, statusFields: { type: Array, default: () => [] }, minimizable: { type: Boolean, default: !1 }, maximizable: { type: Boolean, default: !1 }, closable: { type: Boolean, default: !1 }, draggable: { type: Boolean, default: !1 }, defaultX: { type: [Number, String], default: 0 }, defaultY: { type: [Number, String], default: 0 } }, emits: ["minimize", "maximize", "close"], setup(e, { slots: t, emit: u }) { const i = `window-${$()}`, a = p(!1), l = p(!1), r = p({ x: Number(e.defaultX), y: Number(e.defaultY) }), { dragging: s, offsetX: c, offsetY: m } = te(i, e, a, l), g = E(), v = d(() => e.hasStatus && e.statusFields && e.statusFields.length > 0 || !!g.status), W = d(() => ({ "--window-background-color": e.color, "--title-bar-height": `${z}px`, "--z-index-window": ne, top: `${m.value}px`, left: `${c.value}px` })); function V() { a.value ? (c.value = r.value.x, m.value = r.value.y, a.value = !1) : (r.value = { x: c.value, y: m.value }, c.value = 0, m.value = 0, a.value = !0), u("maximize", a.value); } function N() { if (l.value) m.value = r.value.y, l.value = !1; else { r.value.y = m.value; const { height: S } = k(); m.value = S - z, l.value = !0; } u("minimize", l.value); } return () => n("div", { id: i, class: ["window", "glass", { active: e.active, draggable: e.draggable, dragging: s.value, maximized: a.value, minimized: l.value }], style: W.value }, [n("div", { id: `${i}-header`, class: "title-bar" }, [n("div", { class: "title-bar-text" }, [e.title]), n("div", { class: "title-bar-controls" }, [e.minimizable && n("button", { "aria-label": l.value ? "Restore" : "Minimize", onClick: N }, null), e.maximizable && n("button", { "aria-label": a.value ? "Restore" : "Maximize", onClick: V }, null), e.closable && n("button", { "aria-label": "Close", onClick: () => u("close") }, null)])]), n("div", { class: ["window-body", "has-space", { "has-scrollbar": e.hasScrollbar }], style: { width: e.width } }, [t.default && t.default()]), v.value && n("div", { class: "status-bar" }, [t.status ? t.status() : e.statusFields?.map((S, I) => n("p", { key: I, class: "status-bar-field" }, [S]))])]); } }), ae = 400, le = 200, ue = 1e3, ie = /* @__PURE__ */ o({ name: "WinDialog", props: { modelValue: { type: Boolean, default: !1 }, title: { type: String, default: "Dialog" }, message: { type: String, default: "" }, width: { type: String, default: "400px" }, height: { type: String, default: "auto" }, color: { type: String, default: "#4580c4" }, hasStatus: { type: Boolean, default: !1 }, statusFields: { type: Array, default: () => [] }, permanent: { type: Boolean, default: !1 }, cancelable: { type: Boolean, default: !0 }, draggable: { type: Boolean, default: !1 }, closeOnBackdrop: { type: Boolean, default: !0 }, showActions: { type: Boolean, default: !0 } }, emits: ["accept", "cancel", "close", "update:model-value"], setup(e, { slots: t, emit: u }) { const i = d({ get() { return e.modelValue; }, set(v) { u("update:model-value", v); } }), a = d(() => { const { width: v } = k(); return Math.max(0, (v - ae) / 2); }), l = d(() => { const { height: v } = k(); return Math.max(0, (v - le) / 2); }), r = d(() => ({ "--z-index-dialog": ue })); function s() { i.value = !1, u("accept"); } function c() { i.value = !1, u("cancel"); } function m() { e.permanent || (i.value = !1, u("close")); } function g() { e.closeOnBackdrop && !e.permanent && m(); } return () => n(R, { to: "body" }, { default: () => [i.value && n("div", { class: "dialog-overlay", style: r.value }, [n("div", { class: "dialog-backdrop", onClick: g }, null), n(U, { name: "dialog", appear: !0 }, { default: () => [i.value && n(L, { active: !0, draggable: e.draggable, title: e.title, defaultX: a.value, defaultY: l.value, width: e.width, color: e.color, hasStatus: e.hasStatus, statusFields: e.statusFields, class: "dialog-window", onClose: m }, { default: () => [t.default ? t.default() : e.message && n("p", null, [e.message]), e.showActions && n("section", { class: "dialog-actions" }, [e.cancelable && n("button", { class: "winui-button", onClick: c }, [T("Cancel")]), n("button", { class: "winui-button default", onClick: s }, [T("OK")])])], status: e.hasStatus && t.status ? t.status : void 0 })] })])] }); } }), re = /* @__PURE__ */ o({ name: "WinDropdown", props: { modelValue: { type: [Number, String], default: null }, options: { type: Array, default: () => [] }, placeholder: { type: String, default: null }, itemValue: { type: String, default: "id" }, itemTitle: { type: String, default: "name" } }, emits: ["update:model-value"], setup(e, { slots: t, emit: u }) { const i = d({ get() { return e.modelValue; }, set(a) { u("update:model-value", a); } }); return () => n("select", { class: "winui-dropdown", value: i.value, onChange: (a) => { const l = a.target; i.value = l.value; } }, [t.placeholder ? t.placeholder() : e.placeholder && n("option", { value: void 0, disabled: !0, selected: !0 }, [e.placeholder]), t.options ? t.options() : e.options?.map((a) => n("option", { key: a[e.itemValue], value: a[e.itemValue], disabled: a.disabled, selected: i.value === a[e.itemValue] }, [a[e.itemTitle]]))]); } }), oe = /* @__PURE__ */ o({ name: "WinGroupbox", props: { title: { type: String, default: null }, label: { type: String, default: null } }, setup(e, { slots: t }) { return () => n("fieldset", { class: "winui-groupbox" }, [(e.title || e.label) && n("legend", null, [e.title || e.label]), t.default && t.default()]); } }), de = /* @__PURE__ */ o({ name: "WinLink", props: { prependIcon: { type: String, default: null }, href: { type: String, default: null }, text: { type: String, default: null }, to: { type: [String, Object], default: null }, target: { type: String, default: null } }, setup(e, { slots: t, attrs: u }) { const i = e.href || e.to ? "a" : "button"; return () => n(i, b({ class: "winui-link", href: e.href, target: e.target }, u), { default: () => [e.prependIcon && n(C, { icon: e.prependIcon, size: "16" }, null), t.default ? t.default() : n("span", null, [e.text])] }); } }), se = /* @__PURE__ */ o({ name: "WinListbox", props: { modelValue: { type: [Number, String], required: !0 }, options: { type: Array, required: !0 }, itemValue: { type: String, default: "id" }, itemText: { type: String, default: "name" } }, emits: ["update:model-value"], setup(e, { emit: t }) { const u = d({ get() { return e.modelValue; }, set(l) { t("update:model-value", l); } }); function i(l) { return l[e.itemValue] === u.value ? { "aria-selected": !0 } : {}; } function a(l) { u.value = l; } return () => n("ul", { role: "listbox", class: "winui-listbox" }, [e.options.map((l) => n("li", b({ key: l[e.itemValue], role: "option" }, i(l), { onClick: () => a(l[e.itemValue]) }), [l[e.itemText]]))]); } }), X = /* @__PURE__ */ o({ name: "WinMenu", setup(e, { slots: t }) { return () => n("ul", { class: "winui-menu", role: "menu" }, [t.default && t.default()]); } }), ce = /* @__PURE__ */ o({ name: "WinMenuBar", setup(e, { slots: t }) { return () => n("ul", { class: "winui-menubar", role: "menubar" }, [t.default && t.default()]); } }), fe = /* @__PURE__ */ o({ name: "WinMenuItem", props: { title: { type: String, default: null }, children: { type: Array, default: () => [] } }, setup(e, { slots: t, attrs: u }) { const i = E(), a = d(() => (i?.submenu ? i.submenu() : [])?.length > 0), l = d(() => a.value ? { "aria-haspopup": !0, ...u } : u), r = /* @__PURE__ */ o({ name: "WinMenuItem", props: { title: { type: String, default: null }, children: { type: Array, default: () => [] } }, setup(s) { return () => n("li", { class: "winui-menuitem", role: "menuitem" }, [n("label", { class: "winui-menuitem-button" }, [s.title])]); } }); return () => n("li", b({ class: "winui-menuitem", role: "menuitem" }, l.value), [t.default ? t.default() : a.value ? n("span", null, [e.title]) : n("label", { class: "winui-menuitem-button" }, [e.title]), (t.submenu || e.children && e.children.length > 0) && (t.submenu ? t.submenu() : n(X, null, { default: () => [e.children?.map((s, c) => n(r, { key: c, title: s.title, children: s.children }, null))] }))]); } }), j = /* @__PURE__ */ o({ name: "WinNavbarItem", props: { href: { type: String, default: null }, to: { type: [String, Object], default: null }, active: { type: Boolean, default: !1 }, tag: { type: String, default: null } }, emits: ["click"], setup(e, { slots: t, emit: u }) { const i = d(() => e.tag ? e.tag : e.to ? "router-link" : e.href ? "a" : "button"), a = d(() => e.active), l = (r) => { u("click", r); }; return () => { const r = i.value; return n(r, { href: e.href, to: e.to, class: ["winui-navbar-item", { active: a.value }], onClick: l }, { default: () => [n("span", null, [t.default && t.default()])] }); }; } }), me = /* @__PURE__ */ o({ name: "WinNavbar", props: { items: { type: Array, default: () => [{ text: "Home", href: "#" }, { text: "Download", href: "#" }, { text: "FAQ", href: "#" }, { text: "Discord Server", href: "#" }] } }, setup(e, { slots: t }) { return () => n("nav", { class: ["winui-navbar"] }, [n("div", { class: "navbar-content" }, [n("div", { class: "navbar-items" }, [t.default ? t.default() : e.items?.map((u) => n(j, b({ key: u.text }, u), { default: () => [u.text] }))])])]); } }), ge = /* @__PURE__ */ o({ name: "WinProgress", props: { variant: { type: String, default: "success" }, inert: { type: Boolean, default: !1 }, transition: { type: [Number, String], default: 300 }, indeterminate: { type: Boolean, default: !1 }, progress: { type: [Number, String], default: 0, validator(e) { if (typeof e == "string" && isNaN(Number(e))) return e.endsWith("%"); const t = Number(e); return t >= 0 && t <= 100; } } }, setup(e) { const t = d(() => e.indeterminate ? {} : { "aria-valuemin": 0, "aria-valuemax": 100, "aria-valuenow": typeof e.progress == "string" && isNaN(Number(e.progress)) ? Number(e.progress.slice(0, -1)) : Number(e.progress) }), u = d(() => e.indeterminate ? {} : { "--progress": isNaN(Number(e.progress)) ? e.progress : e.progress + "%", "--transition": Number(e.transition) / 1e3 + "s" }); return () => n("div", b({ role: "progressbar", class: ["winui-progress", e.variant, { marquee: e.indeterminate, animate: !e.inert }] }, t.value), [!e.indeterminate && n("div", { style: u.value }, null)]); } }), ve = /* @__PURE__ */ o({ name: "WinRadio", props: { name: { type: String, required: !0 }, modelValue: { type: [Number, String, Boolean], default: null }, value: { type: [Number, String, Boolean], required: !0 }, disabled: { type: Boolean, default: !1 }, label: { type: String, required: !0 } }, emits: ["update:model-value"], setup(e, { slots: t, emit: u }) { const i = d({ get() { return e.modelValue; }, set(l) { u("update:model-value", l); } }), a = d(() => `${e.name}-${e.value}-radio`); return () => n("div", { class: "winui-radio" }, [n("input", { id: a.value, type: "radio", name: e.name, value: e.value, checked: i.value === e.value, disabled: e.disabled, onChange: (l) => { l.target.checked && (i.value = e.value); } }, null), t.default ? t.default() : n("label", { for: a.value }, [e.label])]); } }), be = /* @__PURE__ */ o({ name: "WinSearchbox", props: { instant: { type: Boolean, default: !1 }, placeholder: { type: String, default: "Search" } }, emits: ["update:search", "search"], setup(e, { attrs: t, emit: u }) { const i = `searchbox-${$()}`, a = p(); function l() { u("search", a.value); } function r(s) { s.key === "Enter" && l(); } return () => e.instant ? n("input", b({ id: i, type: "search", class: "winui-searchbox", placeholder: e.placeholder, value: a.value, onInput: (s) => { const c = s.target; a.value = c.value; }, onKeyup: r }, t), null) : n("div", { class: "searchbox win-searchbox" }, [n("input", { type: "search", placeholder: e.placeholder, value: a.value, onInput: (s) => { const c = s.target; a.value = c.value; } }, null), n("button", { "aria-label": "search", onClick: l }, null)]); } }), ye = /* @__PURE__ */ o({ name: "WinSlider", props: { modelValue: { type: [String, Number], default: 0 } }, emits: ["update:model-value"], setup(e, { attrs: t, emit: u }) { const i = d({ get() { return e.modelValue; }, set(a) { u("update:model-value", a); } }); return () => n("input", b({ type: "range", class: "winui-slider", value: i.value, onChange: (a) => { const l = a.target; i.value = l.value; } }, t), null); } }); function he(e) { return typeof e == "function" || Object.prototype.toString.call(e) === "[object Object]" && !K(e); } const pe = /* @__PURE__ */ o({ name: "WinTabs", props: { modelValue: { type: String, required: !0 }, tabs: { type: Object, required: !0 }, justified: { type: Boolean, default: !1 } }, emits: ["update:model-value"], setup(e, { slots: t, emit: u }) { const i = d({ get() { return e.modelValue; }, set(a) { u("update:model-value", a); } }); return () => n("div", { class: "winui-tabs" }, [n("menu", { role: "tablist", class: { justified: e.justified } }, [Object.entries(e.tabs).map(([a, l]) => n(O, { key: a, "aria-selected": i.value === a, role: "tab", onClick: () => { i.value = a; } }, he(l) ? l : { default: () => [l] }))]), Object.entries(e.tabs).map(([a, l]) => n("article", { key: a, hidden: i.value !== a, role: "tabpanel" }, [t[a] ? t[a]({ title: l, tab: a, hidden: i.value !== a }) : null]))]); } }), Se = /* @__PURE__ */ o({ name: "WinTextbox", props: { modelValue: { type: String, required: !0 }, type: { type: String, default: "text" }, readonly: { type: Boolean, default: !1 } }, emits: ["update:model-value"], setup(e, { attrs: t, emit: u }) { const i = d({ get() { return e.modelValue; }, set(l) { u("update:model-value", l); } }), a = { class: "winui-textbox", readonly: e.readonly, value: i.value, onInput: (l) => { const r = l.target; i.value = r.value; }, ...t }; return () => e.type === "textarea" ? n("textarea", a, null) : n("input", b({ type: e.type }, a), null); } }), xe = /* @__PURE__ */ o({ name: "WinTreeview", setup(e, { slots: t }) { return () => n("ul", { class: "tree-view winui-treeview" }, [t.default && t.default()]); } }), we = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, Balloon: Z, Button: O, Checkbox: P, Collapse: ee, Dialog: ie, Dropdown: re, Groupbox: oe, Icon: C, Link: de, Listbox: se, Menu: X, MenuBar: ce, MenuItem: fe, Navbar: me, NavbarItem: j, Progress: ge, Radio: ve, Searchbox: be, Slider: ye, Tabs: pe, Textbox: Se, Treeview: xe, Window: L }, Symbol.toStringTag, { value: "Module" })), Be = { install(e) { Object.values(we).forEach((t) => { e.component(t.name, t); }); } }; export { Be as default, te as useDraggable };