@openzeppelin/ui-components 1.7.0 → 2.0.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.
package/README.md CHANGED
@@ -137,11 +137,29 @@ components/
137
137
 
138
138
  Components are styled using Tailwind CSS. The necessary Tailwind configuration is expected to be present in the consuming application. The UI package itself does not bundle CSS but provides the class names and structure.
139
139
 
140
- Import the shared styles from `@openzeppelin/ui-styles`:
140
+ Important: a bare Tailwind import is not enough for OpenZeppelin packages. Tailwind v4 must be told to scan the relevant `@openzeppelin/*` sources, or some component classes will be omitted from the final CSS.
141
+
142
+ For consumer apps that use `@openzeppelin/ui-dev-cli`, the recommended workflow is:
143
+
144
+ ```bash
145
+ pnpm exec oz-ui-dev tailwind doctor --project "$PWD"
146
+ pnpm exec oz-ui-dev tailwind fix --project "$PWD"
147
+ ```
148
+
149
+ That creates a managed `oz-tailwind.generated.css` file and keeps the `@source` wiring in sync with your installed dependencies.
150
+
151
+ If you need to configure Tailwind manually, import the shared styles and register the OpenZeppelin package sources explicitly:
141
152
 
142
153
  ```css
154
+ @layer base, components, utilities;
155
+
156
+ @import 'tailwindcss' source(none);
157
+ @source "../node_modules/@openzeppelin/ui-components";
158
+ @source "../node_modules/@openzeppelin/ui-react";
159
+ @source "../node_modules/@openzeppelin/ui-renderer";
160
+ @source "../node_modules/@openzeppelin/ui-styles";
161
+ @source "../node_modules/@openzeppelin/ui-utils";
143
162
  @import '@openzeppelin/ui-styles/global.css';
144
- @import 'tailwindcss';
145
163
  ```
146
164
 
147
165
  ## Development
package/dist/index.cjs CHANGED
@@ -38,7 +38,7 @@ let sonner = require("sonner");
38
38
  let next_themes = require("next-themes");
39
39
 
40
40
  //#region src/version.ts
41
- const VERSION = "1.7.0";
41
+ const VERSION = "2.0.0";
42
42
 
43
43
  //#endregion
44
44
  //#region src/components/ui/accordion.tsx
@@ -2674,13 +2674,13 @@ const MAX_SUGGESTIONS = 5;
2674
2674
  * 2. TransactionForm renders the overall form structure with React Hook Form
2675
2675
  * 3. DynamicFormField selects the appropriate field component (like AddressField) based on field type
2676
2676
  * 4. BaseField provides consistent layout and hook form integration
2677
- * 5. This component handles blockchain address-specific rendering and validation using the passed adapter
2677
+ * 5. This component handles blockchain address-specific rendering and validation using the passed addressing capability
2678
2678
  *
2679
2679
  * The component includes:
2680
2680
  * - Integration with React Hook Form
2681
- * - Blockchain address validation through adapter-provided custom validation
2681
+ * - Blockchain address validation through the provided addressing capability
2682
2682
  * - Automatic error handling and reporting
2683
- * - Chain-agnostic design (validation handled by adapters)
2683
+ * - Chain-agnostic design (validation handled by capabilities)
2684
2684
  * - Full accessibility support with ARIA attributes
2685
2685
  * - Keyboard navigation
2686
2686
  *
@@ -2695,7 +2695,7 @@ const MAX_SUGGESTIONS = 5;
2695
2695
  * The suggestion dropdown includes built-in debouncing, keyboard navigation (Arrow keys,
2696
2696
  * Enter, Escape), click-outside dismissal, and ARIA listbox semantics.
2697
2697
  */
