ml-ui-lib 1.0.32 → 1.0.34

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,15 @@
1
+ .bottom-bar {
2
+ position: fixed;
3
+ bottom: 0;
4
+ left: 0;
5
+ width: 100%;
6
+ background: #fff;
7
+ border-top: 1px solid #eee;
8
+ z-index: 100;
9
+ transition: transform 0.25s ease-in-out;
10
+ }
11
+
12
+ /* Hide downward */
13
+ .bottom-bar--hidden {
14
+ transform: translateY(100%);
15
+ }
@@ -0,0 +1,8 @@
1
+ import React from 'react';
2
+ import './BottomBar.css';
3
+ export interface BottomBarProps {
4
+ children?: React.ReactNode;
5
+ className?: string;
6
+ }
7
+ export declare const BottomBar: React.FC<BottomBarProps>;
8
+ export default BottomBar;
@@ -0,0 +1,41 @@
1
+ 'use client';
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { useEffect, useState } from 'react';
4
+ import './BottomBar.css';
5
+ export const BottomBar = ({ children, className = '', }) => {
6
+ const [hideBar, setHideBar] = useState(false);
7
+ const [lastScrollY, setLastScrollY] = useState(0);
8
+ useEffect(() => {
9
+ let ticking = false;
10
+ const REVEAL_THRESHOLD = 10;
11
+ const handleScroll = () => {
12
+ const currentY = window.scrollY;
13
+ if (!ticking) {
14
+ window.requestAnimationFrame(() => {
15
+ if (currentY <= 0) {
16
+ setHideBar(false);
17
+ setLastScrollY(0);
18
+ ticking = false;
19
+ return;
20
+ }
21
+ const diff = lastScrollY - currentY;
22
+ // scrolling DOWN → hide (move down)
23
+ if (currentY > lastScrollY) {
24
+ setHideBar(true);
25
+ }
26
+ // scrolling UP → show after threshold
27
+ else if (diff > REVEAL_THRESHOLD) {
28
+ setHideBar(false);
29
+ }
30
+ setLastScrollY(currentY);
31
+ ticking = false;
32
+ });
33
+ ticking = true;
34
+ }
35
+ };
36
+ window.addEventListener('scroll', handleScroll, { passive: true });
37
+ return () => window.removeEventListener('scroll', handleScroll);
38
+ }, [lastScrollY]);
39
+ return (_jsx("div", { className: `bottom-bar ${hideBar ? 'bottom-bar--hidden' : ''} ${className}`, children: children }));
40
+ };
41
+ export default BottomBar;
@@ -2,7 +2,7 @@
2
2
  .btn {
3
3
  border: none;
4
4
  border-radius: 25px;
5
- padding: 10px 20px;
5
+ padding: 10px 30px;
6
6
  cursor: pointer;
7
7
  font-size: 16px;
8
8
  font-weight: 500;
@@ -155,7 +155,7 @@
155
155
  opacity: 1;
156
156
  background: #ffffff2b;
157
157
  position: absolute;
158
- padding: 15px 4px;
158
+ padding: 15px 7px;
159
159
  right: 0px;
160
160
  border-radius: 24px;
161
161
  }
@@ -192,7 +192,7 @@
192
192
  opacity: 1;
193
193
  background: #ffffff2b;
194
194
  position: absolute;
195
- padding: 15px 4px;
195
+ padding: 15px 7px;
196
196
  left: 0px;
197
197
  border-radius: 24px;
198
198
  }
@@ -202,3 +202,75 @@
202
202
  }
203
203
 
204
204
  /* label moves right */
