@natykufsky/react-iframe 1.0.15

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.
@@ -0,0 +1,51 @@
1
+ export interface Tab {
2
+ id: string;
3
+ title: string;
4
+ url: string;
5
+ icon?: string;
6
+ isPinned?: boolean;
7
+ lastAccessed: number;
8
+ isHibernated?: boolean;
9
+ }
10
+ export interface ReFrameState {
11
+ tabs: Tab[];
12
+ activeTabId: string | null;
13
+ maxTabs: number;
14
+ }
15
+ export type ReFrameAction = {
16
+ type: 'ADD_TAB';
17
+ payload: Tab;
18
+ } | {
19
+ type: 'REMOVE_TAB';
20
+ payload: {
21
+ id: string;
22
+ };
23
+ } | {
24
+ type: 'FOCUS_TAB';
25
+ payload: {
26
+ id: string;
27
+ };
28
+ } | {
29
+ type: 'CLOSE_OTHERS';
30
+ payload: {
31
+ id: string;
32
+ };
33
+ } | {
34
+ type: 'REORDER_TABS';
35
+ payload: {
36
+ sourceIndex: number;
37
+ destinationIndex: number;
38
+ };
39
+ } | {
40
+ type: 'SET_MAX_TABS';
41
+ payload: number;
42
+ } | {
43
+ type: 'UPDATE_TAB';
44
+ payload: {
45
+ id: string;
46
+ updates: Partial<Tab>;
47
+ };
48
+ } | {
49
+ type: 'HYDRATE';
50
+ payload: ReFrameState;
51
+ };
package/package.json ADDED
@@ -0,0 +1,49 @@
1
+
2
+ {
3
+ "name": "@natykufsky/react-iframe",
4
+ "version": "1.0.15",
5
+ "description": "Multi-instance IFrame workspace manager for React",
6
+ "type": "module",
7
+ "main": "./dist/re-frame.js",
8
+ "module": "./dist/re-frame.js",
9
+ "types": "./dist/index.d.ts",
10
+ "files": [
11
+ "dist",
12
+ "bridge",
13
+ "src/styles",
14
+ "styles.css"
15
+ ],
16
+ "exports": {
17
+ ".": {
18
+ "import": "./dist/re-frame.js",
19
+ "types": "./dist/index.d.ts"
20
+ },
21
+ "./styles.css": "./styles.css",
22
+ "./bridge/ReFrameBridge.js": "./bridge/ReFrameBridge.js"
23
+ },
24
+ "scripts": {
25
+ "dev": "vite",
26
+ "build": "vite build && tsc -p tsconfig.build.json",
27
+ "preview": "vite preview",
28
+ "publish:dry": "npm publish --dry-run",
29
+ "prepack": "npm run build"
30
+ },
31
+ "publishConfig": {
32
+ "access": "public"
33
+ },
34
+ "peerDependencies": {
35
+ "react": ">=18.0.0",
36
+ "react-dom": ">=18.0.0"
37
+ },
38
+ "devDependencies": {
39
+ "@types/react": "^19.0.0",
40
+ "@types/react-dom": "^19.0.0",
41
+ "@vitejs/plugin-react": "^4.3.4",
42
+ "typescript": "^5.7.2",
43
+ "vite": "^6.0.0",
44
+ "vite-plugin-dts": "^4.3.0"
45
+ },
46
+ "dependencies": {
47
+ "framer-motion": "^12.0.0"
48
+ }
49
+ }
@@ -0,0 +1,195 @@
1
+ .re-frame-tab-container {
2
+ display: flex;
3
+ align-items: stretch;
4
+ background: white;
5
+ border-bottom: 1px solid #e2e8f0;
6
+ width: 100%;
7
+ max-width: 100%; /* Changed from 100vw to 100% to stay within parent/sidebar bounds */
8
+ overflow: hidden;
9
+ height: 40px;
10
+ }
11
+
12
+ .re-frame-tab-list {
13
+ display: flex;
14
+ overflow-x: auto;
15
+ overflow-y: hidden;
16
+ scrollbar-width: none;
17
+ background: white;
18
+ padding: 0;
19
+ flex: 1;
20
+ min-width: 0;
21
+ scroll-behavior: smooth;
22
+ }
23
+
24
+ .re-frame-tab-list::-webkit-scrollbar {
25
+ display: none;
26
+ }
27
+
28
+ .scroll-btn {
29
+ display: flex;
30
+ align-items: center;
31
+ justify-content: center;
32
+ width: 32px;
33
+ background: #f8fafc;
34
+ cursor: pointer;
35
+ z-index: 5;
36
+ color: #64748b;
37
+ flex-shrink: 0;
38
+ transition: all 0.2s;
39
+ }
40
+
41
+ .scroll-btn:hover {
42
+ background: #f1f5f9;
43
+ color: #1e293b;
44
+ }
45
+
46
+ .scroll-btn.left {
47
+ border-right: 1px solid #e2e8f0;
48
+ }
49
+
50
+ .scroll-btn.right {
51
+ border-left: 1px solid #e2e8f0;
52
+ }
53
+
54
+ .re-frame-tab-list-mobile {
55
+ display: none;
56
+ }
57
+
58
+ .re-frame-mobile-selector {
59
+ display: flex;
60
+ align-items: center;
61
+ justify-content: space-between;
62
+ width: 100%;
63
+ padding: 8px 12px;
64
+ background: #f8fafc;
65
+ border: 1px solid #e2e8f0;
66
+ border-radius: 6px;
67
+ cursor: pointer;
68
+ font-size: 14px;
69
+ font-weight: 500;
70
+ }
71
+
72
+ .re-frame-mobile-dropdown {
73
+ position: absolute;
74
+ top: 100%;
75
+ left: 16px;
76
+ right: 16px;
77
+ background: white;
78
+ box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1);
79
+ border: 1px solid #e2e8f0;
80
+ border-radius: 0 0 8px 8px;
81
+ z-index: 1000;
82
+ max-height: 300px;
83
+ overflow-y: auto;
84
+ margin-top: -1px;
85
+ }
86
+
87
+ .re-frame-mobile-item {
88
+ padding: 12px 16px;
89
+ font-size: 14px;
90
+ border-bottom: 1px solid #f1f5f9;
91
+ display: flex;
92
+ align-items: center;
93
+ justify-content: space-between;
94
+ }
95
+
96
+ .re-frame-mobile-item.active {
97
+ background: #eff6ff;
98
+ color: #3b82f6;
99
+ font-weight: 600;
100
+ }
101
+
102
+ @media (max-width: 768px) {
103
+ /* No longer hiding the tab list on mobile */
104
+ .re-frame-tab-list-mobile {
105
+ display: none;
106
+ }
107
+
108
+ .re-frame-tab-item {
109
+ min-width: 100px;
110
+ padding: 8px 12px;
111
+ }
112
+ }
113
+
114
+ .re-frame-tab-item {
115
+ display: flex;
116
+ align-items: center;
117
+ padding: 0 16px;
118
+ background: #f8fafc;
119
+ border-right: 1px solid #e2e8f0;
120
+ cursor: pointer;
121
+ user-select: none;
122
+ font-size: 14px;
123
+ color: #64748b;
124
+ position: relative;
125
+ transition: all 0.2s;
126
+ min-width: 120px;
127
+ max-width: 200px;
128
+ flex-shrink: 0;
129
+ white-space: nowrap;
130
+ height: 100%;
131
+ }
132
+
133
+ .re-frame-tab-item .tab-title {
134
+ flex: 1;
135
+ overflow: hidden;
136
+ text-overflow: ellipsis;
137
+ white-space: nowrap;
138
+ }
139
+
140
+ .re-frame-tab-item.active {
141
+ background: white;
142
+ color: #1e293b;
143
+ border-bottom: 2px solid #3b82f6;
144
+ font-weight: 500;
145
+ }
146
+
147
+ .re-frame-tab-item:hover {
148
+ background: #f1f5f9;
149
+ }
150
+
151
+ .re-frame-tab-item .close-btn {
152
+ margin-left: 10px;
153
+ border-radius: 6px;
154
+ width: 24px;
155
+ height: 24px;
156
+ display: flex;
157
+ align-items: center;
158
+ justify-content: center;
159
+ font-size: 18px; /* Larger 'x' symbol */
160
+ font-weight: bold;
161
+ color: #94a3b8;
162
+ transition: all 0.2s;
163
+ opacity: 0.8;
164
+ }
165
+
166
+ .re-frame-tab-item:hover .close-btn, .re-frame-tab-item.active .close-btn {
167
+ opacity: 1;
168
+ color: #475569;
169
+ }
170
+
171
+ .re-frame-tab-item .close-btn:hover {
172
+ background: rgba(239, 68, 68, 0.1);
173
+ color: #ef4444; /* Strong Red color on hover */
174
+ }
175
+
176
+ .re-frame-context-menu {
177
+ position: fixed;
178
+ background: white;
179
+ box-shadow: 0 4px 12px rgba(0,0,0,0.15);
180
+ border-radius: 6px;
181
+ z-index: 1000;
182
+ padding: 4px 0;
183
+ min-width: 160px;
184
+ border: 1px solid #e2e8f0;
185
+ }
186
+
187
+ .re-frame-context-menu-item {
188
+ padding: 8px 16px;
189
+ font-size: 14px;
190
+ cursor: pointer;
191
+ }
192
+
193
+ .re-frame-context-menu-item:hover {
194
+ background: #f1f5f9;
195
+ }
@@ -0,0 +1 @@
1
+ @import './default.css';
package/styles.css ADDED
@@ -0,0 +1 @@
1
+ @import "./src/styles/index.css";