@taicode/common-web 1.0.5 → 1.1.0

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.
Files changed (71) hide show
  1. package/output/helpers/service/index.d.ts +1 -0
  2. package/output/helpers/service/index.d.ts.map +1 -0
  3. package/output/helpers/service/index.js +1 -0
  4. package/output/helpers/service/service.d.ts +5 -0
  5. package/output/helpers/service/service.d.ts.map +1 -0
  6. package/output/helpers/service/service.js +2 -0
  7. package/output/helpers/side-cache/index.d.ts +2 -0
  8. package/output/helpers/side-cache/index.d.ts.map +1 -0
  9. package/output/helpers/side-cache/index.js +1 -0
  10. package/{source/utils/cache/aside.d.ts → output/helpers/side-cache/side-cache.d.ts} +2 -2
  11. package/output/helpers/side-cache/side-cache.d.ts.map +1 -0
  12. package/output/{utils/cache/aside.js → helpers/side-cache/side-cache.js} +12 -12
  13. package/output/helpers/side-cache/side-cache.test.d.ts +2 -0
  14. package/output/helpers/side-cache/side-cache.test.d.ts.map +1 -0
  15. package/output/helpers/side-cache/side-cache.test.js +89 -0
  16. package/output/helpers/use-observer/index.d.ts +2 -0
  17. package/output/helpers/use-observer/index.d.ts.map +1 -0
  18. package/output/helpers/use-observer/index.js +1 -0
  19. package/output/{hooks/mobx.d.ts → helpers/use-observer/use-observer.d.ts} +1 -1
  20. package/output/helpers/use-observer/use-observer.d.ts.map +1 -0
  21. package/output/helpers/use-observer/use-observer.test.d.ts +2 -0
  22. package/output/helpers/use-observer/use-observer.test.d.ts.map +1 -0
  23. package/output/helpers/use-observer/use-observer.test.jsx +134 -0
  24. package/package.json +23 -16
  25. package/output/hooks/mobx.d.ts.map +0 -1
  26. package/output/utils/cache/aside.d.ts +0 -7
  27. package/output/utils/cache/aside.d.ts.map +0 -1
  28. package/output/utils/cache/index.d.ts +0 -2
  29. package/output/utils/cache/index.d.ts.map +0 -1
  30. package/output/utils/cache/index.js +0 -1
  31. package/source/catalyst/CHANGELOG.md +0 -136
  32. package/source/catalyst/README.md +0 -65
  33. package/source/catalyst/alert.tsx +0 -95
  34. package/source/catalyst/auth-layout.tsx +0 -11
  35. package/source/catalyst/avatar.tsx +0 -84
  36. package/source/catalyst/badge.tsx +0 -82
  37. package/source/catalyst/button.tsx +0 -204
  38. package/source/catalyst/checkbox.tsx +0 -157
  39. package/source/catalyst/combobox.tsx +0 -188
  40. package/source/catalyst/description-list.tsx +0 -37
  41. package/source/catalyst/dialog.tsx +0 -86
  42. package/source/catalyst/divider.tsx +0 -20
  43. package/source/catalyst/dropdown.tsx +0 -183
  44. package/source/catalyst/fieldset.tsx +0 -91
  45. package/source/catalyst/heading.tsx +0 -27
  46. package/source/catalyst/input.tsx +0 -94
  47. package/source/catalyst/link.tsx +0 -21
  48. package/source/catalyst/listbox.tsx +0 -177
  49. package/source/catalyst/navbar.tsx +0 -96
  50. package/source/catalyst/pagination.tsx +0 -98
  51. package/source/catalyst/radio.tsx +0 -142
  52. package/source/catalyst/select.tsx +0 -68
  53. package/source/catalyst/sidebar-layout.tsx +0 -82
  54. package/source/catalyst/sidebar.tsx +0 -142
  55. package/source/catalyst/stacked-layout.tsx +0 -79
  56. package/source/catalyst/switch.tsx +0 -195
  57. package/source/catalyst/table.tsx +0 -124
  58. package/source/catalyst/text.tsx +0 -40
  59. package/source/catalyst/textarea.tsx +0 -54
  60. package/source/hooks/mobx.d.ts +0 -3
  61. package/source/hooks/mobx.d.ts.map +0 -1
  62. package/source/hooks/mobx.js +0 -16
  63. package/source/hooks/mobx.ts +0 -24
  64. package/source/utils/cache/aside.d.ts.map +0 -1
  65. package/source/utils/cache/aside.js +0 -106
  66. package/source/utils/cache/aside.ts +0 -39
  67. package/source/utils/cache/index.d.ts +0 -2
  68. package/source/utils/cache/index.d.ts.map +0 -1
  69. package/source/utils/cache/index.js +0 -1
  70. package/source/utils/cache/index.ts +0 -1
  71. /package/output/{hooks/mobx.js → helpers/use-observer/use-observer.js} +0 -0