205
+ /* === Action Symbols === */
206
+ /* Behaves like btn-next animation */
207
+ .btn-action-add::after {
208
+ content: "+";
209
+ position: absolute;
210
+ top: 50%;
211
+ right: -25px;
212
+ transform: translateY(-50%);
213
+ opacity: 0;
214
+ transition: all 0.25s ease;
215
+ font-size: 16px;
216
+ font-weight: bold;
217
+ color: currentColor;
218
+ background: #5d5d5d;
219
+ }
220
+
221
+ .btn-action-cancel::after {
222
+ content: "x";
223
+ position: absolute;
224
+ top: 50%;
225
+ right: -25px;
226
+ transform: translateY(-50%);
227
+ opacity: 0;
228
+ transition: all 0.25s ease;
229
+ font-size: 16px;
230
+ }
231
+
232
+ .btn-action-delete::after {
233
+ content: "🗑";
234
+ position: absolute;
235
+ top: 50%;
236
+ right: -25px;
237
+ transform: translateY(-50%);
238
+ opacity: 0;
239
+ transition: all 0.25s ease;
240
+ font-size: 16px;
241
+ }
242
+
243
+ .btn-action-info::after {
244
+ content: "ℹ";
245
+ position: absolute;
246
+ top: 50%;
247
+ right: -25px;
248
+ transform: translateY(-50%);
249
+ opacity: 0;
250
+ transition: all 0.25s ease;
251
+ font-size: 16px;
252
+ }
253
+
254
+ .btn-action-cancel:hover .btn-label,
255
+ .btn-action-info:hover .btn-label,
256
+ .btn-action-add:hover .btn-label,
257
+ .btn-action-delete:hover .btn-label {
258
+ transform: translateX(-17px);
259
+ transition: transform 0.25s ease;
260
+ }
261
+
262
+ .btn-action-info:hover::after {
263
+ padding: 5px 15px !important;
264
+ }
265
+
266
+ .btn-action-cancel:hover::after,
267
+ .btn-action-info:hover::after,
268
+ .btn-action-add:hover::after,
269
+ .btn-action-delete:hover::after {
270
+ background-color: transparent;
271
+ right: 3px;
272
+ opacity: 1;
273
+ border-radius: 25px;
274
+ border: solid 1px #aeaeae;
275
+ padding: 5px 12px;
276
+ }
@@ -1,6 +1,7 @@
1
1
  import React from "react";
2
2
  import "./Button.css";
3
3
  type ButtonAnimation = "default" | "loading" | "next" | "previous" | "see-more" | "view-more";
