Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Panel component #6809

Merged
merged 35 commits into from
Feb 5, 2024
Merged
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
c2804eb
console: Add news panel item
ryaplots Jan 4, 2024
ae731de
console: Add panel component
ryaplots Jan 4, 2024
8411c02
console: Add toggle
ryaplots Jan 4, 2024
9dbc5a4
console: Add shortcuts panel item
ryaplots Jan 4, 2024
a93079b
console: Add status label
ryaplots Jan 4, 2024
b4000d5
console: Update tabs component
ryaplots Jan 4, 2024
06761ad
console: Fix font sizes, font weights and border radiuses
ryaplots Jan 8, 2024
59254fa
console: Fix styling
ryaplots Jan 17, 2024
e49d806
console: Improve storybook section
ryaplots Jan 17, 2024
79ec796
console: Fix panel
ryaplots Jan 23, 2024
2aa48f9
console: Update panel styling
ryaplots Jan 23, 2024
6e01e25
console: Use color utility class
ryaplots Jan 24, 2024
e4a9fb0
console: Remove max and min width from panel
ryaplots Jan 24, 2024
c54c135
console: Merge utility classes and regular class into the styl file
ryaplots Jan 24, 2024
108c673
console: Use color utility classes to achieve label states
ryaplots Jan 24, 2024
2c4240f
console: Add utility classes into styl class in news item
ryaplots Jan 24, 2024
fd5598f
console: Use Link instead of recreating link behaviour
ryaplots Jan 25, 2024
0e25c50
console: Add a panel divider
ryaplots Jan 25, 2024
f9a3f4d
console: Add news items to story
ryaplots Jan 25, 2024
b905a4e
console: Use link instead of navlink
ryaplots Jan 25, 2024
7f6dfe9
console: Fix line-height
ryaplots Jan 25, 2024
3547f36
console: Add transitions
ryaplots Jan 29, 2024
3d71795
Use text-decoration thickness and offset
ryaplots Jan 29, 2024
b4a315e
console: Fix panel animations and icon
ryaplots Jan 30, 2024
fb7d217
console: Fix animation on shortcut button
ryaplots Jan 31, 2024
3a84c0f
console: Improve animation and add svg to panel
ryaplots Jan 31, 2024
6b40f44
console: Adapt svg to use current color
ryaplots Jan 31, 2024
9b2420f
console: Add star and plus icons
ryaplots Jan 31, 2024
c020a1d
console: Remove comment
ryaplots Feb 1, 2024
3271773
console: Create the folder for the icon components
ryaplots Feb 1, 2024
0f02235
Merge branch 'feature/panel-component' of github.com:TheThingsNetwork…
ryaplots Feb 1, 2024
3a1f579
console: Fix color
ryaplots Feb 1, 2024
a9c609b
console: Introduce replacement icons as part of icon component
kschiffer Feb 2, 2024
1153cf2
console: Add panel shadow token
kschiffer Feb 5, 2024
98e9cd0
dev: Add figma URLs to stories
kschiffer Feb 5, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion config/storybook/preview.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ import messages from '@ttn-lw/locales/en.json'
import backendMessages from '@ttn-lw/locales/.backend/en.json'

import '../../pkg/webui/styles/main.styl'
import '../../pkg/webui/styles/utilities/color.styl'
import '../../pkg/webui/styles/utilities/general.styl'
import '../../pkg/webui/styles/utilities/spacing.styl'
import 'focus-visible/dist/focus-visible'
Expand Down
51 changes: 51 additions & 0 deletions pkg/webui/components/news-panel/news-item/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Copyright © 2023 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 from 'react'

import Link from '@ttn-lw/components/link'

import DateTime from '@ttn-lw/lib/components/date-time'
import Message from '@ttn-lw/lib/components/message'

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

import styles from './news-item.styl'

const NewsItem = ({ articleTitle, articleImage, articleDate }) => (
<Link className={styles.item}>
<img src={articleImage} className={styles.image} />
<div className="d-flex direction-column j-center">
<Message content={articleTitle} className={styles.title} />
<DateTime
value={articleDate}
time={false}
dateFormatOptions={{
year: 'numeric',
month: 'long',
day: '2-digit',
}}
className="c-text-neutral-light"
/>
</div>
</Link>
)

NewsItem.propTypes = {
articleDate: PropTypes.string.isRequired,
articleImage: PropTypes.string.isRequired,
articleTitle: PropTypes.message.isRequired,
}

export default NewsItem
41 changes: 41 additions & 0 deletions pkg/webui/components/news-panel/news-item/news-item.styl
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Copyright © 2023 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.

.item
display: flex
padding: $cs-xs
gap: $cs.m
transition: background-color $ad.m ease-in-out
border-radius: $br.xl
ryaplots marked this conversation as resolved.
Show resolved Hide resolved
padding: $cs.xs

&:hover
background-color: var(--c-bg-neutral-min-hover)

.image
border-radius: $br.l
border: 1px solid var(--c-border-neutral-light)
height: 5rem
width: auto