@@ -0,0 +1 @@
1
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../source/helpers/service/index.ts"],"names":[],"mappings":""}
@@ -0,0 +1 @@
1
+ "use strict";
@@ -0,0 +1,5 @@
1
+ export declare abstract class Service {
2
+ abstract inited: boolean;
3
+ abstract init(): Promise<boolean>;
4
+ }
5
+ //# sourceMappingURL=service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../../source/helpers/service/service.ts"],"names":[],"mappings":"AAAA,8BAAsB,OAAO;IAC3B,SAAgB,MAAM,EAAE,OAAO,CAAA;aACf,IAAI,IAAI,OAAO,CAAC,OAAO,CAAC;CACzC"}
@@ -0,0 +1,2 @@
1
+ export class Service {
2
+ }
@@ -0,0 +1,2 @@
1
+ export { SideCache } from './side-cache';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../source/helpers/side-cache/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA"}
@@ -0,0 +1 @@
1
+ export { SideCache } from './side-cache';
@@ -1,7 +1,7 @@
1
- export declare class AsideCache<T> {
1
+ export declare class SideCache<T> {
2
2
  private accessor currentKey;
3
3
  private accessor cache;
4
4
  get value(): T | null;
5
5
  handle<F extends ((...args: unknown[]) => Promise<T | null>)>(key: unknown, func: F): Promise<T | null>;
6
6
  }
7
- //# sourceMappingURL=aside.d.ts.map
7
+ //# sourceMappingURL=side-cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"side-cache.d.ts","sourceRoot":"","sources":["../../../source/helpers/side-cache/side-cache.ts"],"names":[],"mappings":"AAOA,qBAAa,SAAS,CAAC,CAAC;IAEtB,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAsB;IAGjD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAoC;IAE1D,IACW,KAAK,IAAI,CAAC,GAAG,IAAI,CAG3B;IAGY,MAAM,CAAC,CAAC,SAAS,CAAC,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;CAiBrH"}
@@ -44,8 +44,8 @@ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (
44
44
  return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
45
45
  };
46
46
  import { action, computed, observable, runInAction } from 'mobx';
47
- let AsideCache = (() => {
48
- var _a, _AsideCache_currentKey_accessor_storage, _AsideCache_cache_accessor_storage;
47
+ let SideCache = (() => {
48
+ var _a, _SideCache_currentKey_accessor_storage, _SideCache_cache_accessor_storage;
49
49
  var _b, _c;
50
50
  let _instanceExtraInitializers = [];
51
51
  let _currentKey_decorators;
@@ -56,11 +56,11 @@ let AsideCache = (() => {
56
56
  let _cache_extraInitializers = [];
57
57
  let _get_value_decorators;
58
58
  let _handle_decorators;
59
- return _a = class AsideCache {
60
- get currentKey() { return __classPrivateFieldGet(this, _AsideCache_currentKey_accessor_storage, "f"); }
61
- set currentKey(value) { __classPrivateFieldSet(this, _AsideCache_currentKey_accessor_storage, value, "f"); }
62
- get cache() { return __classPrivateFieldGet(this, _AsideCache_cache_accessor_storage, "f"); }
63
- set cache(value) { __classPrivateFieldSet(this, _AsideCache_cache_accessor_storage, value, "f"); }
59
+ return _a = class SideCache {
60
+ get currentKey() { return __classPrivateFieldGet(this, _SideCache_currentKey_accessor_storage, "f"); }
61
+ set currentKey(value) { __classPrivateFieldSet(this, _SideCache_currentKey_accessor_storage, value, "f"); }
62
+ get cache() { return __classPrivateFieldGet(this, _SideCache_cache_accessor_storage, "f"); }
63
+ set cache(value) { __classPrivateFieldSet(this, _SideCache_cache_accessor_storage, value, "f"); }
64
64
  get value() {
65
65
  var _b;
66
66
  if (this.currentKey == null)
@@ -82,13 +82,13 @@ let AsideCache = (() => {
82
82
  return funcReturn;
83
83
  }
84
84
  constructor() {
85
- _AsideCache_currentKey_accessor_storage.set(this, (__runInitializers(this, _instanceExtraInitializers), __runInitializers(this, _currentKey_initializers, null)));
86
- _AsideCache_cache_accessor_storage.set(this, (__runInitializers(this, _currentKey_extraInitializers), __runInitializers(this, _cache_initializers, {})));
85
+ _SideCache_currentKey_accessor_storage.set(this, (__runInitializers(this, _instanceExtraInitializers), __runInitializers(this, _currentKey_initializers, null)));
86
+ _SideCache_cache_accessor_storage.set(this, (__runInitializers(this, _currentKey_extraInitializers), __runInitializers(this, _cache_initializers, {})));
87
87
  __runInitializers(this, _cache_extraInitializers);
88
88
  }
89
89
  },
90
- _AsideCache_currentKey_accessor_storage = new WeakMap(),
91
- _AsideCache_cache_accessor_storage = new WeakMap(),
90
+ _SideCache_currentKey_accessor_storage = new WeakMap(),
91
+ _SideCache_cache_accessor_storage = new WeakMap(),
92
92
  (() => {
93
93
  const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
94
94
  _currentKey_decorators = [observable];
@@ -103,4 +103,4 @@ let AsideCache = (() => {
103
103
  })(),
104
104
  _a;
105
105
  })();
106
- export { AsideCache };
106
+ export { SideCache };
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=side-cache.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"side-cache.test.d.ts","sourceRoot":"","sources":["../../../source/helpers/side-cache/side-cache.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,89 @@
1
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
2
+ import { SideCache } from './side-cache';
3
+ describe('SideCache', () => {
4
+ let sideCache;
5
+ beforeEach(() => {
6
+ sideCache = new SideCache();
7
+ });
8
+ it('应该创建一个新的SideCache实例', () => {
9
+ expect(sideCache).toBeInstanceOf(SideCache);
10
+ expect(sideCache.value).toBeNull();
11
+ });
12
+ it('应该处理异步函数并缓存结果', async () => {
13
+ const mockFunc = vi.fn().mockResolvedValue('测试数据');
14
+ const key = { id: 1, name: '测试键' };
15
+ const result = await sideCache.handle(key, mockFunc);
16
+ expect(result).toBe('测试数据');
17
+ expect(sideCache.value).toBe('测试数据');
18
+ expect(mockFunc).toHaveBeenCalledTimes(1);
19
+ });
20
+ it('应该为不同的键缓存不同的值', async () => {
21
+ const mockFunc1 = vi.fn().mockResolvedValue('数据1');
22
+ const mockFunc2 = vi.fn().mockResolvedValue('数据2');
23
+ const key1 = { id: 1 };
24
+ const key2 = { id: 2 };
25
+ await sideCache.handle(key1, mockFunc1);
26
+ expect(sideCache.value).toBe('数据1');
27
+ await sideCache.handle(key2, mockFunc2);
28
+ expect(sideCache.value).toBe('数据2');
29
+ });
30
+ it('应该在函数返回null时不缓存结果', async () => {
31
+ const mockFunc = vi.fn().mockResolvedValue(null);
32
+ const key = { id: 1 };
33
+ const result = await sideCache.handle(key, mockFunc);
34
+ expect(result).toBeNull();
35
+ expect(sideCache.value).toBeNull();
36
+ });
37
+ it('应该正确处理相同键的多次调用', async () => {
38
+ const mockFunc = vi.fn().mockResolvedValue('缓存数据');
39
+ const key = { id: 1, name: '相同键' };
40
+ // 第一次调用
41
+ await sideCache.handle(key, mockFunc);
42
+ expect(sideCache.value).toBe('缓存数据');
43
+ // 第二次调用相同键
44
+ const mockFunc2 = vi.fn().mockResolvedValue('新数据');
45
+ await sideCache.handle(key, mockFunc2);
46
+ expect(sideCache.value).toBe('新数据');
47
+ // 验证两个函数都被调用了
48
+ expect(mockFunc).toHaveBeenCalledTimes(1);
49
+ expect(mockFunc2).toHaveBeenCalledTimes(1);
50
+ });
51
+ it('应该正确序列化复杂的键对象', async () => {
52
+ const mockFunc = vi.fn().mockResolvedValue('复杂键数据');
53
+ const complexKey = {
54
+ nested: {
55
+ array: [1, 2, 3],
56
+ string: '测试',
57
+ boolean: true
58
+ }
59
+ };
60
+ await sideCache.handle(complexKey, mockFunc);
61
+ expect(sideCache.value).toBe('复杂键数据');
62
+ });
63
+ it('应该处理异步函数抛出的错误', async () => {
64
+ const mockFunc = vi.fn().mockRejectedValue(new Error('测试错误'));
65
+ const key = { id: 1 };
66
+ await expect(() => sideCache.handle(key, mockFunc)).rejects.toThrow('测试错误');
67
+ expect(sideCache.value).toBeNull();
68
+ });
69
+ it('应该在没有设置当前键时返回null', () => {
70
+ expect(sideCache.value).toBeNull();
71
+ });
72
+ it('应该处理数字类型的缓存数据', async () => {
73
+ const numberCache = new SideCache();
74
+ const mockFunc = vi.fn().mockResolvedValue(42);
75
+ const key = 'number-key';
76
+ const result = await numberCache.handle(key, mockFunc);
77
+ expect(result).toBe(42);
78
+ expect(numberCache.value).toBe(42);
79
+ });
80
+ it('应该处理对象类型的缓存数据', async () => {
81
+ const objectCache = new SideCache();
82
+ const testData = { id: 1, name: '测试对象' };
83
+ const mockFunc = vi.fn().mockResolvedValue(testData);
84
+ const key = 'object-key';
85
+ const result = await objectCache.handle(key, mockFunc);
86
+ expect(result).toEqual(testData);
87
+ expect(objectCache.value).toEqual(testData);
88
+ });
89
+ });
@@ -0,0 +1,2 @@
1
+ export { useObserver } from './use-observer';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../source/helpers/use-observer/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA"}
@@ -0,0 +1 @@
1
+ export { useObserver } from './use-observer';
@@ -1,3 +1,3 @@
1
1
  export declare function useObserver<T>(initialValue: T): T;
2
2
  export declare function useObserver<T, U>(initialValue: T, selector: (v: T) => U): U;
3
- //# sourceMappingURL=mobx.d.ts.map
3
+ //# sourceMappingURL=use-observer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-observer.d.ts","sourceRoot":"","sources":["../../../source/helpers/use-observer/use-observer.ts"],"names":[],"mappings":"AAGA,wBAAgB,WAAW,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,GAAG,CAAC,CAAA;AAClD,wBAAgB,WAAW,CAAC,CAAC,EAAE,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=use-observer.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-observer.test.d.ts","sourceRoot":"","sources":["../../../source/helpers/use-observer/use-observer.test.tsx"],"names":[],"mappings":""}
@@ -0,0 +1,134 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { renderHook, act } from '@testing-library/react';
3
+ import { observable, action } from 'mobx';
4
+ import { useObserver } from './use-observer';
5
+ describe('useObserver', () => {
6
+ it('应该返回初始值当没有selector时', () => {
7
+ const initialValue = '初始值';
8
+ const { result } = renderHook(() => useObserver(initialValue));
9
+ expect(result.current).toBe(initialValue);
10
+ });
11
+ it('应该使用selector转换值', () => {
12
+ const initialValue = { count: 5 };
13
+ const selector = (value) => value.count * 2;
14
+ const { result } = renderHook(() => useObserver(initialValue, selector));
15
+ expect(result.current).toBe(10);
16
+ });
17
+ it('应该在观察对象变化时重新渲染', async () => {
18
+ const observableStore = observable({
19
+ count: 0,
20
+ increment: action(() => {
21
+ observableStore.count++;
22
+ })
23
+ });
24
+ const { result } = renderHook(() => useObserver(observableStore, (store) => store.count));
25
+ expect(result.current).toBe(0);
26
+ // 改变observable的值
27
+ act(() => {
28
+ observableStore.increment();
29
+ });
30
+ // 等待React更新
31
+ await new Promise(resolve => setTimeout(resolve, 0));
32
+ expect(result.current).toBe(1);
33
+ });
34
+ it('应该处理复杂的selector函数', () => {
35
+ const store = observable({
36
+ users: [
37
+ { id: 1, name: '张三', active: true },
38
+ { id: 2, name: '李四', active: false },
39
+ { id: 3, name: '王五', active: true }
40
+ ]
41
+ });
42
+ const selector = (store) => store.users.filter((user) => user.active).map((user) => user.name);
43
+ const { result } = renderHook(() => useObserver(store, selector));
44
+ expect(result.current).toEqual(['张三', '王五']);
45
+ });
46
+ it('应该在observable数组变化时重新渲染', async () => {
47
+ const store = observable({
48
+ items: ['项目1', '项目2'],
49
+ addItem: action((item) => {
50
+ store.items.push(item);
51
+ })
52
+ });
53
+ const { result } = renderHook(() => useObserver(store, (store) => store.items.length));
54
+ expect(result.current).toBe(2);
55
+ act(() => {
56
+ store.addItem('项目3');
57
+ });
58
+ await new Promise(resolve => setTimeout(resolve, 0));
59
+ expect(result.current).toBe(3);
60
+ });
61
+ it('应该处理null值的初始值', () => {
62
+ const { result } = renderHook(() => useObserver(null));
63
+ expect(result.current).toBeNull();
64
+ });
65
+ it('应该处理undefined值的初始值', () => {
66
+ const { result } = renderHook(() => useObserver(undefined));
67
+ expect(result.current).toBeUndefined();
68
+ });
69
+ it('应该在selector为null时返回原值', () => {
70
+ const initialValue = { data: '测试数据' };
71
+ const { result } = renderHook(() => useObserver(initialValue, null));
72
+ expect(result.current).toBe(initialValue);
73
+ });
74
+ it('应该处理嵌套observable对象', async () => {
75
+ const store = observable({
76
+ user: {
77
+ profile: {
78
+ name: '测试用户',
79
+ email: 'test@example.com'
80
+ }
81
+ },
82
+ updateName: action((name) => {
83
+ store.user.profile.name = name;
84
+ })
85
+ });
86
+ const { result } = renderHook(() => useObserver(store, (store) => store.user.profile.name));
87
+ expect(result.current).toBe('测试用户');
88
+ act(() => {
89
+ store.updateName('新用户名');
90
+ });
91
+ await new Promise(resolve => setTimeout(resolve, 0));
92
+ expect(result.current).toBe('新用户名');
93
+ });
94
+ it('应该处理多个observable属性的变化', async () => {
95
+ const store = observable({
96
+ firstName: '张',
97
+ lastName: '三',
98
+ updateFirstName: action((name) => {
99
+ store.firstName = name;
100
+ }),
101
+ updateLastName: action((name) => {
102
+ store.lastName = name;
103
+ })
104
+ });
105
+ const { result } = renderHook(() => useObserver(store, (store) => `${store.firstName}${store.lastName}`));
106
+ expect(result.current).toBe('张三');
107
+ act(() => {
108
+ store.updateFirstName('李');
109
+ });
110
+ await new Promise(resolve => setTimeout(resolve, 0));
111
+ expect(result.current).toBe('李三');
112
+ act(() => {
113
+ store.updateLastName('四');
114
+ });
115
+ await new Promise(resolve => setTimeout(resolve, 0));
116
+ expect(result.current).toBe('李四');
117
+ });
118
+ it('应该在组件卸载时清理reaction', () => {
119
+ const store = observable({ count: 0 });
120
+ const { unmount } = renderHook(() => useObserver(store, (store) => store.count));
121
+ // 卸载组件应该不会抛出错误
122
+ expect(() => unmount()).not.toThrow();
123
+ });
124
+ it('应该处理boolean类型的返回值', () => {
125
+ const store = observable({ isActive: true });
126
+ const { result } = renderHook(() => useObserver(store, (store) => store.isActive));
127
+ expect(result.current).toBe(true);
128
+ });
129
+ it('应该处理数字类型的返回值', () => {
130
+ const store = observable({ count: 42 });
131
+ const { result } = renderHook(() => useObserver(store, (store) => store.count));
132
+ expect(result.current).toBe(42);
133
+ });
134
+ });
package/package.json CHANGED
@@ -1,36 +1,43 @@
1
1
  {
2
2
  "name": "@taicode/common-web",
3
- "version": "1.0.5",
3
+ "version": "1.1.0",
4
4
  "author": "Alain",
5
5
  "license": "ISC",
6
6
  "description": "",
7
+ "exports": {
8
+ "./*": {
9
+ "types": "./output/*/index.d.ts",
10
+ "import": "./output/*/index.js",
11
+ "require": "./output/*/index.js"
12
+ }
13
+ },
14
+ "files": [
15
+ "output"
16
+ ],
7
17
  "scripts": {
18
+ "test": "vitest",
19
+ "test:ui": "vitest --ui",
20
+ "test:run": "vitest run",
8
21
  "build": "tsc -p tsconfig.json",
9
22
  "dev": "tsc -p tsconfig.json --watch"
10
23
  },
11
24
  "peerDependencies": {
25
+ "@taicode/common-base": ">=1.1.0",
26
+ "@needle-di/core": ">=1.0.0",
12
27
  "@types/react": ">=18",
13
28
  "mobx": ">=6",
14
29
  "react": ">=18"
15
30
  },
16
- "files": [
17
- "output",
18
- "source"
19
- ],
20
- "exports": {
21
- "./utils/*": [
22
- "./output/utils/*"
23
- ],
24
- "./hooks/*": [
25
- "./output/hooks/*"
26
- ],
27
- "./catalyst/*": [
28
- "./output/catalyst/*"
29
- ]
30
- },
31
31
  "dependencies": {
32
32
  "@headlessui/react": "^2.2.4",
33
33
  "framer-motion": "^12.19.2",
34
34
  "clsx": "^2.1.1"
35
+ },
36
+ "devDependencies": {
37
+ "@testing-library/react": "^14.0.0",
38
+ "@testing-library/jest-dom": "^6.1.0",
39
+ "jsdom": "^23.0.0",
40
+ "vitest": "^1.0.0",
41
+ "@vitest/ui": "^1.0.0"
35
42
  }
36
43
  }
@@ -1 +0,0 @@
1
- {"version":3,"file":"mobx.d.ts","sourceRoot":"","sources":["../../source/hooks/mobx.ts"],"names":[],"mappings":"AAGA,wBAAgB,WAAW,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,GAAG,CAAC,CAAA;AAClD,wBAAgB,WAAW,CAAC,CAAC,EAAE,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA"}
@@ -1,7 +0,0 @@
1
- export declare class AsideCache<T> {
2
- private accessor currentKey;
3
- private accessor cache;
4
- get value(): T | null;
5
- handle<F extends ((...args: unknown[]) => Promise<T | null>)>(key: unknown, func: F): Promise<T | null>;
6
- }
7
- //# sourceMappingURL=aside.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"aside.d.ts","sourceRoot":"","sources":["../../../source/utils/cache/aside.ts"],"names":[],"mappings":"AAOA,qBAAa,UAAU,CAAC,CAAC;IAEvB,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAsB;IAGjD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAoC;IAE1D,IACW,KAAK,IAAI,CAAC,GAAG,IAAI,CAG3B;IAGY,MAAM,CAAC,CAAC,SAAS,CAAC,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;CAiBrH"}
@@ -1,2 +0,0 @@
1
- export { AsideCache } from './aside';
2
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../source/utils/cache/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA"}
@@ -1 +0,0 @@
1
- export { AsideCache } from './aside';
@@ -1,136 +0,0 @@
1
- # Changelog
2
-
3
- ## 2025-06-05
4
-
5
- - Update `DropdownLabel` to extend a plain `<div>` instead of the `Headless.Label` ([#1699](https://github.com/tailwindlabs/tailwind-plus-issues/issues/1699))
6
-
7
- ## 2025-04-28
8
-
9
- - Update template to Tailwind CSS v4.1.4
10
-
11
- ## 2025-04-22
12
-
13
- - Fix focus styles in the `Avatar`, `Badge`, `Button`, `Checkbox`, and `Switch` components ([#1693](https://github.com/tailwindlabs/tailwind-plus-issues/issues/1693))
14
-
15
- ## 2025-04-17
16
-
17
- - Update `@headlessui/react` dependency to `v2.2.2` to fix listbox performance issues ([#1667](https://github.com/tailwindlabs/tailwind-plus-issues/issues/1667))
18
-
19
- ## 2025-04-04
20
-
21
- - Add new `Combobox` component
22
- - Add new `AuthLayout` component, with example login page, registration page, and forgot password page
23
- - Fix centering of checkboxes, radios, and switches in fields with multi-line labels
24
- - Update template to Tailwind CSS v4.1.3
25
- - Update template to Headless UI v2.2.1 (required for new `Combobox` component)
26
-
27
- ## 2025-03-24
28
-
29
- - Adjust avatar ring opacity from 20% to 10%
30
-
31
- ## 2025-03-22
32
-
33
- - Update template to Tailwind CSS v4.0.15
34
-
35
- ## 2025-02-22
36
-
37
- - Fix border radius of avatars in navbar items
38
-
39
- ## 2025-02-12
40
-
41
- - Fix baseline alignment for buttons with icons ([#1668](https://github.com/tailwindlabs/tailwind-plus-issues/issues/1668))
42
-
43
- ## 2025-02-10
44
-
45
- - Update template to Tailwind CSS v4.0.6
46
-
47
- ## 2025-01-29
48
-
49
- - Fix conflicting outline utilities ([#1661](https://github.com/tailwindlabs/tailwind-plus-issues/issues/1661))
50
-
51
- ## 2025-01-23
52
-
53
- - Update template to Tailwind CSS v4.0
54
-
55
- ## 2024-10-31
56
-
57
- - Fix `disabled` prop in `DropdownItem` component ([#1640](https://github.com/tailwindlabs/tailwind-plus-issues/issues/1640))
58
- - Update types in `SidebarItem` component
59
-
60
- ## 2024-06-09
61
-
62
- - Omit `as` prop from types for Headless UI-based components
63
-
64
- ## 2024-06-26
65
-
66
- - Update `@headlessui/react` dependency to `v2.1.1`
67
- - Update `Dialog`, `Alert`, and `Listbox` to new data-attribute-based transition API
68
-
69
- ## 2024-06-21
70
-
71
- - Update `@headlessui/react` dependency to `v2.1.0`
72
- - Use `DialogBackdrop` in `Alert` and `Dialog` components
73
- - Update to new data-attribute-based transition API
74
-
75
- ## 2024-06-19
76
-
77
- - Prevent content from overflowing the mobile sidebar
78
-
79
- ## 2024-06-18
80
-
81
- - Use consistent `let` and `const` declarations
82
- - Use consistent `clsx` import
83
- - Use consistent `forwardRef` instead of `React.forwardRef` import
84
- - Update `tailwindcss`, `prettier` and `prettier-plugin-tailwindcss` dependencies in Next.js demo app
85
- - Fix class order in `Dropdown` component
86
-
87
- ## 2024-06-10
88
-
89
- - Add `dark:[color-scheme:dark]` class to `Input` component ([#1596](https://github.com/tailwindlabs/tailwind-plus-issues/issues/1596))
90
-
91
- ## 2024-05-31
92
-
93
- - Add Next.js demo app ([#1580](https://github.com/tailwindlabs/tailwind-plus-issues/issues/1580))
94
- - Fix `Avatar` sizing and padding ([#1588](https://github.com/tailwindlabs/tailwind-plus-issues/issues/1588))
95
-
96
- ## 2024-05-27
97
-
98
- - Add `pointer-events-none` to `InputGroup` icon ([#1594](https://github.com/tailwindlabs/tailwind-plus-issues/issues/1594))
99
- - Add default text color to `Table` component ([#1581](https://github.com/tailwindlabs/tailwind-plus-issues/issues/1581))
100
- - Fix TypeScript issues when using `as={Link}` ([#1582](https://github.com/tailwindlabs/tailwind-plus-issues/issues/1582))
101
- - Fix `SidebarItem` import ([#1582](https://github.com/tailwindlabs/tailwind-plus-issues/issues/1582))
102
- - Add `isolate` class to `InputGroup`, `SidebarLayout`, and `StackedLayout` components
103
- - Fix comment indentation and use proper DocBlocks
104
-
105
- ## 2024-05-24
106
-
107
- - Add new `SidebarLayout` component
108
- - Add new `StackedLayout` component
109
- - Add new `Navbar` component
110
- - Add new `Sidebar` component
111
- - Add new `DescriptionList` component
112
- - Add new `Heading` component
113
- - Add new `Divider` component
114
- - Add new `framer-motion` dependency
115
- - Update `@headlessui/react` dependency to `v2.0`
116
- - Remove `as={Fragment}` from the transition components
117
- - Improve and fix a number of types
118
- - Made formatting of `className` and `{...prop}` more consistent across all components
119
- - Made formatting of `forwardRef` consistent across all components
120
- - Update `PaginationGap` component to use a `span` instead of a `div`
121
- - Update the `SidebarHeading` to render use an `h3` instead of a `d`iv
122
- - Remove `children` prop from `Switch` component
123
-
124
- ## 2024-01-08
125
-
126
- - Add `resizable` prop to `Textarea` component ([#1543](https://github.com/tailwindlabs/tailwind-plus-issues/issues/1543))
127
-
128
- ## 2024-01-03
129
-
130
- - Change top-level `let` declarations to `const`
131
- - Fix `--btn-hover-overlay` color for dark/white button ([#1538](https://github.com/tailwindlabs/tailwind-plus-issues/issues/1538))
132
- - Add `forwardRef` to `Input`, `Select`, and `Textarea` components ([#1540](https://github.com/tailwindlabs/tailwind-plus-issues/issues/1540))
133
-
134
- ## 2023-12-20
135
-
136
- - Initial release
@@ -1,65 +0,0 @@
1
- # Catalyst UI Kit
2
-
3
- Catalyst is a modern application UI kit built with [Tailwind CSS](https://tailwindcss.com) and [React](https://react.dev/), designed and built by the Tailwind CSS team and included as part of [Tailwind Plus](https://tailwindcss.com/plus).
4
-
5
- ## Getting started
6
-
7
- To get started, first copy the component files included in the downloaded ZIP file into wherever you keep components in your own project. The components are provided in both TypeScript and plain JavaScript, pick whichever set you prefer.
8
-
9
- Next, install the dependencies used by the components in Catalyst:
10
-
11
- ```sh
12
- npm install @headlessui/react framer-motion clsx
13
- ```
14
-
15
- Catalyst is also designed for the latest version of Tailwind CSS, which is currently Tailwind CSS v4.0. To make sure that you are on the latest version of Tailwind, update it via npm:
16
-
17
- ```sh
18
- npm install tailwindcss@latest
19
- ```
20
-
21
- Now you're ready to start using the components in your project — just import them from wherever you're keeping your components and start using them like any of your other React components:
22
-
23
- ```jsx
24
- import { Input } from './components/input'
25
- import { Field, FieldGroup, Label } from './components/fieldset'
26
- import { Button } from './components/button'
27
-
28
- export default function SettingsForm() {
29
- return (
30
- <form>
31
- <FieldGroup>
32
- <Field>
33
- <Label>Name</Label>
34
- <Input name="name" />
35
- </Field>
36
- <Field>
37
- <Label>Email</Label>
38
- <Input type="email" name="email" />
39
- </Field>
40
- <Button type="submit">Save changes</Button>
41
- </FieldGroup>
42
- </form>
43
- )
44
- }
45
- ```
46
-
47
- Additional installation instructions can be found in the Catalyst documentation.
48
-
49
- ## Documentation
50
-
51
- You can find the Catalyst documentation at https://catalyst.tailwindui.com/docs.
52
-
53
- ## License
54
-
55
- This site template is a commercial product and is licensed under the [Tailwind Plus license](https://tailwindcss.com/plus/license).
56
-
57
- ## Learn more
58
-
59
- To learn more about the technologies used in this site template, see the following resources:
60
-
61
- - [Tailwind CSS](https://tailwindcss.com/docs) - the official Tailwind CSS documentation
62
- - [Headless UI](https://headlessui.dev) - the official Headless UI documentation
63
- - [React](https://react.dev) - the official React documentation
64
- - [Framer Motion](https://www.framer.com/docs/) - the official Framer Motion documentation
65
- - [clsx](https://github.com/lukeed/clsx) - the GitHub repo for the `clsx` helper