Skip to content

Commit

Permalink
#7 - Create new component
Browse files Browse the repository at this point in the history
Criação do componente de filtro
  • Loading branch information
Nandovga committed Nov 8, 2024
1 parent 1036b64 commit 1705fc1
Show file tree
Hide file tree
Showing 11 changed files with 260 additions and 66 deletions.
12 changes: 8 additions & 4 deletions debug/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,22 @@ import React, { useState } from "react";
import { InputFilter } from "../../src/inputfilter";

const Root = () => {
const [value, setValue] = useState("10/10/2024{}28/12/2024");
const [value, setValue] = useState<any>(undefined);

console.log(value);

return (
<Box size="100">
<p className="w-100">Componente - Filtro</p>
<InputFilter required
data={[]}
icon="funnel-fill"
label="Data"
options={["=", ">", "<", ">=", "<=", "{}"]}
type="date"
options={["=", "!="]}
type="autocomplete"
value={value}
onChange={setValue}/>
onChange={setValue}
onSearch={() => null}/>
</Box>
);
};
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@orangesix/react",
"type": "module",
"version": "1.0.9",
"version": "1.0.10-x3",
"description": "Set of components and functions available to be used in a React project.",
"author": "Luiz Fernando Bernardes de Paula",
"license": "MIT",
Expand Down
1 change: 1 addition & 0 deletions rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ const __dependeciesExternal = [
"primereact/editor",
"primereact/column",
"primereact/datatable",
"primereact/autocomplete",
];

/**
Expand Down
17 changes: 17 additions & 0 deletions src/api/css/theme.css
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,20 @@
display: flex;
align-items: flex-start;
gap: .5rem; }
.input-filter-content .p-autocomplete-multiple {
padding: 0; }
.input-filter-content .p-autocomplete-multiple-container {
width: 100%;
padding: .2rem .5rem; }
.input-filter-content .p-autocomplete-multiple-container .form-control {
border: none;
padding: .2rem; }
.input-filter-content .p-autocomplete-multiple-container .p-autocomplete-token {
padding: .2rem .5rem;
margin: 0; }
.input-filter-content .p-autocomplete-multiple-container.p-focus {
box-shadow: none;
border-color: var(--input-filter-border-color); }

.input-filter-select {
width: 40%;
Expand All @@ -403,3 +417,6 @@

.input-filter-field-date.year {
flex: 2; }

.input-filter-autocomplete-panel .p-autocomplete-items {
padding-left: 0 !important; }
30 changes: 30 additions & 0 deletions src/inputfilter/_inputfilter.scss
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,30 @@
display: flex;
align-items: flex-start;
gap: .5rem;

.p-autocomplete-multiple {
padding: 0;
}

.p-autocomplete-multiple-container {
width: 100%;
padding: .2rem .5rem;

.form-control {
border: none;
padding: .2rem;
}

.p-autocomplete-token {
padding: .2rem .5rem;
margin: 0;
}
}

.p-autocomplete-multiple-container.p-focus {
box-shadow: none;
border-color: var(--input-filter-border-color);
}
}

.input-filter-select {
Expand All @@ -30,4 +54,10 @@

.input-filter-field-date.year {
flex: 2;
}

.input-filter-autocomplete-panel {
.p-autocomplete-items {
padding-left: 0 !important;
}
}
36 changes: 36 additions & 0 deletions src/inputfilter/core/autocomplete.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import React from "react";
import { InputFilterCoreProps, InputFilterOptionsMap } from "../types";
import { AutoComplete as AutocompletePrimeReact } from "primereact/autocomplete";
import { handleGetValueAutocomplete, handleSetValueAutocomplete } from "../function/handle";

/**
* Core - `Autocomplete`
* Campo do filtro tipo autocomplete
*/
export function Autocomplete<T extends keyof InputFilterOptionsMap>(props: InputFilterCoreProps<"autocomplete">) {
const value = handleGetValueAutocomplete(props.value, props.options, props.data);

return (
<AutocompletePrimeReact multiple
completeMethod={event => {
let ids = value.map(item => item.id);
props.onSearch(event.query, ids);
}}
appendTo="self"
className="w-100"
disabled={props.disabled}
emptyMessage="Não encontramos dados."
field="label"
id={(props.id ?? "input-filter") + "-" + "autocomplete"}
inputClassName="form-control"
name={(props.name ?? "input-filter") + "-" + "autocomplete"}
panelClassName="input-filter-autocomplete-panel"
placeholder={props.placeholder}
required={props.required}
scrollHeight={props.autocompleteScrollHeight}
selectionLimit={props.autocompleteSelectLimit}
suggestions={props.data}
value={value}
onChange={event => props.onChange(handleSetValueAutocomplete(event.value, props.select))}/>
);
}
33 changes: 20 additions & 13 deletions src/inputfilter/core/date.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,29 @@
import React from "react";
import { InputFilterOptionsMap, InputFilterProps } from "../types";
import { InputFilterCoreProps, InputFilterOptionsMap } from "../types";
import { handleGetValueDate, handleSetValueDate } from "../function/handle";

