tona-ui 1.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) 2021 guangzan
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,81 @@
1
+ # tona-ui
2
+
3
+ Tona UI 组件库,提供可复用的 Preact 组件。
4
+
5
+ ## 安装
6
+
7
+ ```bash
8
+ pnpm add tona-ui
9
+ ```
10
+
11
+ ## 组件
12
+
13
+ ### Button
14
+
15
+ 按钮组件,支持多种变体和尺寸。
16
+
17
+ ```tsx
18
+ import { Button } from 'tona-ui'
19
+
20
+ // 基础用法
21
+ <Button>点击我</Button>
22
+
23
+ // 不同变体
24
+ <Button variant="destructive">删除</Button>
25
+ <Button variant="outline">轮廓</Button>
26
+ <Button variant="ghost">幽灵</Button>
27
+
28
+ // 不同尺寸
29
+ <Button size="sm">小按钮</Button>
30
+ <Button size="lg">大按钮</Button>
31
+ <Button size="icon">图标按钮</Button>
32
+
33
+ // 作为子组件渲染
34
+ <Button asChild>
35
+ <a href="/link">链接按钮</a>
36
+ </Button>
37
+ ```
38
+
39
+ ### Slot
40
+
41
+ Slot 组件用于将 props 传递给子组件,类似于 Radix UI 的 Slot 组件。
42
+
43
+ ```tsx
44
+ import { Slot } from 'tona-ui'
45
+
46
+ // 基础用法
47
+ <Slot className="custom-class">
48
+ <button>按钮</button>
49
+ </Slot>
50
+
51
+ // 事件处理
52
+ <Slot onClick={() => console.log('clicked')}>
53
+ <div>可点击的 div</div>
54
+ </Slot>
55
+ ```
56
+
57
+ ### cn
58
+
59
+ 工具函数,用于合并 CSS 类名。
60
+
61
+ ```tsx
62
+ import { cn } from 'tona-ui'
63
+
64
+ const className = cn('base-class', 'conditional-class', {
65
+ 'active-class': isActive
66
+ })
67
+ ```
68
+
69
+ ## 开发
70
+
71
+ ```bash
72
+ # 开发模式
73
+ pnpm dev
74
+
75
+ # 构建
76
+ pnpm build
77
+ ```
78
+
79
+ ## 许可证
80
+
81
+ MIT
@@ -0,0 +1,27 @@
1
+ import * as preact_compat0 from "preact/compat";
2
+ import * as preact0 from "preact";
3
+ import { ComponentChildren, Ref } from "preact";
4
+
5
+ //#region src/components/slot.d.ts
6
+ /**
7
+ * Slot 组件用于将 props 传递给子组件,类似于 Radix UI 的 Slot 组件
8
+ * 它允许父组件将 props 传递给子组件,而子组件可以决定如何处理这些 props
9
+ */
10
+ interface SlotProps {
11
+ children?: ComponentChildren;
12
+ className?: string;
13
+ style?: any;
14
+ onClick?: (event: Event) => void;
15
+ [key: string]: any;
16
+ }
17
+ /**
18
+ * Slot 组件实现
19
+ * 当作为子组件时,会将父组件的 props 合并到子组件上
20
+ * 当作为普通元素时,会渲染为 div 元素
21
+ */
22
+ declare const Slot: preact0.FunctionalComponent<preact_compat0.PropsWithoutRef<SlotProps> & {
23
+ ref?: Ref<HTMLElement> | undefined;
24
+ }>;
25
+ //#endregion
26
+ export { Slot, type SlotProps };
27
+ //# sourceMappingURL=index.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/components/slot.tsx"],"sourcesContent":[],"mappings":";;;;;;;;;AAOiB,UAAA,SAAA,CACJ;EAYA,QAoBZ,CAAA,EAhCY,iBAgCZ;EApBgB,SAAA,CAAA,EAAA,MAAA;EAAA,KAAA,CAAA,EAAA,GAAA;oBATG;;;;;;;;cASP,cAAI,oBAAA,cAAA,CAAA,gBAAA"}
package/dist/index.mjs ADDED
@@ -0,0 +1,61 @@
1
+ import { cloneElement, forwardRef, isValidElement } from "preact/compat";
2
+ import { jsx } from "preact/jsx-runtime";
3
+
4
+ //#region src/components/slot.tsx
5
+ /**
6
+ * Slot 组件实现
7
+ * 当作为子组件时,会将父组件的 props 合并到子组件上
8
+ * 当作为普通元素时,会渲染为 div 元素
9
+ */
10
+ const Slot = forwardRef(({ children, ...props }, forwardedRef) => {
11
+ if (isValidElement(children)) return cloneElement(children, {
12
+ ...mergeProps(props, children.props),
13
+ ref: forwardedRef ? composeRefs(forwardedRef, children.ref) : children.ref
14
+ });
15
+ return /* @__PURE__ */ jsx("div", {
16
+ ...props,
17
+ ref: forwardedRef,
18
+ children
19
+ });
20
+ });
21
+ Slot.displayName = "Slot";
22
+ /**
23
+ * 合并 props,子组件的 props 优先级更高
24
+ */
25
+ function mergeProps(parentProps, childProps) {
26
+ const overrideProps = { ...childProps };
27
+ for (const propName in childProps) {
28
+ const parentPropValue = parentProps[propName];
29
+ const childPropValue = childProps[propName];
30
+ if (/^on[A-Z]/.test(propName)) {
31
+ if (childPropValue && parentPropValue) overrideProps[propName] = (...args) => {
32
+ childPropValue(...args);
33
+ parentPropValue(...args);
34
+ };
35
+ else if (parentPropValue) overrideProps[propName] = parentPropValue;
36
+ } else if (propName === "style") overrideProps[propName] = {
37
+ ...parentPropValue,
38
+ ...childPropValue
39
+ };
40
+ else if (propName === "className") overrideProps[propName] = [parentPropValue, childPropValue].filter(Boolean).join(" ");
41
+ }
42
+ return {
43
+ ...parentProps,
44
+ ...overrideProps
45
+ };
46
+ }
47
+ /**
48
+ * 组合多个 ref
49
+ */
50
+ function composeRefs(...refs) {
51
+ return (node) => {
52
+ refs.forEach((ref) => {
53
+ if (typeof ref === "function") ref(node);
54
+ else if (ref != null) ref.current = node;
55
+ });
56
+ };
57
+ }
58
+
59
+ //#endregion
60
+ export { Slot };
61
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../src/components/slot.tsx"],"sourcesContent":["import type { ComponentChildren, Ref } from 'preact'\nimport { cloneElement, forwardRef, isValidElement } from 'preact/compat'\n\n/**\n * Slot 组件用于将 props 传递给子组件,类似于 Radix UI 的 Slot 组件\n * 它允许父组件将 props 传递给子组件,而子组件可以决定如何处理这些 props\n */\nexport interface SlotProps {\n children?: ComponentChildren\n className?: string\n style?: any\n onClick?: (event: Event) => void\n [key: string]: any\n}\n\n/**\n * Slot 组件实现\n * 当作为子组件时,会将父组件的 props 合并到子组件上\n * 当作为普通元素时,会渲染为 div 元素\n */\nexport const Slot = forwardRef<HTMLElement, SlotProps>(\n ({ children, ...props }, forwardedRef) => {\n if (isValidElement(children)) {\n return cloneElement(\n children as any,\n {\n ...mergeProps(props, (children as any).props),\n ref: forwardedRef\n ? composeRefs(forwardedRef, (children as any).ref)\n : (children as any).ref,\n } as any,\n )\n }\n\n return (\n <div {...props} ref={forwardedRef as Ref<HTMLDivElement>}>\n {children}\n </div>\n )\n },\n)\n\nSlot.displayName = 'Slot'\n\n/**\n * 合并 props,子组件的 props 优先级更高\n */\nfunction mergeProps(parentProps: any, childProps: any) {\n const overrideProps = { ...childProps }\n\n for (const propName in childProps) {\n const parentPropValue = parentProps[propName]\n const childPropValue = childProps[propName]\n\n const isHandler = /^on[A-Z]/.test(propName)\n if (isHandler) {\n // 对于事件处理器,需要同时调用父组件和子组件的处理器\n if (childPropValue && parentPropValue) {\n overrideProps[propName] = (...args: any[]) => {\n childPropValue(...args)\n parentPropValue(...args)\n }\n } else if (parentPropValue) {\n overrideProps[propName] = parentPropValue\n }\n } else if (propName === 'style') {\n // 对于 style,需要合并对象\n overrideProps[propName] = { ...parentPropValue, ...childPropValue }\n } else if (propName === 'className') {\n // 对于 className,需要合并字符串\n overrideProps[propName] = [parentPropValue, childPropValue]\n .filter(Boolean)\n .join(' ')\n }\n }\n\n return { ...parentProps, ...overrideProps }\n}\n\n/**\n * 组合多个 ref\n */\nfunction composeRefs<T>(...refs: (Ref<T> | undefined)[]): Ref<T> {\n return (node: T | null) => {\n refs.forEach((ref) => {\n if (typeof ref === 'function') {\n ref(node)\n } else if (ref != null) {\n ; (ref as any).current = node\n }\n })\n }\n}\n"],"mappings":";;;;;;;;;AAoBA,MAAa,OAAO,YACjB,EAAE,UAAU,GAAG,SAAS,iBAAiB;AACxC,KAAI,eAAe,SAAS,CAC1B,QAAO,aACL,UACA;EACE,GAAG,WAAW,OAAQ,SAAiB,MAAM;EAC7C,KAAK,eACD,YAAY,cAAe,SAAiB,IAAI,GAC/C,SAAiB;EACvB,CACF;AAGH,QACE,oBAAC;EAAI,GAAI;EAAO,KAAK;EAClB;GACG;EAGX;AAED,KAAK,cAAc;;;;AAKnB,SAAS,WAAW,aAAkB,YAAiB;CACrD,MAAM,gBAAgB,EAAE,GAAG,YAAY;AAEvC,MAAK,MAAM,YAAY,YAAY;EACjC,MAAM,kBAAkB,YAAY;EACpC,MAAM,iBAAiB,WAAW;AAGlC,MADkB,WAAW,KAAK,SAAS,EAGzC;OAAI,kBAAkB,gBACpB,eAAc,aAAa,GAAG,SAAgB;AAC5C,mBAAe,GAAG,KAAK;AACvB,oBAAgB,GAAG,KAAK;;YAEjB,gBACT,eAAc,YAAY;aAEnB,aAAa,QAEtB,eAAc,YAAY;GAAE,GAAG;GAAiB,GAAG;GAAgB;WAC1D,aAAa,YAEtB,eAAc,YAAY,CAAC,iBAAiB,eAAe,CACxD,OAAO,QAAQ,CACf,KAAK,IAAI;;AAIhB,QAAO;EAAE,GAAG;EAAa,GAAG;EAAe;;;;;AAM7C,SAAS,YAAe,GAAG,MAAsC;AAC/D,SAAQ,SAAmB;AACzB,OAAK,SAAS,QAAQ;AACpB,OAAI,OAAO,QAAQ,WACjB,KAAI,KAAK;YACA,OAAO,KACd,CAAC,IAAY,UAAU;IAE3B"}
package/package.json ADDED
@@ -0,0 +1,58 @@
1
+ {
2
+ "name": "tona-ui",
3
+ "version": "1.0.1",
4
+ "description": "UI components for Tona",
5
+ "author": {
6
+ "name": "guangzan",
7
+ "url": "https://www.cnblogs.com/guangzan",
8
+ "email": "guangzan1999@outlook.com"
9
+ },
10
+ "license": "MIT",
11
+ "homepage": "https://github.com/guangzan",
12
+ "repository": {
13
+ "type": "git",
14
+ "url": "git+https://github.com/guangzan/tona.git"
15
+ },
16
+ "bugs": {
17
+ "url": "https://github.com/guangzan/tona/issues"
18
+ },
19
+ "keywords": [
20
+ "ui",
21
+ "components",
22
+ "react",
23
+ "博客园"
24
+ ],
25
+ "sideEffects": false,
26
+ "exports": {
27
+ ".": {
28
+ "types": "./dist/index.d.ts",
29
+ "import": "./dist/index.mjs"
30
+ }
31
+ },
32
+ "main": "./dist/index.mjs",
33
+ "module": "./dist/index.mjs",
34
+ "types": "./dist/index.d.ts",
35
+ "typesVersions": {
36
+ "*": {
37
+ "*": [
38
+ "./dist/*",
39
+ "./dist/index.d.ts"
40
+ ]
41
+ }
42
+ },
43
+ "files": [
44
+ "dist"
45
+ ],
46
+ "devDependencies": {
47
+ "@types/node": "^25.0.3",
48
+ "tsdown": "latest",
49
+ "vitest": "^4.0.16"
50
+ },
51
+ "peerDependencies": {
52
+ "preact": ">=10.0.0"
53
+ },
54
+ "scripts": {
55
+ "dev": "tsdown --watch",
56
+ "build": "tsdown"
57
+ }
58
+ }