funuicss 3.6.20 → 3.7.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.
package/ui/table/Table.js CHANGED
@@ -95,7 +95,7 @@ function Table(_a) {
95
95
  var _b, _c;
96
96
  var children = _a.children, funcss = _a.funcss, bordered = _a.bordered, noStripped = _a.noStripped, hoverable = _a.hoverable, _d = _a.title, title = _d === void 0 ? "" : _d, showTotal = _a.showTotal, light = _a.light, dark = _a.dark, head = _a.head, body = _a.body, data = _a.data, _e = _a.isLoading, isLoading = _e === void 0 ? false : _e, right = _a.right, hideExport = _a.hideExport, height = _a.height, _f = _a.pageSize, pageSize = _f === void 0 ? data ? 10 : 0 : _f, // Default page size,
97
97
  customColumns = _a.customColumns, filterableFields = _a.filterableFields, // New prop
98
- emptyResponse = _a.emptyResponse, filterOnchange = _a.filterOnchange, clearSearch = _a.clearSearch, _g = _a.prioritizeSearchFields, prioritizeSearchFields = _g === void 0 ? [] : _g, onRowClick = _a.onRowClick, rest = __rest(_a, ["children", "funcss", "bordered", "noStripped", "hoverable", "title", "showTotal", "light", "dark", "head", "body", "data", "isLoading", "right", "hideExport", "height", "pageSize", "customColumns", "filterableFields", "emptyResponse", "filterOnchange", "clearSearch", "prioritizeSearchFields", "onRowClick"]);
98
+ emptyResponse = _a.emptyResponse, filterOnchange = _a.filterOnchange, clearSearch = _a.clearSearch, _g = _a.prioritizeSearchFields, prioritizeSearchFields = _g === void 0 ? [] : _g, onRowClick = _a.onRowClick, trCss = _a.trCss, rest = __rest(_a, ["children", "funcss", "bordered", "noStripped", "hoverable", "title", "showTotal", "light", "dark", "head", "body", "data", "isLoading", "right", "hideExport", "height", "pageSize", "customColumns", "filterableFields", "emptyResponse", "filterOnchange", "clearSearch", "prioritizeSearchFields", "onRowClick", "trCss"]);
99
99
  // Check if data is null or undefined before accessing its properties
100
100
  // Replace this in your component
101
101
  var _h = (0, react_1.useState)(''), search = _h[0], setSearch = _h[1];
@@ -188,28 +188,26 @@ function Table(_a) {
188
188
  }, [selectedField, selectedValue]);
189
189
  return (React.createElement("div", { className: "".concat(funcss ? funcss : '', " roundEdge") },
190
190
  data &&
191
- React.createElement("div", { className: "padding bb" },
191
+ React.createElement("div", { className: "pr-4 pl-4 pt-2 pb-2 lighter round-edge mb-2", style: { overflow: "show" } },
192
192
  React.createElement(RowFlex_1.default, { gap: 0.5, justify: 'space-between' },
193
193
  title ?
194
194
  React.createElement("div", null,
195
195
  showTotal && data &&
196
196
  React.createElement("div", null,
197
- React.createElement(Text_1.default, { text: 'Records: ', size: 'sm' }),
198
- React.createElement(Text_1.default, { text: filteredData.length, weight: 600 })),
197
+ React.createElement(Text_1.default, { text: "".concat(filteredData.length, " Records"), size: 'sm', weight: 500 })),
199
198
  title &&
200
199
  React.createElement("div", null,
201
- React.createElement(Text_1.default, { text: title || "", size: 'h6' })))
200
+ React.createElement(Text_1.default, { text: title || "", size: 'h6', lineHeight: '0.8' })))
202
201
  :
203
202
  React.createElement(React.Fragment, null, showTotal && data &&
204
203
  React.createElement("div", null,
205
- React.createElement(Text_1.default, { text: 'Records: ', size: 'sm' }),
206
- React.createElement(Text_1.default, { text: filteredData.length, weight: 600, color: 'primary' }))),
204
+ React.createElement(Text_1.default, { text: "".concat(filteredData.length, " Records"), size: 'sm', weight: 500 }))),
207
205
  data ?
