mrzachnugent / react-native-reusables

Universal shadcn/ui for React Native: Copy, paste, and tailor components to suit your specific requirements.
https://rnr-docs.vercel.app
MIT License
2.78k stars 118 forks source link

[ BUG ] Initial setup error #184

Closed helix-77 closed 1 month ago

helix-77 commented 1 month ago

I followed the Initial Setup method but getting this Tailwind css build error.

What could be the cause? or any easier method to setup rnr in my project environment?

Screenshots

Screenshot 2024-07-16 032328

450205447_993300202450929_2231513306624557934_n

Platform :

Also it'd be great if you can provide a concise & easier method to setup the rnr in the environment

andrii-yar commented 1 month ago

In the docs, we can see that for accordion component we need to copy the code into components/ui/accirdion.tsx file but there is an import from @rn-primitives/accordion, where should we get it from? Do we need to create another file with different code?

image

https://rnr-docs.vercel.app/components/accordion/

also, there are packages directory in the root, we can find a file with name accordion.tsx with this content:

but again this file imports code from @rnr, and that's very confusing since we get two different directories with code which reference at each other

import as React from 'react'; import { Pressable, View, type GestureResponderEvent } from 'react-native'; import as Slot from '@rnr/slot'; import type { PressableRef, SlottablePressableProps, SlottableViewProps, ViewRef, } from '@rnr/types'; import type { AccordionContentProps, AccordionItemProps, AccordionRootProps, RootContext, } from './types'; import { useControllableState } from '@rnr/hooks';

const AccordionContext = React.createContext<RootContext | null>(null);

const Root = React.forwardRef<ViewRef, SlottableViewProps & AccordionRootProps>( ( { asChild, type, disabled, collapsible = true, value: valueProp, onValueChange: onValueChangeProps, defaultValue, ...viewProps }, ref ) => { const [value = type === 'multiple' ? [] : undefined, onValueChange] = useControllableState< (string | undefined) | string[]

({ prop: valueProp, defaultProp: defaultValue, onChange: onValueChangeProps as (state: string | string[] | undefined) => void, });

const Component = asChild ? Slot.View : View;
return (
  <AccordionContext.Provider
    value={{
      type,
      disabled,
      collapsible,
      value,
      onValueChange,
    }}
  >
    <Component ref={ref} {...viewProps} />
  </AccordionContext.Provider>
);

} );

Root.displayName = 'RootNativeAccordion';

function useRootContext() { const context = React.useContext(AccordionContext); if (!context) { throw new Error( 'Accordion compound components cannot be rendered outside the Accordion component' ); } return context; }

type AccordionItemContext = AccordionItemProps & { nativeID: string; isExpanded: boolean; };

const AccordionItemContext = React.createContext<AccordionItemContext | null>(null);

const Item = React.forwardRef<ViewRef, SlottableViewProps & AccordionItemProps>( ({ asChild, value, disabled, ...viewProps }, ref) => { const { value: rootValue } = useRootContext(); const nativeID = React.useId();

const Component = asChild ? Slot.View : View;
return (
  <AccordionItemContext.Provider
    value={{
      value,
      disabled,
      nativeID,
      isExpanded: isItemExpanded(rootValue, value),
    }}
  >
    <Component ref={ref} {...viewProps} />
  </AccordionItemContext.Provider>
);

} );

Item.displayName = 'ItemNativeAccordion';

function useItemContext() { const context = React.useContext(AccordionItemContext); if (!context) { throw new Error( 'AccordionItem compound components cannot be rendered outside the AccordionItem component' ); } return context; }

const Header = React.forwardRef<ViewRef, SlottableViewProps>(({ asChild, ...props }, ref) => { const { disabled: rootDisabled } = useRootContext(); const { disabled: itemDisabled, isExpanded } = useItemContext();

const Component = asChild ? Slot.View : View; return ( <Component ref={ref} role='heading' aria-expanded={isExpanded} aria-disabled={rootDisabled ?? itemDisabled} {...props} /> ); });

Header.displayName = 'HeaderNativeAccordion';

const Trigger = React.forwardRef<PressableRef, SlottablePressableProps>( ({ asChild, onPress: onPressProp, disabled: disabledProp, ...props }, ref) => { const { disabled: rootDisabled, type, onValueChange, value: rootValue, collapsible, } = useRootContext(); const { nativeID, disabled: itemDisabled, value, isExpanded } = useItemContext();

function onPress(ev: GestureResponderEvent) {
  if (rootDisabled || itemDisabled) return;
  if (type === 'single') {
    const newValue = collapsible ? (value === rootValue ? undefined : value) : value;
    onValueChange(newValue);
  }
  if (type === 'multiple') {
    const rootToArray = toStringArray(rootValue);
    const newValue = collapsible
      ? rootToArray.includes(value)
        ? rootToArray.filter((val) => val !== value)
        : rootToArray.concat(value)
      : [...new Set(rootToArray.concat(value))];
    // @ts-ignore - `newValue` is of type `string[]` which is OK
    onValueChange(newValue);
  }
  onPressProp?.(ev);
}

const isDisabled = disabledProp || rootDisabled || itemDisabled;
const Component = asChild ? Slot.Pressable : Pressable;
return (
  <Component
    ref={ref}
    key={`${nativeID}-${JSON.stringify(rootValue)}-${isDisabled}-${collapsible}-${type}`}
    nativeID={nativeID}
    aria-disabled={isDisabled}
    role='button'
    onPress={onPress}
    accessibilityState={{
      expanded: isExpanded,
      disabled: isDisabled,
    }}
    disabled={isDisabled}
    {...props}
  />
);

} );

Trigger.displayName = 'TriggerNativeAccordion';

const Content = React.forwardRef<ViewRef, SlottableViewProps & AccordionContentProps>( ({ asChild, forceMount, ...props }, ref) => { const { type } = useRootContext(); const { nativeID, isExpanded } = useItemContext();

if (!forceMount) {
  if (!isExpanded) {
    return null;
  }
}

const Component = asChild ? Slot.View : View;
return (
  <Component
    ref={ref}
    aria-hidden={!(forceMount || isExpanded)}
    aria-labelledby={nativeID}
    role={type === 'single' ? 'region' : 'summary'}
    {...props}
  />
);

} );

could someone help me with understanding the installation process?

Xenopsia commented 1 month ago

The issue for me was that there was a space in the file-path. Looks like in your example you have a few folders with spaces in the name. Not sure what the workaround for actually fixing this is, but for me it was moving the project into my documents folder and making sure none of the parent folders had spaces in the name.

image

mrzachnugent commented 1 month ago

The issue for me was that there was a space in the file-path. Looks like in your example you have a few folders with spaces in the name. Not sure what the workaround for actually fixing this is, but for me it was moving the project into my documents folder and making sure none of the parent folders had spaces in the name.

image

☝️ This is most likely the issue (not related to react-native-reusables). @helix-77 There are plans to add a react-native-reusables template of create-expo-stack soon to help getting started.

@andrii-yar In the screenshot, in the purple section, it says that you need to add the 2 dependencies for it to work. You can click on them to see how to install/add it to your project. The @rn-primitives/accordion comes from the first dependency accordion-primitive.