Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 21 additions & 1 deletion packages/mini-apps-ui-kit-react/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,32 @@ The library uses the following font **[TWK Lausanne](https://weltkern.com/typefa

## Importing Styles

To use the UI Kit components with their proper styling, you need to import the styles in your application. Add the following import statement to your application's entry point (e.g., `app/layout.tsx` for Next.js or `main.tsx` for Vite):
To use the UI Kit components with their proper styling, you need to import the styles in your application. The library provides multiple CSS files for maximum compatibility:

### **Tailwind v3 Projects (Recommended for most users)**
```typescript
import "@worldcoin/mini-apps-ui-kit-react/styles.css";
// or explicitly
import "@worldcoin/mini-apps-ui-kit-react/styles-v3.css";
```

### **Tailwind v4 Projects**
```typescript
import "@worldcoin/mini-apps-ui-kit-react/styles-v4.css";
```

### **CSS File Differences**

- **`styles.css`** - Backward-compatible version (same as v3, recommended for most users)
- **`styles-v3.css`** - Explicitly marked v3-compatible version
- **`styles-v4.css` - Modern v4 version with @layer directives

### **Why Multiple Versions?**

This library supports both Tailwind v3 and v4 to ensure maximum compatibility across different projects. The v3 versions work in any project, while the v4 version provides modern CSS features for projects that can use them.

> **💡 Tip**: If you're unsure which version to use, start with `styles.css` - it's designed to work everywhere.

## Icons

The library uses a custom set of icons built on top of [Iconoir](https://iconoir.com/). While we provide our own custom set, we highly recommend using Iconoir directly for your miniapps as it offers a comprehensive and well-maintained icon system.
Expand Down
22 changes: 15 additions & 7 deletions packages/mini-apps-ui-kit-react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,11 @@
"storybook": "storybook dev -p 6006",
"format": "prettier --write \"**/*.{ts,tsx,md}\"",
"sb:move": "mv ./storybook-static ../../storybook-static",
"dev:sb": "concurrently \"tailwindcss -i ./styles/globals.css -o ./dist/globals.css --watch\" \"pnpm storybook\"",
"build:tailwind": "tailwindcss -i ./styles/globals.css -o ./dist/globals.css --minify",
"build:sb": "pnpm build:tailwind && storybook build",
"build": "tsc -b ./tsconfig.lib.json && vite build && pnpm build:tailwind",
"dev:sb": "concurrently \"npx @tailwindcss/cli -i ./styles/globals.css -o ./dist/globals.css --watch\" \"pnpm storybook\"",
"build:sb": "vite build && storybook build",
"build": "tsc -b ./tsconfig.lib.json && vite build",
"build:css": "node scripts/build-css.js",
"build:all": "pnpm build && pnpm build:css",
"lint": "eslint .",
"publish:manual": "pnpm build && npm publish --access public",
"generate:country-codes": "node scripts/generate-country-codes.js",
Expand All @@ -37,6 +38,7 @@
},
"devDependencies": {
"@chromatic-com/storybook": "^3.2.2",
"@csstools/postcss-cascade-layers": "^5.0.2",
"@eslint/js": "^9.13.0",
"@storybook/addon-essentials": "^8.4.7",
"@storybook/addon-interactions": "^8.4.7",
Expand All @@ -48,10 +50,12 @@
"@storybook/react-vite": "^8.4.7",
"@storybook/test": "^8.4.7",
"@storybook/theming": "^8.5.5",
"@tailwindcss/vite": "^4.1.11",
"@types/glob": "^8.1.0",
"@types/react": "^18.3.12",
"@types/react-dom": "^18.3.1",
"@vitejs/plugin-react": "^4.3.3",
"autoprefixer": "^10.4.21",
"concurrently": "^9.1.0",
"eslint": "^9.13.0",
"eslint-plugin-react": "^7.37.2",
Expand All @@ -60,12 +64,14 @@
"eslint-plugin-storybook": "^0.11.1",
"glob": "^11.0.0",
"globals": "^15.11.0",
"postcss": "^8",
"postcss-cli": "^11.0.1",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"rollup-plugin-visualizer": "^6.0.3",
"rollup-preserve-directives": "^1.1.3",
"storybook": "^8.4.7",
"tailwindcss": "^3.4.15",
"tailwindcss": "^4.1.11",
"tailwindcss-animate": "^1.0.7",
"typescript": "~5.6.2",
"typescript-eslint": "^8.11.0",
Expand Down Expand Up @@ -98,6 +104,9 @@
"import": "./dist/index.js",
"require": "./dist/index.js"
},
"./styles.css": "./dist/styles.css",
"./styles-v3.css": "./dist/styles-v3.css",
"./styles-v4.css": "./dist/styles-v4.css",
"./Button": {
"types": "./dist/components/Button/index.d.ts",
"default": "./dist/components/Button/index.js"
Expand Down Expand Up @@ -266,7 +275,6 @@
"types": "./dist/tailwind/index.d.ts",
"import": "./dist/tailwind/index.js",
"require": "./dist/tailwind/index.js"
},
"./styles.css": "./dist/globals.css"
}
}
}
8 changes: 8 additions & 0 deletions packages/mini-apps-ui-kit-react/postcss-v3.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import removeLayersPlugin from './scripts/postcss-remove-layers.js';