.title
width: 100%
font-weight: $fwv2.bold
color: var(--c-text-neutral-heavy)
overflow: hidden
display: -webkit-box
-webkit-box-orient: vertical
-webkit-line-clamp: 2 /* start showing ellipsis when 2nd line is reached */
white-space: pre-wrap
line-height: normal
34 changes: 34 additions & 0 deletions pkg/webui/components/news-panel/news-item/story.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Copyright © 2023 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 from 'react'

import loginVisual from '@assets/img/layout/bg/login-visual.jpg'

import NewsItem from '.'

export default {
title: 'Panel/News Panel/News Item',
component: NewsItem,
}

export const Default = () => (
<div style={{ width: '399px' }}>
<NewsItem
articleTitle="Long title of the latest post on our blog that will take more that two line to fit in here"
articleImage={loginVisual}
articleDate="2024-01-01T00:00:00Z"
/>
</div>
)
87 changes: 87 additions & 0 deletions pkg/webui/components/panel/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
// Copyright © 2023 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 from 'react'
import classnames from 'classnames'

import Message from '@ttn-lw/lib/components/message'

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

import Icon from '../icon'
import Link from '../link'

import Toggle from './toggle'

import styles from './panel.styl'

const Panel = ({
children,
title,
icon,
toggleOptions,
activeToggle,
onToggleClick,
buttonTitle,
path,
className,
messageDecorators,
divider,
}) => (
<div className={classnames(styles.panel, className)}>
<div className="d-flex j-between mb-cs-m">
<div className="d-flex gap-cs-xs al-center">
{icon && <Icon icon={icon} className={styles.panelHeaderIcon} />}
<Message content={title} className={styles.panelHeaderTitle} />
{messageDecorators}
</div>
{toggleOptions ? (
<Toggle options={toggleOptions} active={activeToggle} onToggleChange={onToggleClick} />
) : (
<Link primary to={path} className={styles.button}>
<Message content={buttonTitle} /> →
</Link>
)}
</div>
{divider && <hr className={styles.panelDivider} />}
{children}
</div>
)

Panel.propTypes = {
activeToggle: PropTypes.string,
buttonTitle: PropTypes.string,
children: PropTypes.node.isRequired,
className: PropTypes.string,
divider: PropTypes.bool,
icon: PropTypes.string,
messageDecorators: PropTypes.node,
onToggleClick: PropTypes.func,
path: PropTypes.string.isRequired,
title: PropTypes.message.isRequired,
toggleOptions: PropTypes.arrayOf(PropTypes.shape({})),
}

Panel.defaultProps = {
buttonTitle: undefined,
icon: undefined,
toggleOptions: undefined,
activeToggle: undefined,
onToggleClick: () => null,
className: undefined,
messageDecorators: undefined,
divider: false,
}

export default Panel
44 changes: 44 additions & 0 deletions pkg/webui/components/panel/panel.styl
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Copyright © 2023 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.

.panel
width: 100%
border-radius: $br.xl
border: 1px solid var(--c-border-neutral-light)
background-color: var(--c-bg-neutral-min)
box-shadow: 0px 1px 5px 0px rgba(0, 0, 0, 0.09) // TODO: Convert to token.
padding: $cs.xl

&-header
&-title
font-weight: $fwv2.bold
font-size: $fsv2.l
line-height: 1

.button
font-weight: $fwv2.semibold
text-decoration: none

&:hover
color: var(--c-text-brand-normal)
text-decoration: underline

&-divider
border-bottom: 1px solid var(--c-border-neutral-light)
margin-top: $cs.l
margin-bottom: $cs.l
height: 0px

span.panel-header-icon
font-size: 1.5rem
77 changes: 77 additions & 0 deletions pkg/webui/components/panel/story.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
// Copyright © 2023 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 from 'react'

import loginVisual from '@assets/img/layout/bg/login-visual.jpg'

import NewsItem from '../news-panel/news-item'

import Panel from '.'

export default {
title: 'Panel',
component: Panel,
}

export const Default = () => (
<div style={{ width: '32.5rem' }}>
<Panel title="Latest news" icon="feed" buttonTitle="Visit our blog" divider>
<div className="d-flex direction-column gap-cs-xs">
<NewsItem
articleTitle="Long title of the latest post on our blog that will take more that two line to fit in here"
articleImage={loginVisual}
articleDate="2024-01-01T00:00:00Z"
/>
<NewsItem
articleTitle="Long title of the latest post on our blog that will take more that two line to fit in here"
articleImage={loginVisual}
articleDate="2024-01-01T00:00:00Z"
/>
<NewsItem
articleTitle="Long title of the latest post on our blog that will take more that two line to fit in here"
articleImage={loginVisual}
articleDate="2024-01-01T00:00:00Z"
/>
</div>
</Panel>
</div>
)

const Example = props => {
const [active, setActive] = React.useState('option-1')

const handleChange = React.useCallback(
(_, value) => {
setActive(value)
},
[setActive],
)

return <Panel {...props} activeToggle={active} onToggleClick={handleChange} />
}

export const WithToggle = () => {
const options = [
{ label: 'Option 1', value: 'option-1' },
{ label: 'Option 2', value: 'option-2' },
{ label: 'Option 3', value: 'option-3' },
]

return (
<div style={{ width: '32.5rem' }}>
<Example title="Your top entities" icon="star" toggleOptions={options} />
</div>
)
}
Loading
Loading