@rufous/ui 0.2.0-beta.0 → 0.2.0-beta.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.
@@ -0,0 +1,303 @@
1
+ import {
2
+ FloatingInput
3
+ } from "./chunk-UPCMMCPQ.js";
4
+ import {
5
+ useRufousTheme
6
+ } from "./chunk-HMG3FW2Q.js";
7
+ import {
8
+ circularProgress_default
9
+ } from "./chunk-CTBYVXFP.js";
10
+
11
+ // lib/TextFields/AddressLookup.tsx
12
+ import React, { useState, useRef, useEffect } from "react";
13
+ import Axios from "axios";
14
+ import { Country, State, City } from "country-state-city";
15
+ var AddressLookup = ({
16
+ value = {},
17
+ onChange = () => {
18
+ },
19
+ label = "Address",
20
+ error = {},
21
+ size = "medium",
22
+ sx = {},
23
+ layout = "stack",
24
+ required = false,
25
+ token = ""
26
+ }) => {
27
+ const { theme } = useRufousTheme();
28
+ const [suggestions, setSuggestions] = useState([]);
29
+ const [loading, setLoading] = useState(false);
30
+ const [showSuggestions, setShowSuggestions] = useState(false);
31
+ const [googleFields, setGoogleFields] = useState({
32
+ country: false,
33
+ state: false,
34
+ city: false,
35
+ pincode: false
36
+ });
37
+ const debounceTimeout = useRef(null);
38
+ const containerRef = useRef(null);
39
+ const apiKey = token || "";
40
+ const countries = Country.getAllCountries();
41
+ const [states, setStates] = useState([]);
42
+ const [cities, setCities] = useState([]);
43
+ useEffect(() => {
44
+ const handleClickOutside = (event) => {
45
+ if (containerRef.current && !containerRef.current.contains(event.target)) {
46
+ setShowSuggestions(false);
47
+ }
48
+ };
49
+ document.addEventListener("mousedown", handleClickOutside);
50
+ return () => document.removeEventListener("mousedown", handleClickOutside);
51
+ }, []);
52
+ useEffect(() => {
53
+ if (value.country || value.state || value.city || value.pincode) {
54
+ setGoogleFields({
55
+ country: !!value.country,
56
+ state: !!value.state,
57
+ city: !!value.city,
58
+ pincode: !!value.pincode
59
+ });
60
+ }
61
+ }, []);
62
+ useEffect(() => {
63
+ if (value.country) {
64
+ const country = countries.find((c) => c.name === value.country);
65
+ if (country) {
66
+ const stateList = State.getStatesOfCountry(country.isoCode);
67
+ setStates(stateList);
68
+ } else {
69
+ setStates([]);
70
+ }
71
+ } else {
72
+ setStates([]);
73
+ }
74
+ }, [value.country]);
75
+ useEffect(() => {
76
+ if (value.state && value.country) {
77
+ const country = countries.find((c) => c.name === value.country);
78
+ if (country) {
79
+ const state = State.getStatesOfCountry(country.isoCode).find((s) => s.name === value.state);
80
+ if (state) {
81
+ const cityList = City.getCitiesOfState(country.isoCode, state.isoCode);
82
+ setCities(cityList);
83
+ } else {
84
+ setCities([]);
85
+ }
86
+ } else {
87
+ setCities([]);
88
+ }
89
+ } else {
90
+ setCities([]);
91
+ }
92
+ }, [value.state, value.country]);
93
+ const handleChange = (field, newVal) => {
94
+ onChange({
95
+ ...value,
96
+ [field]: newVal
97
+ });
98
+ };
99
+ const fetchPlaceDetails = async (placeId, mainText = "") => {
100
+ if (!apiKey) {
101
+ console.warn("Google Places API Key (token) is missing.");
102
+ return;
103
+ }
104
+ setLoading(true);
105
+ try {
106
+ const res = await Axios.get(
107
+ `https://places.googleapis.com/v1/places/${placeId}`,
108
+ {
109
+ headers: {
110
+ "Content-Type": "application/json",
111
+ "X-Goog-Api-Key": apiKey,
112
+ "X-Goog-FieldMask": "addressComponents,formattedAddress"
113
+ }
114
+ }
115
+ );
116
+ const comps = res.data.addressComponents || [];
117
+ const findComp = (type) => comps.find((c) => c.types.includes(type))?.longText || "";
118
+ const city = findComp("locality") || findComp("sublocality_level_1");
119
+ const state = findComp("administrative_area_level_1");
120
+ const country = findComp("country");
121
+ const pincode = findComp("postal_code");
122
+ setGoogleFields({
123
+ country: !!country,
124
+ state: !!state,
125
+ city: !!city,
126
+ pincode: !!pincode
127
+ });
128
+ const updatedData = {
129
+ ...value,
130
+ addressLine1: mainText || value.addressLine1,
131
+ addressLine2: res.data.formattedAddress || value.addressLine2,
132
+ city,
133
+ state,
134
+ country,
135
+ pincode
136
+ };
137
+ onChange(updatedData);
138
+ setShowSuggestions(false);
139
+ } catch (err) {
140
+ console.error("Error fetching place details:", err);
141
+ } finally {
142
+ setLoading(false);
143
+ }
144
+ };
145
+ const handleQuerySuggestions = async (query) => {
146
+ if (!apiKey || !query || query.length < 3) {
147
+ setSuggestions([]);
148
+ setShowSuggestions(false);
149
+ return;
150
+ }
151
+ setLoading(true);
152
+ try {
153
+ const res = await Axios.post(
154
+ `https://places.googleapis.com/v1/places:autocomplete`,
155
+ { input: query },
156
+ {
157
+ headers: {
158
+ "Content-Type": "application/json",
159
+ "X-Goog-Api-Key": apiKey
160
+ }
161
+ }
162
+ );
163
+ setSuggestions(res.data.suggestions || []);
164
+ setShowSuggestions(true);
165
+ } catch (err) {
166
+ console.error("Autocomplete Error:", err);
167
+ } finally {
168
+ setLoading(false);
169
+ }
170
+ };
171
+ const handleCountryChange = (newCountry) => {
172
+ onChange({
173
+ ...value,
174
+ country: newCountry,
175
+ state: "",
176
+ city: ""
177
+ });
178
+ setGoogleFields({ ...googleFields, country: false, state: false, city: false });
179
+ };
180
+ const handleStateChange = (newState) => {
181
+ onChange({
182
+ ...value,
183
+ state: newState,
184
+ city: ""
185
+ });
186
+ };
187
+ return /* @__PURE__ */ React.createElement("div", { className: "address-lookup-container", style: sx, ref: containerRef }, /* @__PURE__ */ React.createElement("div", { className: `address-lookup-grid address-lookup-grid-${layout}` }, /* @__PURE__ */ React.createElement("div", { className: "address-lookup-grid-item col-l1" }, /* @__PURE__ */ React.createElement(
188
+ FloatingInput,
189
+ {
190
+ label,
191
+ name: "addressLine1",
192
+ value: value.addressLine1 || "",
193
+ required,
194
+ autoComplete: "off",
195
+ onChange: (e) => {
196
+ const val = e.target.value;
197
+ handleChange("addressLine1", val);
198
+ if (!val) {
199
+ onChange({
200
+ ...value,
201
+ addressLine1: "",
202
+ city: "",
203
+ state: "",
204
+ country: "",
205
+ pincode: ""
206
+ });
207
+ setSuggestions([]);
208
+ setShowSuggestions(false);
209
+ setGoogleFields({ country: false, state: false, city: false, pincode: false });
210
+ } else {
211
+ if (debounceTimeout.current) clearTimeout(debounceTimeout.current);
212
+ debounceTimeout.current = setTimeout(() => {
213
+ handleQuerySuggestions(val);
214
+ }, 500);
215
+ }
216
+ },
217
+ onFocus: () => suggestions.length > 0 && setShowSuggestions(true)
218
+ }
219
+ ), loading && /* @__PURE__ */ React.createElement("div", { className: "loading-indicator" }, /* @__PURE__ */ React.createElement(circularProgress_default, { size: 20 })), showSuggestions && suggestions.length > 0 && /* @__PURE__ */ React.createElement("div", { className: "autocomplete-dropdown" }, suggestions.map((option, idx) => /* @__PURE__ */ React.createElement(
220
+ "div",
221
+ {
222
+ key: idx,
223
+ className: "autocomplete-option",
224
+ onClick: () => {
225
+ const mainText = option?.placePrediction?.structuredFormat?.mainText?.text || "";
226
+ handleChange("addressLine1", mainText);
227
+ fetchPlaceDetails(option.placePrediction.placeId, mainText);
228
+ }
229
+ },
230
+ /* @__PURE__ */ React.createElement("div", { className: "autocomplete-main-text" }, option?.placePrediction?.structuredFormat?.mainText?.text),
231
+ /* @__PURE__ */ React.createElement("div", { className: "autocomplete-secondary-text" }, option?.placePrediction?.structuredFormat?.secondaryText?.text)
232
+ ))), error.addressLine1 && /* @__PURE__ */ React.createElement("div", { className: "field-error-text" }, error.addressLine1)), layout === "compact" && /* @__PURE__ */ React.createElement("div", { className: "address-lookup-grid-item col-l2" }, /* @__PURE__ */ React.createElement(
233
+ FloatingInput,
234
+ {
235
+ label: "Address Line 2",
236
+ name: "addressLine2",
237
+ value: value.addressLine2 || "",
238
+ onChange: (e) => handleChange("addressLine2", e.target.value)
239
+ }
240
+ )), layout !== "compact" && /* @__PURE__ */ React.createElement("div", { className: "address-lookup-grid-item col-l2" }, /* @__PURE__ */ React.createElement(
241
+ FloatingInput,
242
+ {
243
+ label: "Address Line 2",
244
+ name: "addressLine2",
245
+ value: value.addressLine2 || "",
246
+ onChange: (e) => handleChange("addressLine2", e.target.value)
247
+ }
248
+ )), /* @__PURE__ */ React.createElement("div", { className: "address-lookup-grid-item col-country" }, /* @__PURE__ */ React.createElement(
249
+ FloatingInput,
250
+ {
251
+ label: "Country",
252
+ name: "country",
253
+ value: value.country || "",
254
+ required,
255
+ className: googleFields.country && value.country ? "field-disabled" : "",
256
+ readOnly: googleFields.country && !!value.country,
257
+ onChange: (e) => handleCountryChange(e.target.value),
258
+ list: "countries-list"
259
+ }
260
+ ), /* @__PURE__ */ React.createElement("datalist", { id: "countries-list" }, countries.map((c) => /* @__PURE__ */ React.createElement("option", { key: c.isoCode, value: c.name }))), error.country && /* @__PURE__ */ React.createElement("div", { className: "field-error-text" }, error.country)), /* @__PURE__ */ React.createElement("div", { className: "address-lookup-grid-item col-state" }, /* @__PURE__ */ React.createElement(
261
+ FloatingInput,
262
+ {
263
+ label: "State",
264
+ name: "state",
265
+ value: value.state || "",
266
+ required,
267
+ disabled: !value.country,
268
+ className: googleFields.state && value.state ? "field-disabled" : "",
269
+ readOnly: googleFields.state && !!value.state,
270
+ onChange: (e) => handleStateChange(e.target.value),
271
+ list: "states-list"
272
+ }
273
+ ), /* @__PURE__ */ React.createElement("datalist", { id: "states-list" }, states.map((s) => /* @__PURE__ */ React.createElement("option", { key: s.isoCode, value: s.name }))), error.state && /* @__PURE__ */ React.createElement("div", { className: "field-error-text" }, error.state)), /* @__PURE__ */ React.createElement("div", { className: "address-lookup-grid-item col-city" }, /* @__PURE__ */ React.createElement(
274
+ FloatingInput,
275
+ {
276
+ label: "City",
277
+ name: "city",
278
+ value: value.city || "",
279
+ required,
280
+ disabled: !value.state,
281
+ className: googleFields.city && value.city ? "field-disabled" : "",
282
+ readOnly: googleFields.city && !!value.city,
283
+ onChange: (e) => handleChange("city", e.target.value),
284
+ list: "cities-list"
285
+ }
286
+ ), /* @__PURE__ */ React.createElement("datalist", { id: "cities-list" }, cities.map((c, i) => /* @__PURE__ */ React.createElement("option", { key: i, value: c.name }))), error.city && /* @__PURE__ */ React.createElement("div", { className: "field-error-text" }, error.city)), /* @__PURE__ */ React.createElement("div", { className: "address-lookup-grid-item col-pin" }, /* @__PURE__ */ React.createElement(
287
+ FloatingInput,
288
+ {
289
+ label: "Pincode",
290
+ name: "pincode",
291
+ value: value.pincode || "",
292
+ required,
293
+ className: googleFields.pincode && value.pincode ? "field-disabled" : "",
294
+ readOnly: googleFields.pincode && !!value.pincode,
295
+ onChange: (e) => handleChange("pincode", e.target.value)
296
+ }
297
+ ), error.pincode && /* @__PURE__ */ React.createElement("div", { className: "field-error-text" }, error.pincode))));
298
+ };
299
+ var AddressLookup_default = AddressLookup;
300
+
301
+ export {
302
+ AddressLookup_default
303
+ };
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  APP_THEMES
3
- } from "./chunk-QGXXOQJF.js";
3
+ } from "./chunk-YXPBXCY5.js";
4
4
 