2698
- function AddressField({ id, label, placeholder, helperText, control, name, width = "full", validation, adapter, readOnly, suggestions: suggestionsProp, onSuggestionSelect }) {
2698
+ function AddressField({ id, label, placeholder, helperText, control, name, width = "full", validation, addressing, readOnly, suggestions: suggestionsProp, onSuggestionSelect }) {
2699
2699
  const isRequired = !!validation?.required;
2700
2700
  const errorId = `${id}-error`;
2701
2701
  const descriptionId = `${id}-description`;
@@ -2778,8 +2778,8 @@ function AddressField({ id, label, placeholder, helperText, control, name, width
2778
2778
  if (value === void 0 || value === null || value === "") return validation?.required ? "This field is required" : true;
2779
2779
  const standardValidationResult = require_ErrorMessage.validateField(value, validation);
2780
2780
  if (standardValidationResult !== true) return standardValidationResult;
2781
- if (adapter && typeof value === "string") {
2782
- if (!adapter.isValidAddress(value)) return "Invalid address format for the selected chain";
2781
+ if (addressing && typeof value === "string") {
2782
+ if (!addressing.isValidAddress(value)) return "Invalid address format for the selected chain";
2783
2783
  }
2784
2784
  return true;
2785
2785
  } },
@@ -3335,7 +3335,7 @@ ArrayField.displayName = "ArrayField";
3335
3335
  * The component combines the functionality of ArrayField and ObjectField to handle
3336
3336
  * complex nested data structures commonly found in blockchain contracts.
3337
3337
  */
3338
- function ArrayObjectField({ id, label, helperText, control, name, width = "full", validation, components = [], minItems = 0, maxItems, renderProperty, collapsible = true, defaultCollapsed = false, readOnly, adapter, contractSchema }) {
3338
+ function ArrayObjectField({ id, label, helperText, control, name, width = "full", validation, components = [], minItems = 0, maxItems, renderProperty, collapsible = true, defaultCollapsed = false, readOnly, typeMapping, contractSchema }) {
3339
3339
  const isRequired = !!validation?.required;
3340
3340
  const errorId = `${id}-error`;
3341
3341
  const descriptionId = `${id}-description`;
@@ -3452,8 +3452,8 @@ function ArrayObjectField({ id, label, helperText, control, name, width = "full"
3452
3452
  }), !isCollapsed && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
3453
3453
  className: "space-y-4 mt-4",
3454
3454
  children: components.map((component) => {
3455
- if (!adapter) throw new Error(`ArrayObjectField: No adapter provided for field generation. Cannot generate field for "${component.name}"`);
3456
- const generatedField = adapter.generateDefaultField(component, contractSchema);
3455
+ if (!typeMapping) throw new Error(`ArrayObjectField: No typeMapping capability provided for field generation. Cannot generate field for "${component.name}"`);
3456
+ const generatedField = typeMapping.generateDefaultField(component, contractSchema);
3457
3457
  const propertyField = {
3458
3458
  ...generatedField,
3459
3459
  id: `${id}-${index}-${component.name}`,
@@ -5166,7 +5166,7 @@ NumberField.displayName = "NumberField";
5166
5166
  * The component reuses existing field components for individual properties,
5167
5167
  * maintaining consistency across the form system while supporting complex nested structures.
5168
5168
  */
5169
- function ObjectField({ id, label, helperText, control, name, width = "full", validation, components = [], renderProperty, showCard = true, readOnly, adapter, contractSchema }) {
5169
+ function ObjectField({ id, label, helperText, control, name, width = "full", validation, components = [], renderProperty, showCard = true, readOnly, typeMapping, contractSchema }) {
5170
5170
  const isRequired = !!validation?.required;
5171
5171
  const errorId = `${id}-error`;
5172
5172
  const descriptionId = `${id}-description`;
@@ -5193,8 +5193,8 @@ function ObjectField({ id, label, helperText, control, name, width = "full", val
5193
5193
  className: "text-muted-foreground text-sm",
5194
5194
  children: "No properties defined for this object"
5195
5195
  }) : components.map((component) => {
5196
- if (!adapter) throw new Error(`ObjectField: No adapter provided for field generation. Cannot generate field for "${component.name}"`);
5197
- const generatedField = adapter.generateDefaultField(component, contractSchema);
5196
+ if (!typeMapping) throw new Error(`ObjectField: No typeMapping capability provided for field generation. Cannot generate field for "${component.name}"`);
5197
+ const generatedField = typeMapping.generateDefaultField(component, contractSchema);
5198
5198
  const propertyField = {
5199
5199
  ...generatedField,
5200
5200
  id: `${id}-${component.name}`,
@@ -6216,19 +6216,19 @@ function useNetworkErrors() {
6216
6216
  return context;
6217
6217
  }
6218
6218
  /**
6219
- * Hook for reporting network errors for a specific adapter
6219
+ * Hook for reporting network errors for a specific runtime-bound capability
6220
6220
  */
6221
- function useNetworkErrorReporter(adapter) {
6221
+ function useNetworkErrorReporter(capability) {
6222
6222
  const { reportNetworkError } = useNetworkErrors();
6223
6223
  return {
6224
6224
  reportRpcError: (0, react.useCallback)((message) => {
6225
- if (!adapter) return;
6226
- reportNetworkError("rpc", adapter.networkConfig.id, adapter.networkConfig.name, message);
6227
- }, [adapter, reportNetworkError]),
6225
+ if (!capability) return;
6226
+ reportNetworkError("rpc", capability.networkConfig.id, capability.networkConfig.name, message);
6227
+ }, [capability, reportNetworkError]),
6228
6228
  reportExplorerError: (0, react.useCallback)((message) => {
6229
- if (!adapter) return;
6230
- reportNetworkError("explorer", adapter.networkConfig.id, adapter.networkConfig.name, message);
6231
- }, [adapter, reportNetworkError])
6229
+ if (!capability) return;
6230
+ reportNetworkError("explorer", capability.networkConfig.id, capability.networkConfig.name, message);
6231
+ }, [capability, reportNetworkError])
6232
6232
  };
6233
6233
  }
6234
6234
 
@@ -6237,15 +6237,15 @@ function useNetworkErrorReporter(adapter) {
6237
6237
  /**
6238
6238
  * Creates an adapter proxy that intercepts and reports network errors
6239
6239
  */
6240
- function useNetworkErrorAwareAdapter(adapter) {
6240
+ function useNetworkErrorAwareAdapter(capability) {
6241
6241
  const { reportNetworkError } = useNetworkErrors();
6242
- const wrappedAdapterRef = (0, react.useRef)(null);
6242
+ const wrappedCapabilityRef = (0, react.useRef)(null);
6243
6243
  (0, react.useEffect)(() => {
6244
- if (!adapter) {
6245
- wrappedAdapterRef.current = null;
6244
+ if (!capability) {
6245
+ wrappedCapabilityRef.current = null;
6246
6246
  return;
6247
6247
  }
6248
- wrappedAdapterRef.current = new Proxy(adapter, { get(target, prop, receiver) {
6248
+ wrappedCapabilityRef.current = new Proxy(capability, { get(target, prop, receiver) {
6249
6249
  const value = Reflect.get(target, prop, receiver);
6250
6250
  if (typeof value === "function" && (prop === "queryViewFunction" || prop === "loadContract")) return async (...args) => {
6251
6251
  try {
@@ -6259,8 +6259,8 @@ function useNetworkErrorAwareAdapter(adapter) {
6259
6259
  };
6260
6260
  return value;
6261
6261
  } });
6262
- }, [adapter, reportNetworkError]);
6263
- return wrappedAdapterRef.current;
6262
+ }, [capability, reportNetworkError]);
6263
+ return wrappedCapabilityRef.current;
6264
6264
  }
6265
6265
 
6266
6266
  //#endregion