feat: 打包

This commit is contained in:
2024-11-02 16:39:26 +08:00
parent acce2c991e
commit af9491e698
14 changed files with 157 additions and 59 deletions

View File

@@ -1,4 +1,4 @@
import { message as Message, createMessage } from '../deploy/message.js';
import { message as Message, createMessage } from '../dist/message.js';
export default {
title: 'ui/message',

View File

@@ -1,6 +1,6 @@
{
"name": "@kevisual/system-ui",
"version": "0.0.1",
"version": "0.0.2",
"description": "",
"main": "dist/index.js",
"privite": false,
@@ -9,6 +9,7 @@
"dev": "rollup -c -w",
"build": "npm run clean && rollup -c",
"build:components": "rollup -c ./config/rollup.components.config.js",
"dev:components": "rollup -c ./config/rollup.components.config.js -w",
"pub": "envision switchOrg system && envision deploy ./dist -v 0.0.2 -k ui -y y",
"clean": "rimraf dist"
},
@@ -33,6 +34,7 @@
"@rollup/plugin-node-resolve": "^15.2.3",
"@rollup/plugin-terser": "^0.4.4",
"@rollup/plugin-typescript": "^11.1.6",
"@types/lodash-es": "^4.17.12",
"@types/postcss-import": "^14.0.3",
"@types/react": "^18.3.8",
"autoprefixer": "^10.4.20",

View File

@@ -41,7 +41,7 @@ export class MessageContainer {
}
.message-wrapper {
display: flex;
transition: transform 2s ease-in-out, opacity 1.2s ease-in-out; /* 缩小并淡出 */
transition: transform 0.5s ease-in-out, opacity 0.5s ease-in-out; /* 缩小并淡出 */
}
.message-wrapper:first-child {
margin-top: 20px;
@@ -49,15 +49,15 @@ export class MessageContainer {
.message {
display: flex;
gap: 10px;
padding: 6px 10px;
padding: 4px 10px;
margin: 0 auto;
border-radius: 4px;
border-radius: 8px;
background-color: white;
box-shadow: 0 6px 16px 0 rgba(0, 0, 0, 0.08),
0 3px 6px -4px rgba(0, 0, 0, 0.12),
0 9px 28px 8px rgba(0, 0, 0, 0.05);
justify-content: center;
align-item: center;
align-items: center;
animation: message-slide-down 0.3s ease-out forwards; /* 应用动画 */
}
/* 添加消失类时 */
@@ -66,8 +66,6 @@ export class MessageContainer {
opacity: 0;
pointer-events: none; /* 防止交互 */
}
.message-success {
}
@keyframes message-slide-down {
0% {
transform: translateY(-100px); /* 从上方开始 */
@@ -87,6 +85,7 @@ export class MessageContainer {
height: 24px;
box-sizing: border-box;
}
.message-icon::before {
content: "";
position: absolute;
@@ -95,27 +94,44 @@ export class MessageContainer {
width: 5px;
height: 10px;
}
.icon-success {
border: 2px solid green; /* 外圆圈 */
background: green; /* 背景颜色为绿色 */
color: white; /* 文字颜色为白色 */
border: 1px solid green; /* 外圆圈2 */
border-radius: 50%; /* 使其为圆形 */
width: 20px;
height: 20px;
position: relative;
box-sizing: border-box;
}
.icon-success::before {
border-right: 2px solid green; /* 打勾的右边部分 */
border-bottom: 2px solid green; /* 打勾的下边部分 */
transform: rotate(45deg);
content: "";
position: absolute;
left: 7px;
top: 3px;
width: 5px;
height: 10px;
border-right: 2px solid white; /* 打勾的右边部分 */
border-bottom: 2px solid white; /* 打勾的下边部分 */
transform: rotate(45deg); /* 旋转形成勾形 */
box-sizing: border-box;
}
.icon-info {
border: 2px solid blue; /* 外圆圈 */
border: 1px solid blue; /* 外圆圈 */
border-radius: 50%; /* 使其为圆形 */
background: blue; /* 背景颜色为蓝色 */
width: 20px;
height: 20px;
}
.icon-info::before {
content: "i";
position: absolute;
top: 0px;
color: blue;
top: -2px;
color: white; /* 文字颜色为白色 */
font-weight: bold;
font-size: 16px;
left: 8px;
}
.icon-error::before, .icon-error::after {
content: "";
@@ -123,13 +139,16 @@ export class MessageContainer {
top: 4px;
left: 50%;
width: 2px;
height: 12px;
background-color: red;
height: 10px;
background-color: white; /* 线条颜色为白色 */
transform-origin: center;
}
.icon-error {
border: 2px solid red; /* 外圆圈 */
border: 1px solid red; /* 外圆圈 */
border-radius: 50%; /* 使其为圆形 */
background: red; /* 背景颜色为红色 */
width: 20px;
height: 20px;
}
.icon-error::before {
transform: translateX(-50%) rotate(45deg); /* 旋转形成叉号的一部分 */
@@ -139,29 +158,24 @@ export class MessageContainer {
transform: translateX(-50%) rotate(-45deg); /* 旋转形成叉号的另一部分 */
}
.icon-warning {
position: relative;
width: 0;
height: 0;
border-left: 12px solid transparent;
border-right: 12px solid transparent;
border-bottom: 24px solid orange; /* 三角形 */
display: inline-block;
transform: scale(0.8); /* 缩小三角形 */
border: 1px solid orange; /* 外圆圈 */
border-radius: 50%; /* 使其为圆形 */
background: orange; /* 背景颜色为蓝色 */
width: 20px;
height: 20px;
}
.icon-warning::before {
content: "!";
position: absolute;
top: 5px;
left: 50%;
transform: translateX(-50%);
color: white;
top: -2px;
color: white; /* 文字颜色为白色 */
font-weight: bold;
font-size: 16px;
}
.icon-loading {
width: 24px;
height: 24px;
width: 20px;
height: 20px;
border: 3px solid #f3f3f3; /* 边框颜色,用于加载圈的背景 */
border-top: 3px solid #3498db; /* 顶部边框的颜色,用于显示加载进度 */
border-radius: 50%; /* 圆形 */
@@ -188,7 +202,15 @@ export class MessageContainer {
}
const controller = new MessageContainer();
export const createMessage = (content, opts) => {
type MessageOpts = {
/** w-20px h-20px */
icon?: string;
key?: string;
style?: string;
className?: string;
type?: string;
};
export const createMessage = (content: string | Element, opts: MessageOpts) => {
let { icon, key, style, className, type } = opts || {};
const div = document.createElement('div');
div.className = 'message-wrapper' + (className ? ' ' + className : '');
@@ -211,7 +233,7 @@ export const createMessage = (content, opts) => {
}
if (content instanceof HTMLElement) {
contentDiv.appendChild(content);
} else {
} else if (typeof content === 'string') {
const text = document.createElement('span');
text.innerText = content;
contentDiv.appendChild(text);
@@ -227,7 +249,7 @@ export class Message {
constructor() {
this.controller = controller;
}
open = (message, timeout = 3000, onClose, opts) => {
open = (message: string | Element, timeout = 3000, onClose, opts) => {
const controller = this.controller;
const div = createMessage(message, opts);
const remove = () => {

View File

@@ -1,5 +1,5 @@
import { Modal, ModalOpts, KV } from './modal';
import { SelectEl, querySelector, elAddCS, ElStyle, elAddCS2 } from '../../utils/query-el';
import { SelectEl, querySelector, ElStyle, elAddCS2 } from '../../utils/query-el';
import { ObjCss } from '../../utils/css';
export class BlankModal extends Modal {
@@ -8,15 +8,18 @@ export class BlankModal extends Modal {
}
}
type DialogModalOpts = {
/** 标题的内容 */
dialogTitle?: string;
dialogTitleClassName?: string;
dialogTitleStyle?: ElStyle;
dialogTitleEl?: HTMLElement;
dialogTitleCloseIcon?: boolean;
/** 内容的模块 */
dialogContentClassName?: string;
dialogContentStyle?: ElStyle;
/** Footer的模块 */
dialogFooterClassName?: string;
dialogFooterStyle?: ElStyle;
} & ModalOpts<KV, DialogDefaultStyle>;

View File

@@ -1,4 +1,4 @@
import { querySelector, elAddCS, ElStyle, elAddCS2 } from '../../utils/query-el';
import { querySelector, ElStyle, elAddCS2 } from '../../utils/query-el';
import { generateId } from '../../utils/nanoid';
import { modalStore } from './store';
import { InitModalEvent } from './event';
@@ -28,6 +28,7 @@ export type ModalOpts<
open?: boolean;
onClose?: () => void;
/** 默认的样式属性, content style 和 mask style 等 */
defaultStyle?: DefaultStyle<U>;
} & T;
export type DefaultStyle<T> = {
@@ -105,8 +106,8 @@ export class Modal<T = any, U = KV> {
return _root;
}
static render<T extends new (...args: any[]) => any>(this: T,el: string | HTMLDivElement, id: string, opts?: ConstructorParameters<T>[0]): InstanceType<T>;
static render<T extends new (...args: any[]) => any>(this: T,el: string | HTMLDivElement, opts?: ConstructorParameters<T>[0]): InstanceType<T>;
static render<T extends new (...args: any[]) => any>(this: T, el: string | HTMLDivElement, id: string, opts?: ConstructorParameters<T>[0]): InstanceType<T>;
static render<T extends new (...args: any[]) => any>(this: T, el: string | HTMLDivElement, opts?: ConstructorParameters<T>[0]): InstanceType<T>;
static render(...args: any[]) {
let [el, id, opts] = args;
const _el = querySelector(el);
@@ -142,7 +143,7 @@ export class Modal<T = any, U = KV> {
_modal.renderEl(_el);
return _modal;
}
static create<T extends new (...args: any[]) => any>(this:T, opts: ModalOpts):InstanceType<T> {
static create<T extends new (...args: any[]) => any>(this: T, opts: ModalOpts): InstanceType<T> {
let _id = opts.id;
let _modal: Modal | undefined;
const modalState = modalStore.getState();
@@ -169,6 +170,7 @@ export class Modal<T = any, U = KV> {
return mask;
}
renderEl(el: HTMLDivElement) {
// base 的模块如果 defaultContentStyle 不存在,则使用默认的样式
const defaultContentStyle = this.defaultStyle?.defaultContentStyle || {
position: 'absolute',
padding: '20px',

View File

@@ -0,0 +1,3 @@
export * from './load-css';
export * from './is';

View File

@@ -0,0 +1,8 @@
import { isNil, isEmpty } from 'lodash-es';
/**
* Check if the value is null or empty object
*/
export const isObjectEmpty = (value: any) => {
return isNil(value) || isEmpty(value);
};

View File

@@ -0,0 +1,23 @@
type LoadCSSOptions = {
key?: string;
url: string;
force?: boolean;
};
export const loadCSS = (opts: LoadCSSOptions | string) => {
if (typeof opts === 'string') {
opts = { url: opts };
}
const { key, url, force } = opts;
let cssKeyDom = document.querySelector('#load-css-' + key);
if (!force && key && cssKeyDom) {
// console.log('css already loaded', key);
return;
} else if (key && cssKeyDom) {
cssKeyDom.remove();
}
const link = document.createElement('link');
link.id = key ? 'load-css-' + key : '';
link.rel = 'stylesheet';
link.href = url;
document.head.appendChild(link);
};

View File

@@ -1,3 +1,8 @@
/**
* 把字符串中的{{key}}替换成对应的值
* @param text
* @returns
*/
export function extractKeysFromBraces(text: string) {
const regex = /\{\{\s*(.*?)\s*\}\}/g;
const keys: string[] = [];

View File

@@ -1,3 +1,5 @@
import { createStore } from 'zustand/vanilla';
import { shallow } from 'zustand/vanilla/shallow';
export type { StateCreator, StoreApi } from 'zustand/vanilla';
export { createStore };
export { createStore, shallow };

View File

@@ -1,14 +1,16 @@
import { message } from '../deploy/message.js'
import { DialogModal } from '@kevisual/ui'
import '@kevisual/ui/dist/index.css'
import { message } from '../dist/message.js'
import { DialogModal } from '@kevisual/system-ui'
import '@kevisual/system-ui/dist/index.css'
Modal
# Modal
> 使用原生js实现的弹窗组件
安装 `npm i @kevisual/system-ui`
export const ShowModal = () => {
const url = 'https://kevisual.xiongxiao.me/system/theme/index.js'
const url = 'https://kevisual.xiongxiao.me/system/ui/index.js'
const onClick = async () => {
console.log('theme', DialogModal)
@@ -44,11 +46,14 @@ export const ShowModal = () => {
<ShowModal />
使用方法
*使用方法*
```js
// import { DialogModal } from 'https://kevisual.xiongxiao.me/system/theme/index.js'
import { DialogModal } from '@kevisual/ui';
import '@kevisual/ui/dist/index.css';
// import { DialogModal, loadCss } from 'https://kevisual.xiongxiao.me/system/ui/index.js'
// loadCss('https://kevisual.xiongxiao.me/system/ui/index.css')
import { DialogModal } from '@kevisual/system-ui';
import '@kevisual/system-ui/dist/index.css';
const content = document.createElement('div');
content.innerHTML = `