Skip to content

Commit

Permalink
converted account-filter to use typeahead-selector
Browse files Browse the repository at this point in the history
  • Loading branch information
rammohan-y committed Jan 6, 2025
1 parent b3e55c3 commit 63c9c10
Show file tree
Hide file tree
Showing 3 changed files with 177 additions and 117 deletions.
59 changes: 23 additions & 36 deletions src/components/account-filter.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { useEffect, useState } from "react";
import React, { useEffect } from "react";
import { classNames } from "@jambonz/ui-kit";

import { Icons } from "src/components/icons";
import { TypeaheadSelector } from "src/components/forms";

import type { Account } from "src/api/types";
import { hasLength, sortLocaleName } from "src/utils";
Expand All @@ -22,12 +22,10 @@ export const AccountFilter = ({
accounts,
defaultOption,
}: AccountFilterProps) => {
const [focus, setFocus] = useState(false);
const classes = {
smsel: true,
"smsel--filter": true,
"account-filter": true,
focused: focus,
};

useEffect(() => {
Expand All @@ -36,41 +34,30 @@ export const AccountFilter = ({
}
}, [accounts, defaultOption, setAccountSid]);

const options = [
...(defaultOption ? [{ name: "All accounts", value: "" }] : []),
...(hasLength(accounts)
? accounts.sort(sortLocaleName).map((acct) => ({
name: acct.name,
value: acct.account_sid,
}))
: []),
];

return (
<div className={classNames(classes)}>
{label && <label htmlFor="account_filter">{label}:</label>}
<div>
<select
id="account_filter"
name="account_filter"
value={accountSid}
onChange={(e) => {
setAccountSid(e.target.value);
setAccountFilter(e.target.value);
}}
onFocus={() => setFocus(true)}
onBlur={() => setFocus(false)}
>
{defaultOption ? (
<option value="">All accounts</option>
) : (
accounts &&
!accounts.length && <option value="">No accounts</option>
)}
{hasLength(accounts) &&
accounts.sort(sortLocaleName).map((acct) => {
return (
<option key={acct.account_sid} value={acct.account_sid}>
{acct.name}
</option>
);
})}
</select>
<span>
<Icons.ChevronUp />
<Icons.ChevronDown />
</span>
</div>
<TypeaheadSelector
id="account_filter"
name="account_filter"
value={accountSid}
options={options}
className="small"
onChange={(e) => {
setAccountSid(e.target.value);
setAccountFilter(e.target.value);
}}
/>
</div>
);
};
19 changes: 15 additions & 4 deletions src/components/forms/typeahead-selector/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,27 @@ import { Icons } from "src/components/icons";

import "./styles.scss";

/**
* Represents an option in the typeahead selector dropdown
* @interface TypeaheadOption
* @property {string} name - The display text shown in the dropdown
* @property {string} value - The underlying value used when the option is selected
*/
export interface TypeaheadOption {
name: string;
value: string;
}

/**
* Represents an option in the typeahead selector dropdown
* @interface TypeaheadOption
* @property {string} name - The display text shown in the dropdown
* @property {string} value - The underlying value used when the option is selected
* Props for the TypeaheadSelector component
* @extends {JSX.IntrinsicElements["input"]} - Inherits all standard HTML input props
* @typedef TypeaheadSelectorProps
* @property {TypeaheadOption[]} options - Array of selectable options to display in the dropdown
* @property {string} [className] - Optional CSS class name to apply to the component
*/
type TypeaheadSelectorProps = JSX.IntrinsicElements["input"] & {
options: TypeaheadOption[];
className?: string;
};

type TypeaheadSelectorRef = HTMLInputElement;
Expand Down Expand Up @@ -54,6 +62,7 @@ export const TypeaheadSelector = forwardRef<
options,
disabled,
onChange,
className,
...restProps
}: TypeaheadSelectorProps,
ref,
Expand All @@ -64,6 +73,7 @@ export const TypeaheadSelector = forwardRef<
const inputRef = React.useRef<HTMLInputElement | null>(null);
const classes = {
"typeahead-selector": true,
[`typeahead-selector${className}`]: true,
focused: isOpen,
disabled: !!disabled,
};
Expand Down Expand Up @@ -327,6 +337,7 @@ export const TypeaheadSelector = forwardRef<
className={classNames({
active: isOpen,
disabled: !!disabled,
pointerevents: true,
})}
onClick={() => {
setIsOpen(!isOpen);
Expand Down
216 changes: 139 additions & 77 deletions src/components/forms/typeahead-selector/styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@
@use "@jambonz/ui-kit/src/styles/vars" as ui-vars;
@use "@jambonz/ui-kit/src/styles/mixins" as ui-mixins;

.typeahead-selector {
// ... imports remain the same ...

// Common mixins for shared styles
@mixin typeahead-base {
position: relative;
width: 100%;
max-width: vars.$widthtypeaheadselector;

&.disabled {
Expand All @@ -23,97 +25,157 @@
background-color: ui-vars.$dark;
}
}
}

input {
@include ui-mixins.m();
appearance: none;
padding: ui-vars.$px01 ui-vars.$px02;
border-radius: ui-vars.$px01;
border: 2px solid ui-vars.$grey;
background-color: ui-vars.$white;
width: 100%;
max-width: vars.$widthtypeaheadinput;
transition: border-color 0.2s ease;
@mixin typeahead-input {
@include ui-mixins.m();
appearance: none;
padding: ui-vars.$px01 ui-vars.$px02;
border-radius: ui-vars.$px01;
border: 2px solid ui-vars.$grey;
background-color: ui-vars.$white;
max-width: vars.$widthtypeaheadinput;
transition: border-color 0.2s ease;
font-family: inherit;

&:focus {
border-color: ui-vars.$dark;
outline: 0;
}
&:focus {
border-color: ui-vars.$dark;
outline: 0;
}

&[disabled] {
@include mixins.disabled();
}
&[disabled] {
@include mixins.disabled();
}
}

span {
height: 100%;
width: 50px;
background-color: ui-vars.$grey;
border-radius: 0 ui-vars.$px01 ui-vars.$px01 0;
position: absolute;
right: 0;
top: 0;
display: flex;
align-items: center;
flex-direction: column;
justify-content: center;
transition: background-color 0.2s ease;

&.disabled {
@include mixins.disabled();
}
@mixin typeahead-span {
height: 100%;
width: 50px;
background-color: ui-vars.$grey;
border-radius: 0 ui-vars.$px01 ui-vars.$px01 0;
position: absolute;
right: 0;
top: 0;
display: flex;
align-items: center;
flex-direction: column;
justify-content: center;
transition: background-color 0.2s ease;

&.active {
background-color: ui-vars.$dark;
}
&.disabled {
@include mixins.disabled();
}

svg {
stroke: ui-vars.$white;
cursor: pointer;
&.active {
background-color: ui-vars.$dark;
}

svg {
stroke: ui-vars.$white;
cursor: default;

&:first-child {
transform: translateY(5px);
}
&:last-child {
transform: translateY(-5px);
}
&:first-child {
transform: translateY(5px);
}
&:last-child {
transform: translateY(-5px);
}
}
}

@mixin typeahead-dropdown {
@include ui-mixins.m();
position: absolute;
top: 100%;
left: 0;
right: 0;
background: ui-vars.$white;
border: 1px solid ui-vars.$dark;
max-height: 200px;
overflow-y: auto;
}

@mixin typeahead-option {
cursor: pointer;
transition: all 0.2s ease;
font-weight: normal;
display: block;
padding-block-start: 0px;
padding-block-end: 1px;
min-block-size: 1.2em;
padding-inline: 2px;
white-space: nowrap;
padding-left: 16px;
font-family: inherit;
line-height: 30.4px;

&:hover,
&.active {
background-color: #006dff;
color: ui-vars.$white;
}

&.active {
cursor: default;
}
}

// Main classes using the mixins
.typeahead-selector {
@include typeahead-base();
width: 100%;

input {
@include typeahead-input();
width: 100%;
}

span {
@include typeahead-span();
}

.typeahead-dropdown {
@include ui-mixins.m();
position: absolute;
top: 100%;
left: 0;
right: 0;
background: ui-vars.$white;
border: 1px solid ui-vars.$dark;
max-height: 200px;
overflow-y: auto;
@include typeahead-dropdown();
z-index: 1000;
}

.typeahead-option {
cursor: pointer;
transition: all 0.2s ease;
font-weight: normal;
display: block;
padding-block-start: 0px;
padding-block-end: 1px;
min-block-size: 1.2em;
padding-inline: 2px;
white-space: nowrap;
padding-left: 16px;
&:hover,
&.active {
background-color: #006dff;
color: ui-vars.$white;
}
@include typeahead-option();
}
}

&.active {
cursor: default;
}
font-family: Arial;
line-height: 30.4px;
.typeahead-selectorsmall {
@include typeahead-base();
width: auto;

input {
@include typeahead-input();
width: auto;
height: 34px;
font-size: var(--mxs-size);
}

span {
@include typeahead-span();
}

.typeahead-dropdown {
@include typeahead-dropdown();
}

.typeahead-option {
@include typeahead-option();
font-size: var(--mxs-size);
}

.pointerevents {
pointer-events: all;
cursor: default;
}
}

.filters--multi {
overflow-x: visible !important;
white-space: nowrap;
grid-gap: 16px;
}

0 comments on commit 63c9c10

Please sign in to comment.