jxom / bumbag-ui Goto Github PK
View Code? Open in Web Editor NEWBuild themeable React & React Native applications with your Bumbag ๐
Home Page: https://bumbag.style
License: MIT License
Build themeable React & React Native applications with your Bumbag ๐
Home Page: https://bumbag.style
License: MIT License
Pretty much radio & checkbox inputs but rendered as buttons instead.
dopeeeee.
At the moment, if we try to compose two components via the use
prop. The component specified via use
will not spread its TS types on the root component. Thus, the following will produce a typescript error on the href
prop:
<Button use={Link} href="https://example.com">Go to Example</Button>
Could you change the docs so when you click on something that's at the bottom of the sidebar the scroll doesn't reset?
React refs do not seem to work correctly on custom components created with applyTheme
.
This seems to be because they are a functional component and they don't correctly forwardRef?
I get this error:
Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?
To Reproduce
const CustomButton = applyTheme(Button, {
styles: {
base: {
minHeight: "unset",
whiteSpace: `nowrap`,
},
},
defaultProps: {
variant: "ghost",
},
});
const App = () => {
const buttonRef = useRef(null);
const handleClick = () => {
console.log(buttonRef.current) // should be defined
}
return (
<CustomButton onClick={handleClick} ref={buttonRef}>
Click
</CustomButton>
);
};
Is your feature request related to a problem? Please describe.
For example onChange
props of Input
component
The Input props:
export type InputProps = BoxProps & LocalInputProps;
There are two type of onChange
from BoxProps
and LocalInputProps
This will make typescript confuse about autocompletion.
Describe the solution you'd like
Remove duplication type from inheritance props (BoxProps)
type IntersectionType = keyof LocalInputProps & keyof BoxProps;
export type InputProps = Omit<BoxProps, IntersectionType> & LocalInputProps;
Additional context
Another issue related to the literal string union ("circle").
There are no options for Intellisense:
Solution and result:
Use simple hack from community
Is your feature request related to a problem? Please describe.
There isn't currently a direct way to style a child if its parent is hovered/focused on.
Describe the solution you'd like
We could implement the pseudo-styles like tailwind pseudo-class-variants(group-hover & group-focus), it could have a similar API to chakra-ui _groupHover
I am willing to make a PR adding those pseudo-styles.
This will work:
<Box padding="major-2">
<Group>
<Button>Send</Button>
<Button>Cancel</Button>
</Group>
</Box>
But this will not:
<Box padding="major-2">
<Group>
<Button>Cancel</Button>
</Group>
</Box>
On Bumbag's input component, there is a prop called isRequired
, which seems like when set, will set the relevant attributes for marking an input as required, with accessibility taken into consideration. At present, the input component only sets the aria-required
and aria-invalid
attributes, but recently HTML5 have introduced a new attribute called required
.
MDN articles below about aria-required
and required
both suggests that while the required
attribute is meant to serve the same purpose as aria-required
, there is no harm putting both just to cover most user agents.
Assistive technology should inform the user that the form control in mandatory based on the required attribute, but adding aria-required="true" doesn't hurt, in case the browser / screen reader combination does not support required yet.
Assistive technology should inform the user that the form control in mandatory based on the required attribute, but adding aria-required="true" doesn't hurt, in case the browser / screen reader combination does not support required yet.
This Feb 2019 article by Paciello Group about Accessibility support of required attribute on different devices provides great insight about the support of the required
attribute and some recommendations on how to use them.
Should we add the required
attribute for when isRequired
prop is set for input components, and (since I'm not an accessibility export), how do we juggle the three things to help ensure that we have greater accessibility coverage?
Alternatively, the current workaround is to set the isRequired
and required
attribute onto the input, which works fine, just that the property isRequired
is not native to html input and seems redundant to tell the input component that it is required and still have to set myself a native HTML5 required
attribute.
<Input isRequired="true" required/>
Other references:
Stackoverflow discussion
Love to have a discussion and happy to do the change PR if someone is willing to provide some context guidance.
When using SelectMenu with hasTags, you can select the same tag twice, and it will be added to the 'value' state variable where user selected tags are stored.
With a Tag Selection Component, it should only allow you to add each option to your selection once to prevent confusion from a user perspective. Adding a duplicate tag also causes a react dom warning, because you end up with two children (the selected tags) that share an identical key.
[Error] Warning: Encountered two children with the same key, `3`.
Keys should be unique so that components maintain their identity across updates.
Non-unique keys may cause children to be duplicated and/or omitted โ
the behavior is unsupported and could change in a future version.
in div (created by ForwardRef(Box))
in ForwardRef(Box)
in Unknown (created by Set)
in Set (created by SelectMenuTags)
in div (created by ForwardRef(Box))
in ForwardRef(Box)
in Unknown (created by Box)
in Box (created by SelectMenuTags)
in SelectMenuTags
in div (created by ForwardRef(Box))
in ForwardRef(Box)
in Unknown (created by DropdownMenu.Popover)
in DropdownMenu.Popover
in div (created by ForwardRef(Box))
in ForwardRef(Box)
in Unknown (created by SelectMenu)
in SelectMenu (at Tags.js:19)
in Tags (at pages/index.js:16)
in div (created by ForwardRef(Box))
Expected behavior
A tag should only be allowed to be selected once
Possible Solution
Use a set for storing the selected tags? There may be some gotchas I'm missing, but it might work.
Device information (please complete the following information):
Describe the bug
The last switch in the SwitchGroup isn't aligned correctly when the orientation is horizontal
To Reproduce
playroom: link
Expected behavior
All switches to be aligned when the orientation is horizontal
Describe the bug
The Dialog/Modal
reports an error when used with next.js
.
To Reproduce
Code: https://codesandbox.io/s/bumbag-dialog-issue-y92q9?file=/components/TestDialog.tsx
import React from "react";
import { Modal, Button, Card, Box } from "bumbag";
const TestDialog = () => {
return (
<Modal.State>
<Modal.Disclosure use={Button}>Open modal</Modal.Disclosure>
<Modal>
<Card>
<Box>Hello world</Box>
<Modal.Disclosure use={Button}>Close</Modal.Disclosure>
</Card>
</Modal>
</Modal.State>
);
};
export default TestDialog;
Expected behavior
Screenshots
Device information (please complete the following information):
Additional context
Thanks for keeping the great work, I reimplemented on nextjs based on latest docs, when trying out to deploy sticky with PageWithHeaders I get this error.
15:09:09.713 | ./src/pages/index.tsx:5:3
15:09:09.713 | Type error: Type '{ children: (string \| Element)[]; sticky: boolean; header: Element; border: string; overrides: { PageWithHeader: { styles: { base: { minHeight: string; }; }; }; }; }' is not assignable to type 'IntrinsicAttributes & Pick<PageWithHeaderProps, "header" \| "slot" \| "style" \| "title" \| "clipPath" \| "filter" \| "marker" \| "mask" \| ... 769 more ... \| "headerHeight"> & RefAttributes<...>'.
15:09:09.713 | Property 'sticky' does not exist on type 'IntrinsicAttributes & Pick<PageWithHeaderProps, "header" \| "slot" \| "style" \| "title" \| "clipPath" \| "filter" \| "marker" \| "mask" \| ... 769 more ... \| "headerHeight"> &
Maybe I'm doing something wrong?
import { Button, Provider as BumbagProvider , PageWithHeader, TopNav, Image, Box} from 'bumbag';
const MyApp = () => (
<BumbagProvider>
<PageWithHeader
sticky
header={
<TopNav>
<TopNav.Section>
<TopNav.Item href="https://bumbag.style" fontWeight="semibold">
<Image src="/vercel.svg" height="44px" />
</TopNav.Item>
<TopNav.Item href="#">Get started</TopNav.Item>
<TopNav.Item href="#">Components</TopNav.Item>
</TopNav.Section>
<TopNav.Section marginRight="major-2">
<TopNav.Item>
<Button variant="ghost" palette="primary">Sign up</Button>
</TopNav.Item>
<TopNav.Item>
<Button palette="primary">Login</Button>
</TopNav.Item>
</TopNav.Section>
</TopNav>
}
border="default"
overrides={{ PageWithHeader: { styles: { base: { minHeight: 'unset' } } } }}
>
<Box padding="major-2">Hello world</Box>
</PageWithHeader>
<Button>
Hello world!
</Button>
</BumbagProvider>
);
export default MyApp
Thanks for any help or pointers you can provide
Switches on popovers are not clickable via mouse
<Popover.State placement="bottom-end">
<Popover.Disclosure use={Button}>
</Popover.Disclosure>
<Popover title={user ? `Welcome ${user.displayName}` : 'Login to Continue!'} usePortal>
<Heading use="h6">User Settings</Heading>
<Switch
label={`${isLightMode ? 'Light' : 'Dark'} Mode`}
checked={isLightMode}
onClick={() => {
if (isLightMode) {
setColorMode('dark');
} else {
setColorMode('light');
}
}}
/>
<hr />
</Popover>
</Popover.State>
You can still toggle it via the spacebar when selected
Hi Jake, first of all thanks for building bumbag, I just found it out and it looks awesome!
I tried the latest release candidate and I can't get SSR to work properly
An example app can be seen here: https://with-bumbag-app.vercel.app/
I think code is availably publicly at https://with-bumbag-app.vercel.app/_src
Let me know iff you need something else, looks like an awesome framework btw
Describe the bug
When clicking on Menu or SelectMenu component the page jumps to a place bottom of the component
To Reproduce
Expected behavior
It should not scroll the page or scrolls to the component, not to the bottom of the page
Screenshots
Device information (please complete the following information):
Is your feature request related to a problem? Please describe.
Is there a way to create Vue version of this project?
I was trying to use Bumbag UI for my Vue application but couldn't find a supported library yet. Is there a way to create one or if it exist can I contribute?
Describe the solution you'd like
I will love to create a Vue version or contribute to any existing one.
Describe alternatives you've considered
Additional context
Autosuggest produces a warning and an error:
MenuDisclosure
has been renamed to MenuButton
. Using <MenuDisclosure />
will no longer work in future versions.
See https://reakit.io/docs/menu
Uncaught TypeError: element.focus is not a function
onMouseDown Dialog.js:65
useDisclosureRef Dialog.js:69
React 6
unstable_runWithPriority scheduler.development.js:653
React 4
unstable_runWithPriority scheduler.development.js:653
React 25
parcelRequire<["App.js"]< App.js:22
newRequire App.d36a57b6.js:47
parcelRequire App.d36a57b6.js:81
App.d36a57b6.js:120
Dialog.js:65:14
onMouseDown Dialog.js:65
(Async: EventListener.handleEvent)
useDisclosureRef Dialog.js:69
React 6
unstable_runWithPriority scheduler.development.js:653
React 3
performSyncWorkOnRoot self-hosted:1218
flushSyncCallbackQueueImpl React
unstable_runWithPriority scheduler.development.js:653
React 6
bind_applyFunctionN self-hosted:1369
dispatchDiscreteEvent self-hosted:1332
React 19
parcelRequire<["App.js"]< App.js:22
newRequire App.d36a57b6.js:47
parcelRequire App.d36a57b6.js:81
App.d36a57b6.js:120
Describe the bug
I'm using a Tooltip inside a Popover component and the Tooltip is behind the Popover.
Not sure if this is intended - imo, tooltips should have the highest z-index.
To Reproduce
<Popover.State placement="bottom-start" gutter={16}>
<Popover.Disclosure use={Button}>Click me</Popover.Disclosure>
<Popover showCloseButton title="Hello">
<Text.Block color="gray700" fontSize="100">
Some information
<Tooltip content="Will appear behind Popup" use="span">
<Icon marginLeft="minor-1" icon="solid-info-circle" />
</Tooltip>
</Text.Block>
</Popover>
</Popover.State>;
Quick fix
I was able to fix this by overwriting the Tooltip's z-index in theme.ts
const theme = {
Tooltip: {
Content: {
styles: {
base: {
// needs to be a string or it won't work
zIndex: `99999999`,
},
},
},
},
};
SelectMenu
and DropdownMenu
(this could possibly affect other components), cause react dom to emit a warning message in the browser console.Sample:
[Error] Warning: Received `false` for a non-boolean attribute `wrap`.
If you want to write it to the DOM, pass a string instead: wrap="false" or wrap={value.toString()}.
If you used to conditionally omit it with wrap={condition && value}, pass wrap={condition ? value : undefined} instead.
in button (created by ForwardRef(Button))
in ForwardRef(Button)
in ForwardRef(Button)
in Unknown (created by Button)
in Button (at DropdownTest.js:16)
in div (created by ForwardRef(Box))
in ForwardRef(Box)
in Unknown (created by DropdownMenu)
in DropdownMenu (at DropdownTest.js:6)
in DropdownTest (at pages/index.js:17)
in div (created by ForwardRef(Box))
in div (created by ForwardRef(Box))
in ForwardRef(Box)
in Unknown (created by PageContent.Wrapper)
in PageContent.Wrapper (created by ForwardRef(Box))
in ForwardRef(Box)
in Unknown (created by PageContent)
in PageContent (at pages/index.js:9)
in Index (at _app.js:6)
in div (created by ForwardRef(Box))
in ForwardRef(Box)
in Unknown (created by Box)
in Box (created by Provider)
in PageProvider (created by Provider)
in ToastProvider (created by Provider)
in IdProvider (created by Provider)
in SystemProvider (created by Provider)
in unstable_IdProvider (created by Provider)
in Provider (created by Provider)
in div (created by ColorModeProvider)
in ColorModeProvider (created by Provider)
in ThemeProvider (created by Provider)
in Provider (at _app.js:5)
in MyApp
in ErrorBoundary (created by ReactDevOverlay)
in ReactDevOverlay (created by Container)
in Container (created by AppContainer)
in AppContainer
in Root
I'm using nextjs, but the playroom example for these components also fails to render, so I suspect it's not limited to next projects.
To reproduce, just import SelectMenu from bumbag in a react file, and load the page with dev console open.
Expected behavior
Device information (please complete the following information):
const Tags = () => {
const [value, setValue] = useState();
return (
<SelectMenu
label='Tags'
isMultiSelect
hasTags
onChange={setValue}
options={[
{ key: 1, label: 'Apples', value: 'apples' },
{ key: 2, label: 'Bananas', value: 'bananas' },
{ key: 3, label: 'Oranges', value: 'oranges' },
{ key: 4, label: 'Mangos', value: 'mangos' },
]}
placeholder='Select a fruit...'
value={value}
/>
);
};
wrap
prop.My best guess it needs to be omitted from the components props when the component is being implemented.
Thanks!
Is your feature request related to a problem? Please describe.
It isn't clear how or there isn't a component yet to make a menu that contains options that could be selected
Describe the solution you'd like
If it's already possible with the current components we could add an example for it in the Docs, If it's not possible with the current set of components we could consider adding a component that handles this use-case.
Using 1.0.0.rc15
Following: https://bumbag.style/components/icon/#usage-via-bumbag-theme
Errror:
yarn run v1.22.4
$ next build
Failed to compile.
./src/pages/_app.tsx:85:23
Type error: Type '{ global: { fontSize: number; css: { root: SerializedStyles; }; }; fonts: { default: string; }; palette: { primary: string; }; breakpoints: { mobile: number; tablet: number; }; Button: { ...; }; Icon: { ...; }; }' is not assignable to type 'ThemeConfig'.
The types of 'Icon.iconSets' are incompatible between these types.
Type '{ icons: IconDefinition[]; prefix: string; type: string; }[]' is not assignable to type '{ icons: IconDefinition[]; prefix?: string; type: "font-awesome" | "font-awesome-standalone"; }[]'.
Type '{ icons: IconDefinition[]; prefix: string; type: string; }' is not assignable to type '{ icons: IconDefinition[]; prefix?: string; type: "font-awesome" | "font-awesome-standalone"; }'.
Types of property 'type' are incompatible.
Type 'string' is not assignable to type '"font-awesome" | "font-awesome-standalone"'.
83 | const { Component, pageProps } = this.props;
84 | return (
> 85 | <BumbagProvider theme={theme}>
| ^
86 | <style jsx>{`
87 | a {
88 | margin: 0 10px 0 0;
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
My _app.tsx
import NextApp from 'next/app';
import { Provider as BumbagProvider, css } from 'bumbag';
import { faIgloo, faSearch, faClipboard, faThumbsUp, faHome } from '@fortawesome/free-solid-svg-icons';
import { faAddressBook } from '@fortawesome/free-regular-svg-icons';
import Router from 'next/router'
import Link from 'next/link'
import Head from 'next/head'
import NProgress from 'nprogress'
Router.events.on('routeChangeStart', (url) => {
console.log(`Loading: ${url}`)
NProgress.start()
})
Router.events.on('routeChangeComplete', () => NProgress.done())
Router.events.on('routeChangeError', () => NProgress.done())
// svg t="1595278670094" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="611" width="200" height="200">
// import { faHome } from '@fortawesome/free-solid-svg-icons'
const theme = {
global: {
fontSize: 18,
css: {
root: css`
html,
body {
// background-color: hotpink;
// color: white;
}
.nav-link {
text-decoration: none;
}
.active {
color: #1890FF;
text-decoration: wavy underline;
.icon {
// color: blue;
// text-decoration: wavy underline;
}
}
.active:before {
// text-decoration: none;
}
`
}
},
fonts: {
default: 'Comic Sans MS'
},
palette: {
primary: '#574FEB',
},
breakpoints: {
mobile: 520,
tablet: 960
},
Button: {
defaultProps: {
palette: 'primary'
}
},
Icon: {
iconSets: [
{
icons: [faIgloo, faSearch, faClipboard, faThumbsUp, faHome],
prefix: 'solid-',
type: 'font-awesome'
},
{
icons: [faAddressBook],
prefix: 'regular-',
type: 'font-awesome'
}
]
}
}
export default class App extends NextApp {
render() {
const { Component, pageProps } = this.props;
return (
<BumbagProvider theme={theme}>
<style jsx>{`
a {
margin: 0 10px 0 0;
}
`}</style>
<Head>
{/* Import CSS for nprogress */}
<link rel="stylesheet" type="text/css" href="/nprogress.css" />
</Head>
<Component {...pageProps} />
</BumbagProvider>
);
}
}
Can't deploy to vercel due build failing bc of this TS error
Describe the bug
When double clicking Autosuggest
it freezes and the user isn't able to search anymore
To Reproduce
Autosuggest
Expected behavior
I should be able to search or focus on the input after double-clicking
Screenshots
Device information (please complete the following information):
Reproduction is simple, start a new gatsby starter project then follow the gatsby instructions on the website. Getting this error:
TypeError: theme.modes is undefined
useLocalStorage
node_modules/bumbag/es/utils/useLocalStorage.js:14
11 | var _useTheme = useTheme(),
12 | theme = _useTheme.theme;
13 |
> 14 | var isEnabled = theme.modes.enableLocalStorage;
15 | var get = useCallback(function (key) {
16 | if (!isEnabled) return;
17 |
Is your feature request related to a problem? Please describe.
Lacking of sections on the Autosuggest componente, like this https://codepen.io/moroshko/pen/qbRNjV
Describe the solution you'd like
Would be nice to have a similar behaviour or even simpler, like tagging each option with a "section" property
Describe alternatives you've considered
Right now I will change the background color depending on the option "type" but putting a header would be ideal
Additional context
I love bumbag
Type definition is not available -
VSCode Typescript Hint:
Could not find a declaration file for module 'bumbag'. '[PATH_TO_DIR]/node_modules/bumbag/lib/index.js' implicitly has an 'any' type.
Trynpm install @types/bumbag
if it exists or add a new declaration (.d.ts) file containingdeclare module 'bumbag';
ts(7016)
Error:
error - ./pages/_app.tsx
Attempted import error: 'Provider' is not exported from 'bumbag' (imported as 'BumbagProvider').
The Show and Hide components seem to respond to a breakpoint above or below the breakpoint supplied.
Open the page at https://bumbag.style/layout/show/ in Chrome. Show Developer Tools with a responsive layout. Change the width of the screen and watch when the message changes. The message should change at a width of 1024px - the desktop breakpoint, as described at https://bumbag.style/breakpoints/ . But, it changes at 768px, the tablet width.
I've seen the same behavior in my own app.
Expected behavior
The message should change at desktop width of 1024px.
It would be nice to have a Skeleton Loading component added to the component library.
It could have a similar API to Chakra-UI Skeleton Component
I am willing to make a PR implementing that component.
to summarize briefly
If necessary, I can support you by participating in your project.
Note: Meanwhile, my knowledge of English is insufficient. :)
Is your feature request related to a problem? Please describe.
Lack of Fotter component
Describe the solution you'd like
As we have a page with header sounds logic to add a Footer too
Describe alternatives you've considered
Add a footer component by hand
Is your feature request related to a problem? Please describe.
N/A
Describe the solution you'd like
A button that just holds an Icon
Describe alternatives you've considered
Additional context
Describe the bug
The last option of the horizontal RadioGroup
is not aligned.
To Reproduce
see docs
Expected behavior
Screenshots
Device information (please complete the following information):
Additional context
Is your feature request related to a problem? Please describe.
When trying to use both PageWithHeader
and PageWithSidebar
, I'm noticing that the sidebar cuts off the bottom pixel of the header:
Describe the solution you'd like
Maybe I'm missing something completely obvious, but it would be nice to have an example of how to use both successfully (i.e. how the docs site does it).
Is your feature request related to a problem? Please describe.
When moving from a library that follows the system-UI theme specification to bumbag we'll need to modify our theme object to conform with bumbag theme object.
Describe the solution you'd like
We can make the theme object of bumbag conform to system-UI and use aliases to make it backward compatible with the old theme specification.
This will allow bumbag-UI to be more interoperable with other libraries and will allow it to leverage tooling that supports system-UI theme specification such as styled-system-figma or fluid-system
Is your feature request related to a problem? Please describe.
I need to know which tab is active, so I can do something(fetch data for instance) when tab is in active state
Describe the solution you'd like
If tabs support the controlled state, I guess I can use the selectedId to know which tab is active
Describe alternatives you've considered
Trying out nextjs with new isSSR, I get this, am I missing something?
react-dom.development.js?d1ee:88 Warning: Prop `id` did not match. Server: "id-f38874" Client: "id-f71d4d"
in div (created by ForwardRef(Box))
in ForwardRef(Box)
in Unknown (created by Disclosure.Content)
in Disclosure.Content
in div (created by ForwardRef(Box))
in ForwardRef(Box)
in Unknown (created by PageWithHeader)
in PageWithHeader (at pages/index.tsx:4)
in div (created by ForwardRef(Box))
in ForwardRef(Box)
in Unknown (created by Box)
in Box (created by Provider)
in PageProvider (created by Provider)
in ToastProvider (created by Provider)
in IdProvider (created by Provider)
in ColorModeProvider (created by Provider)
in ThemeProvider (created by Provider)
in Provider (at pages/index.tsx:3)
in MyApp (at _app.tsx:8)
in div (created by ForwardRef(Box))
in ForwardRef(Box)
in Unknown (created by Box)
in Box (created by Provider)
in PageProvider (created by Provider)
in ToastProvider (created by Provider)
in IdProvider (created by Provider)
in div (created by ColorModeProvider)
in ColorModeProvider (created by Provider)
in ThemeProvider (created by Provider)
in Provider (at _app.tsx:7)
in App
in ErrorBoundary (created by ReactDevOverlay)
in ReactDevOverlay (created by Container)
in Container (created by AppContainer)
in AppContainer
in Root
Hi guys,
I've just created a form component with two SelectMenu inputs on it, each one having its own loadOptions
Expeceted behaviour:
Each SelectMenu should load and display its own options.
Actual behaviour:
Only the first SelectMenu loads the options. The getEpisodes
callback is not executed and the second SelectMenu "inherits" the options loaded by the first one
Am I doing something wrong?
const Form = (props) => {
const [character, setCharacter] = useState(null);
const [episode, setEpisode] = useState(null);
const getCharacters = React.useCallback(async () => {
return fetch(`https://rickandmortyapi.com/api/character`)
.then((res) => res.json())
.then(({ results }) => ({
options: results.map((character) => ({
key: character.id,
label: character.name,
value: character
}))
}))
.catch((err) => ({ options: [] }));
}, []);
const getEpisodes = React.useCallback(async () => {
return fetch(`https://rickandmortyapi.com/api/episode`)
.then((res) => res.json())
.then(({ results }) => ({
options: results.map((episode) => ({
key: episode.id,
label: episode.name,
value: episode
}))
}))
.catch((err) => ({ options: [] }));
}, []);
return (
<div style={formStyle}>
<SelectMenu
placeholder="Characters"
value={character}
onChange={setCharacter}
loadOptions={getCharacters}
/>
<SelectMenu
placeholder="Episodes"
value={episode}
onChange={setEpisode}
loadOptions={getEpisodes}
/>
</div>
);
};
Codesandbox
https://codesandbox.io/s/bumbag-select-menu-3zmzo
Is your feature request related to a problem? Please describe.
I was wondering if there's a way to make submenu's from the
components?Describe the solution you'd like
Would like to have nested submenus where i could select 1 option. Something like this
Describe alternatives you've considered
Considered going to Reakit.
I installed a standard Create React App and used the Autosuggest snippet from the Docs in App.js. I tried the App in Firefox 79 on MacOS 10.15.6, and while it basically works, I get the errors below when I "play around" with the Autosuggest input. It's hard to describe, because I haven't figured out a way to 100% reproduce the problem. But I click in the Autosuggest, click on a suggestion, type something, click outside etc. The only thing that is always triggering the error is a click, be it outside the component, inside the input field or on a suggestion, it doesn't matter. Sometimes the error occurs with the first interactions after loading, sometimes everything is stable for a longer time, but I if this is nothing specific to my setup, I'm sure you will see the error quickly when trying the Autosuggest in Firefox. (Safari and Chromium Edge work fine.)
Below are the tow erros messages, one shows up in the console only, but sometimes (I didn't see any pattern) I get a "full page crash" error with some more details.
Uncaught TypeError: element.focus is not a function
onMouseDown Dialog.js:65
useDisclosureRef Dialog.js:69
React 6
commitHookEffectListMount
commitPassiveHookEffects
callCallback
invokeGuardedCallbackDev
invokeGuardedCallback
flushPassiveEffectsImpl
unstable_runWithPriority scheduler.development.js:653
React 4
runWithPriority$1
flushPassiveEffects
performSyncWorkOnRoot
flushSyncCallbackQueueImpl
unstable_runWithPriority scheduler.development.js:653
React 6
runWithPriority$1
flushSyncCallbackQueueImpl
flushSyncCallbackQueue
discreteUpdates$1
discreteUpdates
dispatchDiscreteEvent
Dialog.js:65
onMouseDown Dialog.js:65
(Async: EventListener.handleEvent)
useDisclosureRef Dialog.js:69
React 6
commitHookEffectListMount
commitPassiveHookEffects
callCallback
invokeGuardedCallbackDev
invokeGuardedCallback
flushPassiveEffectsImpl
unstable_runWithPriority scheduler.development.js:653
React 3
runWithPriority$1
flushPassiveEffects
performSyncWorkOnRoot
performSyncWorkOnRoot self-hosted:982
flushSyncCallbackQueueImpl React
unstable_runWithPriority scheduler.development.js:653
React 6
runWithPriority$1
flushSyncCallbackQueueImpl
flushSyncCallbackQueue
discreteUpdates$1
discreteUpdates
dispatchDiscreteEvent
bind_applyFunctionN self-hosted:1133
dispatchDiscreteEvent self-hosted:1096
TypeError: element.focus is not a function
onMouseDown
node_modules/reakit/es/Dialog/Dialog.js:65
62 | var onMouseDown = function onMouseDown(event) {
63 | var element = event.currentTarget;
64 | event.preventDefault();
65 | element.focus();
| ^ 66 | };
67 |
68 | var disclosure = ((_options$unstable_dis = options.unstable_disclosureRef) === null || _options$unstable_dis === void 0 ? void 0 : _options$unstable_dis.current) || ref.current;
EventListener.handleEvent*useDisclosureRef/<
node_modules/reakit/es/Dialog/Dialog.js:69
66 | };
67 |
68 | var disclosure = ((_options$unstable_dis = options.unstable_disclosureRef) === null || _options$unstable_dis === void 0 ? void 0 : _options$unstable_dis.current) || ref.current;
69 | disclosure === null || disclosure === void 0 ? void 0 : disclosure.addEventListener("mousedown", onMouseDown);
| ^ 70 | return function () {
71 | return disclosure === null || disclosure === void 0 ? void 0 : disclosure.removeEventListener("mousedown", onMouseDown);
72 | };
commitHookEffectListMount
node_modules/react-dom/cjs/react-dom.development.js:19731
19728 | if ((effect.tag & tag) === tag) {
19729 | // Mount
19730 | var create = effect.create;
19731 | effect.destroy = create();
| ^ 19732 |
19733 | {
19734 | var destroy = effect.destroy;
commitPassiveHookEffects
node_modules/react-dom/cjs/react-dom.development.js:19769
19766 | // before calling any create functions. The current approach only serializes
19767 | // these for a single fiber.
19768 | commitHookEffectListUnmount(Passive$1 | HasEffect, finishedWork);
19769 | commitHookEffectListMount(Passive$1 | HasEffect, finishedWork);
| ^ 19770 | break;
19771 | }
19772 | }
callCallback
node_modules/react-dom/cjs/react-dom.development.js:188
185 | window.event = windowEvent;
186 | }
187 |
188 | func.apply(context, funcArgs);
| ^ 189 | didError = false;
190 | } // Create a global error event handler. We use this to capture the value
191 | // that was thrown. It's possible that this error handler will fire more
invokeGuardedCallbackDev
node_modules/react-dom/cjs/react-dom.development.js:237
234 | // errors, it will trigger our global error handler.
235 |
236 | evt.initEvent(evtType, false, false);
237 | fakeNode.dispatchEvent(evt);
| ^ 238 |
239 | if (windowEventDescriptor) {
240 | Object.defineProperty(window, 'event', windowEventDescriptor);
invokeGuardedCallback
node_modules/react-dom/cjs/react-dom.development.js:292
289 | function invokeGuardedCallback(name, func, context, a, b, c, d, e, f) {
290 | hasError = false;
291 | caughtError = null;
292 | invokeGuardedCallbackImpl$1.apply(reporter, arguments);
293 | }
294 | /**
295 | * Same as invokeGuardedCallback, but instead of returning an error, it stores
flushPassiveEffectsImpl
node_modules/react-dom/cjs/react-dom.development.js:22853
22850 | while (_effect2 !== null) {
22851 | {
22852 | setCurrentFiber(_effect2);
22853 | invokeGuardedCallback(null, commitPassiveHookEffects, null, _effect2);
| ^ 22854 |
22855 | if (hasCaughtError()) {
22856 | if (!(_effect2 !== null)) {
unstable_runWithPriority
node_modules/scheduler/cjs/scheduler.development.js:653
650 | currentPriorityLevel = priorityLevel;
651 |
652 | try {
653 | return eventHandler();
| ^ 654 | } finally {
655 | currentPriorityLevel = previousPriorityLevel;
656 | }
runWithPriority$1
node_modules/react-dom/cjs/react-dom.development.js:11039
11036 |
11037 | function runWithPriority$1(reactPriorityLevel, fn) {
11038 | var priorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel);
11039 | return Scheduler_runWithPriority(priorityLevel, fn);
11040 | }
11041 | function scheduleCallback(reactPriorityLevel, callback, options) {
11042 | var priorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel);
flushPassiveEffects
node_modules/react-dom/cjs/react-dom.development.js:22820
22817 | if (pendingPassiveEffectsRenderPriority !== NoPriority) {
22818 | var priorityLevel = pendingPassiveEffectsRenderPriority > NormalPriority ? NormalPriority : pendingPassiveEffectsRenderPriority;
22819 | pendingPassiveEffectsRenderPriority = NoPriority;
22820 | return runWithPriority$1(priorityLevel, flushPassiveEffectsImpl);
22821 | }
22822 | }
22823 |
performSyncWorkOnRoot
node_modules/react-dom/cjs/react-dom.development.js:21737
21734 | }
21735 | }
21736 |
21737 | flushPassiveEffects(); // If the root or expiration time have changed, throw out the existing stack
| ^ 21738 | // and prepare a fresh one. Otherwise we'll continue where we left off.
21739 |
21740 | if (root !== workInProgressRoot || expirationTime !== renderExpirationTime$1) {
flushSyncCallbackQueueImpl/<
node_modules/react-dom/cjs/react-dom.development.js:11089
11086 | var callback = queue[i];
11087 |
11088 | do {
11089 | callback = callback(_isSync);
| ^ 11090 | } while (callback !== null);
11091 | }
11092 | });
unstable_runWithPriority
node_modules/scheduler/cjs/scheduler.development.js:653
650 | currentPriorityLevel = priorityLevel;
651 |
652 | try {
653 | return eventHandler();
| ^ 654 | } finally {
655 | currentPriorityLevel = previousPriorityLevel;
656 | }
runWithPriority$1
node_modules/react-dom/cjs/react-dom.development.js:11039
11036 |
11037 | function runWithPriority$1(reactPriorityLevel, fn) {
11038 | var priorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel);
11039 | return Scheduler_runWithPriority(priorityLevel, fn);
11040 | }
11041 | function scheduleCallback(reactPriorityLevel, callback, options) {
11042 | var priorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel);
flushSyncCallbackQueueImpl
node_modules/react-dom/cjs/react-dom.development.js:11084
11081 | try {
11082 | var _isSync = true;
11083 | var queue = syncQueue;
11084 | runWithPriority$1(ImmediatePriority, function () {
| ^ 11085 | for (; i < queue.length; i++) {
11086 | var callback = queue[i];
11087 |
flushSyncCallbackQueue
node_modules/react-dom/cjs/react-dom.development.js:11072
11069 | Scheduler_cancelCallback(node);
11070 | }
11071 |
11072 | flushSyncCallbackQueueImpl();
11073 | }
11074 |
11075 | function flushSyncCallbackQueueImpl() {
discreteUpdates$1
node_modules/react-dom/cjs/react-dom.development.js:21893
21890 |
21891 | if (executionContext === NoContext) {
21892 | // Flush the immediate callbacks that were scheduled during this batch
21893 | flushSyncCallbackQueue();
21894 | }
21895 | }
21896 | }
discreteUpdates
node_modules/react-dom/cjs/react-dom.development.js:806
803 | isInsideEventHandler = true;
804 |
805 | try {
806 | return discreteUpdatesImpl(fn, a, b, c, d);
| ^ 807 | } finally {
808 | isInsideEventHandler = prevIsInsideEventHandler;
809 |
dispatchDiscreteEvent
node_modules/react-dom/cjs/react-dom.development.js:4168
4165 |
4166 | function dispatchDiscreteEvent(topLevelType, eventSystemFlags, container, nativeEvent) {
4167 | flushDiscreteUpdatesIfNeeded(nativeEvent.timeStamp);
4168 | discreteUpdates(dispatchEvent, topLevelType, eventSystemFlags, container, nativeEvent);
4169 | }
4170 |
4171 | function dispatchUserBlockingUpdate(topLevelType, eventSystemFlags, container, nativeEvent) {
EventListener.handleEvent*addEventCaptureListener
node_modules/react-dom/cjs/react-dom.development.js:4030
4027 | element.addEventListener(eventType, listener, false);
4028 | }
4029 | function addEventCaptureListener(element, eventType, listener) {
4030 | element.addEventListener(eventType, listener, true);
4031 | }
4032 |
4033 | // do it in two places, which duplicates logic
trapEventForPluginEventSystem
node_modules/react-dom/cjs/react-dom.development.js:4160
4157 | var rawEventName = getRawEventName(topLevelType);
4158 |
4159 | if (capture) {
4160 | addEventCaptureListener(container, rawEventName, listener);
| ^ 4161 | } else {
4162 | addEventBubbleListener(container, rawEventName, listener);
4163 | }
trapCapturedEvent
node_modules/react-dom/cjs/react-dom.development.js:4136
4133 | trapEventForPluginEventSystem(element, topLevelType, false);
4134 | }
4135 | function trapCapturedEvent(topLevelType, element) {
4136 | trapEventForPluginEventSystem(element, topLevelType, true);
4137 | }
4138 |
4139 | function trapEventForPluginEventSystem(container, topLevelType, capture) {
legacyListenToTopLevelEvent
node_modules/react-dom/cjs/react-dom.development.js:3613
3610 |
3611 | case TOP_FOCUS:
3612 | case TOP_BLUR:
3613 | trapCapturedEvent(TOP_FOCUS, mountAt);
| ^ 3614 | trapCapturedEvent(TOP_BLUR, mountAt); // We set the flag for a single dependency later in this function,
3615 | // but this ensures we mark both as attached rather than just one.
3616 |
legacyListenToEvent
node_modules/react-dom/cjs/react-dom.development.js:3601
3598 |
3599 | for (var i = 0; i < dependencies.length; i++) {
3600 | var dependency = dependencies[i];
3601 | legacyListenToTopLevelEvent(dependency, mountAt, listenerMap);
3602 | }
3603 | }
3604 | function legacyListenToTopLevelEvent(topLevelType, mountAt, listenerMap) {
ensureListeningTo
node_modules/react-dom/cjs/react-dom.development.js:5761
5758 | function ensureListeningTo(rootContainerElement, registrationName) {
5759 | var isDocumentOrFragment = rootContainerElement.nodeType === DOCUMENT_NODE || rootContainerElement.nodeType === DOCUMENT_FRAGMENT_NODE;
5760 | var doc = isDocumentOrFragment ? rootContainerElement : rootContainerElement.ownerDocument;
5761 | legacyListenToEvent(registrationName, doc);
5762 | }
5763 |
5764 | function getOwnerDocumentFromRootContainer(rootContainerElement) {
setInitialProperties
node_modules/react-dom/cjs/react-dom.development.js:5995
5992 | trapBubbledEvent(TOP_INVALID, domElement); // For controlled components we always need to ensure we're listening
5993 | // to onChange. Even if there is no listener.
5994 |
5995 | ensureListeningTo(rootContainerElement, 'onChange');
| ^ 5996 | break;
5997 |
5998 | case 'option':
finalizeInitialChildren
node_modules/react-dom/cjs/react-dom.development.js:7499
7496 | parentInstance.appendChild(child);
7497 | }
7498 | function finalizeInitialChildren(domElement, type, props, rootContainerInstance, hostContext) {
7499 | setInitialProperties(domElement, type, props, rootContainerInstance);
7500 | return shouldAutoFocusHostComponent(type, props);
7501 | }
7502 | function prepareUpdate(domElement, type, oldProps, newProps, rootContainerInstance, hostContext) {
completeWork
node_modules/react-dom/cjs/react-dom.development.js:18978
18975 | // Make sure such renderers get scheduled for later work.
18976 |
18977 |
18978 | if (finalizeInitialChildren(instance, type, newProps, rootContainerInstance)) {
| ^ 18979 | markUpdate(workInProgress);
18980 | }
18981 | }
completeUnitOfWork
node_modules/react-dom/cjs/react-dom.development.js:22192
22189 | next = completeWork(current, workInProgress, renderExpirationTime$1);
22190 | } else {
22191 | startProfilerTimer(workInProgress);
22192 | next = completeWork(current, workInProgress, renderExpirationTime$1); // Update render duration assuming we didn't error.
| ^ 22193 |
22194 | stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false);
22195 | }
performUnitOfWork
node_modules/react-dom/cjs/react-dom.development.js:22165
22162 |
22163 | if (next === null) {
22164 | // If this doesn't spawn new work, complete the current work.
22165 | next = completeUnitOfWork(unitOfWork);
| ^ 22166 | }
22167 |
22168 | ReactCurrentOwner$2.current = null;
workLoopSync
node_modules/react-dom/cjs/react-dom.development.js:22130
22127 | function workLoopSync() {
22128 | // Already timed out, so perform work without checking if we need to yield.
22129 | while (workInProgress !== null) {
22130 | workInProgress = performUnitOfWork(workInProgress);
22131 | }
22132 | }
22133 | /** @noinline */
performSyncWorkOnRoot
node_modules/react-dom/cjs/react-dom.development.js:21756
21753 |
21754 | do {
21755 | try {
21756 | workLoopSync();
| ^ 21757 | break;
21758 | } catch (thrownValue) {
21759 | handleError(root, thrownValue);
scheduleUpdateOnFiber
node_modules/react-dom/cjs/react-dom.development.js:21188
21185 | // root inside of batchedUpdates should be synchronous, but layout updates
21186 | // should be deferred until the end of the batch.
21187 |
21188 | performSyncWorkOnRoot(root);
| ^ 21189 | } else {
21190 | ensureRootIsScheduled(root);
21191 | schedulePendingInteractions(root, expirationTime);
updateContainer
node_modules/react-dom/cjs/react-dom.development.js:24373
24370 | }
24371 |
24372 | enqueueUpdate(current$1, update);
24373 | scheduleWork(current$1, expirationTime);
24374 | return expirationTime;
24375 | }
24376 | function getPublicRootInstance(container) {
legacyRenderSubtreeIntoContainer/<
node_modules/react-dom/cjs/react-dom.development.js:24758
24755 |
24756 |
24757 | unbatchedUpdates(function () {
24758 | updateContainer(children, fiberRoot, parentComponent, callback);
| ^ 24759 | });
24760 | } else {
24761 | fiberRoot = root._internalRoot;
unbatchedUpdates
node_modules/react-dom/cjs/react-dom.development.js:21903
21900 | executionContext |= LegacyUnbatchedContext;
21901 |
21902 | try {
21903 | return fn(a);
| ^ 21904 | } finally {
21905 | executionContext = prevExecutionContext;
21906 |
legacyRenderSubtreeIntoContainer
node_modules/react-dom/cjs/react-dom.development.js:24757
24754 | } // Initial mount should not be batched.
24755 |
24756 |
24757 | unbatchedUpdates(function () {
| ^ 24758 | updateContainer(children, fiberRoot, parentComponent, callback);
24759 | });
24760 | } else {
render
node_modules/react-dom/cjs/react-dom.development.js:24840
24837 | }
24838 | }
24839 |
24840 | return legacyRenderSubtreeIntoContainer(null, element, container, false, callback);
24841 | }
24842 | function unstable_renderSubtreeIntoContainer(parentComponent, element, containerNode, callback) {
24843 | if (!isValidContainer(containerNode)) {
./src/index.js
src/index.js:8
5 |
6 | import App from "./App";
7 |
8 | ReactDOM.render(
9 | <React.StrictMode>
10 |
11 |
webpack_require
/Users/wwb/Projekte/Ignore/bumbag/webpack/bootstrap:784
781 | };
782 |
783 | // Execute the module function
784 | modules[moduleId].call(module.exports, module, module.exports, hotCreateRequire(moduleId));
| ^ 785 |
786 | // Flag the module as loaded
787 | module.l = true;
fn
/Users/wwb/Projekte/Ignore/bumbag/webpack/bootstrap:150
147 | );
148 | hotCurrentParents = [];
149 | }
150 | return webpack_require(request);
| ^ 151 | };
152 | var ObjectFactory = function ObjectFactory(name) {
153 | return {
1
http://localhost:3000/static/js/main.chunk.js:271:18
webpack_require
/Users/wwb/Projekte/Ignore/bumbag/webpack/bootstrap:784
781 | };
782 |
783 | // Execute the module function
784 | modules[moduleId].call(module.exports, module, module.exports, hotCreateRequire(moduleId));
| ^ 785 |
786 | // Flag the module as loaded
787 | module.l = true;
checkDeferredModules
/Users/wwb/Projekte/Ignore/bumbag/webpack/bootstrap:45
42 | }
43 | if(fulfilled) {
44 | deferredModules.splice(i--, 1);
45 | result = webpack_require(webpack_require.s = deferredModule[0]);
| ^ 46 | }
47 | }
48 |
webpackJsonpCallback
/Users/wwb/Projekte/Ignore/bumbag/webpack/bootstrap:32
29 | deferredModules.push.apply(deferredModules, executeModules || []);
30 |
31 | // run deferred modules when all chunks ready
32 | return checkDeferredModules();
| ^ 33 | };
34 | function checkDeferredModules() {
35 | var result;
(anonymous function)
http://localhost:3000/static/js/main.chunk.js:1:75
When a table has more columns than the container width just cuts.
To Reproduce
Expected behavior
Some scrollbar or toggle collapse
Device information (please complete the following information):
Additional context
Tried with style={{overFlowX: "auto"}} with no success
Thanks!
The main content area in the /components section is difficult to access using the keyboard.
Open https://bumbag.style/components/button/, click area around the buttons in the first example, then hit tab.
The "TopNavItem" (Bumbag logo/link) on the top left takes the focus. To make matters worse, I have to tab through all the options in the top menu and all the links on the left nav in order to get to the main content.
Either or both one of these:
Is your feature request related to a problem? Please describe.
When adding ActionButtons to a Dialog, I want to add a space-between the two buttons so the cancel button will be placed on the left of the footer and the primary button be placed on the right side of the footer.
Example:
Describe the solution you'd like
We should implement an API to be able to add space, space-out the two buttons.
Describe alternatives you've considered
I've tried using the normal Button
components and the footer
prop on Dialog.Modal
but I had the same issue as #54
Playroom: link
I can see 1px transparent line before header/TopNav
<PageWithHeader style={{marginTop: "-1px"}}
sticky
...
I can fix it adding this.
Describe the bug
When adding direction="rtl"
to the page some components layout looks broken.
And other components have prop values of left
and right
but when the direction changes the values aren't semantically correct.
To Reproduce
Playroom examples with broken layout when the direction is rtl
:
Alert: Link
Group: Link
Blockquote: link
Code Block: link (I think this could have a fixed direction of ltr
since code is written in ltr)
List: link
Badge: link (should be attached to the top-left)
Breadcrumb: link
Button with Icon: link
Callout: link (close icon should be on the left)
Card > Header with addons: link (the header and footer action buttons have a fixed margin-left)
Dialog: link
DropdownMenu: link
Menu: link
Pagination: link
Popover: link (ActionButtons have fixed margin-left)
Rating: link (accessibility: keyboard navigation is going in the opposite direction)
SideNav: link
Table: link (table has a default text-align
with value left
, would be better to have the value to be start
)
Tabs: Link
Tag: link
Toast: link
TopNav: link (TopNav.Item
last child has a fixed margin-right
)
Autosuggest: link
Checkbox: link
CheckboxGroup: link (checkbox items have a fixed margin-left
)
FieldStack: link
FieldWrapper: link
Radio: link
RadioGroup: link
Select: link
SelectMenu: link (the tags have a fixed margin-left
)
Switch: link
Rover: link (accessibility: keyboard navigation is going in the opposite direction)
Components with prop values that aren't semantic with the writing direction:
Container (align
): link
Set (alignX
): link
Stack (alignX
): link
Tabs.List (align
): link
ToastManager (placement
)?: link (couldn't find docs on the API of ToastManager
)
Tooltip (placement
, arrowProps.expand
): link
Drawer (placement
): link
Modal (placement
): link
Overlay (placement
): link
Expected behavior
For the components to use a writing mode agnostic CSS properties such as CSS Logical Properties and Values(margin-inline-start
, padding-inline-end
, etc.) and have prop values that respect the writing mode, ex. rather than left
and right
we could use start
and end
values.
I know that this will require changes across a lot of components so I am willing to help out ๐.
Describe the bug
When passing a component with the prop width="100%"
to Dialog.Modal
's footer
prop, the footer still takes the width of the content of the passed component.
To Reproduce
<Box width="100%" backgroundColor="primary">hello</Box>
to Dialog.Modal
's footer
propExpected behavior
The passed component should take the full width of the footer
Screenshots
Playroom: link
Device information (please complete the following information):
Please consider providing more flexibility to control the size of a Textarea component. Right now, sizes are provided, but setting size= small, medium or large affects both the height of the text area and the font size. I'd like to be able to specify the font size and the number of rows visible independently. This could be as simple as exposing the HTML "rows=". It would also be nice to be able to set the textarea so that it is not resizable by the user (get rid of handle in lower right), but still allows scrolling.
In the CONTRIBUTING.md file, the Guide to developing a new component
has broken links for all the realistic examples.
Describe the bug
As soon as the content of a Table.Cell
gets wider than 11 characters, the Pagination
in the footer will collapse and display a mobile version where the last elements are pushed into a new line for every resolution bigger than 375px.
To Reproduce
See this Playroom example
Change the text of the last column to be shorter or longer and see the result.
Expected behavior
The Pagination
element would use the full width and only push the last elements to a new line if the space is not enough. This is correct for any resolution below 375px.
Screenshots
Actual:
Hi guys.
How can I configure the props onChange() and value element SelectMenu to works with Typescript.
I try this many ways, but is not working...
const [fruits, setFruits] = useState();
....
<SelectMenu
hasTags
isMultiSelect
onChange={(e: React.ChangeEvent<HTMLSelectElement>) => {
setFruits(e.target.value);
}}
options={[
{ key: 1, label: 'Apples', value: 'apples' },
{ key: 2, label: 'Bananas', value: 'bananas' },
{ key: 3, label: 'Oranges', value: 'oranges' },
{ key: 4, label: 'Mangos', value: 'mangos' },
]}
placeholder="Select a fruit..."
value={fruits}
/>
Error:
TypeScript error in /mnt/c/Users/kados/Documents/Dev/projetos/harpa-crista/admin/src/pages/Hinos/Editar/index.tsx(127,19):
Type '(e: React.ChangeEvent<HTMLSelectElement>) => void' is not assignable to type '((event: FormEvent<any>) => void) & ((newOptions: "" | Option | Option[], option: "" | Option) => void)'.
Type '(e: React.ChangeEvent<HTMLSelectElement>) => void' is not assignable to type '(newOptions: "" | Option | Option[], option: "" | Option) => void'.
Types of parameters 'e' and 'newOptions' are incompatible.
Type '"" | Option | Option[]' is not assignable to type 'ChangeEvent<HTMLSelectElement>'.
Type '""' is not assignable to type 'ChangeEvent<HTMLSelectElement>'. TS2322
125 | hasTags
126 | isMultiSelect
> 127 | onChange={(e: React.ChangeEvent<HTMLSelectElement>) => {
| ^
128 | setFruits(e.target.value);
129 | }}
130 | options={[
Is your feature request related to a problem? Please describe.
I don't know how to manage active menu item properly.
Doing it like in Top.Nav using navId="id" would be useful.
as you can see it works great with next/router pathnames for active. I might need to refactor for not so simple routes like 1st level ones only but still!
See as mobile in dev-tools to see drawer-mode menu
https://webapp.agu.vercel.app/
my current code
import { TopNav, Image, Hide, Button, Drawer, Menu } from 'bumbag';
import Link from 'next/link';
import { useRouter } from 'next/router'
import React from 'react'
function Header() {
const router = useRouter()
console.log(router.pathname)
//@ts-ignore
const [selectedId, setSelectedId] = React.useState( router.pathname )
return(
<>
<Hide below="desktop">
{/*
// @ts-ignore*/}
<TopNav selectedId={selectedId} onChange={(id:{id: any})=> setSelectedId(id)}>
<TopNav.Section>
<Link href="/">
<TopNav.Item navId="/" >
<Image src="/logo.svg" maxWidth="130px" style={{cursor: 'pointer', paddingLeft: 20}} />
</TopNav.Item>
</Link>
<Link href="/cruises">
<TopNav.Item navId="/cruises" >
Cruceros
</TopNav.Item>
</Link>
<Link href="/luxury">
<TopNav.Item navId="/luxury">
Lujo
</TopNav.Item>
</Link>
<Link href="/river">
<TopNav.Item navId="/river">
Fluviales
</TopNav.Item>
</Link>
</TopNav.Section>
<TopNav.Section marginRight="major-5">
<Link href="/signup">
<TopNav.Item navId="/signup">
{/* <Button variant="ghost" size='small' palette="primary"> */}
Registro
{/* </Button> */}
</TopNav.Item>
</Link>
<Link href="/login">
<TopNav.Item navId="/login">
{/* <Button variant="call-to-action" size="small" palette="primary"> */}
Entrar
{/* </Button> */}
</TopNav.Item>
</Link>
</TopNav.Section>
</TopNav>
</Hide>
<Hide above="desktop">
<TopNav>
<TopNav.Section marginLeft="major-1" >
<TopNav.Item>
<Drawer.State>
<Drawer.Disclosure>
<Button iconBefore="solid-bars">
MENU
</Button>
</Drawer.Disclosure>
<Drawer>
<Menu>
<Menu.Group >
<Link href="/">
<Menu.Item >
<Image src="/logo.svg" maxWidth="240px" style={{cursor: 'pointer'}} />
</Menu.Item>
</Link>
</Menu.Group>
<Menu.Group title="Cruceros">
<Link href="/cruises">
<Menu.Item >
Cruceros
</Menu.Item>
</Link>
<Link href="/luxury">
<Menu.Item >
Lujo
</Menu.Item>
</Link>
<Link href="/river">
<Menu.Item >
Fluviales
</Menu.Item>
</Link>
</Menu.Group>
<Menu.Divider />
<Menu.Group title="Area de cliente">
<Link href="/signup">
<Menu.Item >
{/* <Button variant="ghost" size='small' palette="primary"> */}
Registro
{/* </Button> */}
</Menu.Item>
</Link>
<Link href="/login">
<Menu.Item >
{/* <Button variant="call-to-action" size="small" palette="primary"> */}
Entrar
{/* </Button> */}
</Menu.Item>
</Link>
</Menu.Group>
</Menu>
</Drawer>
</Drawer.State>
</TopNav.Item>
{/* </TopNav.Section> */}
{/* <TopNav.Section> */}
<TopNav.Item>
<Image src="/logo.svg" maxWidth="130px" style={{cursor: 'pointer', paddingLeft: 10}} />
</TopNav.Item>
</TopNav.Section>
</TopNav>
</Hide>
</>
)
}
export default Header
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.