4
+ export type ButtonAction = "add" | "cancel" | "delete" | "info";
4
5
  export interface ButtonProps {
5
6
  label: string;
6
7
  variant?: "default" | "white" | "red" | "black" | "transparent-white";
@@ -12,6 +13,8 @@ export interface ButtonProps {
12
13
  bgColor?: string;
13
14
  textColor?: string;
14
15
  borderColor?: string;
16
+ /** Action symbol */
17
+ action?: ButtonAction;
15
18
  }
16
19
  export declare const Button: React.FC<ButtonProps>;
17
20
  export {};
@@ -1,14 +1,20 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import "./Button.css";
3
- export const Button = ({ label, variant = "default", onClick, disabled = false, animationStyle = "default", loading = false, bgColor, textColor, borderColor }) => {
3
+ export const Button = ({ label, variant = "default", onClick, disabled = false, animationStyle = "default", loading = false, bgColor, textColor, borderColor, action, }) => {
4
4
  const customStyle = {
5
5
  background: bgColor,
6
6
  color: textColor,
7
- border: borderColor ? `1px solid ${borderColor}` : undefined
7
+ border: borderColor ? `1px solid ${borderColor}` : undefined,
8
8
  };
9
+ // Determine the class for hover arrow based on action
10
+ let actionClass = "";
11
+ if (action) {
12
+ actionClass = `btn-action-${action}`;
13
+ }
9
14
  return (_jsx("button", { className: `
10
- btn btn-${variant}
11
- ${animationStyle === "next" ? "btn-next" : ""}
12
- ${animationStyle === "previous" ? "btn-previous" : ""}
13
- `, onClick: onClick, disabled: disabled, style: customStyle, children: _jsx("span", { className: "btn-content", children: loading ? (_jsxs("span", { className: "btn-loader", children: [_jsx("span", {}), _jsx("span", {}), _jsx("span", {})] })) : (_jsx("span", { className: "btn-label", children: label })) }) }));
15
+ btn btn-${variant}
16
+ ${animationStyle === "next" || action ? "btn-next" : ""}
17
+ ${animationStyle === "previous" ? "btn-previous" : ""}
18
+ ${actionClass}
19
+ `, onClick: onClick, disabled: disabled, style: customStyle, children: _jsx("span", { className: "btn-content", children: loading ? (_jsxs("span", { className: "btn-loader", children: [_jsx("span", {}), _jsx("span", {}), _jsx("span", {})] })) : (_jsx("span", { className: "btn-label", children: label })) }) }));
14
20
  };
@@ -14,7 +14,7 @@
14
14
  /* Hoverable behavior only if enabled */
15
15
  .card.hoverable:hover {
16
16
  transform: scale(1.05);
17
- box-shadow: 0 6px 16px rgba(0, 0, 0, 0.15);
17
+ /* box-shadow: 0 6px 16px rgba(0, 0, 0, 0.15); */
18
18
  cursor: pointer;
19
19
  }
20
20
 
@@ -89,130 +89,145 @@
89
89
  border-bottom: none;
90
90
  } */
91
91
  }
92
+
92
93
  .cards {
93
- width: 100%;
94
- display: flex;
95
- justify-content: center;
96
- max-width: 820px;
94
+ width: 100%;
95
+ display: flex;
96
+ justify-content: center;
97
+ max-width: 820px;
97
98
  }
98
99
 
99
100
  .card {
100
- margin-right: 25px;
101
- transition: box-shadow 0.4s cubic-bezier(0.175, 0.885, 0, 1);
102
- background-color: #fff;
103
- width: 33.3%;
104
- position: relative;
105
- border-radius: 12px;
106
- overflow: hidden;
107
- box-shadow: 0px 13px 10px -7px rgba(0, 0, 0, 0.1);
101
+ margin-right: 25px;
102
+ transition: box-shadow 0.4s cubic-bezier(0.175, 0.885, 0, 1);
103
+ background-color: #fff;
104
+ width: 33.3%;
105
+ position: relative;
106
+ border-radius: 12px;
107
+ overflow: hidden;
108
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
108
109
  }
109
110
 
110
111
  /* Card itself does not scale */
111
112
  .card:hover {
112
- box-shadow: 0px 30px 18px -8px rgba(0, 0, 0, 0.1);
113
- transform: none;
113
+ /* box-shadow: 0px 30px 18px -8px rgba(0, 0, 0, 0.1); */
114
+ transform: none;
114
115
  }
115
116
 
116
117
  /* First image (default) */
117
118
  .card__img {
118
- background-size: cover;
119
- background-position: center;
120
- background-repeat: no-repeat;
121
- width: 100%;
122
- height: 235px;
123
- border-top-left-radius: 12px;
124
- border-top-right-radius: 12px;
125
- transition: opacity 0.3s ease; /* smooth fade */
119
+ background-size: cover;
120
+ background-position: center;
121
+ background-repeat: no-repeat;
122
+ width: 100%;
123
+ height: 235px;
124
+ border-top-left-radius: 12px;
125
+ border-top-right-radius: 12px;
126
+ transition: opacity 0.3s ease;
127
+ /* smooth fade */
126
128
  }
127
129
 
128
130
  /* Hover overlay image */
129
131
  .card__img--hover {
130
- transition: all 0.4s ease; /* smooth fade + expand */
131
- background-size: cover;
132
- background-position: center;
133
- background-repeat: no-repeat;
134
- width: 100%;
135
- height: 100%; /* cover full card */
136
- position: absolute;
137
- top: 0;
138
- left: 0;
139
- border-radius: 12px; /* covers whole card corners */
140
- opacity: 0; /* hidden by default */
141
- pointer-events: none;
142
- z-index: 1;
132
+ transition: all 0.4s ease;
133
+ /* smooth fade + expand */
134
+ background-size: cover;
135
+ background-position: center;
136
+ background-repeat: no-repeat;
137
+ width: 100%;
138
+ height: 100%;
139
+ /* cover full card */
140
+ position: absolute;
141
+ top: 0;
142
+ left: 0;
143
+ border-radius: 12px;
144
+ /* covers whole card corners */
145
+ opacity: 0;
146
+ /* hidden by default */
147
+ pointer-events: none;
148
+ z-index: 1;
143
149
  }
144
150
 
145
151
  /* Hover effects: overlay fades in and zooms */
146
152
  .card:hover .card__img--hover {
147
- opacity: 0.3; /* fade in overlay */
148
- transform: scale(1.1); /* zoom slightly */
153
+ opacity: 0.3;
154
+ /* fade in overlay */
155
+ transform: scale(1.1);
156
+ /* zoom slightly */
149
157
  }
150
158
 
151
159
  /* Info section */
152
160
  .card__info {
153
- z-index: 2;
154
- background-color: #fff;
155
- border-bottom-left-radius: 12px;
156
- border-bottom-right-radius: 12px;
157
- padding: 16px 24px 24px 24px;
158
- transition: background-color 0.3s ease;
161
+ z-index: 2;
162
+ background-color: #fff;
163
+ border-bottom-left-radius: 12px;
164
+ border-bottom-right-radius: 12px;
165
+ padding: 16px 24px 24px 24px;
166
+ transition: background-color 0.3s ease;
159
167
  }
160
168
 
161
169
  /* Info content styling */
162
170
  .card__category {
163
- font-family: 'Raleway', sans-serif;
164
- text-transform: uppercase;
165
- font-size: 13px;
166
- letter-spacing: 2px;
167
- font-weight: 500;
168
- color: #868686;
171
+ font-family: 'Raleway', sans-serif;
172
+ text-transform: uppercase;
173
+ font-size: 13px;
174
+ letter-spacing: 2px;
175
+ font-weight: 500;
176
+ color: #868686;
169
177
  }
178
+
170
179
  .card__title {
171
- margin-top: 5px;
172
- margin-bottom: 10px;
173
- font-family: 'Roboto Slab', serif;
180
+ margin-top: 5px;
181
+ margin-bottom: 10px;
182
+ font-family: 'Roboto Slab', serif;
174
183
  }
184
+
175
185
  .card__by {
176
- font-size: 12px;
177
- font-family: 'Raleway', sans-serif;
178
- font-weight: 500;
186
+ font-size: 12px;
187
+ font-family: 'Raleway', sans-serif;
188
+ font-weight: 500;
179
189
  }
190
+
180
191
  .card__author {
181
- font-weight: 600;
182
- text-decoration: none;
183
- color: #AD7D52;
192
+ font-weight: 600;
193
+ text-decoration: none;
194
+ color: #AD7D52;
184
195
  }
185
196
 
186
197
  /* Clock & like icons */
187
198
  .card__like {
188
- width: 18px;
199
+ width: 18px;
189
200
  }
201
+
190
202
  .card__clock {
191
- width: 15px;
192
- vertical-align: middle;
193
- fill: #AD7D52;
203
+ width: 15px;
204
+ vertical-align: middle;
205
+ fill: #AD7D52;
194
206
  }
207
+
195
208
  .card__time {
196
- font-size: 12px;
197
- color: #AD7D52;
198
- vertical-align: middle;
199
- margin-left: 5px;
209
+ font-size: 12px;
210
+ color: #AD7D52;
211
+ vertical-align: middle;
212
+ margin-left: 5px;
200
213
  }
214
+
201
215
  .card__clock-info {
202
- float: right;
216
+ float: right;
203
217
  }
204
218
 
205
219
  /* Fade out first image on hover */
206
220
  .card:hover .card__img {
207
- opacity: 0;
221
+ opacity: 0;
208
222
  }
209
223
 
210
224
  /* Info hover overlay */
211
225
  .card:hover .card__info {
212
- background-color: transparent;
213
- position: relative;
226
+ background-color: transparent;
227
+ position: relative;
214
228
  }
215
229
 
216
230
  .card:hover .card__info-hover {
217
- opacity: 1; /* show overlay info */
218
- }
231
+ opacity: 1;
232
+ /* show overlay info */
233
+ }
@@ -10,5 +10,5 @@ export const Link = ({ label, href = "#", onClick, variant = "default", animatio
10
10
  ${animationStyle === "see-more" ? "link-more" : ""}
11
11
  ${animationStyle === "view-more" ? "link-more" : ""}
12
12
  `, style: customStyle, children: [_jsx("span", { className: "link-text", children: label }), (animationStyle === "see-more" ||
13
- animationStyle === "view-more") && (_jsx("span", { className: "link-arrow", children: _jsxs("svg", { xmlns: 'http://www.w3.org/2000/svg', width: '20', height: '20', fill: 'none', stroke: 'currentColor', "stroke-width": '2', "stroke-linecap": 'round', "stroke-linejoin": 'round', children: [_jsx("path", { stroke: 'none', d: 'M0 0h24v24H0z', fill: 'none' }), _jsx("path", { d: 'M5 12l14 0' }), _jsx("path", { d: 'M13 18l6 -6' }), _jsx("path", { d: 'M13 6l6 6' })] }) }))] }));
13
+ animationStyle === "view-more") && (_jsx("span", { className: "link-arrow", children: _jsxs("svg", { xmlns: 'http://www.w3.org/2000/svg', width: '20', height: '20', fill: 'none', stroke: 'currentColor', strokeWidth: '2', strokeLinecap: 'round', strokeLinejoin: 'round', children: [_jsx("path", { stroke: 'none', d: 'M0 0h24v24H0z', fill: 'none' }), _jsx("path", { d: 'M5 12l14 0' }), _jsx("path", { d: 'M13 18l6 -6' }), _jsx("path", { d: 'M13 6l6 6' })] }) }))] }));
14
14
  };