/**
* Core - `Date`
* Campo do filtro tipo data
*/
export function Date<T extends keyof InputFilterOptionsMap = "text">(props: InputFilterProps<T> & {
options: any[]
select: string
}) {
let date = handleGetValueDate<T>(props.value, props.options, props.select);
export function Date<T extends keyof InputFilterOptionsMap>(props: InputFilterCoreProps<T>) {
let date = handleGetValueDate(props.value, props.options, props.select);

return (props.type === "date") && (
function handleChangeValue(value: string) {
if (props.select === "{}" && value === "0/0/0{}0/0/0") {
props.onChange(null);
} else {
if ((date[0] == 0 || isNaN(date[0] as number)) &&
(date[1] == 0 || isNaN(date[1] as number)) &&
(date[2] == 0 || isNaN(date[2] as number))) {
props.onChange(null);
} else {
props.onChange(value);
}
}
}

return (
<div className="d-flex w-100 flex-column">
<div className="w-100 d-flex gap-2">
{date.map((item, index) => {
Expand All @@ -25,9 +36,7 @@ export function Date<T extends keyof InputFilterOptionsMap = "text">(props: Inpu
name={(props.name ?? "input-filter") + "-" + index}
placeholder={props.placeholder}
value={item === 0 ? "" : item}
onChange={event => {
props.onChange(handleSetValueDate(event.target.value, index, date));
}}/>
onChange={event => handleChangeValue(handleSetValueDate(event.target.value, index, date))}/>
);
}
})}
Expand All @@ -44,9 +53,7 @@ export function Date<T extends keyof InputFilterOptionsMap = "text">(props: Inpu
name={(props.name ?? "input-filter") + "-" + index}
placeholder={props.placeholder}
value={item === 0 ? "" : item}
onChange={event => {
props.onChange(handleSetValueDate(event.target.value, index, date));
}}/>
onChange={event => handleChangeValue(handleSetValueDate(event.target.value, index, date))}/>
);
}
})}
Expand Down
11 changes: 4 additions & 7 deletions src/inputfilter/core/text.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,19 @@
import React from "react";
import { handleGetValueText } from "../function/handle";
import { InputFilterOptionsMap, InputFilterProps } from "../types";
import { InputFilterCoreProps, InputFilterOptionsMap } from "../types";

