Releases: AINativeKit/chatgpt-apps-sdk-ui
0.17.0
[0.17.0] - 2025-11-26
Fixed
-
Map Component:
- Resolved Stamen tile 401 errors by adding free tile provider alternatives
- Removed non-functional settings icon from sidebar header
-
PhotoCarousel Component:
- Navigation arrows now use Button component for consistent styling
- Added dark mode support to navigation dots using design tokens
- Improved nav button hover/active states to match Carousel component
Changed
- Carousel Component:
- Updated nav button hover/active states for consistency with PhotoCarousel
Documentation
- Added
imagesarray example to FullscreenMap stories showing multi-photo locations - Documented PhotoCarousel integration with MapInspector
0.16.0
[0.16.0] - 2025-11-25
Added
- Map Component Features:
- Multi-Tile Provider Support: Added 15+ built-in tile provider presets
- OpenStreetMap variants (Standard, HOT, France, Black & White)
- CartoDB variants (Positron, Voyager, Dark Matter)
- Stadia Maps (OSM Bright, Outdoors, Alidade Smooth)
- Stamen terrain maps
- USGS topographic maps
- Easily switch between providers with
tileProviderprop
- Attribution Control: New
hideAttributionprop to hide tile provider attribution- Default:
false(attribution shown) - Useful for screenshots or when attribution is provided elsewhere
- Default:
- Multi-Tile Provider Support: Added 15+ built-in tile provider presets
Changed
- ExpandableText Component:
- Enhanced text truncation logic for more accurate line counting
- Updated default labels: "view more" → "View more", "view less" → "View less" (capitalized)
- Improved HTML tag support documentation with
<br>tag examples - Increased default
maxLinesfrom 3 to 4 for better content preview
Fixed
- Map Component:
- Cleaner attribution display with proper spacing and formatting
- ExpandableText Component:
- Fixed text rendering to properly handle browser default line heights
- Improved expand/collapse behavior for edge cases
- MapInspector Component:
- Fixed literal
<br>tags displaying in descriptions instead of line breaks - Now properly renders HTML line breaks in location descriptions
- Fixed literal
- Storybook:
- Fixed dark mode toggle functionality in Storybook environment
- Theme switching now works correctly for development and documentation
0.15.0
🗺️ Map Component Enhancements & Display Mode Sync
A new release is here — bringing major improvements to the Map component and fixing a critical display-mode synchronization issue with the ChatGPT Apps SDK.
✨ Key Features
🔄 Display Mode Synchronization
- Automatic sync with ChatGPT: The Map now listens for changes to ChatGPT’s displayMode.
- Auto-collapse on close: When the user clicks ChatGPT’s “X” fullscreen close button, the map collapses back to compact mode.
- Two-way sync: The widget reacts to internal and external mode changes.
- State-aware behavior: Sync applies only in uncontrolled mode, allowing apps with external state management to stay in control.
🚀 Auto-Expand on Carousel Click
- Introduces a new autoExpandOnCarouselClick prop.
- When enabled, clicking a carousel card automatically expands the map to fullscreen.
- Makes accessing detailed location info a one-click action.
- Default: false (opt-in).
🎯 Interaction Controls
Popup Control (showPopup)
- Allows disabling marker popup bubbles.
- Useful when using side panels, inspectors, or custom UI.
- Default: true.
Scroll Wheel Zoom (scrollWheelZoom)
- Fine-tune zoom behavior:
- true: Native Leaflet scroll-wheel zoom (best for fullscreen)
- false: Custom pinch-to-zoom for embedded maps
- Default: false.
🎨 Custom Marker Rendering
- New renderMarker API supporting React-based marker customization.
- Works for global marker styles, per-location overrides, or hybrid patterns.
- Includes performance-friendly cleanup routines.
📚 Documentation Updates
- Added detailed explanation of display-mode synchronization.
- New ChatGPT Apps SDK Integration section.
- Updated interaction-control docs.
- Added examples for custom marker rendering.
🐛 Bug Fixes
Fixed: Display Mode Sync Regression
Before:
- Map did not respond when ChatGPT switched from fullscreen → inline.
- Result: fullscreen maps remained stuck open.
Now:
- Map collapses correctly when ChatGPT exits fullscreen.
- Achieved using a new useDisplayMode() hook and an effect sync loop.
📦 Installation
npm install @ainativekit/ui@0.15.0
🔗 Links
- npm Package
- https://www.npmjs.com/package/@ainativekit/ui/v/0.15.0
- Changelog
- https://github.com/AINativeKit/chatgpt-apps-sdk-ui/blob/main/CHANGELOG.md#0150—2025-11-25
- Documentation
- https://github.com/AINativeKit/chatgpt-apps-sdk-ui#readme
0.14.0
[0.14.0] - 2025-11-24
Breaking Changes
-
Map Components: Removed
markerColorandselectedMarkerColorprops- Markers now use
var(--ai-color-brand-primary)from ThemeProvider - Migration: Remove color props, customize via
<ThemeProvider brandColors={{ primary: '#your-color' }}> - Simplifies API by 40% (fewer props to manage)
- Markers now use
-
Component Rename:
LocationCard→MapPlaceCard- Updated all exports, tests, and documentation
- Migration: Update imports from
LocationCardtoMapPlaceCard - Added new
variantprop:'carousel' | 'list'
Added
-
Map Features:
- Hybrid marker variant: dots for unselected, pins for selected markers
- React element support for Feature icons (custom SVG components)
- Three marker variants:
'pin','dot','hybrid'(recommended)
-
New Components:
PhotoCarousel: Embla-based carousel with navigation dots and arrowsExpandableText: Text with inline "view more/less" functionalityOverlay: Generic overlay component for images (extracted from SummaryCard)
-
MapInspector Enhancements:
- Multiple images support with PhotoCarousel
- ExpandableText for long descriptions
- Uses Button component for bottom actions
- Added
imagesandtopOverlayfields to LocationData type
-
Storybook:
- ThemeProvider integration with
brandColorsconfiguration - Marker variants showcase (pin, dot, hybrid side-by-side)
- Separate state per example to prevent race conditions
- ThemeProvider integration with
Changed
-
Visual Design:
- Replaced box-shadows with borders for cleaner appearance
- Map popup arrow positioning improved (seamless connection)
- MapInspector image aspect ratio: 16:9 → 5:4 (better for property photos)
- Overlay default height: 40px → 56px
-
Theme System:
- All accent colors standardized to
var(--ai-color-brand-primary) - Components: AlbumCard, FilmStrip, Button, List, LocationCard focus outlines
- Optional theme context with graceful CSS variable fallback
- All accent colors standardized to
-
Code Quality:
- MapPlaceCard variant system (~700 lines removed)
- SummaryCard uses shared Overlay component
- MapInspector uses Button component instead of custom CSS
- MapSidebar simplified (92 lines removed)
Fixed
- Map popup arrow displays cleanly below popup box (no overlapping borders)
- Dot marker variant now properly shows dots for selected state
- React Hook dependency warnings (added MARKER_COLOR to deps)
- TypeScript errors with optional theme context
- SummaryCard test selectors updated for renamed CSS classes
0.13.0
🎉 What's New
Embla Carousel Integration
This release implements Embla Carousel's official Thumbnails pattern for the Album components, providing smooth, accessible photo navigation with proper API-to-API synchronization.
✨ Features
AlbumViewer Enhancements
- 🎠 Embla Carousel Integration - Replaced custom navigation with Embla carousel
- 👆 Swipe Gestures - Native touch/swipe support for photo navigation
- 🔄 API Synchronization - Proper carousel sync between main viewer and thumbnails
- 📭 Empty State Support - New
hideWhenEmptyandemptyStateContentprops - ⌨️ Enhanced Keyboard Navigation - Arrow keys and Escape integrated with Embla API
FilmStrip Improvements
- 🎠 Vertical Carousel - Converted to Embla carousel with vertical axis
- 🖱️ Mouse-Wheel Support - Added
embla-carousel-wheel-gesturesplugin for desktop accessibility - 🎯 Drag-Free Scrolling - Natural, momentum-based thumbnail navigation
- 🔄 Smart Synchronization - API-to-API sync with main photo carousel
- 🎨 Vertical Centering - Better UX with centered thumbnail layout
Responsive Design
- 📱 3-Breakpoint System - Progressive enhancement across mobile (< 640px), tablet (≥ 640px), and desktop-wide (≥ 1024px)
- 📐 Adaptive Padding - 8px mobile → 16px tablet → 24px desktop-wide
- 👁️ Consistent Breakpoints - Sidebar visibility aligned with padding at 640px
🐛 Bug Fixes
Critical UX Issues Resolved
-
hideWhenEmpty Effects Issue
- Problem: Body scroll lock and keyboard listeners mounted before early return, freezing page scroll when component returned null
- Solution: Added
isViewerVisibleflag to conditionally run effects only when viewer is rendered - Impact: Prevents UX regression in "Hide When Empty" story
-
FilmStrip Thumbnail Clicks
- Problem: Thumbnail clicks no-op when mainApi undefined/null, breaking standalone use and early clicks
- Solution: Always call
onSelectfirst, then conditionally scroll mainApi if available - Impact: Enables standalone FilmStrip use and handles early clicks gracefully
-
Mouse-Wheel Scrolling
- Problem: FilmStrip used Embla with overflow:hidden, removing mouse-wheel scrolling for desktop users
- Solution: Added
embla-carousel-wheel-gesturesplugin - Impact: Restored desktop accessibility with proper mouse-wheel support
📚 Documentation
- 📖 Comprehensive Responsive Docs - Added detailed responsive behavior section to Album pattern docs
- 🎯 Breakpoint Documentation - All three breakpoints and their behaviors fully documented
- 💡 Feature Descriptions - Updated with Embla carousel integration details
📦 Dependencies
- ➕ Added:
embla-carousel-wheel-gestures@^8.1.0- Mouse-wheel support for carousels
🔧 Technical Details
New Props
AlbumViewer.hideWhenEmpty?: boolean- Hide viewer completely when album has no photosAlbumViewer.emptyStateContent?: React.ReactNode- Custom empty state contentFilmStrip.mainApi?: EmblaCarouselType | null- Main carousel API for synchronization
Breaking Changes
None - This release is fully backward compatible.
🚀 Installation
npm install @ainativekit/ui@0.13.0🙏 Acknowledgments
Thanks to the Embla Carousel team for their excellent carousel library and comprehensive documentation!
Full Changelog: v0.12.0...v0.13.0
0.12.0
Changed
- Carousel: Default viewport padding is now
0instead ofvar(--ai-spacing-10)- Padding is now opt-in instead of opt-out
- Prevents layout issues in constrained spaces (e.g., 640px ChatGPT iframe)
- Use
viewportPadding="var(--ai-spacing-10)"to restore previous behavior
Fixed
- SummaryCard.Overlay: Height calculation now correctly includes padding
- Added
box-sizing: border-boxsoheight={40}withpadding={8}results in 40px total, not 56px - Overlay content now clips properly to image rounded corners with
overflow: hidden
- Added
0.11.0
✨ New Features
Light/Dark Mode Brand Colors
Brand colors now support theme-aware variants, allowing different colors for light and dark modes.
<ThemeProvider
brandColors={{
// Simple: Same for both modes
primary: '#6366F1',
// Theme-aware: Different per mode
success: { light: '#059669', dark: '#34D399' },
warning: { light: '#D97706', dark: '#FBBF24' },
error: { light: '#DC2626', dark: '#F87171' },
}}
>
<App />
</ThemeProvider>Key improvements:
- New BrandColorValue type: string | { light: string; dark: string }
- Backward compatible - existing string colors work unchanged
- Automatic CSS generation for both themes
- Validation caching prevents duplicate console warnings
- Comprehensive unit tests (697 total tests passing)
📚 Documentation
- Updated all README files with brand color customization examples
- Added CSS variable reference table in TOKEN_USAGE.md
- Replaced brand-specific colors with generic Tailwind CSS colors
🔧 Fixes
- Added missing ESLint TypeScript plugins to workspace root
Full Changelog: v0.10.0...v0.11.0
0.10.0
[0.10.0] - 2025-11-11
Changed
-
Repository Rename: Renamed from
ainativekit-uitochatgpt-apps-sdk-uifor improved discoverability- GitHub repository now at
AINativeKit/chatgpt-apps-sdk-ui - NPM package name remains
@ainativekit/uifor backward compatibility - All documentation URLs updated to reflect new repository name
- GitHub repository now at
-
Branding & Positioning: Updated to "AINativeKit - ChatGPT Apps SDK UI"
- Emphasizes "ChatGPT Apps SDK" positioning for better SEO and target audience clarity
- Subtitle: "The React UI library for ChatGPT Apps SDK"
- Tagline: "Build beautiful ChatGPT Apps 10x faster"
-
Documentation Enhancements:
- Added "Who This Is For" section targeting ChatGPT Apps developers
- Added comparison table showing value proposition (before/after scenarios)
- Replaced Contributing section with "Support the Project" featuring stronger CTAs
- Added SEO footer with keywords and descriptive paragraph for search optimization
- Updated badges: added npm downloads and GitHub stars, removed TypeScript badge
-
NPM Optimization:
- Updated package description to emphasize "ChatGPT Apps SDK"
- Added 5 new high-value keywords:
chatgpt-apps-sdk,react-components,ui-components,chatgpt-ui,mcp
Note: This is a documentation and marketing release. No breaking changes to components or APIs.
0.9.0
[0.9.0] - 2025-11-10
Fixed
- Carousel: Fixed horizontal page overflow in width-constrained containers (Issue #17)
- Replaced negative margin gap implementation with CSS
gapproperty - Carousel now properly contains itself without requiring parent containers to use
overflow-x: hidden - Self-contained component handles its own overflow correctly
- Replaced negative margin gap implementation with CSS
0.8.0
[0.8.0] - 2025-11-09
Fixed
- SummaryCard: Button skeleton width now matches button width (Issue #15)
- Skeleton buttons use the same width logic as real buttons
buttonFullWidth={false}→ auto-width (min 120px) for both skeleton and buttonbuttonFullWidth={true}→ full-width (100%) for both skeleton and buttonbuttonFullWidth={undefined}→ variant-based (full for default, auto for flat)
Changed
- SummaryCard: Simplified
buttonFullWidthbehaviorbuttonFullWidth={false}: Always auto-width (min 120px)buttonFullWidth={true}: Always full-width (100%)buttonFullWidth={undefined}: Full-width for default variant, auto-width for flat variant- Button width is now fixed and predictable - no responsive behavior
- Simpler implementation using standard CSS
Technical Details
All components use simple, predictable viewport-based media queries for responsive behavior:
/* SummaryCard: Fixed button widths based on prop */
.buttonSection[data-full-width='false'] .button {
width: auto;
min-width: 120px;
}
/* List & AlbumViewer: Viewport-based responsive behavior */
@media (min-width: 640px) {
/* Tablet/desktop styles */
}