5
5
  // lib/Contexts/rufousThemeProvider.tsx
6
6
  import React, {
@@ -23,26 +23,45 @@ var RufousThemeProvider = ({ children }) => {
23
23
  const themeVars = useMemo(() => {
24
24
  const config = APP_THEMES[colorScheme][mode];
25
25
  return {
26
+ "--rufous-primary-color": config.primary,
27
+ "--rufous-secondary-color": config.secondary,
28
+ "--rufous-background-color": config.background,
29
+ "--rufous-surface-color": config.surface,
30
+ "--rufous-text-color": config.text,
31
+ "--rufous-text-secondary": config.textSecondary,
32
+ "--rufous-border-color": config.border,
33
+ "--rufous-hover-color": config.hover,
34
+ "--rufous-selection-color": config.selection,
35
+ "--rufous-icon-color": config.icon,
36
+ // Keep legacy variables for backward compatibility during transition
26
37
  "--primary-color": config.primary,
27
- "--secondary-color": config.secondary,
28
38
  "--background-color": config.background,
29
- "--surface-color": config.surface,
30
39
  "--text-color": config.text,
31
- "--text-secondary": config.textSecondary,
32
40
  "--border-color": config.border,
33
- "--hover-color": config.hover,
34
- "--selection-color": config.selection,
35
- "--icon-color": config.icon
41
+ "--surface-color": config.surface
36
42
  };
37
43
  }, [colorScheme, mode]);
38
44
  const toggleMode = () => {
39
45
  const newMode = mode === "light" ? "dark" : "light";
40
46
  setMode(newMode);
41
- localStorage.setItem("themeMode", newMode);
42
47
  };
43
48
  const changeScheme = (scheme) => {
44
- setColorScheme(scheme);
45
- localStorage.setItem("colorScheme", scheme);
49
+ if (APP_THEMES[scheme]) {
50
+ setColorScheme(scheme);
51
+ }
52
+ };
53
+ const saveTheme = () => {
54
+ localStorage.setItem("colorScheme", colorScheme);
55
+ localStorage.setItem("themeMode", mode);
56
+ };
57
+ const updateSettings = (settings) => {
58
+ if (!settings) return;
59
+ if (settings.theme && APP_THEMES[settings.theme]) {
60
+ setColorScheme(settings.theme);
61
+ }
62
+ if (settings.mode) {
63
+ setMode(settings.mode);
64
+ }
46
65
  };
47
66
  return /* @__PURE__ */ React.createElement(
48
67
  RufousThemeContext.Provider,
@@ -52,6 +71,11 @@ var RufousThemeProvider = ({ children }) => {
52
71
  mode,
53
72
  toggleMode,
54
73
  changeScheme,
74
+ previewTheme: changeScheme,
75
+ updateSettings,
76
+ saveTheme,
77
+ theme: APP_THEMES[colorScheme][mode],
78
+ // Direct access to current theme config
55
79
  themeConfig: APP_THEMES[colorScheme][mode]
56
80
  }
57
81
  },
@@ -1,4 +1,4 @@
1
- // lib/CheckBoxes/CheckBox.jsx
1
+ // lib/CheckBoxes/CheckBox.tsx
2
2
  import React from "react";
3
3
  var Checkbox = ({
4
4
  id,
@@ -12,7 +12,14 @@ var APP_THEMES = {
12
12
  border: "#e0e0e0",
13
13
  hover: "#fff5f5",
14
14
  selection: "#fce4ec",
15
- icon: "#a41b06"
15
+ icon: "#a41b06",
16
+ get customStyles() {
17
+ return {
18
+ iconColor: this.icon,
19
+ primaryColor: this.primary,
20
+ secondaryColor: this.secondary
21
+ };
22
+ }
16
23
  },
17
24
  dark: {
18
25
  primary: "#dc2626",
@@ -24,7 +31,14 @@ var APP_THEMES = {
24
31
  border: "#333333",
25
32
  hover: "#2d1a1a",
26
33
  selection: "#4a1212",
27
- icon: "#dc2626"
34
+ icon: "#dc2626",
35
+ get customStyles() {
36
+ return {
37
+ iconColor: this.icon,
38
+ primaryColor: this.primary,
39
+ secondaryColor: this.secondary
40
+ };
41
+ }
28
42
  }
29
43
  },
30
44
  slate: {
@@ -39,7 +53,14 @@ var APP_THEMES = {
39
53
  border: "#e2e8f0",
40
54
  hover: "#f1f5f9",
41
55
  selection: "#e0f2fe",
42
- icon: "#334155"
56
+ icon: "#334155",
57
+ get customStyles() {
58
+ return {
59
+ iconColor: this.icon,
60
+ primaryColor: this.primary,
61
+ secondaryColor: this.secondary
62
+ };
63
+ }
43
64
  },
44
65
  dark: {
45
66
  primary: "#94a3b8",
@@ -51,7 +72,14 @@ var APP_THEMES = {
51
72
  border: "#334155",
52
73
  hover: "#1e293b",
53
74
  selection: "#0c4a6e",
54
- icon: "#94a3b8"
75
+ icon: "#94a3b8",
76
+ get customStyles() {
77
+ return {
78
+ iconColor: this.icon,
79
+ primaryColor: this.primary,
80
+ secondaryColor: this.secondary
81
+ };
82
+ }
55
83
  }
56
84
  }
57
85
  };
@@ -1,4 +1,7 @@
1
1
  import "../chunk-E5RTHYCU.js";
2
+ import {
3
+ unsubscribeIcon_default
4
+ } from "../chunk-EZI3QGYJ.js";
2
5
  import {
3
6
  uploadIcon_default
4
7
  } from "../chunk-QTGVW36I.js";
@@ -11,6 +14,9 @@ import {
11
14
  import {
12
15
  workItemIcon_default
13
16
  } from "../chunk-QJPQC544.js";
17
+ import {
18
+ softSkillsIcon_default
19
+ } from "../chunk-3Y6QBRGD.js";
14
20
  import {
15
21
  subscribeIcon_default
16
22
  } from "../chunk-JVN6QVET.js";
@@ -33,8 +39,8 @@ import {
33
39
  unArchivedIcon_default
34
40
  } from "../chunk-ZJAV3FEQ.js";
35
41
  import {
36
- unsubscribeIcon_default
37
- } from "../chunk-EZI3QGYJ.js";
42
+ questionTypeSingleIcon_default
43
+ } from "../chunk-Q4DHI3B5.js";
38
44
  import {
39
45
  refreshIcon_default
40
46
  } from "../chunk-YTVUM76D.js";
@@ -57,8 +63,8 @@ import {
57
63
  sidebarIcon_default
58
64
  } from "../chunk-DK3DA5LH.js";
59
65
  import {
60
- softSkillsIcon_default
61
- } from "../chunk-3Y6QBRGD.js";
66
+ qualificationsIcon_default
67
+ } from "../chunk-UTBCFDOX.js";
62
68
  import {
63
69
  questionStatusAllIcon_default
64
70
  } from "../chunk-4Y7SQ5EP.js";
@@ -81,8 +87,8 @@ import {
81
87
  questionTypeMultipleIcon_default
82
88
  } from "../chunk-Z7USRFM2.js";
83
89
  import {
84
- questionTypeSingleIcon_default
85
- } from "../chunk-Q4DHI3B5.js";
90
+ industryIcon_default
91
+ } from "../chunk-4BTXGP7U.js";
86
92
  import {
87
93
  invoiceIcon_default
88
94
  } from "../chunk-6SUKO6QW.js";
@@ -105,8 +111,8 @@ import {
105
111
  projectIcon_default
106
112
  } from "../chunk-DLJHWFNG.js";
107
113
  import {
108
- qualificationsIcon_default
109
- } from "../chunk-UTBCFDOX.js";
114
+ editChatIcon_default
115
+ } from "../chunk-XCE3QE6Q.js";
110
116
  import {
111
117
  editIcon_default
112
118
  } from "../chunk-H372BAXA.js";
@@ -126,8 +132,8 @@ import {
126
132
  inactiveGroupIcon_default
127
133
  } from "../chunk-77QDKDFI.js";
128
134
  import {
129
- industryIcon_default
130
- } from "../chunk-4BTXGP7U.js";
135
+ copyIcon_default
136
+ } from "../chunk-6FEUS4CQ.js";
131
137
  import {
132
138
  difficultyAllIcon_default
133
139
  } from "../chunk-5XKFPQLH.js";
@@ -149,9 +155,6 @@ import {
149
155
  import {
150
156
  downloadPdfIcon_default
151
157
  } from "../chunk-N26C33E6.js";
152
- import {
153
- editChatIcon_default
154
- } from "../chunk-XCE3QE6Q.js";
155
158
  import {
156
159
  activateUserIcon_default
157
160
  } from "../chunk-AH6RCYDL.js";
@@ -164,9 +167,6 @@ import {
164
167
  import {
165
168
  closeIcon_default
166
169
  } from "../chunk-Q5XKCUE3.js";
167
- import {
168
- copyIcon_default
169
- } from "../chunk-6FEUS4CQ.js";
170
170
  import "../chunk-LI4N7JWK.js";
171
171
  export {
172
172
  activateUserIcon_default as ActivateUserIcon,