@w5-ui/react 0.2.1 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +118 -4
- package/package.json +2 -2
- package/src/components/AppLayout.tsx +38 -0
- package/src/components/AppShell.tsx +41 -49
- package/src/components/Body.tsx +32 -0
- package/src/components/BodyLg.tsx +29 -0
- package/src/components/Caption.tsx +29 -0
- package/src/components/Card.tsx +13 -0
- package/src/components/CardMore.tsx +22 -0
- package/src/components/Code.tsx +27 -0
- package/src/components/ColumnToggle.tsx +1 -0
- package/src/components/CommandPalette.tsx +1 -0
- package/src/components/ContextMenu.tsx +5 -1
- package/src/components/DateRangePicker.tsx +16 -9
- package/src/components/Delta.tsx +29 -0
- package/src/components/Display1.tsx +33 -0
- package/src/components/Display2.tsx +32 -0
- package/src/components/ExpandableRow.tsx +1 -0
- package/src/components/Eyebrow.tsx +28 -0
- package/src/components/FieldStack.tsx +19 -0
- package/src/components/FormActions.tsx +20 -0
- package/src/components/FormRow.tsx +19 -0
- package/src/components/Grid.tsx +21 -0
- package/src/components/H1.tsx +32 -0
- package/src/components/H2.tsx +32 -0
- package/src/components/H3.tsx +32 -0
- package/src/components/H4.tsx +31 -0
- package/src/components/Label.tsx +30 -0
- package/src/components/Mac.tsx +25 -0
- package/src/components/Modal.tsx +16 -2
- package/src/components/Mono.tsx +31 -0
- package/src/components/Muted.tsx +27 -0
- package/src/components/NameCell.tsx +45 -0
- package/src/components/NotifDot.tsx +24 -0
- package/src/components/NumberInput.tsx +1 -0
- package/src/components/PageHeader.tsx +20 -0
- package/src/components/PasswordInput.tsx +1 -0
- package/src/components/RadioGroup.tsx +2 -1
- package/src/components/SrOnly.tsx +25 -0
- package/src/components/StatNumber.tsx +25 -0
- package/src/components/StatusRing.tsx +38 -0
- package/src/components/Submeta.tsx +23 -0
- package/src/components/TablePager.tsx +27 -0
- package/src/components/TableShell.tsx +23 -0
- package/src/components/TagInput.tsx +7 -2
- package/src/components/TopbarActions.tsx +70 -0
- package/src/components/Unit.tsx +25 -0
- package/src/index.ts +33 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { HTMLAttributes, ReactNode } from 'react'
|
|
2
|
+
|
|
3
|
+
export interface TablePagerProps extends HTMLAttributes<HTMLDivElement> {
|
|
4
|
+
children?: ReactNode
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Sibling row that sits directly under a `<TableShell>` (or
|
|
9
|
+
* `<div className="table-shell">`) and carries the rows-per-page control on
|
|
10
|
+
* the left and the `<Pagination>` nav on the right. Renders the canonical
|
|
11
|
+
* `<div class="table-pager">` markup so the flex / space-between / 12 px top
|
|
12
|
+
* margin from `@w5-ui/tokens/dashboard.css` applies and userland drops the
|
|
13
|
+
* inline `style={{ display: 'flex', justifyContent: 'space-between', … }}`
|
|
14
|
+
* wrapper that every reference page used to ship.
|
|
15
|
+
*
|
|
16
|
+
* Typed equivalent of the manual `<div className="table-pager">` pattern
|
|
17
|
+
* documented in **Foundations / Tables**. Render it as a sibling of
|
|
18
|
+
* `<TableShell>` — never inside it — so the focus rings on the pager buttons
|
|
19
|
+
* are not clipped by `overflow: hidden`.
|
|
20
|
+
*/
|
|
21
|
+
export function TablePager({ className = '', children, ...rest }: TablePagerProps) {
|
|
22
|
+
return (
|
|
23
|
+
<div className={`table-pager ${className}`.trim()} {...rest}>
|
|
24
|
+
{children}
|
|
25
|
+
</div>
|
|
26
|
+
)
|
|
27
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { HTMLAttributes, ReactNode } from 'react'
|
|
2
|
+
|
|
3
|
+
export interface TableShellProps extends HTMLAttributes<HTMLDivElement> {
|
|
4
|
+
children?: ReactNode
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Rounded, bordered wrapper for any full-width `<table>` on a page. Carries the
|
|
9
|
+
* 8 px radius, `--neutral-09` background, single 1 px border and `overflow:
|
|
10
|
+
* hidden` clip so userland tables read like the reference Devices / Clients
|
|
11
|
+
* pages without inline `border` / `borderRadius` styles.
|
|
12
|
+
*
|
|
13
|
+
* Typed equivalent of `<div className="table-shell">` from
|
|
14
|
+
* `@w5-ui/tokens/dashboard.css`. Render the `<Pagination>` row as a sibling
|
|
15
|
+
* below, not inside, so its focus rings aren't clipped.
|
|
16
|
+
*/
|
|
17
|
+
export function TableShell({ className = '', children, ...rest }: TableShellProps) {
|
|
18
|
+
return (
|
|
19
|
+
<div className={`table-shell ${className}`.trim()} {...rest}>
|
|
20
|
+
{children}
|
|
21
|
+
</div>
|
|
22
|
+
)
|
|
23
|
+
}
|
|
@@ -61,7 +61,13 @@ export function TagInput({
|
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
return (
|
|
64
|
-
|
|
64
|
+
// Click-to-focus lives on the presentational wrapper rather than the
|
|
65
|
+
// role="group" element, so a non-interactive ARIA role never carries a
|
|
66
|
+
// mouse handler.
|
|
67
|
+
<div
|
|
68
|
+
className={`tag-input-wrapper${className ? ` ${className}` : ''}`}
|
|
69
|
+
onClick={() => inputRef.current?.focus()}
|
|
70
|
+
>
|
|
65
71
|
{label && (
|
|
66
72
|
<label htmlFor={inputId} className="tag-input__label">
|
|
67
73
|
{label}
|
|
@@ -72,7 +78,6 @@ export function TagInput({
|
|
|
72
78
|
role="group"
|
|
73
79
|
aria-label={label ?? 'Tags'}
|
|
74
80
|
className={`tag-input${disabled ? ' tag-input--disabled' : ''}`}
|
|
75
|
-
onClick={() => inputRef.current?.focus()}
|
|
76
81
|
>
|
|
77
82
|
{tags.map((t, i) => (
|
|
78
83
|
<Tag key={t} label={t} onRemove={disabled ? undefined : () => removeTag(i)} />
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { SearchIcon, UpdatesIcon, BellIcon, HelpIcon } from '../icons.js'
|
|
2
|
+
import { Avatar } from './Avatar.js'
|
|
3
|
+
import { IconButton } from './Button.js'
|
|
4
|
+
import { NotifDot } from './NotifDot.js'
|
|
5
|
+
|
|
6
|
+
export interface TopbarActionsProps {
|
|
7
|
+
/** Avatar initials shown in the trailing account chip. */
|
|
8
|
+
initials?: string
|
|
9
|
+
/** Unread count surfaced via the bell `aria-label` and the red `NotifDot`
|
|
10
|
+
* overlay. `0` hides the dot. */
|
|
11
|
+
notificationCount?: number
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* The canonical right-side action group inside `<Topbar>`: Search, Updates,
|
|
16
|
+
* Notifications (with `<NotifDot>` overlay when unread), Help, and the account
|
|
17
|
+
* `<Avatar>`. Renders the same five controls in the same order as the default
|
|
18
|
+
* block inside `<Topbar>` itself.
|
|
19
|
+
*
|
|
20
|
+
* Pass `<Topbar actions={...}>` replaces the default block in full — userland
|
|
21
|
+
* that wants to inject a theme toggle, status pill, or environment switch
|
|
22
|
+
* usually wants those _alongside_ the canonical controls, not instead of them.
|
|
23
|
+
* `<TopbarActions>` is that re-entry point: compose your custom controls plus
|
|
24
|
+
* `<TopbarActions />` and userland keeps the search / bell / avatar rhythm the
|
|
25
|
+
* reference dashboards ship without copying classes or icons.
|
|
26
|
+
*
|
|
27
|
+
* ```tsx
|
|
28
|
+
* <Topbar
|
|
29
|
+
* siteName="HQ"
|
|
30
|
+
* activeApp="system"
|
|
31
|
+
* onAppChange={setApp}
|
|
32
|
+
* actions={
|
|
33
|
+
* <>
|
|
34
|
+
* <ThemeToggle />
|
|
35
|
+
* <TopbarActions notificationCount={3} initials="WS" />
|
|
36
|
+
* </>
|
|
37
|
+
* }
|
|
38
|
+
* />
|
|
39
|
+
* ```
|
|
40
|
+
*
|
|
41
|
+
* The `<NotifDot>` ring colour, the `IconButton` 28 px square, and the
|
|
42
|
+
* `Avatar` `size="sm"` chip all come from `@w5-ui/tokens/dashboard.css` — drop
|
|
43
|
+
* the primitive in and the topbar reads identically to the Dashboard story.
|
|
44
|
+
*/
|
|
45
|
+
export function TopbarActions({ initials = 'MS', notificationCount = 1 }: TopbarActionsProps) {
|
|
46
|
+
return (
|
|
47
|
+
<>
|
|
48
|
+
<IconButton aria-label="Search" title="Search">
|
|
49
|
+
<SearchIcon />
|
|
50
|
+
</IconButton>
|
|
51
|
+
<IconButton aria-label="Updates" title="Updates">
|
|
52
|
+
<UpdatesIcon />
|
|
53
|
+
</IconButton>
|
|
54
|
+
<IconButton
|
|
55
|
+
aria-label={
|
|
56
|
+
notificationCount > 0 ? `Notifications, ${notificationCount} new` : 'Notifications'
|
|
57
|
+
}
|
|
58
|
+
title="Notifications"
|
|
59
|
+
style={{ position: 'relative' }}
|
|
60
|
+
>
|
|
61
|
+
<BellIcon />
|
|
62
|
+
{notificationCount > 0 && <NotifDot />}
|
|
63
|
+
</IconButton>
|
|
64
|
+
<IconButton aria-label="Help" title="Help">
|
|
65
|
+
<HelpIcon />
|
|
66
|
+
</IconButton>
|
|
67
|
+
<Avatar initials={initials} size="sm" alt={`Account, ${initials}`} />
|
|
68
|
+
</>
|
|
69
|
+
)
|
|
70
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { HTMLAttributes, ReactNode } from 'react'
|
|
2
|
+
|
|
3
|
+
export interface UnitProps extends HTMLAttributes<HTMLSpanElement> {
|
|
4
|
+
children?: ReactNode
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Small inline label that trails a hero number inside a `.stat` row or a
|
|
9
|
+
* `<Card>` title row (e.g. "Mbps · down", "Last 24 h", "ms · jitter band").
|
|
10
|
+
* Renders a `<span class="unit">` so the `.unit` rule in
|
|
11
|
+
* `@w5-ui/tokens/dashboard.css` sets the canonical muted colour, 12 px size,
|
|
12
|
+
* and inline-block rhythm. Stops userland reaching for inline `font-size` /
|
|
13
|
+
* `color` overrides next to bare numbers.
|
|
14
|
+
*
|
|
15
|
+
* Typed equivalent of `<span className="unit">`; pair with `<Stat>` (which
|
|
16
|
+
* already wires this internally) for hero tiles, or compose by hand inside a
|
|
17
|
+
* `<Card>` when the headline number sits above a chart.
|
|
18
|
+
*/
|
|
19
|
+
export function Unit({ className = '', children, ...rest }: UnitProps) {
|
|
20
|
+
return (
|
|
21
|
+
<span className={`unit ${className}`.trim()} {...rest}>
|
|
22
|
+
{children}
|
|
23
|
+
</span>
|
|
24
|
+
)
|
|
25
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -18,6 +18,38 @@ export * from './components/Signal.js'
|
|
|
18
18
|
export * from './components/Donut.js'
|
|
19
19
|
export * from './components/StatusIndicator.js'
|
|
20
20
|
export * from './components/AppShell.js'
|
|
21
|
+
export * from './components/AppLayout.js'
|
|
22
|
+
export * from './components/Grid.js'
|
|
23
|
+
export * from './components/FieldStack.js'
|
|
24
|
+
export * from './components/FormRow.js'
|
|
25
|
+
export * from './components/FormActions.js'
|
|
26
|
+
export * from './components/TableShell.js'
|
|
27
|
+
export * from './components/TablePager.js'
|
|
28
|
+
export * from './components/Submeta.js'
|
|
29
|
+
export * from './components/Delta.js'
|
|
30
|
+
export * from './components/CardMore.js'
|
|
31
|
+
export * from './components/Unit.js'
|
|
32
|
+
export * from './components/StatNumber.js'
|
|
33
|
+
export * from './components/Mac.js'
|
|
34
|
+
export * from './components/NameCell.js'
|
|
35
|
+
export * from './components/SrOnly.js'
|
|
36
|
+
export * from './components/NotifDot.js'
|
|
37
|
+
export * from './components/StatusRing.js'
|
|
38
|
+
export * from './components/TopbarActions.js'
|
|
39
|
+
export * from './components/Muted.js'
|
|
40
|
+
export * from './components/Code.js'
|
|
41
|
+
export * from './components/Eyebrow.js'
|
|
42
|
+
export * from './components/Mono.js'
|
|
43
|
+
export * from './components/Caption.js'
|
|
44
|
+
export * from './components/BodyLg.js'
|
|
45
|
+
export * from './components/Body.js'
|
|
46
|
+
export * from './components/Label.js'
|
|
47
|
+
export * from './components/Display1.js'
|
|
48
|
+
export * from './components/Display2.js'
|
|
49
|
+
export * from './components/H1.js'
|
|
50
|
+
export * from './components/H2.js'
|
|
51
|
+
export * from './components/H3.js'
|
|
52
|
+
export * from './components/H4.js'
|
|
21
53
|
export * from './components/Skeleton.js'
|
|
22
54
|
export * from './components/Spinner.js'
|
|
23
55
|
export * from './components/SkipLink.js'
|
|
@@ -157,4 +189,5 @@ export * from './components/SelectionToolbar.js'
|
|
|
157
189
|
export * from './components/FilterBuilder.js'
|
|
158
190
|
export * from './components/RankedList.js'
|
|
159
191
|
export * from './components/GroupedList.js'
|
|
192
|
+
export * from './components/PageHeader.js'
|
|
160
193
|
export * from './icons.js'
|