export default {
plugins: {
autoprefixer: {},
removeLayersPlugin: {},
},
};
5 changes: 5 additions & 0 deletions packages/mini-apps-ui-kit-react/postcss.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export default {
plugins: {
autoprefixer: {},
},
};
92 changes: 92 additions & 0 deletions packages/mini-apps-ui-kit-react/scripts/build-css.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
#!/usr/bin/env node

import fs from 'fs';
import path from 'path';
import { execSync } from 'child_process';

console.log('🚀 Building CSS files for both Tailwind v3 and v4...');

// First, build the project using Vite (this generates the v4 CSS)
console.log('\n📦 Building project with Vite (generates v4 CSS)...');
try {
execSync('pnpm build', { stdio: 'inherit' });
console.log('✅ Vite build completed successfully');
} catch (error) {
console.error('❌ Failed to build project:', error.message);
process.exit(1);
}

// Check if the v4 CSS was generated
const v4CSSPath = './dist/styles.css';
if (!fs.existsSync(v4CSSPath)) {
console.error('❌ V4 CSS file not found. Make sure the build completed successfully.');
process.exit(1);
}

// Read the v4 CSS immediately after Vite build (before any processing)
console.log('\n📦 Reading generated v4 CSS...');
const v4CSS = fs.readFileSync(v4CSSPath, 'utf8');

// Create v4 CSS file (preserve with @layer directives)
console.log('\n📦 Creating v4 CSS file...');
fs.writeFileSync('./dist/styles-v4.css', v4CSS);
console.log('✅ v4 CSS file created (with @layer directives preserved)');

// Create v3 compatible CSS using PostCSS with @csstools/postcss-cascade-layers
console.log('\n📦 Creating v3 compatible CSS using PostCSS...');
try {
// Import PostCSS and the cascade layers plugin
const postcss = await import('postcss');
const cascadeLayers = await import('@csstools/postcss-cascade-layers');
const autoprefixer = await import('autoprefixer');

// Process the CSS to remove @layer directives
const result = await postcss.default([
cascadeLayers.default({
// This will remove all @layer directives and flatten the CSS
onRevertLayerKeyword: (layerName) => {
console.log(`Removing @layer directive: ${layerName}`);
}
}),
autoprefixer.default
]).process(v4CSS, {
from: undefined,
to: undefined
});

// Write the processed CSS
fs.writeFileSync('./dist/styles-v3.css', result.css);
console.log('✅ v3 CSS file created using @csstools/postcss-cascade-layers');

} catch (error) {
console.error('❌ Failed to process CSS with PostCSS:', error.message);
console.log('🔄 Falling back to regex method...');

// Fallback to regex method
const v3CSS = v4CSS
.replace(/@layer\s+(\w+)\s*\{([^}]*)\}/g, '$2')
.replace(/@layer\s+[^;]+;/g, '')
.replace(/@layer\s+\w+\s*\{/g, '')
.replace(/\}\s*@layer/g, '')
.replace(/\n\s*\n\s*\n/g, '\n\n')
.trim();

