Design System Randomize with fixing certain properties
I really like about the newly released design system. One feature I like the most was the randomize feature. I think small update would make this randomize feature immensely powerful. When I like something about the randomly generated property I want to pin/fix it and only randomize other variables. That way I can gradually build the theme without having to think too much. Thank you !

Jeonghoon Lee about 2 hours ago
π‘ Feature Request
Design System Randomize with fixing certain properties
I really like about the newly released design system. One feature I like the most was the randomize feature. I think small update would make this randomize feature immensely powerful. When I like something about the randomly generated property I want to pin/fix it and only randomize other variables. That way I can gradually build the theme without having to think too much. Thank you !

Jeonghoon Lee about 2 hours ago
π‘ Feature Request
Android Theme
The default theme uses styling that tends more towards iOS look & feel. It would be great to have a theme that provides a more native Android look & feel for use on those devices.

Matt Marsh 1 day ago
π‘ Feature Request
Android Theme
The default theme uses styling that tends more towards iOS look & feel. It would be great to have a theme that provides a more native Android look & feel for use on those devices.

Matt Marsh 1 day ago
π‘ Feature Request
Navigation menu with floating dropdown
Navigation Menu similar to radix (https://www.radix-ui.com/primitives/docs/components/navigation-menu) with a floating dropdown and smooth animated width changes between items

davidz 7 days ago
π Components Request
Navigation menu with floating dropdown
Navigation Menu similar to radix (https://www.radix-ui.com/primitives/docs/components/navigation-menu) with a floating dropdown and smooth animated width changes between items

davidz 7 days ago
π Components Request
Update Bottom Sheet Component
can we move away from @gorhom/bottom-sheet or making the bottom sheet implementation pluggable? gorhom is great/powerful but it adds reanimatedd/gesture handler dependency complexity. @lodev09/react-native-true-sheet and @swmansion/react-native-bottom-sheet seem like solid fits to try out instead of gorhom. even if HeroUI keeps Gorhom as the default an adapter layer would let teams choose a native sheet implementation without forking

Aren Dalloul 15 days ago
π Components Request
Update Bottom Sheet Component
can we move away from @gorhom/bottom-sheet or making the bottom sheet implementation pluggable? gorhom is great/powerful but it adds reanimatedd/gesture handler dependency complexity. @lodev09/react-native-true-sheet and @swmansion/react-native-bottom-sheet seem like solid fits to try out instead of gorhom. even if HeroUI keeps Gorhom as the default an adapter layer would let teams choose a native sheet implementation without forking

Aren Dalloul 15 days ago
π Components Request
AI Components (for React Native)
Can we get AI components for React Native (similar to what web components have currently) https://heroui.pro/docs/react/components/chat-conversation

Aren Dalloul 16 days ago
π Components Request
AI Components (for React Native)
Can we get AI components for React Native (similar to what web components have currently) https://heroui.pro/docs/react/components/chat-conversation

Aren Dalloul 16 days ago
π Components Request
Inline combobox
Just like the inline select, can we have inline combobox? I want to use it in a datagrid like inline select
Vinod Kumar 16 days ago
π‘ Feature Request
Inline combobox
Just like the inline select, can we have inline combobox? I want to use it in a datagrid like inline select
Vinod Kumar 16 days ago
π‘ Feature Request
Semi Circle Progress component
A component with a semi circle. Maybe an option to configure it so the circle is 180Β° or 240Β° or a variable in between. I would love to see this for my dashboard.

Stybo 22 days ago
π Components Request
Semi Circle Progress component
A component with a semi circle. Maybe an option to configure it so the circle is 180Β° or 240Β° or a variable in between. I would love to see this for my dashboard.

Stybo 22 days ago
π Components Request
Planned
DataGrid footer support
The Pro DataGrid renders a self-contained internally (only a Table.ScrollContainer as its child) and exposes no way to use the OSS Table.Footer slot. Today users must render pagination/summary as a separate sibling below the grid (as the team-members demo does) and manually re-apply.table__footer styling to match. There's no footer/renderFooter prop and no children pass-through.

Marcus Wong 22 days ago
π‘ Feature Request
Planned
DataGrid footer support
The Pro DataGrid renders a self-contained internally (only a Table.ScrollContainer as its child) and exposes no way to use the OSS Table.Footer slot. Today users must render pagination/summary as a separate sibling below the grid (as the team-members demo does) and manually re-apply.table__footer styling to match. There's no footer/renderFooter prop and no children pass-through.

Marcus Wong 22 days ago
π‘ Feature Request
lost access to a template
Hello, I seem to have lost access to a template that I previously purchased. When I log into my account and open the dashboard, the template is no longer available, as if I never owned it. Could you please check my account and restore access to the purchased template if possible? I can provide my purchase details, invoice number, or any other information you need to verify ownership. Thank you for your assistance.

yakhadzhiev.sh about 1 month ago
π₯ Feedback
lost access to a template
Hello, I seem to have lost access to a template that I previously purchased. When I log into my account and open the dashboard, the template is no longer available, as if I never owned it. Could you please check my account and restore access to the purchased template if possible? I can provide my purchase details, invoice number, or any other information you need to verify ownership. Thank you for your assistance.

yakhadzhiev.sh about 1 month ago
π₯ Feedback
NumberField: Runaway onChange loop when spam-tapping increment/decrement buttons (iOS)
# NumberField: Runaway onChange loop when spam-tapping increment/decrement buttons (iOS) **Category:** Bug **Severity:** High **Component:** `NumberField` (heroui-native-pro) --- ## Description When using `NumberField` in controlled mode (`value` + `onChange`), rapidly tapping the increment (+) or decrement (-) button on iOS causes `onChange` to fire in an infinite loop. The value runs away to `maxValue` or `minValue` and does not stop even after tapping stops. This is also reproducible in the official **HeroUI Native iOS app**. ## Environment - heroui-native-pro: 1.0.0-beta.4 (also reproduced on beta.3) - heroui-native: ^1.0.3 - expo: ~55.0.26 - react-native: 0.83 - Platform: iOS ## Steps to Reproduce 1. Render a `NumberField` in controlled mode with `value`, `onChange`, `step={50}`, `minValue={0}`, `maxValue={10000}` 2. On iOS, rapidly tap (spam-press) the increment (+) or decrement (-) button 3. Observe the value β it keeps incrementing/decrementing on its own and does not stop ## Expected Behavior Each tap increments/decrements by `step` once. Rapid taps should increment once per tap. The value should stop changing when tapping stops. ## Actual Behavior After rapid taps, `onChange` continues firing in a loop. The value runs away to `maxValue`/`minValue` without stopping. ## Root Cause (from source inspection) Two issues in `useLongPressRepeat`: ### 1. Timer leak on rapid press-in `onPressIn` sets `timerRef.current` to a new `setTimeout` **without clearing the previous one**. During spam-tapping, if two `onPressIn` events fire before `onPressOut` clears them (iOS touch coalescing), the first timeout is leaked β its ref was overwritten, so `clear()` can never cancel it. That orphaned timeout spawns a `setInterval` that runs indefinitely. ```js // useLongPressRepeat.js β current code const onPressIn = useCallback(() => { actionRef.current(); timerRef.current = setTimeout(() => { // β overwrites without clearing intervalRef.current = setInterval(() => { // β also overwrites without clearing actionRef.current(); }, interval); }, delay); }, [delay, interval]); ``` ### 2. Stale closure in increment/decrement The `increment`/`decrement` callbacks in `NumberFieldRoot` close over `numberValue` via `useCallback`. When the orphaned interval fires, `actionRef.current` may hold a closure with a stale `numberValue`, causing each tick to re-compute the same step and emit duplicate `onChange` calls. ## Suggested Fix In `useLongPressRepeat`, clear existing timers before starting new ones: ```js const onPressIn = useCallback(() => { if (isDisabledRef.current) return; clear(); // β clear any existing timer/interval first actionRef.current(); timerRef.current = setTimeout(() => { intervalRef.current = setInterval(() => { actionRef.current(); }, interval); }, delay); }, [delay, interval, clear]); ``` Additionally, consider using a ref for `numberValue` inside `increment`/`decrement` instead of closing over it, so interval ticks always read the latest value. ## Minimal Repro ```tsx import { useCallback, useMemo, useState } from "react"; import { View } from "react-native"; import { Text } from "heroui-native"; import { NumberField } from "heroui-native-pro"; export default function NumberFieldRepro() { const [amount, setAmount] = useState(0); const [changeCount, setChangeCount] = useState(0); const formatOptions = useMemo ( () => ({ style: "currency", currency: "USD", minimumFractionDigits: 0, maximumFractionDigits: 0 }), [], ); const handleChange = useCallback((newValue: number) => { if (isNaN(newValue)) return; console.log(`[NumberField onChange] newValue=${newValue}`); setChangeCount((c) => c + 1); setAmount(newValue); }, []); return (

Stefan Kudla about 2 months ago
π Bug Reports
NumberField: Runaway onChange loop when spam-tapping increment/decrement buttons (iOS)
# NumberField: Runaway onChange loop when spam-tapping increment/decrement buttons (iOS) **Category:** Bug **Severity:** High **Component:** `NumberField` (heroui-native-pro) --- ## Description When using `NumberField` in controlled mode (`value` + `onChange`), rapidly tapping the increment (+) or decrement (-) button on iOS causes `onChange` to fire in an infinite loop. The value runs away to `maxValue` or `minValue` and does not stop even after tapping stops. This is also reproducible in the official **HeroUI Native iOS app**. ## Environment - heroui-native-pro: 1.0.0-beta.4 (also reproduced on beta.3) - heroui-native: ^1.0.3 - expo: ~55.0.26 - react-native: 0.83 - Platform: iOS ## Steps to Reproduce 1. Render a `NumberField` in controlled mode with `value`, `onChange`, `step={50}`, `minValue={0}`, `maxValue={10000}` 2. On iOS, rapidly tap (spam-press) the increment (+) or decrement (-) button 3. Observe the value β it keeps incrementing/decrementing on its own and does not stop ## Expected Behavior Each tap increments/decrements by `step` once. Rapid taps should increment once per tap. The value should stop changing when tapping stops. ## Actual Behavior After rapid taps, `onChange` continues firing in a loop. The value runs away to `maxValue`/`minValue` without stopping. ## Root Cause (from source inspection) Two issues in `useLongPressRepeat`: ### 1. Timer leak on rapid press-in `onPressIn` sets `timerRef.current` to a new `setTimeout` **without clearing the previous one**. During spam-tapping, if two `onPressIn` events fire before `onPressOut` clears them (iOS touch coalescing), the first timeout is leaked β its ref was overwritten, so `clear()` can never cancel it. That orphaned timeout spawns a `setInterval` that runs indefinitely. ```js // useLongPressRepeat.js β current code const onPressIn = useCallback(() => { actionRef.current(); timerRef.current = setTimeout(() => { // β overwrites without clearing intervalRef.current = setInterval(() => { // β also overwrites without clearing actionRef.current(); }, interval); }, delay); }, [delay, interval]); ``` ### 2. Stale closure in increment/decrement The `increment`/`decrement` callbacks in `NumberFieldRoot` close over `numberValue` via `useCallback`. When the orphaned interval fires, `actionRef.current` may hold a closure with a stale `numberValue`, causing each tick to re-compute the same step and emit duplicate `onChange` calls. ## Suggested Fix In `useLongPressRepeat`, clear existing timers before starting new ones: ```js const onPressIn = useCallback(() => { if (isDisabledRef.current) return; clear(); // β clear any existing timer/interval first actionRef.current(); timerRef.current = setTimeout(() => { intervalRef.current = setInterval(() => { actionRef.current(); }, interval); }, delay); }, [delay, interval, clear]); ``` Additionally, consider using a ref for `numberValue` inside `increment`/`decrement` instead of closing over it, so interval ticks always read the latest value. ## Minimal Repro ```tsx import { useCallback, useMemo, useState } from "react"; import { View } from "react-native"; import { Text } from "heroui-native"; import { NumberField } from "heroui-native-pro"; export default function NumberFieldRepro() { const [amount, setAmount] = useState(0); const [changeCount, setChangeCount] = useState(0); const formatOptions = useMemo ( () => ({ style: "currency", currency: "USD", minimumFractionDigits: 0, maximumFractionDigits: 0 }), [], ); const handleChange = useCallback((newValue: number) => { if (isNaN(newValue)) return; console.log(`[NumberField onChange] newValue=${newValue}`); setChangeCount((c) => c + 1); setAmount(newValue); }, []); return (

Stefan Kudla about 2 months ago
π Bug Reports
The theme sync functionality in the theme builder for heroui pro is not working properly
And the difference between the normal theme builder seen in the heroui docs is that the hero ui theme builder gets every single css variable: /* HeroUI Theme Customization Add this to your global.css after importing @heroui/styles Only includes variables users need to customize @see https://heroui.com/docs/react/getting-started/theming */ :root, .light, .default, [data-theme="light"], [data-theme="default"] { /* Theme Colors (Light Mode) */ --accent: oklch(0 0 0); --accent-foreground: oklch(99.11% 0 0); --background: oklch(97.02% 0.0000 0.00); --border: oklch(90.00% 0.0000 0.00); --danger: oklch(0.573 0.2249 21.97); --danger-foreground: oklch(98% 0.0200 21.97); --default: oklch(94.00% 0.0000 0.00); --default-foreground: oklch(21.03% 0.0059 0.00); --field-background: oklch(100.00% 0.0000 0.00); --field-border: transparent; --field-foreground: oklch(21.03% 0.0000 0.00); --field-placeholder: oklch(55.17% 0.0000 0.00); --focus: oklch(0 0 0); --foreground: oklch(21.03% 0.0000 0.00); --muted: oklch(55.17% 0.0000 0.00); --overlay: oklch(100.00% 0.0000 0.00); --overlay-foreground: oklch(21.03% 0.0000 0.00); --scrollbar: oklch(87.10% 0.0000 0.00); --segment: oklch(100.00% 0.0000 0.00); --segment-foreground: oklch(21.03% 0.0000 0.00); --separator: oklch(92.00% 0.0000 0.00); --success: oklch(0.6277 0.1604 153.06); --success-foreground: oklch(98% 0.0160 153.06); --surface: oklch(100.00% 0.0000 0.00); --surface-foreground: oklch(21.03% 0.0000 0.00); --surface-secondary: oklch(95.24% 0.0000 0.00); --surface-secondary-foreground: oklch(21.03% 0.0000 0.00); --surface-tertiary: oklch(93.73% 0.0000 0.00); --surface-tertiary-foreground: oklch(21.03% 0.0000 0.00); --warning: oklch(0.8446 0.1525 80.6); --warning-foreground: oklch(15% 0.0457 80.60); --accent-soft-foreground: oklch(0 0 0); /* Border Radius */ --radius: 0.25rem; --field-radius: 0.25rem; /* Font Family / / Make sure to load Inter font in your app */ --font-sans: var(--font-inter); } .dark, [data-theme="dark"] { color-scheme: dark; /* Theme Colors (Dark Mode) */ --accent: oklch(0.9848 0 0); --accent-foreground: oklch(15% 0.0000 0.00); --background: oklch(12.00% 0.0000 0.00); --border: oklch(28.00% 0.0000 0.00); --danger: oklch(0.7044 0.1872 23.19); --danger-foreground: oklch(15% 0.0500 23.19); --default: oklch(27.40% 0.0000 0.00); --default-foreground: oklch(99.11% 0 0); --field-background: oklch(21.03% 0.0000 0.00); --field-border: transparent; --field-foreground: oklch(99.11% 0.0000 0.00); --field-placeholder: oklch(70.50% 0.0000 0.00); --focus: oklch(0.9848 0 0); --foreground: oklch(99.11% 0.0000 0.00); --muted: oklch(70.50% 0.0000 0.00); --overlay: oklch(21.03% 0.0000 0.00); --overlay-foreground: oklch(99.11% 0.0000 0.00); --scrollbar: oklch(70.50% 0.0000 0.00); --segment: oklch(39.64% 0.0000 0.00); --segment-foreground: oklch(99.11% 0.0000 0.00); --separator: oklch(25.00% 0.0000 0.00); --success: oklch(0.6514 0.1321 156.22); --success-foreground: oklch(15% 0.0396 156.22); --surface: oklch(21.03% 0.0000 0.00); --surface-foreground: oklch(99.11% 0.0000 0.00); --surface-secondary: oklch(25.70% 0.0000 0.00); --surface-secondary-foreground: oklch(99.11% 0.0000 0.00); --surface-tertiary: oklch(27.21% 0.0000 0.00); --surface-tertiary-foreground: oklch(99.11% 0.0000 0.00); --warning: oklch(0.8803 0.1348 86.06); --warning-foreground: oklch(15% 0.0404 86.06); --accent-soft-foreground: oklch(0.9848 0 0); } This is the pro version: /* HeroUI Pro Theme Add this to your globals.css after importing @heroui/styles @see https://heroui.com/docs/react/getting-started/theming */ /* Font: Inter Load this font in your app: */ @import "@heroui-pro

Juan Carlos Tremols S about 2 months ago
π Bug Reports
The theme sync functionality in the theme builder for heroui pro is not working properly
And the difference between the normal theme builder seen in the heroui docs is that the hero ui theme builder gets every single css variable: /* HeroUI Theme Customization Add this to your global.css after importing @heroui/styles Only includes variables users need to customize @see https://heroui.com/docs/react/getting-started/theming */ :root, .light, .default, [data-theme="light"], [data-theme="default"] { /* Theme Colors (Light Mode) */ --accent: oklch(0 0 0); --accent-foreground: oklch(99.11% 0 0); --background: oklch(97.02% 0.0000 0.00); --border: oklch(90.00% 0.0000 0.00); --danger: oklch(0.573 0.2249 21.97); --danger-foreground: oklch(98% 0.0200 21.97); --default: oklch(94.00% 0.0000 0.00); --default-foreground: oklch(21.03% 0.0059 0.00); --field-background: oklch(100.00% 0.0000 0.00); --field-border: transparent; --field-foreground: oklch(21.03% 0.0000 0.00); --field-placeholder: oklch(55.17% 0.0000 0.00); --focus: oklch(0 0 0); --foreground: oklch(21.03% 0.0000 0.00); --muted: oklch(55.17% 0.0000 0.00); --overlay: oklch(100.00% 0.0000 0.00); --overlay-foreground: oklch(21.03% 0.0000 0.00); --scrollbar: oklch(87.10% 0.0000 0.00); --segment: oklch(100.00% 0.0000 0.00); --segment-foreground: oklch(21.03% 0.0000 0.00); --separator: oklch(92.00% 0.0000 0.00); --success: oklch(0.6277 0.1604 153.06); --success-foreground: oklch(98% 0.0160 153.06); --surface: oklch(100.00% 0.0000 0.00); --surface-foreground: oklch(21.03% 0.0000 0.00); --surface-secondary: oklch(95.24% 0.0000 0.00); --surface-secondary-foreground: oklch(21.03% 0.0000 0.00); --surface-tertiary: oklch(93.73% 0.0000 0.00); --surface-tertiary-foreground: oklch(21.03% 0.0000 0.00); --warning: oklch(0.8446 0.1525 80.6); --warning-foreground: oklch(15% 0.0457 80.60); --accent-soft-foreground: oklch(0 0 0); /* Border Radius */ --radius: 0.25rem; --field-radius: 0.25rem; /* Font Family / / Make sure to load Inter font in your app */ --font-sans: var(--font-inter); } .dark, [data-theme="dark"] { color-scheme: dark; /* Theme Colors (Dark Mode) */ --accent: oklch(0.9848 0 0); --accent-foreground: oklch(15% 0.0000 0.00); --background: oklch(12.00% 0.0000 0.00); --border: oklch(28.00% 0.0000 0.00); --danger: oklch(0.7044 0.1872 23.19); --danger-foreground: oklch(15% 0.0500 23.19); --default: oklch(27.40% 0.0000 0.00); --default-foreground: oklch(99.11% 0 0); --field-background: oklch(21.03% 0.0000 0.00); --field-border: transparent; --field-foreground: oklch(99.11% 0.0000 0.00); --field-placeholder: oklch(70.50% 0.0000 0.00); --focus: oklch(0.9848 0 0); --foreground: oklch(99.11% 0.0000 0.00); --muted: oklch(70.50% 0.0000 0.00); --overlay: oklch(21.03% 0.0000 0.00); --overlay-foreground: oklch(99.11% 0.0000 0.00); --scrollbar: oklch(70.50% 0.0000 0.00); --segment: oklch(39.64% 0.0000 0.00); --segment-foreground: oklch(99.11% 0.0000 0.00); --separator: oklch(25.00% 0.0000 0.00); --success: oklch(0.6514 0.1321 156.22); --success-foreground: oklch(15% 0.0396 156.22); --surface: oklch(21.03% 0.0000 0.00); --surface-foreground: oklch(99.11% 0.0000 0.00); --surface-secondary: oklch(25.70% 0.0000 0.00); --surface-secondary-foreground: oklch(99.11% 0.0000 0.00); --surface-tertiary: oklch(27.21% 0.0000 0.00); --surface-tertiary-foreground: oklch(99.11% 0.0000 0.00); --warning: oklch(0.8803 0.1348 86.06); --warning-foreground: oklch(15% 0.0404 86.06); --accent-soft-foreground: oklch(0.9848 0 0); } This is the pro version: /* HeroUI Pro Theme Add this to your globals.css after importing @heroui/styles @see https://heroui.com/docs/react/getting-started/theming */ /* Font: Inter Load this font in your app: */ @import "@heroui-pro

Juan Carlos Tremols S about 2 months ago
π Bug Reports
Notification center
It would be great to have a notification center component. Similar to ones you see right here on the feedback page when you click on the Bell icon button
Vinod Kumar about 2 months ago
π‘ Feature Request
Notification center
It would be great to have a notification center component. Similar to ones you see right here on the feedback page when you click on the Bell icon button
Vinod Kumar about 2 months ago
π‘ Feature Request
Searchable Select
Iβd like to be able to have a search bar inside of a Select component See GitHub issue: https://github.com/heroui-inc/heroui/discussions/5656

Ben King 2 months ago
π Components Request
Searchable Select
Iβd like to be able to have a search bar inside of a Select component See GitHub issue: https://github.com/heroui-inc/heroui/discussions/5656

Ben King 2 months ago
π Components Request