@14ch/svelte-ui 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.
Files changed (109) hide show
  1. package/README.md +359 -0
  2. package/dist/assets/styles/README.md +144 -0
  3. package/dist/assets/styles/core.scss +61 -0
  4. package/dist/assets/styles/import.scss +11 -0
  5. package/dist/assets/styles/optional/fonts.scss +23 -0
  6. package/dist/assets/styles/optional/reset.scss +230 -0
  7. package/dist/assets/styles/variables.scss +805 -0
  8. package/dist/components/Button.svelte +574 -0
  9. package/dist/components/Button.svelte.d.ts +56 -0
  10. package/dist/components/COMPONENT_DESIGN_GUIDELINES.md +127 -0
  11. package/dist/components/Checkbox.svelte +523 -0
  12. package/dist/components/Checkbox.svelte.d.ts +42 -0
  13. package/dist/components/CheckboxGroup.svelte +82 -0
  14. package/dist/components/CheckboxGroup.svelte.d.ts +13 -0
  15. package/dist/components/ColorPicker.svelte +496 -0
  16. package/dist/components/ColorPicker.svelte.d.ts +45 -0
  17. package/dist/components/Combobox.svelte +576 -0
  18. package/dist/components/Combobox.svelte.d.ts +52 -0
  19. package/dist/components/ConfirmDialog.svelte +116 -0
  20. package/dist/components/ConfirmDialog.svelte.d.ts +20 -0
  21. package/dist/components/Datepicker.svelte +578 -0
  22. package/dist/components/Datepicker.svelte.d.ts +72 -0
  23. package/dist/components/DatepickerCalendar.svelte +925 -0
  24. package/dist/components/DatepickerCalendar.svelte.d.ts +31 -0
  25. package/dist/components/Dialog.svelte +245 -0
  26. package/dist/components/Dialog.svelte.d.ts +38 -0
  27. package/dist/components/Drawer.svelte +383 -0
  28. package/dist/components/Drawer.svelte.d.ts +39 -0
  29. package/dist/components/Fab.svelte +486 -0
  30. package/dist/components/Fab.svelte.d.ts +51 -0
  31. package/dist/components/FileUploader.svelte +456 -0
  32. package/dist/components/FileUploader.svelte.d.ts +36 -0
  33. package/dist/components/Icon.svelte +167 -0
  34. package/dist/components/Icon.svelte.d.ts +21 -0
  35. package/dist/components/IconButton.svelte +557 -0
  36. package/dist/components/IconButton.svelte.d.ts +60 -0
  37. package/dist/components/ImageUploader.svelte +516 -0
  38. package/dist/components/ImageUploader.svelte.d.ts +37 -0
  39. package/dist/components/ImageUploaderPreview.svelte +157 -0
  40. package/dist/components/ImageUploaderPreview.svelte.d.ts +13 -0
  41. package/dist/components/Input.svelte +885 -0
  42. package/dist/components/Input.svelte.d.ts +75 -0
  43. package/dist/components/LoadingSpinner.svelte +116 -0
  44. package/dist/components/LoadingSpinner.svelte.d.ts +10 -0
  45. package/dist/components/Modal.svelte +313 -0
  46. package/dist/components/Modal.svelte.d.ts +34 -0
  47. package/dist/components/Pagination.svelte +276 -0
  48. package/dist/components/Pagination.svelte.d.ts +14 -0
  49. package/dist/components/Popup.svelte +676 -0
  50. package/dist/components/Popup.svelte.d.ts +40 -0
  51. package/dist/components/PopupMenu.svelte +421 -0
  52. package/dist/components/PopupMenu.svelte.d.ts +24 -0
  53. package/dist/components/PopupMenuButton.svelte +365 -0
  54. package/dist/components/PopupMenuButton.svelte.d.ts +42 -0
  55. package/dist/components/Radio.svelte +548 -0
  56. package/dist/components/Radio.svelte.d.ts +42 -0
  57. package/dist/components/RadioGroup.svelte +74 -0
  58. package/dist/components/RadioGroup.svelte.d.ts +14 -0
  59. package/dist/components/Select.svelte +479 -0
  60. package/dist/components/Select.svelte.d.ts +47 -0
  61. package/dist/components/Slider.svelte +473 -0
  62. package/dist/components/Slider.svelte.d.ts +46 -0
  63. package/dist/components/Snackbar.svelte +124 -0
  64. package/dist/components/Snackbar.svelte.d.ts +9 -0
  65. package/dist/components/SnackbarItem.svelte +423 -0
  66. package/dist/components/SnackbarItem.svelte.d.ts +21 -0
  67. package/dist/components/Switch.svelte +454 -0
  68. package/dist/components/Switch.svelte.d.ts +40 -0
  69. package/dist/components/Tab.svelte +193 -0
  70. package/dist/components/Tab.svelte.d.ts +14 -0
  71. package/dist/components/TabItem.svelte +140 -0
  72. package/dist/components/TabItem.svelte.d.ts +17 -0
  73. package/dist/components/Textarea.svelte +702 -0
  74. package/dist/components/Textarea.svelte.d.ts +64 -0
  75. package/dist/components/skeleton/Skeleton.svelte +235 -0
  76. package/dist/components/skeleton/Skeleton.svelte.d.ts +13 -0
  77. package/dist/components/skeleton/SkeletonAvatar.svelte +97 -0
  78. package/dist/components/skeleton/SkeletonAvatar.svelte.d.ts +8 -0
  79. package/dist/components/skeleton/SkeletonBox.svelte +105 -0
  80. package/dist/components/skeleton/SkeletonBox.svelte.d.ts +12 -0
  81. package/dist/components/skeleton/SkeletonButton.svelte +71 -0
  82. package/dist/components/skeleton/SkeletonButton.svelte.d.ts +8 -0
  83. package/dist/components/skeleton/SkeletonHeading.svelte +49 -0
  84. package/dist/components/skeleton/SkeletonHeading.svelte.d.ts +8 -0
  85. package/dist/components/skeleton/SkeletonMedia.svelte +115 -0
  86. package/dist/components/skeleton/SkeletonMedia.svelte.d.ts +9 -0
  87. package/dist/components/skeleton/SkeletonText.svelte +75 -0
  88. package/dist/components/skeleton/SkeletonText.svelte.d.ts +8 -0
  89. package/dist/index.d.ts +42 -0
  90. package/dist/index.js +43 -0
  91. package/dist/types/icon.d.ts +4 -0
  92. package/dist/types/icon.js +2 -0
  93. package/dist/types/menuItem.d.ts +8 -0
  94. package/dist/types/menuItem.js +1 -0
  95. package/dist/types/options.d.ts +6 -0
  96. package/dist/types/options.js +4 -0
  97. package/dist/types/skeleton.d.ts +77 -0
  98. package/dist/types/skeleton.js +19 -0
  99. package/dist/utils/accessibility.d.ts +48 -0
  100. package/dist/utils/accessibility.js +87 -0
  101. package/dist/utils/formatText.d.ts +4 -0
  102. package/dist/utils/formatText.js +44 -0
  103. package/dist/utils/mobile.d.ts +9 -0
  104. package/dist/utils/mobile.js +47 -0
  105. package/dist/utils/snackbar.svelte.d.ts +51 -0
  106. package/dist/utils/snackbar.svelte.js +107 -0
  107. package/dist/utils/style.d.ts +17 -0
  108. package/dist/utils/style.js +22 -0
  109. package/package.json +102 -0
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Mobile detection and utilities
3
+ */
4
+ // モバイルデバイス検出
5
+ export const isMobileDevice = () => {
6
+ if (typeof window === 'undefined')
7
+ return false;
8
+ // User agent based detection
9
+ const userAgent = window.navigator.userAgent.toLowerCase();
10
+ const mobileKeywords = ['mobile', 'android', 'iphone', 'ipad', 'tablet', 'touch'];
11
+ const isMobileUA = mobileKeywords.some((keyword) => userAgent.includes(keyword));
12
+ // Screen size based detection
13
+ const isSmallScreen = window.innerWidth <= 768;
14
+ // Touch capability detection
15
+ const hasTouchCapability = 'ontouchstart' in window || navigator.maxTouchPoints > 0;
16
+ return isMobileUA || (isSmallScreen && hasTouchCapability);
17
+ };
18
+ // ビューポートサイズの取得
19
+ export const getViewportSize = () => {
20
+ if (typeof window === 'undefined') {
21
+ return { width: 0, height: 0 };
22
+ }
23
+ return {
24
+ width: window.innerWidth,
25
+ height: window.innerHeight
26
+ };
27
+ };
28
+ // モバイルでのスクロール無効化
29
+ export const disableBodyScroll = () => {
30
+ if (typeof document === 'undefined')
31
+ return () => { };
32
+ const originalStyle = window.getComputedStyle(document.body);
33
+ const originalOverflow = originalStyle.overflow;
34
+ const originalPosition = originalStyle.position;
35
+ document.body.style.overflow = 'hidden';
36
+ if (isMobileDevice()) {
37
+ document.body.style.position = 'fixed';
38
+ document.body.style.width = '100%';
39
+ }
40
+ return () => {
41
+ document.body.style.overflow = originalOverflow;
42
+ document.body.style.position = originalPosition;
43
+ if (isMobileDevice()) {
44
+ document.body.style.width = '';
45
+ }
46
+ };
47
+ };
@@ -0,0 +1,51 @@
1
+ import type { Snippet } from 'svelte';
2
+ export type SnackbarItem = {
3
+ id: string;
4
+ message?: string;
5
+ children?: Snippet;
6
+ type: 'info' | 'success' | 'warning' | 'error' | 'default';
7
+ variant?: 'filled' | 'outlined';
8
+ color?: string;
9
+ textColor?: string;
10
+ duration?: number;
11
+ position?: 'top' | 'bottom';
12
+ closable?: boolean;
13
+ actionLabel?: string;
14
+ onAction?: () => void;
15
+ onClose?: () => void;
16
+ createdAt: number;
17
+ };
18
+ export type SnackbarConfig = {
19
+ maxVisible?: number;
20
+ defaultDuration?: number;
21
+ defaultVariant?: 'filled' | 'outlined';
22
+ defaultPosition?: 'top' | 'bottom';
23
+ };
24
+ declare class SnackbarManager {
25
+ private _items;
26
+ private queue;
27
+ private config;
28
+ constructor(config?: SnackbarConfig);
29
+ get items(): SnackbarItem[];
30
+ configure(config: SnackbarConfig): void;
31
+ setDefaultPosition(position: 'top' | 'bottom'): void;
32
+ setDefaults(config: {
33
+ position?: 'top' | 'bottom';
34
+ maxVisible?: number;
35
+ defaultDuration?: number;
36
+ defaultVariant?: 'filled' | 'outlined';
37
+ }): void;
38
+ private show;
39
+ success(message: string, options?: Partial<Omit<SnackbarItem, 'id' | 'type' | 'message' | 'createdAt'>>): string;
40
+ error(message: string, options?: Partial<Omit<SnackbarItem, 'id' | 'type' | 'message' | 'createdAt'>>): string;
41
+ warning(message: string, options?: Partial<Omit<SnackbarItem, 'id' | 'type' | 'message' | 'createdAt'>>): string;
42
+ info(message: string, options?: Partial<Omit<SnackbarItem, 'id' | 'type' | 'message' | 'createdAt'>>): string;
43
+ default(message: string, options?: Partial<Omit<SnackbarItem, 'id' | 'type' | 'message' | 'createdAt'>>): string;
44
+ custom(children: Snippet, type: SnackbarItem['type'], options?: Partial<Omit<SnackbarItem, 'id' | 'type' | 'children' | 'createdAt'>>): string;
45
+ remove(id: string): void;
46
+ clear(): void;
47
+ getItemsByPosition(position: 'top' | 'bottom'): SnackbarItem[];
48
+ }
49
+ export declare const snackbarManager: SnackbarManager;
50
+ export declare const snackbar: SnackbarManager;
51
+ export default snackbarManager;
@@ -0,0 +1,107 @@
1
+ // src/lib/utils/snackbar.ts
2
+ class SnackbarManager {
3
+ _items = $state([]);
4
+ queue = $state([]);
5
+ config = $state({
6
+ maxVisible: 5,
7
+ defaultDuration: 3000,
8
+ defaultVariant: 'filled',
9
+ defaultPosition: 'bottom'
10
+ });
11
+ constructor(config) {
12
+ if (config) {
13
+ this.config = { ...this.config, ...config };
14
+ }
15
+ }
16
+ // 現在表示中のアイテムを取得
17
+ get items() {
18
+ return this._items;
19
+ }
20
+ // 設定更新
21
+ configure(config) {
22
+ this.config = { ...this.config, ...config };
23
+ }
24
+ // デフォルト位置を設定
25
+ setDefaultPosition(position) {
26
+ this.config.defaultPosition = position;
27
+ }
28
+ // デフォルト設定を一括更新
29
+ setDefaults(config) {
30
+ if (config.position !== undefined)
31
+ this.config.defaultPosition = config.position;
32
+ if (config.maxVisible !== undefined)
33
+ this.config.maxVisible = config.maxVisible;
34
+ if (config.defaultDuration !== undefined)
35
+ this.config.defaultDuration = config.defaultDuration;
36
+ if (config.defaultVariant !== undefined)
37
+ this.config.defaultVariant = config.defaultVariant;
38
+ }
39
+ // 基本的なshow メソッド
40
+ show(options) {
41
+ const id = `snackbar-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
42
+ const item = {
43
+ id,
44
+ variant: this.config.defaultVariant,
45
+ duration: this.config.defaultDuration,
46
+ position: this.config.defaultPosition,
47
+ ...options,
48
+ createdAt: Date.now()
49
+ };
50
+ // 最大表示数を超えた場合、キューに追加
51
+ if (this._items.length >= this.config.maxVisible) {
52
+ this.queue = [...this.queue, item];
53
+ return id;
54
+ }
55
+ // 表示数以内の場合は即座に表示
56
+ this._items = [...this._items, item];
57
+ return id;
58
+ }
59
+ // タイプ別メソッド
60
+ success(message, options) {
61
+ return this.show({ message, type: 'success', ...options });
62
+ }
63
+ error(message, options) {
64
+ return this.show({ message, type: 'error', ...options });
65
+ }
66
+ warning(message, options) {
67
+ return this.show({ message, type: 'warning', ...options });
68
+ }
69
+ info(message, options) {
70
+ return this.show({ message, type: 'info', ...options });
71
+ }
72
+ default(message, options) {
73
+ return this.show({ message, type: 'default', ...options });
74
+ }
75
+ // カスタムコンテンツ用メソッド
76
+ custom(children, type, options) {
77
+ return this.show({ children, type, ...options });
78
+ }
79
+ // 削除メソッド
80
+ remove(id) {
81
+ const filteredItems = this._items.filter((item) => item.id !== id);
82
+ // キューに待機中のアイテムがあり、表示数に余裕がある場合は次を表示
83
+ if (this.queue.length > 0 && filteredItems.length < this.config.maxVisible) {
84
+ const nextItem = this.queue[0];
85
+ this.queue = this.queue.slice(1);
86
+ this._items = [...filteredItems, nextItem];
87
+ }
88
+ else {
89
+ this._items = filteredItems;
90
+ }
91
+ }
92
+ // 全削除メソッド
93
+ clear() {
94
+ this._items = [];
95
+ this.queue = [];
96
+ }
97
+ // 位置別のアイテムを取得
98
+ getItemsByPosition(position) {
99
+ return this._items.filter((item) => item.position === position);
100
+ }
101
+ }
102
+ // グローバルインスタンス
103
+ export const snackbarManager = new SnackbarManager();
104
+ // 後方互換性のため、snackbarとしてもエクスポート
105
+ export const snackbar = snackbarManager;
106
+ // デフォルトエクスポート(後方互換性のため)
107
+ export default snackbarManager;
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Style utility functions
3
+ */
4
+ /**
5
+ * Converts a number or string value to a CSS style value.
6
+ * If the value is a number, it appends 'px' to it.
7
+ * If the value is already a string, it returns as is.
8
+ *
9
+ * @param value - The value to convert (number or string)
10
+ * @returns CSS style value as string
11
+ *
12
+ * @example
13
+ * getStyleFromNumber(100) // "100px"
14
+ * getStyleFromNumber("50%") // "50%"
15
+ * getStyleFromNumber("2rem") // "2rem"
16
+ */
17
+ export declare const getStyleFromNumber: (value: string | number | undefined, defaultValue?: string) => string | undefined;
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Style utility functions
3
+ */
4
+ /**
5
+ * Converts a number or string value to a CSS style value.
6
+ * If the value is a number, it appends 'px' to it.
7
+ * If the value is already a string, it returns as is.
8
+ *
9
+ * @param value - The value to convert (number or string)
10
+ * @returns CSS style value as string
11
+ *
12
+ * @example
13
+ * getStyleFromNumber(100) // "100px"
14
+ * getStyleFromNumber("50%") // "50%"
15
+ * getStyleFromNumber("2rem") // "2rem"
16
+ */
17
+ export const getStyleFromNumber = (value, defaultValue) => {
18
+ if (value === undefined || value === null) {
19
+ return defaultValue;
20
+ }
21
+ return typeof value === 'number' ? `${value}px` : value;
22
+ };
package/package.json ADDED
@@ -0,0 +1,102 @@
1
+ {
2
+ "name": "@14ch/svelte-ui",
3
+ "description": "Modern Svelte UI components library with TypeScript support",
4
+ "private": false,
5
+ "version": "0.0.1",
6
+ "type": "module",
7
+ "keywords": [
8
+ "svelte",
9
+ "ui",
10
+ "components",
11
+ "typescript",
12
+ "sveltekit",
13
+ "library"
14
+ ],
15
+ "author": "14ch",
16
+ "license": "MIT",
17
+ "repository": {
18
+ "type": "git",
19
+ "url": "git+https://github.com/iyodatakashi/svelte-ui.git"
20
+ },
21
+ "homepage": "https://github.com/iyodatakashi/svelte-ui#readme",
22
+ "bugs": {
23
+ "url": "https://github.com/iyodatakashi/svelte-ui/issues"
24
+ },
25
+ "main": "dist/index.js",
26
+ "exports": {
27
+ ".": {
28
+ "types": "./dist/index.d.ts",
29
+ "svelte": "./dist/index.js"
30
+ },
31
+ "./styles": "./dist/assets/styles/import.scss",
32
+ "./styles/*": "./dist/assets/styles/*"
33
+ },
34
+ "files": [
35
+ "dist/components/",
36
+ "dist/types/",
37
+ "dist/utils/",
38
+ "dist/assets/",
39
+ "dist/index.js",
40
+ "dist/index.d.ts"
41
+ ],
42
+ "svelte": "./dist/index.js",
43
+ "types": "./dist/index.d.ts",
44
+ "scripts": {
45
+ "dev": "vite dev",
46
+ "build": "vite build",
47
+ "package": "svelte-package",
48
+ "preview": "vite preview",
49
+ "prepare": "svelte-kit sync || echo ''",
50
+ "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
51
+ "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
52
+ "format": "prettier --write .",
53
+ "lint": "prettier --check . && eslint .",
54
+ "test:unit": "vitest",
55
+ "test": "npm run test:unit -- --run",
56
+ "test:browser": "vitest --config vitest.config.ts --run",
57
+ "storybook": "storybook dev -p 6006",
58
+ "build-storybook": "storybook build",
59
+ "prepublishOnly": "npm run package"
60
+ },
61
+ "devDependencies": {
62
+ "@chromatic-com/storybook": "^4.1.1",
63
+ "@eslint/compat": "^1.2.5",
64
+ "@eslint/js": "^9.18.0",
65
+ "@storybook/addon-a11y": "^9.1.5",
66
+ "@storybook/addon-docs": "^9.1.5",
67
+ "@storybook/addon-svelte-csf": "^5.0.8",
68
+ "@storybook/addon-themes": "^9.1.5",
69
+ "@storybook/addon-vitest": "^9.1.5",
70
+ "@storybook/sveltekit": "^9.1.5",
71
+ "@sveltejs/adapter-static": "^3.0.8",
72
+ "@sveltejs/kit": "^2.16.0",
73
+ "@sveltejs/package": "^2.3.7",
74
+ "@sveltejs/vite-plugin-svelte": "^5.0.0",
75
+ "@types/node": "^20",
76
+ "@vitest/browser": "3.2.4",
77
+ "@vitest/coverage-v8": "^3.2.4",
78
+ "eslint": "^9.18.0",
79
+ "eslint-config-prettier": "^10.0.1",
80
+ "eslint-plugin-storybook": "^9.1.5",
81
+ "eslint-plugin-svelte": "^3.0.0",
82
+ "globals": "^16.0.0",
83
+ "prettier": "^3.4.2",
84
+ "prettier-plugin-svelte": "^3.3.3",
85
+ "storybook": "^9.1.5",
86
+ "svelte": "^5.0.0",
87
+ "svelte-check": "^4.0.0",
88
+ "typescript": "^5.0.0",
89
+ "typescript-eslint": "^8.20.0",
90
+ "vite": "^6.2.6",
91
+ "vitest": "3.2.4",
92
+ "vitest-browser-svelte": "^1.1.0"
93
+ },
94
+ "dependencies": {
95
+ "dayjs": "^1.11.13",
96
+ "dompurify": "^3.2.6",
97
+ "sass": "^1.89.2"
98
+ },
99
+ "peerDependencies": {
100
+ "svelte": "^5.0.0"
101
+ }
102
+ }