/**
* Core - `Text`
* Campo do filtro tipo texto
*/
export function Text<T extends keyof InputFilterOptionsMap = "text">(props: InputFilterProps<T> & {
options: any[]
select: string
}) {
return (!props.type || props.type === "text") && (
export function Text<T extends keyof InputFilterOptionsMap>(props: InputFilterCoreProps<T>) {
return (
<input className="form-control input-filter-field"
disabled={props.disabled}
id={(props.id ?? "input-filter") + "-text"}
name={(props.name ?? "input-filter") + "-text"}
placeholder={props.placeholder}
value={handleGetValueText<T>(props.value, props.options)}
value={handleGetValueText(props.value, props.options) ?? ""}
onChange={event => props.onChange(event.target.value + props.select)}/>
);
}
76 changes: 57 additions & 19 deletions src/inputfilter/function/handle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ import { InputFilterOptionsMap } from "../types";
* @param options - Um array de opções de filtro disponíveis.
* @returns A opção de filtro correspondente ou a primeira opção se nenhuma correspondência for encontrada.
*/
export function handleGetOption<T extends keyof InputFilterOptionsMap = "text">(
value: string,
export function handleGetOption<T extends keyof InputFilterOptionsMap>(
value: string | undefined,
options: Array<InputFilterOptionsMap[T]>
): string {
let exists = options.filter(option => value.includes(option));
let exists = options.filter(option => value?.includes(option));
return exists[exists.length - 1] ?? options[0];
}

Expand All @@ -23,19 +23,19 @@ export function handleGetOption<T extends keyof InputFilterOptionsMap = "text">(
* @param options - Um array de opções de filtro disponíveis.
* @returns O valor sem as opções de filtro.
*/
export function handleGetValueText<T extends keyof InputFilterOptionsMap = "text">(
value: string,
options: Array<InputFilterOptionsMap[T]>
): string {
export function handleGetValueText(
value: string | undefined,
options: Array<InputFilterOptionsMap["text"]>
): string | null {
let str = value;
let exists = options
.slice()
.reverse()
.find(item => str.endsWith(item));
if (exists) {
.find(item => str?.endsWith(item));
if (exists && str !== undefined) {
return str.slice(0, -exists.length);
}
return str;
return str ?? null;
}

/**
Expand All @@ -46,18 +46,18 @@ export function handleGetValueText<T extends keyof InputFilterOptionsMap = "text
* @param select - Seletor do tipo de filtro
* @returns O valor sem as opções de filtro.
*/
export function handleGetValueDate<T extends keyof InputFilterOptionsMap = "text">(
value: string,
options: Array<InputFilterOptionsMap[T]>,
export function handleGetValueDate(
value: string | undefined,
options: Array<InputFilterOptionsMap["date"]>,
select: null | string = null
): Array<number | string> {
let str = value;
let optsRegex = /(=|!=|<|>|<=|>=|\{\})/;
let optsMatch = value.match(optsRegex);
let optsMatch = value?.match(optsRegex);
let opts = optsMatch ? optsMatch[0].trim() : options[0];

let parts: any[] = [];
let interval = str.split("{}");
let interval = str?.split("{}") ?? [];

interval.forEach((value, index) => {
let clean = value.replace(optsRegex, "").trim();
Expand All @@ -77,7 +77,9 @@ export function handleGetValueDate<T extends keyof InputFilterOptionsMap = "text
if (parts[1] && opts === "{}") {
return [...validateDate(parts[0]), select ?? opts].concat(...validateDate(parts[1]));
}
return [...validateDate(parts[0]), select ?? opts];
return parts.length === 0
? [0, 0, 0, opts]
: [...validateDate(parts[0]), select ?? opts];
}

/**
Expand All @@ -90,10 +92,12 @@ export function handleGetValueDate<T extends keyof InputFilterOptionsMap = "text
*/
export function handleSetValueDate(
value: string,
position: number,
position: number | null,
date: (number | string)[]
): string {
date[position] = parseInt(value);
if (position !== null) {
date[position] = parseInt(value);
}

let opts = date[3];
let firstDate = date.slice(0, 3);
Expand All @@ -103,7 +107,41 @@ export function handleSetValueDate(
return `${firstDate[0]}/${firstDate[1]}/${firstDate[2]}${opts}`;
}

let lastDate = date.slice(-3);
let lastDate = isNaN(parseInt(date[date.length - 1] as string)) && position === null
? [0, 0, 0]
: date.slice(-3);
lastDate = validateDate(lastDate as number[]);
return `${firstDate[0]}/${firstDate[1]}/${firstDate[2]}${opts}${lastDate[0]}/${lastDate[1]}/${lastDate[2]}`;
}

/**
* Obtém os valores selecionados do autocomplete a partir da string de valor e dos dados disponíveis.
*
* @param value - String contendo os IDs dos itens selecionados, separados por ponto e vírgula.
* @param options - Array de opções de filtro disponíveis para o autocomplete.
* @param data - Array de objetos contendo os dados disponíveis para seleção.
* @returns Array de objetos correspondentes aos IDs selecionados.
*/
export function handleGetValueAutocomplete(
value: string | undefined,
options: Array<InputFilterOptionsMap["autocomplete"]>,
data: Array<{ id: number, label: string }>
) {
let values: any[] = value?.split(";").map(item => parseInt(item)) ?? [];
return data.filter(item => values.includes(item.id));
}

/**
* Converte os valores selecionados do autocomplete em uma string formatada para o filtro.
*
* @param value - Array de objetos selecionados no autocomplete.
* @param select - String representando a opção de filtro selecionada.
* @returns String formatada com os IDs dos itens selecionados e a opção de filtro.
*/
export function handleSetValueAutocomplete(
value: Array<{ id: number, label: string }>,
select: string,
): string | null {
let ids = value.map(item => item.id);
return ids.length === 0 ? null : ids.join(";") + select;
}
Loading

0 comments on commit 1705fc1

Please sign in to comment.