Skip to content

Commit

Permalink
Rearranging the component
Browse files Browse the repository at this point in the history
- The component was redone by separating the components well.
-The jsdoc is also added
- Accessibility has been greatly improved
- ReadMe Improvement
  • Loading branch information
VoidSplit committed Aug 30, 2023
1 parent c878c0a commit d4423bf
Show file tree
Hide file tree
Showing 9 changed files with 414 additions and 213 deletions.
115 changes: 113 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,21 @@ React select component library

It's a react component made for Openclassroom hr-net project

# Summary

- [Getting Started](#getting-started)
- [Dependencies](#dependencies)
- [Installing](#installing)
- [Executing program](#executing-program)
- [Props](#props)
- [Data Structure](#data-structure)
- [Category Object](#category-object)
- [Item Object](#item-object)
- [Example usage](#example-usage)
---
- [Authors](#authors)
- [Version History](#version-history)

## Getting Started

### Dependencies
Expand All @@ -25,34 +40,124 @@ npm install voidsplit-select-component
```
import { SelectMenu } from 'voidsplit_select_component';
<SelectMenu innerRef={ComponentRef} data={ComponentData} id="ComponentId"/>
<SelectMenu innerRef={componentRef} data={componentData} id="menuId" label="Menu Label" />
```
* Data Example:
```
```javascript
const data = [
{
type: "category",
categoryName: "Category 0",
categoryContent: [
{
type: "item",
id: 0,
display: "Item Display Value",
disabled: true
},
{
type: "item",
id: 1,
display: "2nd Item Display Value"
}
]
},
{
type: "item",
id: 2,
abbreviation: "Item Abreviation",
display: "3rd Item Display Value"
}
]
```

### Props
The `SelectMenu` component accepts the following props:

- `innerRef` (function): A reference callback to access the DOM element of the input.
- `data` (array): An array of objects representing the data to be displayed in the selection menu.
- `id` (string): A unique identifier for the selection menu component.
- `label` (string): The label for the selection menu.

## Data Structure

The data structure for the selection menu component should follow a specific format to ensure proper rendering. The data array should consist of objects representing either categories or individual items. Here's how the data should be structured:

Each object in the `data` array represents either a category or an item:

### Category Object

A category object should have the following properties:

- `type` *(string)*: Set to `"category"` to indicate that this object represents a category.
- `categoryName` *(string)*: The name of the category.
- `categoryContent` *(array)*: An array containing the items within the category. Each item should be an object with its own properties.

### Item Object

An item object should have the following properties:

- `type` *(string)*: Set to `"item"` to indicate that this object represents an item.
- `display` *(string)*: The display text for the item.
- `abbreviation` *(string, optional)*: Abbreviated text for the item (optional).
- `id` *(number)*: A unique identifier for the item.
- `disabled` *(boolean, optional)*: Whether the item is disabled (optional).

Here's an example of a properly structured `data` array:

```javascript
const componentData = [
{
type: "category",
categoryName: "Category 0",
categoryContent: [
{
type: "item",
display: "Item Display Value",
abbreviation: "Item Abbreviation",
id: 0
},
{
type: "item",
display: "2nd Item Display Value",
id: 1
}
]
},
{
type: "item",
display: "3rd Item Display Value",
abbreviation: "Item Abbreviation",
id: 2
},
// ... more items or categories
];

```

## Example usage

Here's an example of how to use the component:
```javascript
import React, { useRef } from 'react';
import { SelectMenu } from 'voidsplit_select_component';

const App = () => {
const componentRef = useRef(null);

const componentData = [
// ... your data array
];

return (
<div>
<SelectMenu innerRef={componentRef} data={componentData} id="myComponent" label="Select an Item" />
</div>
);
}

export default App;
```
## Authors

Contributors names and contact info
Expand All @@ -61,6 +166,12 @@ Contributors names and contact info

## Version History

* 0.3.1
* Component Optimisations
* Adding jsdoc documentation
* Improved readMe documentation
* 0.3.0
* Total component redesign
* 0.2.13
* SEO optimization on npm
* 0.2.12
Expand Down
7 changes: 3 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 11 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
{
"name": "voidsplit_select_component",
"version": "0.2.13",
"keywords": ["react", "react component", "select", "select menu", "vite", "select component", "openclassroom"],
"version": "0.3.0",
"keywords": [
"react",
"react component",
"select",
"select menu",
"vite",
"select component",
"openclassroom"
],
"type": "module",
"main": "./dist/react-vite-library.umd.cjs",
"module": "./dist/react-vite-library.es.js",
Expand All @@ -27,6 +35,7 @@
"dependencies": {
"@emotion/react": "^11.10.8",
"@emotion/styled": "^11.10.8",
"prop-types": "^15.8.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"tailwindcss": "^3.3.2",
Expand Down
42 changes: 42 additions & 0 deletions src/components/SelectMenu/Category.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// import PropTypes from 'prop-types';
/* eslint-disable react/prop-types */

import Item from "./Item";

/**
* Represents a category within a selection menu.
*
* @component
* @param {Object} props - The component properties.
* @param {string} props.name - The name of the category.
* @param {Array} props.list - The list of items within the category.
* @param {function} props.itemCallback - The callback function triggered when an item within the category is selected.
* @param {number} props.selected - The ID of the currently selected item.
* @param {function} props.toggleOpen - Callback to toggle the open state of the menu.
* @returns {JSX.Element} A component representing a category in the selection menu.
*/
export default function Category({name, list, itemCallback, selected, toggleOpen}) {
return (
<div className="category">
<div className="category-name">{name}</div>
{/* Loop through the list to render items within the category */}
{list.map((el, index) => {
switch(el.type) {
case "item":
return <Item toggleOpen={toggleOpen} selected={el.id === selected} key={index} display={el.display} abbreviation={el.abbreviation} action={itemCallback} id={el.id} />
default:
return false
}
})}
</div>
);
}


// Category.propTypes = {
// name: PropTypes.string,
// list: PropTypes.array,
// itemCallback: PropTypes.func,
// selected: PropTypes.bool,
// toggleOpen: PropTypes.func
// }
50 changes: 50 additions & 0 deletions src/components/SelectMenu/Item.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// import PropTypes from 'prop-types';
/* eslint-disable react/prop-types */

/**
* Represents an item within a selection menu.
*
* @component
* @param {Object} props - The component properties.
* @param {function} props.action - The callback function triggered when the item is selected.
* @param {string} props.display - The display text for the item.
* @param {string} props.abbreviation - The abbreviated text for the item (optional).
* @param {number} props.id - The unique identifier for the item.
* @param {boolean} props.selected - Indicates whether the item is currently selected.
* @param {function} props.toggleOpen - Callback to toggle the open state of the menu.
* @returns {JSX.Element} A button representing the selectable item.
*/
export default function Item({action, display, abbreviation, id, selected, toggleOpen}) {
// Determine the displayed text based on abbreviation or display value
let displayed = abbreviation ? abbreviation : display ? display : "error"
return (
<button
className={`item ${selected ? "selected" : ""}`}
tabIndex={0}
onKeyDown={(e) => {
if (e.key === "Enter") {
e.preventDefault()
action(id)
}
}} onClick={(e) => {
action(id)
e.preventDefault()
}} onFocus={() => {
toggleOpen(true)
}} onBlur={() => {
toggleOpen(false)
}}>
{displayed}
</button>
);
}


// Item.propTypes = {
// action: PropTypes.func,
// display: PropTypes.string,
// abbreviation: PropTypes.string,
// id: PropTypes.number,
// selected: PropTypes.bool,
// toggleOpen: PropTypes.func
// }
Loading

0 comments on commit d4423bf

Please sign in to comment.