@niibase/uniwind 1.5.0 → 1.6.0

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.
Files changed (108) hide show
  1. package/CHANGELOG.md +1197 -0
  2. package/dist/common/components/web/ActivityIndicator.js +3 -1
  3. package/dist/common/components/web/Button.js +3 -1
  4. package/dist/common/components/web/FlatList.js +3 -1
  5. package/dist/common/components/web/Image.js +3 -1
  6. package/dist/common/components/web/ImageBackground.js +3 -1
  7. package/dist/common/components/web/KeyboardAvoidingView.js +3 -1
  8. package/dist/common/components/web/Modal.js +3 -1
  9. package/dist/common/components/web/Pressable.js +3 -1
  10. package/dist/common/components/web/RefreshControl.js +3 -1
  11. package/dist/common/components/web/SafeAreaView.js +3 -1
  12. package/dist/common/components/web/ScrollView.js +3 -1
  13. package/dist/common/components/web/SectionList.js +3 -1
  14. package/dist/common/components/web/Switch.js +3 -1
  15. package/dist/common/components/web/Text.js +3 -1
  16. package/dist/common/components/web/TextInput.js +3 -1
  17. package/dist/common/components/web/TouchableHighlight.js +3 -1
  18. package/dist/common/components/web/TouchableOpacity.js +3 -1
  19. package/dist/common/components/web/TouchableWithoutFeedback.js +3 -1
  20. package/dist/common/components/web/View.js +2 -0
  21. package/dist/common/components/web/VirtualizedList.js +3 -1
  22. package/dist/common/components/web/generateDataSet.js +18 -0
  23. package/dist/common/core/config/config.common.js +6 -3
  24. package/dist/common/core/web/cssListener.js +58 -6
  25. package/dist/common/core/web/getWebStyles.js +20 -18
  26. package/dist/common/css/extraUtilities.js +19 -0
  27. package/dist/common/css/index.js +2 -3
  28. package/dist/common/css/insets.js +2 -2
  29. package/dist/common/css/overwrite.js +2 -2
  30. package/dist/common/css/variants.js +2 -2
  31. package/dist/metro/metro-transformer.cjs +41 -7
  32. package/dist/metro/metro-transformer.mjs +41 -7
  33. package/dist/module/components/web/ActivityIndicator.js +3 -1
  34. package/dist/module/components/web/Button.js +3 -1
  35. package/dist/module/components/web/FlatList.js +3 -1
  36. package/dist/module/components/web/Image.js +3 -1
  37. package/dist/module/components/web/ImageBackground.js +3 -1
  38. package/dist/module/components/web/KeyboardAvoidingView.js +3 -1
  39. package/dist/module/components/web/Modal.js +3 -1
  40. package/dist/module/components/web/Pressable.js +3 -1
  41. package/dist/module/components/web/RefreshControl.js +3 -1
  42. package/dist/module/components/web/SafeAreaView.js +3 -1
  43. package/dist/module/components/web/ScrollView.js +3 -1
  44. package/dist/module/components/web/SectionList.js +3 -1
  45. package/dist/module/components/web/Switch.js +3 -1
  46. package/dist/module/components/web/Text.js +3 -1
  47. package/dist/module/components/web/TextInput.js +3 -1
  48. package/dist/module/components/web/TouchableHighlight.js +3 -1
  49. package/dist/module/components/web/TouchableOpacity.js +3 -1
  50. package/dist/module/components/web/TouchableWithoutFeedback.js +3 -1
  51. package/dist/module/components/web/View.js +2 -0
  52. package/dist/module/components/web/VirtualizedList.js +3 -1
  53. package/dist/module/components/web/generateDataSet.d.ts +32 -0
  54. package/dist/module/components/web/generateDataSet.js +9 -0
  55. package/dist/module/core/config/config.common.d.ts +2 -1
  56. package/dist/module/core/config/config.common.js +6 -3
  57. package/dist/module/core/web/cssListener.d.ts +6 -1
  58. package/dist/module/core/web/cssListener.js +58 -6
  59. package/dist/module/core/web/getWebStyles.js +21 -18
  60. package/dist/module/css/extraUtilities.d.ts +1 -0
  61. package/dist/module/css/extraUtilities.js +20 -0
  62. package/dist/module/css/index.js +8 -8
  63. package/dist/module/css/insets.d.ts +1 -1
  64. package/dist/module/css/insets.js +2 -1
  65. package/dist/module/css/overwrite.d.ts +1 -1
  66. package/dist/module/css/overwrite.js +1 -1
  67. package/dist/module/css/variants.d.ts +1 -1
  68. package/dist/module/css/variants.js +2 -1
  69. package/dist/module/index.d.ts +1 -0
  70. package/dist/shared/{uniwind.DTMo4epG.cjs → uniwind.BZyFsest.cjs} +28 -6
  71. package/dist/shared/{uniwind.BWb5KNML.mjs → uniwind.C-rHhHOg.mjs} +28 -6
  72. package/dist/vite/index.cjs +1 -1
  73. package/dist/vite/index.mjs +1 -1
  74. package/package.json +4 -2
  75. package/src/components/web/ActivityIndicator.tsx +2 -0
  76. package/src/components/web/Button.tsx +2 -0
  77. package/src/components/web/FlatList.tsx +2 -0
  78. package/src/components/web/Image.tsx +2 -0
  79. package/src/components/web/ImageBackground.tsx +2 -0
  80. package/src/components/web/KeyboardAvoidingView.tsx +2 -0
  81. package/src/components/web/Modal.tsx +2 -0
  82. package/src/components/web/Pressable.tsx +2 -0
  83. package/src/components/web/RefreshControl.tsx +2 -0
  84. package/src/components/web/SafeAreaView.tsx +2 -0
  85. package/src/components/web/ScrollView.tsx +2 -0
  86. package/src/components/web/SectionList.tsx +2 -0
  87. package/src/components/web/Switch.tsx +2 -0
  88. package/src/components/web/Text.tsx +2 -0
  89. package/src/components/web/TextInput.tsx +2 -0
  90. package/src/components/web/TouchableHighlight.tsx +2 -0
  91. package/src/components/web/TouchableOpacity.tsx +2 -0
  92. package/src/components/web/TouchableWithoutFeedback.tsx +2 -0
  93. package/src/components/web/View.tsx +2 -0
  94. package/src/components/web/VirtualizedList.tsx +2 -0
  95. package/src/components/web/generateDataSet.ts +52 -0
  96. package/src/components/web/rnw.ts +1 -1
  97. package/src/core/config/config.common.ts +7 -3
  98. package/src/core/web/cssListener.ts +73 -6
  99. package/src/core/web/getWebStyles.ts +26 -25
  100. package/src/css/extraUtilities.ts +26 -0
  101. package/src/css/index.ts +8 -8
  102. package/src/css/insets.ts +3 -1
  103. package/src/css/overwrite.ts +1 -1
  104. package/src/css/variants.ts +3 -1
  105. package/src/index.ts +1 -0
  106. package/src/metro/processor/css.ts +35 -0
  107. package/src/metro/utils/serialize.ts +13 -8
  108. package/uniwind.css +8 -0
