react-native-collapsible icon indicating copy to clipboard operation
react-native-collapsible copied to clipboard

fix: Add sections to onChange props

Open nitaking opened this issue 7 years ago • 10 comments
trafficstars

When I tried to create a menu component using Accordion, I attempted to implement Accordion in Accordion.

The use case is below.

  1. Perform specific processing at onChange (onPress)
    • At that time Accordion will not open
    • Which menu was pressed is determined by the index of onChange (index)
  2. When there is a nest Accordion
    • Open Accordion with onChange

In such a case, you can not distinguish nested menus with the onChange index alone. So, we added sections to props on onChange. This section represents sections in the same hierarchy as onChange.


I thought that this problem can be implemented if we use <Collapsible> without using <Accordion>. However, in that case I thought that it was redundant, implementing a feature like <Accordion> in <Collapsible>.

I feel that adding the above props is smartest, but what about it?

nitaking avatar Nov 11 '18 09:11 nitaking

example source code.


const list = [
  {
    path: '',
    image: '',
    title: '',
    subMenuList: [
      {
        path: '',
        title: '',
        uri: '',
      },
      {
        path: '',
        title: '',
        uri: '',
      },
    ],
  },
];
...

export class SubMenuContents extends Component<Props> {
  state = {
    activeSections: [],
    activeSubSections: [],
  };

  onNestSection = (activeSections, sections) => {
    const activeMenu = sections[activeSections];
    goTo(activeMenu.path, { uri: activeMenu.uri });
  };

  setSections = (activeSections: $index[]) => {
    const { list } = this.props;

    this.setState({ activeSections });

    const pressMenu = activeSections.length ?
      list[activeSections] :
      list[this.state.activeSections];
    goTo(pressMenu.path, { uri: pressMenu.uri });
  };

  _render = (section) => {
    const { image, title } = section;
    return (
      <MenuItem title={title} image={image} />
    );
  };

  renderHeader = section => {
    return this._render(section);
  };

  renderContent = section => {
    if ('subMenuList' in section) {
      return (
        <Accordion
          sections={section.subMenuList}
          activeSections={this.state.activeSubSections}
          renderSectionTitle={() => <View />}
          renderHeader={this.renderHeader}
          renderContent={this.renderContent}
          onChange={this.onNestSection}
          touchableComponent={TouchableOpacity}
        />
      );
    }
    return <View />;
  };

  render() {
    const { list } = this.props;

    return (
      <Accordion
        sections={list}
        activeSections={this.state.activeSections}
        renderSectionTitle={() => <View />}
        renderHeader={this.renderHeader}
        renderContent={this.renderContent}
        onChange={this.setSections}
        touchableComponent={TouchableOpacity}
      />
    );
  }
}

nitaking avatar Nov 11 '18 10:11 nitaking

@iRoachie how is it?

nitaking avatar Nov 26 '18 13:11 nitaking

Correct me if I'm wrong. The sections param that you want to add is already passed in through props, why do you want to pass back the same sections prop in the onChange? Why not just use the variable that sets the sections prop directly?

https://github.com/oblador/react-native-collapsible/blob/2fd64a8a358c4c507642bee815c0c819444d05c1/Accordion.js#L76

iRoachie avatar Nov 29 '18 06:11 iRoachie

@iRoachie When nesting, I think that the same section is useless.

First we tried to use an already existing sections. If you use it directly as a nested accordion, it will be in the following state.

const list = [
  { title: 'A' },
  {
    title: 'B',
    subList: [{ title: 'B-1' }, { title: 'B-2' } ],
  },
];

The result...

master branch:

displayTitle displayTitle
A
B A
B

The result I would like is...

this PR:

displayTitle displayTitle
A
B B-1
B-2

The reason is that I make the following reference.

master branch:

displayTitle index props.section displayTitle index props.section
A: list[0] 0 list
B: list[1] 1 list A: list[0] 0 list
B: list[1] 1 list

this PR:

displayTitle index props.section displayTitle index props.section
A: list[0] 0 list
B: list[1] 1 list B-1: list[1].subList[0] 0 subList
B-1: list[1].subList[1] 1 subList

nitaking avatar Nov 29 '18 17:11 nitaking

Can you make a quick snack on http://snack.expo.io that i could test this with? I'll copy it locally and then use your branch/changes.

iRoachie avatar Dec 12 '18 17:12 iRoachie

@iRoachie Hi. It is not snack, but I made a mock with codesandbox. I could not use forked repo, but you touch the problematic phenomenon. Please press title 5 under title 4.

https://codesandbox.io/s/qz0zrlkyrq

nitaking avatar Feb 14 '19 17:02 nitaking

2019-02-15 02 18 20 I need sub list value.

nitaking avatar Feb 14 '19 17:02 nitaking

After I apply your change, how would the example change to be able to get the information for the sublist?

iRoachie avatar Feb 18 '19 03:02 iRoachie

@iRoachie check this https://github.com/oblador/react-native-collapsible/pull/260#issuecomment-437657643

nitaking avatar Jun 19 '19 00:06 nitaking

I think this is a change that should be merged soon.

nitaking avatar Jun 19 '19 00:06 nitaking