frutjam 0.0.3 → 0.0.5

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/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Frutjam Useful Prebuilt Plugins & UI Components for TailwindCSS
1
+ ## Frutjam Useful Prebuilt Plugins & UI Components for TailwindCSS
2
2
 
3
3
  Frutjam is a powerful library with an array of useful plugins and UI components created exclusively for use with Tailwind CSS. Whether you're creating a web app, a website, or a digital product, Frutjam offers a variety of tools to help you boost your development process and improve user experience. Furthermore, it provides numerous customization options within its plugins, allowing you to design your solutions precisely to your requirements.
4
4
 
@@ -43,7 +43,6 @@ Import the `Notification` class from Frutjam:
43
43
 
44
44
  ```typescript
45
45
  import { Notification } from "frutjam";
46
- import "frutjam/dist/notification.css";
47
46
  ```
48
47
 
49
48
  Create a new notification instance with custom configurations:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "frutjam",
3
- "version": "0.0.3",
3
+ "version": "0.0.5",
4
4
  "description": "Frutjam includes prebuilt UI components and plugins that are completely open-source",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -10,8 +10,10 @@
10
10
  "url": "git+https://github.com/nezanuha/frutjam.git"
11
11
  },
12
12
  "scripts": {
13
- "dev": "tsup --watch",
14
- "build": "tsup",
13
+ "dev-tsup": "tsup --watch",
14
+ "build-tsup": "tsup",
15
+ "dev": "webpack --watch --mode=development",
16
+ "build": "webpack --mode=production",
15
17
  "test": "echo \"Error: no test specified\" && exit 1"
16
18
  },
17
19
  "keywords": [
@@ -29,9 +31,14 @@
29
31
  ],
30
32
  "devDependencies": {
31
33
  "autoprefixer": "^10.4.19",
32
- "postcss": "^8.4.38",
34
+ "css-loader": "^7.1.1",
35
+ "postcss-loader": "^8.1.1",
36
+ "style-loader": "^4.0.0",
33
37
  "tailwindcss": "^3.4.3",
34
- "tsup": "^8.0.2",
35
- "typescript": "^5.4.5"
38
+ "terser-webpack-plugin": "^5.3.10",
39
+ "ts-loader": "^9.5.1",
40
+ "typescript": "^5.4.5",
41
+ "webpack": "^5.91.0",
42
+ "webpack-cli": "^5.1.4"
36
43
  }
37
44
  }
package/src/index.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  export { default as Notification } from './plugins/notification'
2
2
  export { default as TelephoneInput } from './plugins/telephoneInput'
3
- export { default as Popover } from './plugins/popover'
3
+ export { default as Popover } from './plugins/popover'
4
+ export { default as Tabs } from './plugins/tabs'
@@ -0,0 +1,112 @@
1
+
2
+ /*
3
+ * Tabs
4
+ * @version: 0.0.2
5
+ * @author: Nezanuha
6
+ * @license: Licensed under MIT
7
+ * Copyright 2024 Nezanuha
8
+ */
9
+
10
+ import { TabOptions } from "./types";
11
+
12
+ export default class Tabs {
13
+ private tabs: HTMLElement[];
14
+ private tabContents: HTMLElement[];
15
+ private options: TabOptions;
16
+
17
+ constructor(options?: TabOptions) {
18
+ this.tabs = Array.from(document.querySelectorAll('.tab'));
19
+ this.tabContents = Array.from(document.querySelectorAll('.tab-content'));
20
+ this.options = options || {};
21
+
22
+ this.init();
23
+ this.handleInitialTabState();
24
+ }
25
+
26
+ private init() {
27
+ this.tabs.forEach(tab => {
28
+ tab.addEventListener('click', () => this.toggleTab(tab));
29
+ });
30
+ }
31
+
32
+ private toggleTab(selectedTab: HTMLElement) {
33
+ const tabId = selectedTab.dataset.tab;
34
+
35
+ if (!tabId || selectedTab.classList.contains('disabled')) return;
36
+
37
+ this.tabs.forEach(tab => {
38
+ tab.classList.remove('active');
39
+ });
40
+ selectedTab.classList.add('active');
41
+
42
+ this.tabContents.forEach(content => {
43
+ if (content.id === tabId) {
44
+ content.style.display = 'block';
45
+ this.animateTab(content);
46
+ if (this.options.onTabActive) {
47
+ this.options.onTabActive(tabId);
48
+ }
49
+ } else {
50
+ content.style.display = 'none';
51
+ }
52
+ });
53
+ }
54
+
55
+ private animateTab(content: HTMLElement) {
56
+ // Implement your animation logic here
57
+ content.style.opacity = '0';
58
+ setTimeout(() => {
59
+ content.style.opacity = '1';
60
+ }, 300);
61
+ }
62
+
63
+ private handleInitialTabState() {
64
+ if (this.options.disableTabs === 'all') {
65
+ this.disableAllTabs();
66
+ } else if (Array.isArray(this.options.disableTabs)) {
67
+ this.disableTabs(this.options.disableTabs);
68
+ } else if (this.options.enableTabs === 'all') {
69
+ this.enableAllTabs();
70
+ } else if (Array.isArray(this.options.enableTabs)) {
71
+ this.enableTabs(this.options.enableTabs);
72
+ }
73
+ }
74
+
75
+ private disableAllTabs() {
76
+ this.tabs.forEach(tab => {
77
+ tab.classList.add('disabled');
78
+ });
79
+ }
80
+
81
+ private enableAllTabs() {
82
+ this.tabs.forEach(tab => {
83
+ tab.classList.remove('disabled');
84
+ });
85
+ }
86
+
87
+ enableTabs(tabIds?: string[] | 'all') {
88
+ if (tabIds === 'all') {
89
+ this.enableAllTabs();
90
+ } else if (Array.isArray(tabIds)) {
91
+ tabIds.forEach(tabId => {
92
+ const tab = this.tabs.find(tab => tab.dataset.tab === tabId);
93
+ if (tab) {
94
+ tab.classList.remove('disabled');
95
+ }
96
+ });
97
+ }
98
+ }
99
+
100
+ disableTabs(tabIds?: string[] | 'all') {
101
+ if (tabIds === 'all') {
102
+ this.disableAllTabs();
103
+ } else if (Array.isArray(tabIds)) {
104
+ tabIds.forEach(tabId => {
105
+ const tab = this.tabs.find(tab => tab.dataset.tab === tabId);
106
+ if (tab) {
107
+ tab.classList.add('disabled');
108
+ }
109
+ });
110
+ }
111
+ }
112
+ }
@@ -0,0 +1,7 @@
1
+ type TabOptions = {
2
+ disableTabs?: string[] | 'all'; // Array of tab IDs to disable or 'all' to disable all tabs
3
+ enableTabs?: string[] | 'all'; // Array of tab IDs to enable or 'all' to enable all tabs
4
+ onTabActive?: (tabId: string) => void;
5
+ };
6
+
7
+ export type { TabOptions }