@@ -1,19 +1,24 @@
1
1
  declare class CSSListenerBuilder {
2
+ activeRules: Set<CSSStyleRule>;
2
3
  private classNameMediaQueryListeners;
3
4
  private listeners;
4
- private registeredRules;
5
+ private registeredRulesMediaQueries;
5
6
  private processedStyleSheets;
6
7
  private pendingInitialization;
7
8
  constructor();
8
9
  subscribeToClassName(classNames: string, listener: VoidFunction): () => void;
9
10
  private scheduleInitialization;
10
11
  private cancelPendingInitialization;
12
+ private pruneStaleRules;
11
13
  private initialize;
12
14
  private isStyleRule;
13
15
  private isMediaRule;
16
+ private isSupportsRule;
14
17
  private collectParentMediaQueries;
15
18
  private addMediaQueriesDeep;
16
19
  private addMediaQuery;
20
+ private isRuleLive;
21
+ private toggleRule;
17
22
  }
18
23
  export declare const CSSListener: CSSListenerBuilder;
19
24
  export {};
@@ -1,9 +1,10 @@
1
1
  import { StyleDependency } from "../../types.js";
2
2
  import { UniwindListener } from "../listener.js";
3
3
  class CSSListenerBuilder {
4
+ activeRules = /* @__PURE__ */ new Set();
4
5
  classNameMediaQueryListeners = /* @__PURE__ */ new Map();
5
6
  listeners = /* @__PURE__ */ new Map();
6
- registeredRules = /* @__PURE__ */ new Map();
7
+ registeredRulesMediaQueries = /* @__PURE__ */ new Map();
7
8
  processedStyleSheets = /* @__PURE__ */ new WeakSet();
8
9
  pendingInitialization = void 0;
9
10
  constructor() {
@@ -12,6 +13,17 @@ class CSSListenerBuilder {
12
13
  }
13
14
  const observer = new MutationObserver((mutations) => {
14
15
  for (const mutation of mutations) {
16
+ if (mutation.type === "attributes") {
17
+ const el = mutation.target;
18
+ if (!("sheet" in el)) {
19
+ continue;
20
+ }
21
+ const sheet = el.sheet;
22
+ if (sheet) {
23
+ this.processedStyleSheets.delete(sheet);
24
+ }
25
+ this.scheduleInitialization();
26
+ }
15
27
  if (mutation.type === "childList") {
16
28
  this.scheduleInitialization();
17
29
  }
@@ -65,8 +77,17 @@ class CSSListenerBuilder {
65
77
  this.pendingInitialization = void 0;
66
78
  }
67
79
  }
80
+ pruneStaleRules() {
81
+ const activeSheets = new Set(Array.from(document.styleSheets));
82
+ for (const rule of this.activeRules) {
83
+ if (!rule.parentStyleSheet || !activeSheets.has(rule.parentStyleSheet)) {
84
+ this.activeRules.delete(rule);
85
+ }
86
+ }
87
+ }
68
88
  initialize() {
69
89
  this.pendingInitialization = void 0;
90
+ this.pruneStaleRules();
70
91
  for (const sheet of Array.from(document.styleSheets)) {
71
92
  if (this.processedStyleSheets.has(sheet)) {
72
93
  continue;
@@ -90,6 +111,9 @@ class CSSListenerBuilder {
90
111
  isMediaRule(rule) {
91
112
  return rule.constructor.name === "CSSMediaRule";
92
113
  }
114
+ isSupportsRule(rule) {
115
+ return rule.constructor.name === "CSSSupportsRule";
116
+ }
93
117
  collectParentMediaQueries(rule, acc = []) {
94
118
  const { parentRule } = rule;
95
119
  if (!parentRule) {
@@ -106,32 +130,60 @@ class CSSListenerBuilder {
106
130
  for (const rule of Array.from(rules)) {
107
131
  if (this.isStyleRule(rule)) {
108
132
  const mediaQueries = this.collectParentMediaQueries(rule);
133
+ this.activeRules.add(rule);
109
134
  if (mediaQueries.length > 0) {
110
- this.addMediaQuery(mediaQueries, rule.selectorText);
135
+ this.addMediaQuery(mediaQueries, rule);
111
136
  }
112
137
  continue;
113
138
  }
139
+ if (this.isSupportsRule(rule)) {
140
+ if (!CSS.supports(rule.conditionText)) {
141
+ continue;
142
+ }
143
+ this.addMediaQueriesDeep(rule.cssRules);
144
+ continue;
145
+ }
114
146
  if ("cssRules" in rule && rule.cssRules instanceof CSSRuleList) {
115
147
  this.addMediaQueriesDeep(rule.cssRules);
116
148
  continue;
117
149
  }
118
150
  }
119
151
  }
120
- addMediaQuery(mediaQueries, className) {
152
+ addMediaQuery(mediaQueries, rule) {
153
+ const className = rule.selectorText;
121
154
  const rules = mediaQueries.map((mediaQuery) => mediaQuery.conditionText).sort().join(" and ");
122
155
  const parsedClassName = className.replace(".", "").replace("\\", "");
123
- const cachedMediaQueryList = this.registeredRules.get(rules);
156
+ const cachedMediaQueryList = this.registeredRulesMediaQueries.get(rules);
124
157
  if (cachedMediaQueryList) {
125
158
  this.classNameMediaQueryListeners.set(parsedClassName, cachedMediaQueryList);
159
+ this.toggleRule(cachedMediaQueryList, rule);
160
+ cachedMediaQueryList.addEventListener("change", () => {
161
+ this.toggleRule(cachedMediaQueryList, rule);
162
+ });
126
163
  return;
127
164
  }
128
165
  const mediaQueryList = window.matchMedia(rules);
129
- this.registeredRules.set(rules, mediaQueryList);
166
+ this.toggleRule(mediaQueryList, rule);
167
+ this.registeredRulesMediaQueries.set(rules, mediaQueryList);
130
168
  this.listeners.set(mediaQueryList, /* @__PURE__ */ new Set());
131
169
  this.classNameMediaQueryListeners.set(parsedClassName, mediaQueryList);
132
170
  mediaQueryList.addEventListener("change", () => {
133
- this.listeners.get(mediaQueryList).forEach((listener) => listener());
171
+ this.listeners.get(mediaQueryList).forEach((listener) => {
172
+ listener();
173
+ });
174
+ this.toggleRule(mediaQueryList, rule);
134
175
  });
135
176
  }
177
+ isRuleLive(rule) {
178
+ const sheet = rule.parentStyleSheet;
179
+ return sheet !== null && Array.from(document.styleSheets).includes(sheet);
180
+ }
181
+ toggleRule(mqList, rule) {
182
+ if (mqList.matches && this.isRuleLive(rule)) {
183
+ this.activeRules.add(rule);
184
+ } else {
185
+ this.activeRules.delete(rule);
186
+ }
187
+ }
136
188
  }
137
189
  export const CSSListener = new CSSListenerBuilder();
@@ -1,3 +1,4 @@
1
+ import { CSSListener } from "./cssListener.js";
1
2
  import { parseCSSValue } from "./parseCSSValue.js";
2
3
  const dummyParent = typeof document !== "undefined" ? Object.assign(document.createElement("div"), {
3
4
  style: "display: none"
@@ -7,28 +8,30 @@ if (dummyParent && dummy) {
7
8
  document.body.appendChild(dummyParent);
8
9
  dummyParent.appendChild(dummy);
9
10
  }
10
- const getComputedStyles = () => {
11
+ const getActiveStylesForClass = (className) => {
12
+ const extractedStyles = {};
11
13
  if (!dummy) {
12
- return {};
14
+ return extractedStyles;
13
15
  }
16
+ const classNames = className.split(/\s+/).filter(Boolean);
14
17
  const computedStyles = window.getComputedStyle(dummy);
15
- const styles = {};
16
- for (let i = 0; i < computedStyles.length; i++) {
17
- const prop = computedStyles[i];
18
- styles[prop] = computedStyles.getPropertyValue(prop);
19
- }
20
- return styles;
21
- };
22
- const initialStyles = typeof document !== "undefined" ? getComputedStyles() : {};
23
- const getObjectDifference = (obj1, obj2) => {
24
- const diff = {};
25
- const keys = Object.keys(obj2);
26
- keys.forEach((key) => {
27
- if (obj2[key] !== obj1[key]) {
28
- diff[key] = obj2[key];
18
+ CSSListener.activeRules.forEach((rule) => {
19
+ const selector = rule.selectorText;
20
+ const mightMatch = classNames.some((cls) => selector.includes(`.${CSS.escape(cls)}`));
21
+ if (!mightMatch) {
22
+ return;
23
+ }
24
+ const safeSelector = selector.replace(/::[a-z-]+/gi, "");
25
+ try {
26
+ if (safeSelector !== "" && dummy.matches(safeSelector)) {
27
+ for (const propertyName of rule.style) {
28
+ extractedStyles[propertyName] = computedStyles.getPropertyValue(propertyName);
29
+ }
30
+ }
31
+ } catch {
29
32
  }
30
33
  });
31
- return diff;
34
+ return extractedStyles;
32
35
  };
33
36
  export const getWebStyles = (className, uniwindContext) => {
34
37
  if (className === void 0) {
@@ -43,7 +46,7 @@ export const getWebStyles = (className, uniwindContext) => {
43
46
  dummyParent?.removeAttribute("class");
44
47
  }
45
48
  dummy.className = className;
46
- const computedStyles = getObjectDifference(initialStyles, getComputedStyles());
49
+ const computedStyles = getActiveStylesForClass(className);
47
50
  return Object.fromEntries(
48
51
  Object.entries(computedStyles).map(([key, value]) => {
49
52
  const parsedKey = key[0] === "-" ? key : key.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase());
@@ -0,0 +1 @@
1
+ export declare const EXTRA_UTILITIES_CSS: string;
@@ -0,0 +1,20 @@
1
+ const toKebabCase = (str) => str.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`);
2
+ const generateExtraUtilities = (map) => {
3
+ return Object.entries(map).map(
4
+ ([name, style]) => [
5
+ `@utility ${name} {`,
6
+ ...Object.entries(style).map(([key, value]) => ` ${toKebabCase(key)}: ${value};`),
7
+ `}`,
8
+ ""
9
+ ].join("\n")
10
+ ).join("\n");
11
+ };
12
+ const EXTRA_UTILITIES_MAP = {
13
+ "border-continuous": {
14
+ borderCurve: "continuous"
15
+ },
16
+ "border-circular": {
17
+ borderCurve: "circular"
18
+ }
19
+ };
20
+ export const EXTRA_UTILITIES_CSS = generateExtraUtilities(EXTRA_UTILITIES_MAP);
@@ -1,20 +1,20 @@
1
1
  import fs from "fs";
2
2
  import path from "path";
3
- import { generateCSSForInsets } from "./insets.js";
4
- import { overwrite } from "./overwrite.js";
3
+ import { EXTRA_UTILITIES_CSS } from "./extraUtilities.js";
4
+ import { INSETS_CSS } from "./insets.js";
5
+ import { OVERWRITE_CSS } from "./overwrite.js";
5
6
  import { generateCSSForThemes } from "./themes.js";
6
- import { generateCSSForVariants } from "./variants.js";
7
+ import { VARIANTS_CSS } from "./variants.js";
7
8
  const dirname = typeof __dirname !== "undefined" ? __dirname : import.meta.dirname;
8
9
  export const buildCSS = async (themes, input) => {
9
- const variants = generateCSSForVariants();
10
- const insets = generateCSSForInsets();
11
10
  const themesCSS = await generateCSSForThemes(themes, input);
12
11
  const cssFilePath = path.join(dirname, "../../uniwind.css");
13
12
  const oldCSSFile = fs.existsSync(cssFilePath) ? fs.readFileSync(cssFilePath, "utf-8") : "";
14
13
  const newCssFile = [
15
- variants,
16
- insets,
17
- overwrite,
14
+ VARIANTS_CSS,
15
+ INSETS_CSS,
16
+ OVERWRITE_CSS,
17
+ EXTRA_UTILITIES_CSS,
18
18
  themesCSS
19
19
  ].join("\n");
20
20
  if (oldCSSFile === newCssFile) {
@@ -1 +1 @@
1
- export declare const generateCSSForInsets: () => string;
1
+ export declare const INSETS_CSS: string;
@@ -3,7 +3,7 @@ const sides = ["inset", "x", "y", "top", "bottom", "left", "right"];
3
3
  const safeAreaTypes = ["safe", "safe-or-*", "safe-offset-*"];
4
4
  const spacing = "--spacing(--value(integer))";
5
5
  const length = "--value([length], --spacing-*)";
6
- export const generateCSSForInsets = () => {
6
+ const generateCSSForInsets = () => {
7
7
  let css = `@utility h-screen-safe {
8
8
  height: calc(100vh - (env(safe-area-inset-top) + env(safe-area-inset-bottom)));
9
9
  }
@@ -86,3 +86,4 @@ export const generateCSSForInsets = () => {
86
86
  });
87
87
  return css.slice(0, -1);
88
88
  };
89
+ export const INSETS_CSS = generateCSSForInsets();
@@ -1 +1 @@
1
- export declare const overwrite = "@custom-variant disabled {\n &:disabled {\n @slot;\n }\n\n &[aria-disabled=\"true\"] {\n @slot;\n }\n\n &[readonly] {\n @slot;\n }\n}\n";
1
+ export declare const OVERWRITE_CSS = "@custom-variant disabled {\n &:disabled {\n @slot;\n }\n\n &[aria-disabled=\"true\"] {\n @slot;\n }\n\n &[readonly] {\n @slot;\n }\n}\n";
@@ -12,4 +12,4 @@ const overwriteDisabled = `@custom-variant disabled {
12
12
  }
13
13
  }
14
14
  `;
15
- export const overwrite = overwriteDisabled;
15
+ export const OVERWRITE_CSS = overwriteDisabled;
@@ -1 +1 @@
1
- export declare const generateCSSForVariants: () => string;
1
+ export declare const VARIANTS_CSS: string;
@@ -1,5 +1,5 @@
1
1
  const variants = ["ios", "android", "web", "native", "tv", "android-tv", "apple-tv"];
2
- export const generateCSSForVariants = () => {
2
+ const generateCSSForVariants = () => {
3
3
  let css = "";
4
4
  variants.forEach((variant) => {
5
5
  css += `@custom-variant ${variant} (${variant === "web" ? "html &" : `@media ${variant}`});
@@ -7,3 +7,4 @@ export const generateCSSForVariants = () => {
7
7
  });
8
8
  return css;
9
9
  };
10
+ export const VARIANTS_CSS = generateCSSForVariants();
@@ -1,5 +1,6 @@
1
1
  export * from './components/ScopedTheme';
2
2
  export { Uniwind } from './core';
3
+ export type { ThemeName } from './core/types';
3
4
  export { withUniwind } from './hoc';
4
5
  export type { ApplyUniwind, ApplyUniwindOptions } from './hoc/types';
5
6
  export { useCSSVariable, useResolveClassNames, useUniwind } from './hooks';
@@ -215,6 +215,27 @@ class UniwindCSSVisitor {
215
215
  StyleSheet;
216
216
  }
217
217
 
218
+ const toKebabCase = (str) => str.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`);
219
+ const generateExtraUtilities = (map) => {
220
+ return Object.entries(map).map(
221
+ ([name, style]) => [
222
+ `@utility ${name} {`,
223
+ ...Object.entries(style).map(([key, value]) => ` ${toKebabCase(key)}: ${value};`),
224
+ `}`,
225
+ ""
226
+ ].join("\n")
227
+ ).join("\n");
228
+ };
229
+ const EXTRA_UTILITIES_MAP = {
230
+ "border-continuous": {
231
+ borderCurve: "continuous"
232
+ },
233
+ "border-circular": {
234
+ borderCurve: "circular"
235
+ }
236
+ };
237
+ const EXTRA_UTILITIES_CSS = generateExtraUtilities(EXTRA_UTILITIES_MAP);
238
+
218
239
  const types = ["margin", "padding", "inset"];
219
240
  const sides = ["inset", "x", "y", "top", "bottom", "left", "right"];
220
241
  const safeAreaTypes = ["safe", "safe-or-*", "safe-offset-*"];
@@ -301,6 +322,7 @@ const generateCSSForInsets = () => {
301
322
  });
302
323
  return css.slice(0, -1);
303
324
  };
325
+ const INSETS_CSS = generateCSSForInsets();
304
326
 
305
327
  const overwriteDisabled = `@custom-variant disabled {
306
328
  &:disabled {
@@ -316,7 +338,7 @@ const overwriteDisabled = `@custom-variant disabled {
316
338
  }
317
339
  }
318
340
  `;
319
- const overwrite = overwriteDisabled;
341
+ const OVERWRITE_CSS = overwriteDisabled;
320
342
 
321
343
  const readFileSafe = (filePath) => {
322
344
  try {
@@ -440,18 +462,18 @@ const generateCSSForVariants = () => {
440
462
  });
441
463
  return css;
442
464
  };
465
+ const VARIANTS_CSS = generateCSSForVariants();
443
466
 
444
467
  const dirname = typeof __dirname !== "undefined" ? __dirname : undefined;
445
468
  const buildCSS = async (themes, input) => {
446
- const variants = generateCSSForVariants();
447
- const insets = generateCSSForInsets();
448
469
  const themesCSS = await generateCSSForThemes(themes, input);
449
470
  const cssFilePath = path__default.join(dirname, "../../uniwind.css");
450
471
  const oldCSSFile = fs__default.existsSync(cssFilePath) ? fs__default.readFileSync(cssFilePath, "utf-8") : "";
451
472
  const newCssFile = [
452
- variants,
453
- insets,
454
- overwrite,
473
+ VARIANTS_CSS,
474
+ INSETS_CSS,
475
+ OVERWRITE_CSS,
476
+ EXTRA_UTILITIES_CSS,
455
477
  themesCSS
456
478
  ].join("\n");
457
479
  if (oldCSSFile === newCssFile) {
@@ -208,6 +208,27 @@ class UniwindCSSVisitor {
208
208
  StyleSheet;
209
209
  }
210
210
 
211
+ const toKebabCase = (str) => str.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`);
212
+ const generateExtraUtilities = (map) => {
213
+ return Object.entries(map).map(
214
+ ([name, style]) => [
215
+ `@utility ${name} {`,
216
+ ...Object.entries(style).map(([key, value]) => ` ${toKebabCase(key)}: ${value};`),
217
+ `}`,
218
+ ""
219
+ ].join("\n")
220
+ ).join("\n");
221
+ };
222
+ const EXTRA_UTILITIES_MAP = {
223
+ "border-continuous": {
224
+ borderCurve: "continuous"
225
+ },
226
+ "border-circular": {
227
+ borderCurve: "circular"
228
+ }
229
+ };
230
+ const EXTRA_UTILITIES_CSS = generateExtraUtilities(EXTRA_UTILITIES_MAP);
231
+
211
232
  const types = ["margin", "padding", "inset"];
212
233
  const sides = ["inset", "x", "y", "top", "bottom", "left", "right"];
213
234
  const safeAreaTypes = ["safe", "safe-or-*", "safe-offset-*"];
@@ -294,6 +315,7 @@ const generateCSSForInsets = () => {
294
315
  });
295
316
  return css.slice(0, -1);
296
317
  };
318
+ const INSETS_CSS = generateCSSForInsets();
297
319
 
298
320
  const overwriteDisabled = `@custom-variant disabled {
299
321
  &:disabled {
@@ -309,7 +331,7 @@ const overwriteDisabled = `@custom-variant disabled {
309
331
  }
310
332
  }
311
333
  `;
312
- const overwrite = overwriteDisabled;
334
+ const OVERWRITE_CSS = overwriteDisabled;
313
335
 
314
336
  const readFileSafe = (filePath) => {
315
337
  try {
@@ -433,18 +455,18 @@ const generateCSSForVariants = () => {
433
455
  });
434
456
  return css;
435
457
  };
458
+ const VARIANTS_CSS = generateCSSForVariants();
436
459
 
437
460
  const dirname = typeof __dirname !== "undefined" ? __dirname : import.meta.dirname;
438
461
  const buildCSS = async (themes, input) => {
439
- const variants = generateCSSForVariants();
440
- const insets = generateCSSForInsets();
441
462
  const themesCSS = await generateCSSForThemes(themes, input);
442
463
  const cssFilePath = path.join(dirname, "../../uniwind.css");
443
464
  const oldCSSFile = fs.existsSync(cssFilePath) ? fs.readFileSync(cssFilePath, "utf-8") : "";
444
465
  const newCssFile = [
445
- variants,
446
- insets,
447
- overwrite,
466
+ VARIANTS_CSS,
467
+ INSETS_CSS,
468
+ OVERWRITE_CSS,
469
+ EXTRA_UTILITIES_CSS,
448
470
  themesCSS
449
471
  ].join("\n");
450
472
  if (oldCSSFile === newCssFile) {
@@ -3,7 +3,7 @@
3
3
  const node = require('@tailwindcss/node');
4
4
  const path = require('path');
5
5
  const common = require('../shared/uniwind.nl8746mK.cjs');
6
- const stringifyThemes = require('../shared/uniwind.DTMo4epG.cjs');
6
+ const stringifyThemes = require('../shared/uniwind.BZyFsest.cjs');
7
7
  require('fs');
8
8
  require('lightningcss');
9
9
 
@@ -1,7 +1,7 @@
1
1
  import { normalizePath } from '@tailwindcss/node';
2
2
  import path from 'path';
3
3
  import { u as uniq, n as name } from '../shared/uniwind.F-0-Rr--.mjs';
4
- import { s as stringifyThemes, U as UniwindCSSVisitor, a as buildCSS, b as buildDtsFile } from '../shared/uniwind.BWb5KNML.mjs';
4
+ import { s as stringifyThemes, U as UniwindCSSVisitor, a as buildCSS, b as buildDtsFile } from '../shared/uniwind.C-rHhHOg.mjs';
5
5
  import 'fs';
6
6
  import 'lightningcss';
7
7
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "private": false,
3
3
  "name": "@niibase/uniwind",
4
- "version": "1.5.0",
4
+ "version": "1.6.0",
5
5
  "description": "A fork of Uniwind with Reanimated 4 support",
6
6
  "homepage": "https://uniwind.dev",
7
7
  "author": "Unistack",
@@ -18,6 +18,7 @@
18
18
  "prepublishOnly": "bun run build",
19
19
  "circular:check": "dpdm --no-warning --no-tree -T --exit-code circular:1 'src/**/*.ts' 'src/**/*.tsx'",
20
20
  "build:css": "bun run src/css/index.ts",
21
+ "postinstall": "node scripts/postinstall.mjs",
21
22
  "test:native": "jest --config jest.config.native.js",
22
23
  "test:web": "jest --config jest.config.web.js",
23
24
  "test:e2e": "playwright test",
@@ -77,6 +78,7 @@
77
78
  "uniwind.css",
78
79
  "types.d.ts",
79
80
  "readme.md",
81
+ "CHANGELOG.md",
80
82
  "LICENSE"
81
83
  ],
82
84
  "dependencies": {
@@ -119,7 +121,7 @@
119
121
  "ts-jest": "29.4.6",
120
122
  "typescript": "catalog:",
121
123
  "unbuild": "3.6.1",
122
- "vite": "7.3.1",
124
+ "vite": "catalog:",
123
125
  "esbuild": "0.27.3"
124
126
  }
125
127
  }
@@ -1,6 +1,7 @@
1
1
  import { ActivityIndicator as RNActivityIndicator, ActivityIndicatorProps } from 'react-native'
2
2
  import { useUniwindAccent } from '../../hooks'
3
3
  import { copyComponentProperties } from '../utils'
4
+ import { generateDataSet } from './generateDataSet'
4
5
  import { toRNWClassName } from './rnw'
5
6
 
6
7
  export const ActivityIndicator = copyComponentProperties(RNActivityIndicator, (props: ActivityIndicatorProps) => {
@@ -11,6 +12,7 @@ export const ActivityIndicator = copyComponentProperties(RNActivityIndicator, (p
11
12
  {...props}
12
13
  style={[toRNWClassName(props.className), props.style]}
13
14
  color={props.color ?? color}
15
+ dataSet={generateDataSet(props)}
14
16
  />
15
17
  )
16
18
  })
@@ -1,6 +1,7 @@
1
1
  import { Button as RNButton, ButtonProps } from 'react-native'
2
2
  import { useUniwindAccent } from '../../hooks'
3
3
  import { copyComponentProperties } from '../utils'
4
+ import { generateDataSet } from './generateDataSet'
4
5
 
5
6
  export const Button = copyComponentProperties(RNButton, (props: ButtonProps) => {
6
7
  const color = useUniwindAccent(props.colorClassName)
@@ -9,6 +10,7 @@ export const Button = copyComponentProperties(RNButton, (props: ButtonProps) =>
9
10
  <RNButton
10
11
  {...props}
11
12
  color={props.color ?? color}
13
+ dataSet={generateDataSet(props)}
12
14
  />
13
15
  )
14
16
  })
@@ -1,5 +1,6 @@
1
1
  import { FlatList as RNFlatList, FlatListProps } from 'react-native'
2
2
  import { copyComponentProperties } from '../utils'
3
+ import { generateDataSet } from './generateDataSet'
3
4
  import { toRNWClassName } from './rnw'
4
5
 
5
6
  export const FlatList = copyComponentProperties(RNFlatList, (props: FlatListProps<unknown>) => {
@@ -13,6 +14,7 @@ export const FlatList = copyComponentProperties(RNFlatList, (props: FlatListProp
13
14
  contentContainerStyle={[toRNWClassName(props.contentContainerClassName), props.contentContainerStyle]}
14
15
  ListFooterComponentStyle={[toRNWClassName(props.ListFooterComponentClassName), props.ListFooterComponentStyle]}
15
16
  ListHeaderComponentStyle={[toRNWClassName(props.ListHeaderComponentClassName), props.ListHeaderComponentStyle]}
17
+ dataSet={generateDataSet(props)}
16
18
  />
17
19
  )
18
20
  })
@@ -1,6 +1,7 @@
1
1
  import { Image as RNImage, ImageProps } from 'react-native'
2
2
  import { useResolveClassNames, useUniwindAccent } from '../../hooks'
3
3
  import { copyComponentProperties } from '../utils'
4
+ import { generateDataSet } from './generateDataSet'
4
5
  import { toRNWClassName } from './rnw'
5
6
 
6
7
  export const Image = copyComponentProperties(RNImage, (props: ImageProps) => {
@@ -18,6 +19,7 @@ export const Image = copyComponentProperties(RNImage, (props: ImageProps) => {
18
19
  {...props}
19
20
  style={[toRNWClassName(props.className), styleReset, props.style]}
20
21
  tintColor={props.tintColor ?? tintColor}
22
+ dataSet={generateDataSet(props)}
21
23
  />
22
24
  )
23
25
  })
@@ -1,6 +1,7 @@
1
1
  import { ImageBackground as RNImageBackground, ImageBackgroundProps } from 'react-native'
2
2
  import { useUniwindAccent } from '../../hooks'
3
3
  import { copyComponentProperties } from '../utils'
4
+ import { generateDataSet } from './generateDataSet'
4
5
  import { toRNWClassName } from './rnw'
5
6
 
6
7
  export const ImageBackground = copyComponentProperties(RNImageBackground, (props: ImageBackgroundProps) => {
@@ -12,6 +13,7 @@ export const ImageBackground = copyComponentProperties(RNImageBackground, (props
12
13
  style={[toRNWClassName(props.className), props.style]}
13
14
  imageStyle={[toRNWClassName(props.imageClassName), props.imageStyle]}
14
15
  tintColor={props.tintColor ?? tintColor}
16
+ dataSet={generateDataSet(props)}
15
17
  />
16
18
  )
17
19
  })
@@ -1,5 +1,6 @@
1
1
  import { KeyboardAvoidingView as RNKeyboardAvoidingView, KeyboardAvoidingViewProps } from 'react-native'
2
2
  import { copyComponentProperties } from '../utils'
3
+ import { generateDataSet } from './generateDataSet'
3
4
  import { toRNWClassName } from './rnw'
4
5
 
5
6
  export const KeyboardAvoidingView = copyComponentProperties(RNKeyboardAvoidingView, (props: KeyboardAvoidingViewProps) => {
@@ -8,6 +9,7 @@ export const KeyboardAvoidingView = copyComponentProperties(RNKeyboardAvoidingVi
8
9
  {...props}
9
10
  style={[toRNWClassName(props.className), props.style]}
10
11
  contentContainerStyle={[toRNWClassName(props.contentContainerClassName), props.contentContainerStyle]}
12
+ dataSet={generateDataSet(props)}
11
13
  />
12
14
  )
13
15
  })
@@ -1,5 +1,6 @@
1
1
  import { Modal as RNModal, ModalProps } from 'react-native'
2
2
  import { copyComponentProperties } from '../utils'
3
+ import { generateDataSet } from './generateDataSet'
3
4
  import { toRNWClassName } from './rnw'
4
5
 
5
6
  export const Modal = copyComponentProperties(RNModal, (props: ModalProps) => {
@@ -7,6 +8,7 @@ export const Modal = copyComponentProperties(RNModal, (props: ModalProps) => {
7
8
  <RNModal
8
9
  {...props}
9
10
  style={[toRNWClassName(props.className), props.style]}
11
+ dataSet={generateDataSet(props)}
10
12
  />
11
13
  )
12
14
  })
@@ -1,5 +1,6 @@
1
1
  import { Pressable as RNPressable, PressableProps } from 'react-native'
2
2
  import { copyComponentProperties } from '../utils'
3
+ import { generateDataSet } from './generateDataSet'
3
4
  import { toRNWClassName } from './rnw'
4
5
 
5
6
  export const Pressable = copyComponentProperties(RNPressable, (props: PressableProps) => {
@@ -7,6 +8,7 @@ export const Pressable = copyComponentProperties(RNPressable, (props: PressableP
7
8
  <RNPressable
8
9
  {...props}
9
10
  style={state => [toRNWClassName(props.className), typeof props.style === 'function' ? props.style(state) : props.style]}
11
+ dataSet={generateDataSet(props)}
10
12
  />
11
13
  )
12
14
  })
@@ -1,5 +1,6 @@
1
1
  import { RefreshControl as RNRefreshControl, RefreshControlProps } from 'react-native'
2
2
  import { copyComponentProperties } from '../utils'
3
+ import { generateDataSet } from './generateDataSet'
3
4
  import { toRNWClassName } from './rnw'
4
5
 
5
6
  export const RefreshControl = copyComponentProperties(RNRefreshControl, (props: RefreshControlProps) => {
@@ -7,6 +8,7 @@ export const RefreshControl = copyComponentProperties(RNRefreshControl, (props:
7
8
  <RNRefreshControl
8
9
  {...props}
9
10
  style={[toRNWClassName(props.className), props.style]}
11
+ dataSet={generateDataSet(props)}
10
12
  />
11
13
  )
12
14
  })