2

Test

Posted by anonymous234 11 months ago
2
1

I want to build a custom select element. I won't do much with regards to accessibility, but I'll at least not render the options when they are supposed to be closed, so screen readers and keyboard navigators won't get confused.

Currently the code looks like this

```

import { IconChevronUp } from "@tabler/icons-react";

import { useState } from "react";

import SCSelect from "./Select.styled";

export default function Select({ current, options, change }) {

const [open, setOpen] = useState(false);

function handle_change(event) {

const choice = event.target.value;

change(choice);

}

function handle_checkbox(event) {

setOpen(event.target.checked);

}

return (

{current}

{options.map((option) => (

{option}

))}

);

}

```

It's probably not a good idea to set the value of the option as the key, but I'll overlook that for now. The CSS looks like this

```

import styled from "styled-components";

const SCSelect = styled.div`

background: #fed2e3;

position: relative;

padding: 10px;

.controls {

display: flex;

justify-content: space-between;

align-items: center;

position: relative;

input[type="checkbox"] {

appearance: none;

position: absolute;

inset: 0;

:checked {

+ svg {

transform: rotate(180deg);

}

}

}

svg {

transition: transform 0.33s;

pointer-events: none;

}

}

.options {

background: #fed2e3;

box-shadow: 0 5px 10px 1px #342424;

display: flex;

flex-direction: column;

gap: 10px;

position: absolute;

bottom: 100%;

left: 0;

right: 0;

transition: bottom 0.33s, transform 0.33s;

opacity: 0;

&.closed {

animation: hide 0.33s forwards;

}

&.open {

bottom: 0;

transform: translateY(100%);

visibility: visible;

animation: fade 0.33s forwards;

}

@keyframes fade {

from {

opacity: 0;

}

to {

opacity: 1;

}

}

@keyframes hide {

from {

visibility: visible;

opacity: 1;

}

to {

visibility: hidden;

opacity: 0;

}

}

}

`;

export default SCSelect;

```

The idea is for it to also transition smoothly between shown and hidden states. The problem is that right now the options section shows briefly when the component is mounted, I want to fix that.

I think I juts have to rethink how to manage the opacity, since everything else seems to work properly. When the options are hidden, they have opacity of zero. If the className of the options changes to open the opacity becomes one, but I want to be a smooth transition over .33 seconds. I'm using an animation to set the visibility to hidden since the only other option I can think of is setting up and effect with a timeout to set up an extra class on the options section.

What would be other way of doing this? The component is mounted, the options are closed, so they are not shown, which means that they have opacity of zero and visibility set to hidden. The user then opens the options, which changes `open` state variable to true, which renders the options. The problem is that the current code works, except for when the component is mounted. I think I'll need another variable to indicate when the options have been opened, if they haven't been opened, I'll give the options a different class that hides them as usual, otherwise I'll give them the regular class.

That seems to have fixed the issue, but I wonder if there's a better way.

Edited 11 months ago

Comments (1)

Want to leave a comment?

Sort by: Best
1
Cicero

try code tags

reply permalink report gild save