fs.writeFileSync('./dist/styles-v3.css', v3CSS);
console.log('✅ v3 CSS file created using fallback method');
}

// Update the main styles.css to be v3 compatible (for backward compatibility)
console.log('\n📦 Updating main styles.css to be v3 compatible...');
const v3CSS = fs.readFileSync('./dist/styles-v3.css', 'utf8');
fs.writeFileSync('./dist/styles.css', v3CSS);
console.log('✅ Main styles.css updated for v3 compatibility');

console.log('\n🎉 All CSS files built successfully!');
console.log('\n📁 Generated files:');
console.log(' • dist/styles.css (v3 compatible, backward compatible)');
console.log(' • dist/styles-v3.css (v3 compatible, @layer directives removed)');
console.log(' • dist/styles-v4.css (v4 compatible, @layer directives preserved)');
console.log('\n💡 Usage:');
console.log(' • For Tailwind v3 projects: import "styles.css" or "styles-v3.css"');
console.log(' • For Tailwind v4 projects: import "styles-v4.css"');
console.log('\n⚠️ Note: The v3 versions have @layer directives safely removed using @csstools/postcss-cascade-layers');
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/**
* PostCSS plugin to remove @layer directives for Tailwind v3 compatibility
*/
export default function removeLayersPlugin() {
return {
postcssPlugin: 'postcss-remove-layers',
AtRule: {
layer(atRule) {
console.log(`Found @layer: ${atRule.name} with ${atRule.nodes?.length || 0} nodes`);

// Remove the @layer atrule but keep its content
if (atRule.nodes && atRule.nodes.length > 0) {
// Move all child nodes to the parent
atRule.parent.insertBefore(atRule, atRule.nodes);
}
// Remove the @layer atrule itself (including standalone statements)
atRule.remove();
}
},
// Also handle any remaining @layer references that might not be caught
Once(root) {
// Find and remove any remaining @layer statements
root.walkAtRules('layer', (atRule) => {
console.log(`Walking found @layer: ${atRule.name}`);
if (atRule.nodes && atRule.nodes.length > 0) {
atRule.parent.insertBefore(atRule, atRule.nodes);
}
atRule.remove();
});
}
};
}