@@ -127,7 +127,7 @@
127
127
  }
128
128
 
129
129
  .separator {
130
- display: block !important;
130
+ display: none !important;
131
131
  }
132
132
 
133
133
  /* -------------------------
@@ -207,7 +207,7 @@
207
207
  ------------------------- */
208
208
  @media (max-width: 1100px) {
209
209
  .navbar-container {
210
- margin: 0 20px;
210
+ /* margin: 0 20px; */
211
211
  padding: 1rem 1.5rem;
212
212
  justify-content: space-between;
213
213
  }
@@ -95,6 +95,6 @@ export const Navbar = ({ siteUrl, items, logoSrc = '', logoAlt = 'Logo', logoWid
95
95
  setMenuOpen(false);
96
96
  setOpenDropdown(null);
97
97
  }, children: sub.name }, sub.name))) }) }))] }, item.name));
98
- }) }), isMobile && login && !logedinData && (_jsx("div", { className: 'navbar-item', style: { background: '#ffffff' }, children: _jsx("button", { className: "mobile-login-btn", onClick: toggleLogin, children: "Login" }) }))] }), _jsx("div", { className: 'separator', style: { color: '#aaaaaa', fontSize: '27px', padding: '0 15px' }, children: " | " }), _jsxs("div", { className: "navbar-right", children: [_jsxs("button", { className: `burger ${menuOpen ? 'active' : ''}`, onClick: toggleMenu, children: [_jsx("span", {}), _jsx("span", {}), _jsx("span", {})] }), !isMobile && login && !logedinData && (_jsx("span", { className: "login-btn", onClick: toggleLogin, children: "Login" }))] })] })] }) }), login && !logedinData && (_jsx(_Fragment, { children: !isMobile ? (showLogin && (_jsxs(_Fragment, { children: [_jsx("div", { className: "overlay-side-content", children: otherContent }), _jsx("div", { className: "navbar-login-panel", children: _jsxs(SlidingPanel, { isOpen: showLogin && !isClosing, width: "400px", height: "100%", position: "right", closeOnOverlayClick: false, onClose: handleInternalClose, children: [_jsx("div", { className: "navbar-panel-header" }), _jsx("div", { className: "navbar-panel-content", children: loginContent })] }) })] }))) : (_jsx("div", { className: "navbar-login-panel", children: _jsxs(SlidingPanel, { isOpen: showLogin, height: "70%", position: "bottom", onClose: handleInternalClose, children: [_jsx("div", { className: "navbar-panel-header" }), _jsx("div", { className: "navbar-panel-content", children: loginContent })] }) })) }))] }));
98
+ }) }), isMobile && login && !logedinData && (_jsx("div", { className: 'navbar-item', style: { background: '#ffffff' }, children: _jsx("button", { className: "mobile-login-btn", onClick: toggleLogin, children: "Login" }) }))] }), _jsxs("div", { className: "navbar-right", children: [_jsxs("button", { className: `burger ${menuOpen ? 'active' : ''}`, onClick: toggleMenu, children: [_jsx("span", {}), _jsx("span", {}), _jsx("span", {})] }), !isMobile && login && !logedinData && (_jsx("span", { className: "login-btn", onClick: toggleLogin, children: "Login" }))] })] })] }) }), login && !logedinData && (_jsx(_Fragment, { children: !isMobile ? (showLogin && (_jsxs(_Fragment, { children: [_jsx("div", { className: "overlay-side-content", children: otherContent }), _jsx("div", { className: "navbar-login-panel", children: _jsxs(SlidingPanel, { isOpen: showLogin && !isClosing, width: "400px", height: "100%", position: "right", closeOnOverlayClick: false, onClose: handleInternalClose, children: [_jsx("div", { className: "navbar-panel-header" }), _jsx("div", { className: "navbar-panel-content", children: loginContent })] }) })] }))) : (_jsx("div", { className: "navbar-login-panel", children: _jsxs(SlidingPanel, { isOpen: showLogin, height: "70%", position: "bottom", onClose: handleInternalClose, children: [_jsx("div", { className: "navbar-panel-header" }), _jsx("div", { className: "navbar-panel-content", children: loginContent })] }) })) }))] }));
99
99
  };
100
100
  export default Navbar;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ml-ui-lib",
3
- "version": "1.0.32",
3
+ "version": "1.0.34",
4
4
  "main": "dist/index.js",
5
5
  "module": "dist/index.esm.js",
6
6
  "types": "dist/index.d.ts",