208
206
  React.createElement("div", null,
209
207
  React.createElement(Flex_1.default, { width: '100%', wrap: 'nowrap', alignItems: 'center', gap: 0.7 },
210
208
  !selectedField && !showSearch && filterableFields &&
211
209
  React.createElement("div", null,
212
- React.createElement(Select_1.default, { fullWidth: true, searchable: true, funcss: 'min-w-300 w-full', rounded: true, value: selectedField || '', onChange: function (e) { return handleFieldChange(e); }, options: __spreadArray([
210
+ React.createElement(Select_1.default, { fullWidth: true, searchable: true, funcss: 'min-w-300 w-full bg', rounded: true, value: selectedField || '', onChange: function (e) { return handleFieldChange(e); }, options: __spreadArray([
213
211
  { text: '🔍 Filter', value: '' },
214
212
  { text: 'All*', value: '' }
215
213
  ], (filterableFields || []).map(function (field) { return ({
@@ -217,7 +215,7 @@ function Table(_a) {
217
215
  value: field
218
216
  }); }), true) })),
219
217
  selectedField && !showSearch && filterableFields && (React.createElement("div", { className: '' },
220
- React.createElement(Select_1.default, { rounded: true, searchable: true, funcss: 'min-w-300 w-full', fullWidth: true, value: selectedValue || '', onChange: function (e) {
218
+ React.createElement(Select_1.default, { rounded: true, searchable: true, funcss: 'min-w-300 w-full bg', fullWidth: true, value: selectedValue || '', onChange: function (e) {
221
219
  if (e === 'clear_all') {
222
220
  setSelectedField('');
223
221
  }
@@ -238,21 +236,21 @@ function Table(_a) {
238
236
  showSearch ?
239
237
  React.createElement(Flex_1.default, { gap: 0.5, wrap: 'nowrap', alignItems: 'center' },
240
238
  React.createElement("div", { className: 'animated slide-up' },
241
- React.createElement(Input_1.default, { borderless: true, funcss: 'min-w-300', fullWidth: true, rounded: true, value: searchQuery, onChange: function (e) { return setsearchQuery(e.target.value); }, label: "Search..." })),
239
+ React.createElement(Input_1.default, { borderless: true, funcss: 'min-w-300 bg', fullWidth: true, rounded: true, value: searchQuery, onChange: function (e) { return setsearchQuery(e.target.value); }, label: "Search..." })),
242
240
  React.createElement("div", { className: 'animated fade-in' },
243
241
  React.createElement("div", { onClick: function () { return setshowSearch(false); } },
244
242
  React.createElement(ToolTip_1.default, null,
245
243
  filterableFields ? React.createElement(io5_1.IoFilterOutline, { className: 'pointer' })
246
244
  :
247
245
  React.createElement(pi_1.PiXThin, { className: 'pointer', size: 23, onClick: function () { return setshowSearch(false); } }),
248
- React.createElement(Tip_1.default, { tip: "bottom", animation: "Opacity", duration: 1, content: filterableFields ? "Filter" : "Close Search" })))))
246
+ React.createElement(Tip_1.default, { tip: "top", animation: "Opacity", duration: 1, content: filterableFields ? "Filter" : "Close Search" })))))
249
247
  :
250
248
  React.createElement("div", { className: 'animated fade-in' },
251
249
  React.createElement(ToolTip_1.default, null,
252
250
  React.createElement(ci_1.CiSearch, { className: 'pointer', size: 23, onClick: function () { return setshowSearch(true); } }),
253
- React.createElement(Tip_1.default, { tip: "bottom", animation: "Opacity", duration: 1, content: "Search Data" })))))
251
+ React.createElement(Tip_1.default, { tip: "top", animation: "Opacity", duration: 1, content: "Search Data" })))))
254
252
  : '',
255
- React.createElement(React.Fragment, null,
253
+ React.createElement(React.Fragment, null, (right || !hideExport) &&
256
254
  React.createElement(RowFlex_1.default, { gap: 0.5 },
257
255
  right && right,
258
256
  !hideExport &&
@@ -260,7 +258,7 @@ function Table(_a) {
260
258
  React.createElement(ToolTip_1.default, null,
261
259
  React.createElement(Circle_1.default, { bg: 'lighter', bordered: true, onClick: Export },
262
260
  React.createElement(pi_1.PiExportThin, null)),
263
- React.createElement(Tip_1.default, { tip: "bottom", animation: "Opacity", duration: 1, content: "Export Data" }))))))),
261
+ React.createElement(Tip_1.default, { tip: "top", animation: "Opacity", duration: 1, content: "Export Data" }))))))),
264
262
  React.createElement("main", { style: { overflow: "auto", width: "100%" } },
265
263
  React.createElement("table", __assign({ className: "table ".concat(bordered ? 'border' : '', " ").concat(noStripped ? '' : 'stripped', " ").concat(hoverable ? 'hoverableTr' : '', " ").concat(light ? 'light' : '', " ").concat(dark ? 'dark' : ''), style: {
266
264
  height: height ? height + "px" : "",
@@ -269,8 +267,7 @@ function Table(_a) {
269
267
  } }, rest),
270
268
  data &&
271
269
  (data === null || data === void 0 ? void 0 : data.titles) &&
272
- React.createElement(Head_1.default, null, data.titles.map(function (mdoc) { return (React.createElement("th", { key: mdoc },
273
- React.createElement(Text_1.default, { text: mdoc, weight: 500, funcss: 'text-secondary' }))); })),
270
+ React.createElement(Head_1.default, null, data.titles.map(function (mdoc, index) { return (React.createElement("th", { key: mdoc, className: "text-secondary \n ".concat(index === 0 ? "first_table_data" : "", " \n ").concat(index === (data.titles.length - 1) ? "last_table_data" : "", " \n ") }, mdoc)); })),
274
271
  head && React.createElement(Head_1.default, null, head),
275
272
  body && React.createElement(Body_1.default, null, body),
276
273
  data &&
@@ -278,7 +275,7 @@ function Table(_a) {
278
275
  var results = (0, Query_1.getAdvancedFilteredData)(filteredData, searchQuery, data, getNestedValue, prioritizeSearchFields);
279
276
  var shouldSlice = !searchQuery || results.length > 10;
280
277
  return (shouldSlice ? results.slice(startIndex, endIndex) : results)
281
- .map(function (mdoc, index) { return (React.createElement("tr", { className: 'animated slide-up', key: index, onClick: onRowClick ? function () { return onRowClick(mdoc); } : undefined },
278
+ .map(function (mdoc, index) { return (React.createElement("tr", { className: "animated slide-up ".concat(trCss), key: index, onClick: onRowClick ? function () { return onRowClick(mdoc); } : undefined },
282
279
  data.fields.map(function (fdoc, findex) {
283
280
  var _a;
284
281
  return (React.createElement(Data_1.default, { key: fdoc, funcss: data.funcss ? ((_a = data === null || data === void 0 ? void 0 : data.funcss) === null || _a === void 0 ? void 0 : _a[findex]) || '' : '' }, getNestedValue(mdoc, fdoc)));
package/ui/text/Text.js CHANGED
@@ -28,59 +28,99 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
28
28
  Object.defineProperty(exports, "__esModule", { value: true });
29
29
  var react_1 = __importDefault(require("react"));
30
30
  var pi_1 = require("react-icons/pi");
31
- var getCssVariable_1 = require("../../utils/getCssVariable");
32
31
  var componentUtils_1 = require("../../utils/componentUtils");
33
32
  var Text = function (_a) {
34
33
  var id = _a.id, bg = _a.bg, color = _a.color, children = _a.children, hoverBg = _a.hoverBg, hoverText = _a.hoverText, text = _a.text, funcss = _a.funcss, emp = _a.emp, bold = _a.bold, block = _a.block, body = _a.body, article = _a.article, light = _a.light, lighter = _a.lighter, italic = _a.italic, weight = _a.weight, underline = _a.underline, align = _a.align, lineHeight = _a.lineHeight, letterSpacing = _a.letterSpacing, uppercase = _a.uppercase, lowercase = _a.lowercase, capitalize = _a.capitalize, textDecoration = _a.textDecoration, textTransform = _a.textTransform, whiteSpace = _a.whiteSpace, wordBreak = _a.wordBreak, fontFamily = _a.fontFamily, truncate = _a.truncate, textShadow = _a.textShadow, textAlign = _a.textAlign, customStyles = _a.customStyles, monospace = _a.monospace, quote = _a.quote, opacity = _a.opacity, _b = _a.variant, variant = _b === void 0 ? '' : _b, _c = _a.size, size = _c === void 0 ? 'base' : _c, margin = _a.margin, padding = _a.padding, rest = __rest(_a, ["id", "bg", "color", "children", "hoverBg", "hoverText", "text", "funcss", "emp", "bold", "block", "body", "article", "light", "lighter", "italic", "weight", "underline", "align", "lineHeight", "letterSpacing", "uppercase", "lowercase", "capitalize", "textDecoration", "textTransform", "whiteSpace", "wordBreak", "fontFamily", "truncate", "textShadow", "textAlign", "customStyles", "monospace", "quote", "opacity", "variant", "size", "margin", "padding"]);
35
- // Use the component config hook
36
- var mergeWithLocal = (0, componentUtils_1.useComponentConfiguration)('Text', variant).mergeWithLocal;
34
+ // Only use component config if variant is provided and not empty
35
+ var shouldUseConfig = variant !== undefined && variant !== '';
36
+ // Use the component config hook only when needed
37
+ var mergeWithLocal = (0, componentUtils_1.useComponentConfiguration)('Text', shouldUseConfig ? variant : undefined).mergeWithLocal;
38
+ // Create local props object
39
+ var localProps = __assign({ bg: bg, color: color, funcss: funcss, emp: emp, bold: bold, block: block, body: body, article: article, light: light, lighter: lighter, italic: italic, weight: weight, underline: underline, align: align, lineHeight: lineHeight, letterSpacing: letterSpacing, uppercase: uppercase, lowercase: lowercase, capitalize: capitalize, textDecoration: textDecoration, textTransform: textTransform, whiteSpace: whiteSpace, wordBreak: wordBreak, fontFamily: fontFamily, truncate: truncate, textShadow: textShadow, textAlign: textAlign, monospace: monospace, quote: quote, opacity: opacity, size: size, margin: margin, padding: padding }, rest);
37
40
  // Merge config with local props - local props override config
38
- var mergedProps = mergeWithLocal(__assign({ bg: bg, color: color, funcss: funcss, emp: emp, bold: bold, block: block, body: body, article: article, light: light, lighter: lighter, italic: italic, weight: weight, underline: underline, align: align, lineHeight: lineHeight, letterSpacing: letterSpacing, uppercase: uppercase, lowercase: lowercase, capitalize: capitalize, textDecoration: textDecoration, textTransform: textTransform, whiteSpace: whiteSpace, wordBreak: wordBreak, fontFamily: fontFamily, truncate: truncate, textShadow: textShadow, textAlign: textAlign, monospace: monospace, quote: quote, opacity: opacity, size: size, margin: margin, padding: padding }, rest)).props;
41
+ var mergedProps = (shouldUseConfig
42
+ ? mergeWithLocal(localProps)
43
+ : { props: localProps }).props;
44
+ // Extract final values - local props take precedence, handle empty strings properly
45
+ var final = {
46
+ bg: bg !== undefined ? bg : mergedProps.bg,
47
+ color: color !== undefined ? color : mergedProps.color,
48
+ funcss: funcss !== undefined ? funcss : mergedProps.funcss,
49
+ emp: emp !== undefined ? emp : mergedProps.emp,
50
+ bold: bold !== undefined ? bold : mergedProps.bold,
51
+ block: block !== undefined ? block : mergedProps.block,
52
+ body: body !== undefined ? body : mergedProps.body,
53
+ article: article !== undefined ? article : mergedProps.article,
54
+ light: light !== undefined ? light : mergedProps.light,
55
+ lighter: lighter !== undefined ? lighter : mergedProps.lighter,
56
+ italic: italic !== undefined ? italic : mergedProps.italic,
57
+ weight: weight !== undefined ? weight : mergedProps.weight,
58
+ underline: underline !== undefined ? underline : mergedProps.underline,
59
+ align: align !== undefined ? align : mergedProps.align,
60
+ lineHeight: lineHeight !== undefined ? lineHeight : mergedProps.lineHeight,
61
+ letterSpacing: letterSpacing !== undefined ? letterSpacing : mergedProps.letterSpacing,
62
+ uppercase: uppercase !== undefined ? uppercase : mergedProps.uppercase,
63
+ lowercase: lowercase !== undefined ? lowercase : mergedProps.lowercase,
64
+ capitalize: capitalize !== undefined ? capitalize : mergedProps.capitalize,
65
+ textDecoration: textDecoration !== undefined ? textDecoration : mergedProps.textDecoration,
66
+ textTransform: textTransform !== undefined ? textTransform : mergedProps.textTransform,
67
+ whiteSpace: whiteSpace !== undefined ? whiteSpace : mergedProps.whiteSpace,
68
+ wordBreak: wordBreak !== undefined ? wordBreak : mergedProps.wordBreak,
69
+ fontFamily: fontFamily !== undefined ? fontFamily : mergedProps.fontFamily,
70
+ truncate: truncate !== undefined ? truncate : mergedProps.truncate,
71
+ textShadow: textShadow !== undefined ? textShadow : mergedProps.textShadow,
72
+ textAlign: textAlign !== undefined ? textAlign : mergedProps.textAlign,
73
+ monospace: monospace !== undefined ? monospace : mergedProps.monospace,
74
+ quote: quote !== undefined ? quote : mergedProps.quote,
75
+ opacity: opacity !== undefined ? opacity : mergedProps.opacity,
76
+ size: size !== undefined ? size : mergedProps.size,
77
+ margin: margin !== undefined ? margin : mergedProps.margin,
78
+ padding: padding !== undefined ? padding : mergedProps.padding,
79
+ };
39
80
  // If margin is provided, force block display
40
- var shouldBeBlock = mergedProps.block || !!mergedProps.margin;
81
+ var shouldBeBlock = final.block || !!final.margin;
41
82
  var Tag = shouldBeBlock ? 'div' : 'span';
42
- var sizeClass = "".concat(mergedProps.size === 'h1' ? "h1" :
43
- mergedProps.size === 'h2' ? "h2" :
44
- mergedProps.size === 'h3' ? "h3" :
45
- mergedProps.size === 'h4' ? "h4" :
46
- mergedProps.size === 'h5' ? "h5" :
47
- mergedProps.size === 'h6' ? "h6" :
48
- "text-".concat(mergedProps.size));
49
- var bdFontWeight = (0, getCssVariable_1.getCssVariableValue)('bd-font-weight');
50
- var mergedStyles = __assign(__assign({ display: shouldBeBlock ? 'block' : undefined, fontWeight: mergedProps.bold ? 'bold' : mergedProps.weight ? mergedProps.weight : Number(bdFontWeight), lineHeight: mergedProps.lineHeight, letterSpacing: mergedProps.letterSpacing, textTransform: mergedProps.textTransform, textDecoration: mergedProps.textDecoration, fontFamily: mergedProps.fontFamily, textShadow: mergedProps.textShadow, textAlign: mergedProps.textAlign, whiteSpace: mergedProps.whiteSpace, wordBreak: mergedProps.wordBreak, transform: mergedProps.transform, margin: mergedProps.margin, padding: mergedProps.padding }, customStyles), (mergedProps.truncate
83
+ var sizeClass = "".concat(final.size === 'h1' ? "h1" :
84
+ final.size === 'h2' ? "h2" :
85
+ final.size === 'h3' ? "h3" :
86
+ final.size === 'h4' ? "h4" :
87
+ final.size === 'h5' ? "h5" :
88
+ final.size === 'h6' ? "h6" :
89
+ "text-".concat(final.size));
90
+ var mergedStyles = __assign(__assign({ display: shouldBeBlock ? 'block' : undefined, fontWeight: final.bold ? 'bold' : final.weight ? final.weight : undefined, lineHeight: final.lineHeight, letterSpacing: final.letterSpacing, textTransform: final.textTransform, textDecoration: final.textDecoration, fontFamily: final.fontFamily, textShadow: final.textShadow, textAlign: final.textAlign, whiteSpace: final.whiteSpace, wordBreak: final.wordBreak, margin: final.margin, padding: final.padding }, customStyles), (final.truncate
51
91
  ? {
52
92
  display: '-webkit-box',
53
93
  WebkitBoxOrient: 'vertical',
54
- WebkitLineClamp: mergedProps.truncate,
94
+ WebkitLineClamp: final.truncate,
55
95
  overflow: 'hidden',
56
96
  textOverflow: 'ellipsis',
57
97
  }
58
98
  : {}));
59
99
  var classNames = [
60
- mergedProps.funcss || '',
100
+ final.funcss || '',
61
101
  sizeClass,
62
- mergedProps.color ? " text-".concat(mergedProps.color, " ") : '',
63
- mergedProps.align ? " text-".concat(mergedProps.align, " ") : '',
64
- mergedProps.monospace ? 'monospace' : '',
65
- mergedProps.bg || '',
102
+ final.color ? " text-".concat(final.color, " ") : '',
103
+ final.align ? " text-".concat(final.align, " ") : '',
104
+ final.monospace ? 'monospace' : '',
105
+ final.bg || '',
66
106
  hoverText ? "hover-text-".concat(hoverText) : '',
67
107
  hoverBg ? "hover-".concat(hoverBg) : '',
68
- mergedProps.light ? 'lightText' : mergedProps.lighter ? 'lighterText' : '',
69
- mergedProps.italic ? 'italicText' : '',
70
- mergedProps.underline ? 'underlineText' : '',
71
- mergedProps.body ? 'body' : '',
72
- mergedProps.article ? 'article' : '',
73
- mergedProps.emp ? 'emp' : '',
74
- mergedProps.bold ? 'bold' : '',
75
- mergedProps.uppercase ? 'uppercase' : '',
76
- mergedProps.lowercase ? 'lowercase' : '',
77
- mergedProps.capitalize ? 'capitalize' : '',
78
- mergedProps.opacity ? 'opacity-' + mergedProps.opacity : '',
108
+ final.light ? 'lightText' : final.lighter ? 'lighterText' : '',
109
+ final.italic ? 'italicText' : '',
110
+ final.underline ? 'underlineText' : '',
111
+ final.body ? 'body' : '',
112
+ final.article ? 'article' : '',
113
+ final.emp ? 'emp' : '',
114
+ final.bold ? 'bold' : '',
115
+ final.uppercase ? 'uppercase' : '',
116
+ final.lowercase ? 'lowercase' : '',
117
+ final.capitalize ? 'capitalize' : '',
118
+ final.opacity ? 'opacity-' + final.opacity : '',
79
119
  ]
80
120
  .filter(Boolean)
81
121
  .join(' ');
82
- return (react_1.default.createElement(Tag, __assign({ id: id, className: classNames, style: mergedStyles }, mergedProps),
83
- mergedProps.quote && (react_1.default.createElement("div", null,
122
+ return (react_1.default.createElement(Tag, __assign({ id: id, className: classNames, style: mergedStyles }, rest),
123
+ final.quote && (react_1.default.createElement("div", null,
84
124
  react_1.default.createElement(pi_1.PiQuotesLight, null))),
85
125
  children,
86
126
  text));
@@ -4,6 +4,10 @@ export type ThemeName = 'light' | 'dark' | 'dark-blue' | 'light-gray' | 'pastel-
4
4
  interface ThemeConfig {
5
5
  [key: string]: any;
6
6
  }
7
+ interface Variable {
8
+ name: string;
9
+ value: any;
10
+ }
7
11
  interface ProjectData {
8
12
  theme_config?: {
9
13
  colors?: Record<string, string>;
@@ -12,6 +16,7 @@ interface ProjectData {
12
16
  };
13
17
  components?: Record<string, any>;
14
18
  default_variation?: ThemeVariant;
19
+ variables?: Variable[];
15
20
  name?: string;
16
21
  project_id?: string;
17
22
  version?: number;
@@ -38,6 +43,11 @@ export declare const useVariant: () => {
38
43
  variant: ThemeVariant;
39
44
  setVariant: React.Dispatch<React.SetStateAction<ThemeVariant>>;
40
45
  };
46
+ export declare const getVariable: (name: string) => {
47
+ name: string;
48
+ value: any;
49
+ } | undefined;
50
+ export declare const getAllVariables: () => Variable[];
41
51
  declare const ThemeProvider: React.FC<ThemeProviderProps>;
42
52
  export default ThemeProvider;
43
53
  export declare const useThemeValue: (key: string) => string | undefined;
@@ -49,3 +59,5 @@ export declare const useProjectData: () => ProjectData | null;
49
59
  export declare const useColor: (colorName: string) => string | undefined;
50
60
  export declare const useTypographyValue: (property: string) => string | undefined;
51
61
  export declare const useComponentVariant: (componentName: string, variantName?: string) => any;
62
+ export declare const useVariables: () => Variable[];
63
+ export declare const useVariable: (name: string) => any;
package/ui/theme/theme.js CHANGED
@@ -70,7 +70,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
70
70
  }
71
71
  };
72
72
  Object.defineProperty(exports, "__esModule", { value: true });
73
- exports.useComponentVariant = exports.useTypographyValue = exports.useColor = exports.useProjectData = exports.useThemeConfig = exports.useTypography = exports.useColors = exports.useComponentConfig = exports.useThemeValue = exports.useVariant = exports.useTheme = void 0;
73
+ exports.useVariable = exports.useVariables = exports.useComponentVariant = exports.useTypographyValue = exports.useColor = exports.useProjectData = exports.useThemeConfig = exports.useTypography = exports.useColors = exports.useComponentConfig = exports.useThemeValue = exports.getAllVariables = exports.getVariable = exports.useVariant = exports.useTheme = void 0;
74
74
  var react_1 = __importStar(require("react"));
75
75
  var themes_1 = require("./themes");
76
76
  var darkenUtils_1 = require("./darkenUtils");
@@ -97,53 +97,64 @@ var useVariant = function () {
97
97
  };
98
98
  exports.useVariant = useVariant;
99
99
  /* -------------------------------------------------------------------------- */
100
- /* CDN THEME LOADER */
100
+ /* LOCAL FILE MANAGEMENT */
101
101
  /* -------------------------------------------------------------------------- */
102
- var loadThemeFromCDN = function (projectId) { return __awaiter(void 0, void 0, void 0, function () {
103
- var publicResponse, data, error_1, publicUrl, response, data, error_2;
102
+ var loadLocalTheme = function () { return __awaiter(void 0, void 0, void 0, function () {
103
+ var response, data, error_1;
104
104
  return __generator(this, function (_a) {
105
105
  switch (_a.label) {
106
106
  case 0:
107
107
  _a.trys.push([0, 4, , 5]);
108
- return [4 /*yield*/, fetch("/funui.json", {
108
+ return [4 /*yield*/, fetch('/funui.json', {
109
109
  cache: 'no-cache',
110
110
  })];
111
111
  case 1:
112
- publicResponse = _a.sent();
113
- if (!publicResponse.ok) return [3 /*break*/, 3];
114
- return [4 /*yield*/, publicResponse.json()];
112
+ response = _a.sent();
113
+ if (!response.ok) return [3 /*break*/, 3];
114
+ return [4 /*yield*/, response.json()];
115
115
  case 2:
116
116
  data = _a.sent();
117
- console.log('✅ Loaded theme from public folder');
117
+ console.log('✅ Loaded theme from local file');
118
118
  return [2 /*return*/, data];
119
119
  case 3: return [3 /*break*/, 5];
120
120
  case 4:
121
121
  error_1 = _a.sent();
122
- console.log('No theme in public folder, checking Firebase Storage...');
122
+ console.log('No local theme file found');
123
123
  return [3 /*break*/, 5];
124
- case 5:
125
- _a.trys.push([5, 10, , 11]);
124
+ case 5: return [2 /*return*/, null];
125
+ }
126
+ });
127
+ }); };
128
+ /* -------------------------------------------------------------------------- */
129
+ /* CDN THEME LOADER */
130
+ /* -------------------------------------------------------------------------- */
131
+ var loadThemeFromCDN = function (projectId) { return __awaiter(void 0, void 0, void 0, function () {
132
+ var publicUrl, response, data, error_2;
133
+ return __generator(this, function (_a) {
134
+ switch (_a.label) {
135
+ case 0:
136
+ _a.trys.push([0, 5, , 6]);
126
137
  publicUrl = "https://firebasestorage.googleapis.com/v0/b/funui-4bcd1.firebasestorage.app/o/themes%2F".concat(projectId, ".json?alt=media");
127
138
  return [4 /*yield*/, fetch(publicUrl, {
128
139
  cache: 'no-cache',
129
140
  })];
130
- case 6:
141
+ case 1:
131
142
  response = _a.sent();
132
- if (!response.ok) return [3 /*break*/, 8];
143
+ if (!response.ok) return [3 /*break*/, 3];
133
144
  return [4 /*yield*/, response.json()];
134
- case 7:
145
+ case 2:
135
146
  data = _a.sent();
136
147
  console.log('✅ Loaded theme from Firebase Storage CDN');
137
148
  return [2 /*return*/, data];
138
- case 8:
149
+ case 3:
139
150
  console.error('Firebase Storage fetch failed:', response.status, response.statusText);
140
- _a.label = 9;
141
- case 9: return [3 /*break*/, 11];
142
- case 10:
151
+ _a.label = 4;
152
+ case 4: return [3 /*break*/, 6];
153
+ case 5:
143
154
  error_2 = _a.sent();
144
155
  console.error('Error loading from Firebase Storage:', error_2);
145
- return [3 /*break*/, 11];
146
- case 11: return [2 /*return*/, null];
156
+ return [3 /*break*/, 6];
157
+ case 6: return [2 /*return*/, null];
147
158
  }
148
159
  });
149
160
  }); };
@@ -155,7 +166,6 @@ var applyTypographyVariables = function (typography, root) {
155
166
  return;
156
167
  Object.entries(typography).forEach(function (_a) {
157
168
  var key = _a[0], value = _a[1];
158
- // Convert flat keys to CSS custom property format
159
169
  var cssVarName = "--".concat(key.replace(/_/g, '-'));
160
170
  root.style.setProperty(cssVarName, value);
161
171
  });
@@ -165,7 +175,6 @@ var applyColorVariables = function (colors, root) {
165
175
  return;
166
176
  Object.entries(colors).forEach(function (_a) {
167
177
  var key = _a[0], value = _a[1];
168
- // Convert flat keys to CSS custom property format
169
178
  var cssVarName = "--".concat(key.replace(/_/g, '-'));
170
179
  root.style.setProperty(cssVarName, value);
171
180
  });
@@ -173,15 +182,12 @@ var applyColorVariables = function (colors, root) {
173
182
  var applyThemeConfig = function (themeConfig, root) {
174
183
  if (!themeConfig)
175
184
  return;
176
- // Apply colors if they exist
177
185
  if (themeConfig.colors) {
178
186
  applyColorVariables(themeConfig.colors, root);
179
187
  }
180
- // Apply typography if it exists
181
188
  if (themeConfig.typography) {
182
189
  applyTypographyVariables(themeConfig.typography, root);
183
190
  }
184
- // Apply any other theme config properties
185
191
  Object.entries(themeConfig).forEach(function (_a) {
186
192
  var key = _a[0], value = _a[1];
187
193
  if (key !== 'colors' && key !== 'typography' && typeof value === 'string') {
@@ -191,6 +197,23 @@ var applyThemeConfig = function (themeConfig, root) {
191
197
  });
192
198
  };
193
199
  /* -------------------------------------------------------------------------- */
200
+ /* VARIABLES HELPER */
201
+ /* -------------------------------------------------------------------------- */
202
+ var cachedProjectData = null;
203
+ var getVariable = function (name) {
204
+ if (!(cachedProjectData === null || cachedProjectData === void 0 ? void 0 : cachedProjectData.variables)) {
205
+ console.warn('No variables available. Make sure ThemeProvider is mounted.');
206
+ return undefined;
207
+ }
208
+ var variable = cachedProjectData.variables.find(function (v) { return v.name === name; });
209
+ return variable;
210
+ };
211
+ exports.getVariable = getVariable;
212
+ var getAllVariables = function () {
213
+ return (cachedProjectData === null || cachedProjectData === void 0 ? void 0 : cachedProjectData.variables) || [];
214
+ };
215
+ exports.getAllVariables = getAllVariables;
216
+ /* -------------------------------------------------------------------------- */
194
217
  /* COMPONENT */
195
218
  /* -------------------------------------------------------------------------- */
196
219
  var ThemeProvider = function (_a) {
@@ -223,7 +246,7 @@ var ThemeProvider = function (_a) {
223
246
  });
224
247
  }
225
248
  }, [theme]);
226
- /* ---------------------- CDN Theme Sync ----------------------- */
249
+ /* ---------------------- CDN Theme Sync with Local File ----------------------- */
227
250
  (0, react_1.useEffect)(function () {
228
251
  if (typeof window === 'undefined' || !projectId) {
229
252
  setIsLoading(false);
@@ -232,51 +255,68 @@ var ThemeProvider = function (_a) {
232
255
  }
233
256
  var root = document.documentElement;
234
257
  var pollTimer;
235
- var fetchFromCDN = function () { return __awaiter(void 0, void 0, void 0, function () {
236
- var cdnTheme, newVersion, err_1;
258
+ var syncTheme = function () { return __awaiter(void 0, void 0, void 0, function () {
259
+ var localTheme, localVersion, cdnTheme, cdnVersion, err_1;
237
260
  return __generator(this, function (_a) {
238
261
  switch (_a.label) {
239
262
  case 0:
240
- _a.trys.push([0, 2, 3, 4]);
241
- return [4 /*yield*/, loadThemeFromCDN(projectId)];
263
+ _a.trys.push([0, 3, 4, 5]);
264
+ return [4 /*yield*/, loadLocalTheme()];
242
265
  case 1:
266
+ localTheme = _a.sent();
267
+ localVersion = (localTheme === null || localTheme === void 0 ? void 0 : localTheme.version) || 0;
268
+ return [4 /*yield*/, loadThemeFromCDN(projectId)];
269
+ case 2:
243
270
  cdnTheme = _a.sent();
271
+ cdnVersion = (cdnTheme === null || cdnTheme === void 0 ? void 0 : cdnTheme.version) || 0;
244
272
  if (cdnTheme) {
245
- newVersion = cdnTheme.version || Date.now();
246
- if (!currentVersion || newVersion !== currentVersion) {
247
- // Apply theme data to CSS variables and state
273
+ // Compare versions and use the newer one
274
+ if (cdnVersion !== localVersion) {
275
+ console.log("\uD83D\uDD04 Version mismatch: Local(".concat(localVersion, ") vs CDN(").concat(cdnVersion, ")"));
276
+ console.log('â„šī¸ Using CDN version. Please update your local funui.json file manually.');
277
+ }
278
+ // Always use CDN theme if available
279
+ if (!currentVersion || cdnVersion !== currentVersion) {
248
280
  applyThemeData(cdnTheme, root);
249
- setCurrentVersion(newVersion);
250
- console.log('✅ Theme updated from CDN');
281
+ setCurrentVersion(cdnVersion);
282
+ console.log('✅ Theme loaded from CDN');
251
283
  }
252
284
  else {
253
- console.log('✓ Theme unchanged');
285
+ console.log('✓ Theme up to date');
254
286
  }
255
287
  setError(null);
256
288
  }
289
+ else if (localTheme) {
290
+ // CDN not available but we have local
291
+ console.log('âš ī¸ Using local theme (CDN unavailable)');
292
+ applyThemeData(localTheme, root);
293
+ setCurrentVersion(localVersion);
294
+ setError(null);
295
+ }
257
296
  else {
258
- console.warn('âš ī¸ No theme found in CDN');
259
- setError('Theme not found in CDN');
297
+ // No theme available anywhere
298
+ console.warn('âš ī¸ No theme found');
299
+ setError('Theme not found');
260
300
  }
261
- return [3 /*break*/, 4];
262
- case 2:
263
- err_1 = _a.sent();
264
- console.error('Error loading theme from CDN:', err_1);
265
- setError('Failed to load theme from CDN');
266
- return [3 /*break*/, 4];
301
+ return [3 /*break*/, 5];
267
302
  case 3:
303
+ err_1 = _a.sent();
304
+ console.error('Error syncing theme:', err_1);
305
+ setError('Failed to sync theme');
306
+ return [3 /*break*/, 5];
307
+ case 4:
268
308
  setIsLoading(false);
269
309
  setIsInitialLoad(false);
270
310
  return [7 /*endfinally*/];
271
- case 4: return [2 /*return*/];
311
+ case 5: return [2 /*return*/];
272
312
  }
273
313
  });
274
314
  }); };
275
- // Initial load
276
- fetchFromCDN();
315
+ // Initial sync
316
+ syncTheme();
277
317
  // Poll for updates every 5 minutes
278
318
  pollTimer = setInterval(function () {
279
- fetchFromCDN();
319
+ syncTheme();
280
320
  }, 5 * 60 * 1000);
281
321
  return function () {
282
322
  clearInterval(pollTimer);
@@ -289,6 +329,8 @@ var ThemeProvider = function (_a) {
289
329
  setVariant(newVariant);
290
330
  setThemeConfig(themeConfig);
291
331
  setProjectData(data);
332
+ // Cache for variable access
333
+ cachedProjectData = data;
292
334
  // Apply all theme config to CSS variables
293
335
  applyThemeConfig(themeConfig, root);
294
336
  };
@@ -346,22 +388,32 @@ var useProjectData = function () {
346
388
  return projectData;
347
389
  };
348
390
  exports.useProjectData = useProjectData;
349
- // Get specific color value
350
391
  var useColor = function (colorName) {
351
392
  var colors = (0, exports.useColors)();
352
393
  return colors[colorName];
353
394
  };
354
395
  exports.useColor = useColor;
355
- // Get specific typography value
356
396
  var useTypographyValue = function (property) {
357
397
  var typography = (0, exports.useTypography)();
358
398
  return typography[property];
359
399
  };
360
400
  exports.useTypographyValue = useTypographyValue;
361
- // Get component variant
362
401
  var useComponentVariant = function (componentName, variantName) {
363
402
  if (variantName === void 0) { variantName = 'default'; }
364
403
  var componentConfig = (0, exports.useComponentConfig)(componentName);
365
404
  return componentConfig[variantName] || {};
366
405
  };
367
406
  exports.useComponentVariant = useComponentVariant;
407
+ // Hook to access variables
408
+ var useVariables = function () {
409
+ var projectData = (0, exports.useTheme)().projectData;
410
+ return (projectData === null || projectData === void 0 ? void 0 : projectData.variables) || [];
411
+ };
412
+ exports.useVariables = useVariables;
413
+ // Hook to get a specific variable
414
+ var useVariable = function (name) {
415
+ var variables = (0, exports.useVariables)();
416
+ var variable = variables.find(function (v) { return v.name === name; });
417
+ return variable === null || variable === void 0 ? void 0 : variable.value;
418
+ };
419
+ exports.useVariable = useVariable;