Skip to content

Commit

Permalink
console,account: Apply more fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
kschiffer committed Jan 11, 2024
1 parent c988bda commit 513c7bc
Show file tree
Hide file tree
Showing 36 changed files with 494 additions and 510 deletions.
9 changes: 5 additions & 4 deletions pkg/webui/components/breadcrumbs/breadcrumb/breadcrumb.styl
Original file line number Diff line number Diff line change
Expand Up @@ -14,29 +14,30 @@


.container
display: flex

&:not(:last-child):after
material-icon()
nudge('down', 1px)
margin: 0 $cs.xxs
content: 'keyboard_arrow_right'
color: $tc-subtle-gray


.link
one-liner()
text-decoration: none
color: $tc-subtle-gray
min-height: 18px
display: flex
align-items: center
+focus-visible()
text-decoration: underline
color: $tc-deep-gray


.last
one-liner()
display: flex
align-items: center
color: $tc-deep-gray
min-height: 18px
font-weight: $fw.bold
+media-query($bp.s)
&:last-child
Expand Down
6 changes: 3 additions & 3 deletions pkg/webui/components/breadcrumbs/breadcrumb/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,17 +30,17 @@ const Breadcrumb = ({ className, path, content, isLast }) => {
if (!isLast) {
Component = Link
componentProps = {
className: classnames(className, style.container, style.link),
className: style.link,
to: path,
secondary: true,
}
} else {
Component = 'span'
componentProps = { className: classnames(className, style.container, style.last) }
componentProps = { className: classnames(className, style.last) }
}

return (
<span {...componentProps}>
<span className={classnames(className, style.container)}>
<Component {...componentProps}>
{isRawText ? content : <Message content={content} />}
</Component>
Expand Down
5 changes: 1 addition & 4 deletions pkg/webui/components/breadcrumbs/breadcrumbs.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
import React from 'react'
import ReactDom from 'react-dom'
import classnames from 'classnames'
import { Container } from 'react-grid-system'

import PropTypes from '@ttn-lw/lib/prop-types'

Expand Down Expand Up @@ -52,9 +51,7 @@ const PortalledBreadcrumbs = ({ className, ...rest }) => {
nodes.push(
ReactDom.createPortal(
<div className={classnames(className, style.breadcrumbsContainer)}>
<Container>
<Breadcrumbs {...rest} />
</Container>
<Breadcrumbs {...rest} />
</div>,
element,
),
Expand Down
4 changes: 3 additions & 1 deletion pkg/webui/components/breadcrumbs/breadcrumbs.styl
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@

.breadcrumbs
color: $tc-subtle-gray
height: $breadcrumbs-bar-height
display: flex
align-items: center
overflow: hidden
height: 1rem

+media-query($bp.s)
overflow: auto
Expand All @@ -30,3 +30,5 @@
&-container
box-sizing: border-box
height: $breadcrumbs-bar-height
display: flex
align-items: center
17 changes: 7 additions & 10 deletions pkg/webui/components/button/button.styl
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
&.primary, &.secondary, &.naked
position: relative
display: inline-flex
transition: 80ms all ease-in-out
transition: 80ms background ease-in-out, 80ms color ease-in-out, 80ms border-color ease-in-out, 80ms box-shadow ease-in-out
border-radius: $br.m
outline: 0
cursor: pointer
Expand All @@ -35,23 +35,20 @@
white-space: nowrap
box-sizing: border-box

.arrow-icon
transform: rotate(0deg)
transition: transform .2s ease-in-out
margin-right: - $cs.xs

.arrow-icon-expanded
transform: rotate(180deg)
transition: transform .2s ease-in-out

.icon
margin-left: - $cs.xxs

&:only-child
margin-right: - $cs.xxs

.expand-icon
color: $c.grey-500
font-size: 1.285rem
margin-right: - $cs.xxs

&.only-icon
gap: 0
padding: 0 $cs.s

&.primary
color: white
Expand Down
59 changes: 16 additions & 43 deletions pkg/webui/components/button/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

import React, { useCallback, forwardRef, useMemo, useState, useRef } from 'react'
import React, { useCallback, forwardRef, useMemo, useRef } from 'react'
import classnames from 'classnames'
import { useIntl } from 'react-intl'

Expand Down Expand Up @@ -51,7 +51,8 @@ const assembleClassnames = ({
className,
error,
}) =>
classnames(style.button, className, {
classnames(style.button, {
[className]: !Boolean(dropdownItems), // If there are dropdown items, the button is wrapped in a div with the className.
[style.danger]: danger,
[style.warning]: warning,
[style.primary]: primary,
Expand All @@ -67,24 +68,15 @@ const assembleClassnames = ({
})

const buttonChildren = props => {
const { dropdownItems, icon, busy, message, expanded, noDropdownIcon, children } = props
const { dropdownItems, icon, busy, message, noDropdownIcon, children } = props

const content = (
<>
{icon && <Icon className={style.icon} icon={icon} />}
{message && <Message content={message} className={style.linkButtonMessage} />}
{children}
{dropdownItems && (
<>
{!noDropdownIcon && (
<Icon
className={classnames(style.arrowIcon, {
[style['arrow-icon-expanded']]: expanded,
})}
icon="expand_more"
/>
)}
</>
<>{!noDropdownIcon && <Icon className={style.expandIcon} icon="expand_more" />}</>
)}
</>
)
Expand All @@ -103,6 +95,7 @@ const Button = forwardRef((props, ref) => {
disabled,
dropdownItems,
dropdownClassName,
dropdownPosition,
name,
type,
value,
Expand All @@ -111,48 +104,26 @@ const Button = forwardRef((props, ref) => {
onBlur,
onClick,
form,
className,
...rest
} = props
const [expanded, setExpanded] = useState(false)
const innerRef = useRef()
const combinedRef = combineRefs([ref, innerRef])

const dataProps = useMemo(() => filterDataProps(rest), [rest])

const handleClickOutside = useCallback(
e => {
if (innerRef.current && !innerRef.current.contains(e.target)) {
setExpanded(false)
}
},
[innerRef],
)

const toggleDropdown = useCallback(() => {
setExpanded(oldExpanded => {
const newState = !oldExpanded
if (newState) document.addEventListener('mousedown', handleClickOutside)
else document.removeEventListener('mousedown', handleClickOutside)
return newState
})
}, [handleClickOutside])

const handleClick = useCallback(
evt => {
if (busy || disabled) {
return
}

if (dropdownItems) {
toggleDropdown()
return
}
// Passing a value to the onClick handler is useful for components that
// are rendered multiple times, e.g. in a list. The value can be used to
// identify the component that was clicked.
onClick(evt, value)
},
[busy, disabled, dropdownItems, onClick, toggleDropdown, value],
[busy, disabled, onClick, value],
)

const intl = useIntl()
Expand All @@ -169,7 +140,7 @@ const Button = forwardRef((props, ref) => {
<button
className={buttonClassNames}
onClick={handleClick}
children={buttonChildren({ ...props, expanded })}
children={buttonChildren({ ...props })}
disabled={busy || disabled}
ref={combinedRef}
{...htmlProps}
Expand All @@ -178,11 +149,15 @@ const Button = forwardRef((props, ref) => {

if (dropdownItems) {
return (
<div className="pos-relative">
<div className={classnames(className, 'pos-relative')}>
{buttonElement}
<Dropdown className={classnames(dropdownClassName)} open={expanded}>
<Dropdown.Attached
className={dropdownClassName}
attachedRef={innerRef}
position={dropdownPosition}
>
{dropdownItems}
</Dropdown>
</Dropdown.Attached>
</div>
)
}
Expand Down Expand Up @@ -289,7 +264,6 @@ buttonChildren.propTypes = {
*/
busy: commonPropTypes.busy,
children: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.node), PropTypes.node]),
expanded: PropTypes.bool,
icon: commonPropTypes.icon,
message: commonPropTypes.message,
}
Expand All @@ -299,7 +273,6 @@ buttonChildren.defaultProps = {
icon: undefined,
message: undefined,
children: null,
expanded: false,
small: false,
}

Expand Down
85 changes: 85 additions & 0 deletions pkg/webui/components/dropdown/attached.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
// Copyright © 2024 The Things Network Foundation, The Things Industries B.V.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import React, { useCallback, useEffect } from 'react'

import Dropdown from '@ttn-lw/components/dropdown'

import PropTypes from '@ttn-lw/lib/prop-types'

const AttachedDropdown = ({ attachedRef, onItemsClick, hover, onOutsideClick, ...rest }) => {
const [open, setOpen] = React.useState(false)

useEffect(() => {
if (!attachedRef.current) {
return
}
const openEvent = hover ? 'mouseenter' : 'click'
const node = attachedRef.current
const toggleDropdown = () => setOpen(val => !val)
const closeDropdown = () => setOpen(false)

node.addEventListener(openEvent, toggleDropdown)
if (hover) {
node.addEventListener('mouseleave', closeDropdown)
}
return () => {
node.removeEventListener(openEvent, toggleDropdown)
if (hover) {
node.removeEventListener('mouseleave', closeDropdown)
}
}
}, [attachedRef, hover, open])

const handleItemsClick = useCallback(() => {
setOpen(false)
onItemsClick()
}, [onItemsClick])

const handleOutsideClick = useCallback(
e => {
if (attachedRef.current && attachedRef.current.contains(e.target)) {
// Ignore clicks on the attached element, so that toggling is possible.
return
}
setOpen(false)
onOutsideClick()
},
[attachedRef, onOutsideClick],
)

return (
<Dropdown
open={open}
onItemsClick={handleItemsClick}
onOutsideClick={handleOutsideClick}
{...rest}
/>
)
}

AttachedDropdown.propTypes = {
attachedRef: PropTypes.shape({ current: PropTypes.instanceOf(Element) }).isRequired,
hover: PropTypes.bool,
onItemsClick: PropTypes.func,
onOutsideClick: PropTypes.func,
}

AttachedDropdown.defaultProps = {
onItemsClick: () => null,
onOutsideClick: () => null,
hover: false,
}

export default AttachedDropdown
Loading

0 comments on commit 513c7bc

Please sign in to comment.