removeLayersPlugin.postcss = true;
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { forwardRef } from "react";
const bottomBarVariants = cva("w-full gap-4", {
variants: {
direction: {
horizontal: "grid grid-cols-1 [&>*]:col-span-1 [&:has(>*:nth-child(2))]:grid-cols-2",
horizontal: "grid grid-cols-1 *:col-span-1 [&:has(>*:nth-child(2))]:grid-cols-2",
vertical: "flex flex-col-reverse",
},
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@ const sizeClasses: Record<CircularIconSize, string> = {
sm: "size-11",
md: "size-12",
lg: "size-16",
xl: "size-[5.5rem]",
xl: "size-22",
};

const iconClasses: Record<CircularIconSize, string> = {
xs: "size-[0.875rem]",
sm: "size-[1.5rem]",
md: "size-[1.625rem]",
lg: "size-[2.125rem]",
xs: "size-3.5",
sm: "size-6",
md: "size-6.5",
lg: "size-8.5",
xl: "size-12",
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ function CircularState({ value, size, className, ...props }: CircularStateProps)
"text-gray-0",
size !== "xs" && "shadow-[inset_0_0_0_1px_rgba(255,255,255,0.3)]",
iconClasses[value],
"bg-[radial-gradient(111.32%_111.8%_at_22.73%_0%,_rgba(255,255,255,0.2)_0%,_rgba(255,255,255,0)_100%)]",
"bg-[radial-gradient(111.32%_111.8%_at_22.73%_0%,rgba(255,255,255,0.2)_0%,rgba(255,255,255,0)_100%)]",
className,
)}
size={size}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const ColorPickerItem = forwardRef<HTMLButtonElement, ColorPickerItemProps>(
<RadioGroup.Item
ref={ref}
value={value}
className="size-[3.25rem] cursor-default rounded-full outline-none flex items-center justify-center relative disabled:opacity-90 disabled:cursor-not-allowed"
className="size-13 cursor-default rounded-full outline-none flex items-center justify-center relative disabled:opacity-90 disabled:cursor-not-allowed"
style={{
background: value,
}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ const Message = forwardRef<
<RadixForm.Message
ref={ref}
className={cn(
"h-[1.625rem] mt-1 flex items-center",
"h-6.5 mt-1 flex items-center",
typographyVariants({
variant: "body",
level: 4,
Expand Down
12 changes: 6 additions & 6 deletions packages/mini-apps-ui-kit-react/src/components/Input/Input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const inputContainerVariants = cva(
[
"bg-gray-100",
"text-gray-900",
"h-[3.5rem]",
"h-14",
"inline-flex",
"w-full",
"shrink",
Expand Down Expand Up @@ -100,16 +100,16 @@ const floatingLabelVariants = cva([
"ease-out",
// Peer states for floating effect (when input has value or is focused)
"peer-focus:pointer-events-auto",
"peer-focus:top-[1.125rem]",
"peer-focus:top-4.5",
"peer-focus:text-xs",
"peer-focus:bg-base-100", // Match input background
// State when placeholder is not shown (i.e., input has value)
"peer-[:not(:placeholder-shown)]:pointer-events-auto",
"peer-[:not(:placeholder-shown)]:top-[1.125rem]",
"peer-[:not(:placeholder-shown)]:text-xs",
"peer-not-placeholder-shown:pointer-events-auto",
"peer-not-placeholder-shown:top-4.5",
"peer-not-placeholder-shown:text-xs",
]);

const dividerVariants = cva("border-r h-[1.625rem] w-1", {
const dividerVariants = cva("border-r h-6.5 w-1", {
variants: {
error: {
true: "border-error-600",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { forwardRef } from "react";
import { Typography } from "../Typography";

const listItemStyles = cva(
"h-[4.75rem] bg-gray-50 p-4 rounded-2xl flex items-center text-gray-900 w-full disabled:text-gray-400 disabled:cursor-not-allowed",
"h-19 bg-gray-50 p-4 rounded-2xl flex items-center text-gray-900 w-full disabled:text-gray-400 disabled:cursor-not-allowed",
);

/**
Expand All @@ -32,8 +32,8 @@ const ListItem = forwardRef<HTMLButtonElement, ListItemProps>(
({ children, label, description, startAdornment, endAdornment, disabled, ...props }, ref) => {
return (
<button ref={ref} className={listItemStyles()} {...props} disabled={disabled}>
{startAdornment && <div className="mr-3 flex-shrink-0">{startAdornment}</div>}
<div className="flex flex-col flex-grow min-w-0 items-start gap-0.5">
{startAdornment && <div className="mr-3 shrink-0">{startAdornment}</div>}
<div className="flex flex-col grow min-w-0 items-start gap-0.5">
{label && (
<Typography variant="subtitle" level={2} className="truncate grow w-full text-left">
{label}
Expand All @@ -51,7 +51,7 @@ const ListItem = forwardRef<HTMLButtonElement, ListItemProps>(
</Typography>
)}
</div>
{endAdornment && <div className="ml-4 flex-shrink-0">{endAdornment}</div>}
{endAdornment && <div className="ml-4 shrink-0">{endAdornment}</div>}
</button>
);
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const Marble = forwardRef<HTMLImageElement, ComponentProps<"img">>((props, ref)
ref={ref}
alt="Marble"
className={cn(
"rounded-full border-2 border-gray-100 p-[3px] aspect-square w-[7.5rem] object-cover",
"rounded-full border-2 border-gray-100 p-[3px] aspect-square w-30 object-cover",
className,
)}
{...rest}
Expand Down
Loading