@prestack/thread-ui 0.1.10 → 0.1.12
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/CHANGELOG.md +375 -0
- package/dist/ui/attach.js +6 -7
- package/dist/ui/compositions.d.ts +0 -8
- package/dist/ui/compositions.js +3 -166
- package/dist/ui/generators/routes.js +1 -0
- package/package.json +2 -2
- package/dist/ui/animations/anm_appear.ts +0 -13
- package/dist/ui/animations/anm_blur_in.ts +0 -19
- package/dist/ui/animations/anm_blur_out.ts +0 -18
- package/dist/ui/animations/anm_dismiss.ts +0 -18
- package/dist/ui/animations/anm_drop.ts +0 -19
- package/dist/ui/animations/anm_fall.ts +0 -18
- package/dist/ui/animations/anm_flash.ts +0 -18
- package/dist/ui/animations/anm_glow.ts +0 -16
- package/dist/ui/animations/anm_lift.ts +0 -16
- package/dist/ui/animations/anm_nudge.ts +0 -16
- package/dist/ui/animations/anm_pop_in.ts +0 -23
- package/dist/ui/animations/anm_pop_out.ts +0 -22
- package/dist/ui/animations/anm_press.ts +0 -12
- package/dist/ui/animations/anm_pulse.ts +0 -13
- package/dist/ui/animations/anm_rise.ts +0 -19
- package/dist/ui/animations/anm_shake.ts +0 -13
- package/dist/ui/animations/anm_slide_in_left.ts +0 -19
- package/dist/ui/animations/anm_slide_in_right.ts +0 -19
- package/dist/ui/animations/anm_slide_out_left.ts +0 -18
- package/dist/ui/animations/anm_slide_out_right.ts +0 -18
- package/dist/ui/animations/anm_spin.ts +0 -12
- package/dist/ui/animations/anm_swell.ts +0 -16
- package/dist/ui/animations/anm_wobble.ts +0 -24
- package/dist/ui/animations/anm_zoom_in.ts +0 -19
- package/dist/ui/animations/anm_zoom_out.ts +0 -18
- package/dist/ui/animations.ts +0 -308
- package/dist/ui/attach.ts +0 -553
- package/dist/ui/charts.tsx +0 -69
- package/dist/ui/checked.ts +0 -32
- package/dist/ui/collector.ts +0 -140
- package/dist/ui/compositions.ts +0 -613
- package/dist/ui/consent.ts +0 -55
- package/dist/ui/content.tsx +0 -27
- package/dist/ui/contrast.ts +0 -27
- package/dist/ui/controls.tsx +0 -25
- package/dist/ui/disclosure.tsx +0 -20
- package/dist/ui/dismiss-layer.ts +0 -87
- package/dist/ui/door.ts +0 -140
- package/dist/ui/drag.ts +0 -316
- package/dist/ui/elements/accordion.tsx +0 -47
- package/dist/ui/elements/accordion.works.ts +0 -66
- package/dist/ui/elements/aspect-ratio.tsx +0 -31
- package/dist/ui/elements/aspect-ratio.works.ts +0 -5
- package/dist/ui/elements/avatar.tsx +0 -34
- package/dist/ui/elements/avatar.works.ts +0 -16
- package/dist/ui/elements/badge.tsx +0 -33
- package/dist/ui/elements/badge.works.ts +0 -9
- package/dist/ui/elements/bars.tsx +0 -50
- package/dist/ui/elements/bars.works.ts +0 -29
- package/dist/ui/elements/box.tsx +0 -36
- package/dist/ui/elements/breadcrumb.tsx +0 -38
- package/dist/ui/elements/breadcrumb.works.ts +0 -24
- package/dist/ui/elements/button.tsx +0 -46
- package/dist/ui/elements/button.works.tsx +0 -52
- package/dist/ui/elements/column.tsx +0 -29
- package/dist/ui/elements/consent.tsx +0 -71
- package/dist/ui/elements/consent.works.tsx +0 -132
- package/dist/ui/elements/donut.tsx +0 -45
- package/dist/ui/elements/donut.works.ts +0 -42
- package/dist/ui/elements/each.tsx +0 -34
- package/dist/ui/elements/each.works.tsx +0 -82
- package/dist/ui/elements/empty.tsx +0 -33
- package/dist/ui/elements/field.tsx +0 -45
- package/dist/ui/elements/field.works.ts +0 -65
- package/dist/ui/elements/funnel.tsx +0 -50
- package/dist/ui/elements/funnel.works.ts +0 -37
- package/dist/ui/elements/gauge.tsx +0 -40
- package/dist/ui/elements/gauge.works.ts +0 -42
- package/dist/ui/elements/glyph.tsx +0 -30
- package/dist/ui/elements/glyph.works.tsx +0 -42
- package/dist/ui/elements/grid.tsx +0 -29
- package/dist/ui/elements/heatmap.tsx +0 -48
- package/dist/ui/elements/heatmap.works.ts +0 -24
- package/dist/ui/elements/hit-box.tsx +0 -47
- package/dist/ui/elements/hit-box.works.tsx +0 -576
- package/dist/ui/elements/image.tsx +0 -29
- package/dist/ui/elements/line-chart.tsx +0 -45
- package/dist/ui/elements/line-chart.works.ts +0 -41
- package/dist/ui/elements/link.tsx +0 -38
- package/dist/ui/elements/link.works.ts +0 -25
- package/dist/ui/elements/media.tsx +0 -57
- package/dist/ui/elements/menu.tsx +0 -51
- package/dist/ui/elements/menu.works.tsx +0 -154
- package/dist/ui/elements/money.tsx +0 -36
- package/dist/ui/elements/money.works.ts +0 -9
- package/dist/ui/elements/pagination.tsx +0 -39
- package/dist/ui/elements/pagination.works.ts +0 -20
- package/dist/ui/elements/progress.tsx +0 -34
- package/dist/ui/elements/progress.works.ts +0 -8
- package/dist/ui/elements/radio-group.tsx +0 -50
- package/dist/ui/elements/radio-group.works.ts +0 -33
- package/dist/ui/elements/row.tsx +0 -29
- package/dist/ui/elements/scatter.tsx +0 -42
- package/dist/ui/elements/scatter.works.ts +0 -38
- package/dist/ui/elements/select.tsx +0 -43
- package/dist/ui/elements/select.works.ts +0 -5
- package/dist/ui/elements/separator.tsx +0 -31
- package/dist/ui/elements/skeleton.tsx +0 -31
- package/dist/ui/elements/slider.tsx +0 -34
- package/dist/ui/elements/slider.works.ts +0 -5
- package/dist/ui/elements/sparkline.tsx +0 -37
- package/dist/ui/elements/sparkline.works.ts +0 -32
- package/dist/ui/elements/spinner.tsx +0 -33
- package/dist/ui/elements/stack.tsx +0 -29
- package/dist/ui/elements/stat.tsx +0 -36
- package/dist/ui/elements/stat.works.ts +0 -14
- package/dist/ui/elements/surface.tsx +0 -36
- package/dist/ui/elements/surface.works.ts +0 -9
- package/dist/ui/elements/table.tsx +0 -62
- package/dist/ui/elements/table.works.ts +0 -30
- package/dist/ui/elements/tabs.tsx +0 -47
- package/dist/ui/elements/tabs.works.ts +0 -84
- package/dist/ui/elements/text.tsx +0 -33
- package/dist/ui/elements/textarea.tsx +0 -38
- package/dist/ui/elements/textarea.works.ts +0 -5
- package/dist/ui/elements/time.tsx +0 -40
- package/dist/ui/elements/time.works.ts +0 -29
- package/dist/ui/elements/toggle.tsx +0 -34
- package/dist/ui/elements/toggle.works.ts +0 -5
- package/dist/ui/elements/tooltip.tsx +0 -40
- package/dist/ui/elements/tooltip.works.ts +0 -77
- package/dist/ui/elements/value.tsx +0 -38
- package/dist/ui/elements/value.works.ts +0 -9
- package/dist/ui/elements.ts +0 -127
- package/dist/ui/focus-scope.ts +0 -121
- package/dist/ui/fonts.ts +0 -355
- package/dist/ui/generators/dev.d.ts +0 -1
- package/dist/ui/generators/dev.js +0 -62
- package/dist/ui/generators/dev.ts +0 -75
- package/dist/ui/generators/elements.ts +0 -796
- package/dist/ui/generators/i18n.ts +0 -283
- package/dist/ui/generators/icons.ts +0 -207
- package/dist/ui/generators/react.ts +0 -267
- package/dist/ui/generators/routes.ts +0 -847
- package/dist/ui/generators/show.ts +0 -261
- package/dist/ui/generators/styles.ts +0 -677
- package/dist/ui/generators/variants.ts +0 -196
- package/dist/ui/i18n/catalogs/en.ts +0 -191
- package/dist/ui/i18n/format.ts +0 -221
- package/dist/ui/i18n/locales.ts +0 -33
- package/dist/ui/i18n/parse.ts +0 -315
- package/dist/ui/i18n/translator.ts +0 -31
- package/dist/ui/i18n/types.ts +0 -96
- package/dist/ui/icons.ts +0 -331
- package/dist/ui/islands/map.ts +0 -58
- package/dist/ui/localizations.ts +0 -75
- package/dist/ui/material.ts +0 -236
- package/dist/ui/materials/mat_bordered.ts +0 -13
- package/dist/ui/materials/mat_ceramic.ts +0 -13
- package/dist/ui/materials/mat_clay.ts +0 -13
- package/dist/ui/materials/mat_elevated.ts +0 -24
- package/dist/ui/materials/mat_flat.ts +0 -34
- package/dist/ui/materials/mat_glass.ts +0 -20
- package/dist/ui/materials/mat_lit.ts +0 -13
- package/dist/ui/materials/mat_moulded.ts +0 -11
- package/dist/ui/materials.ts +0 -197
- package/dist/ui/modes.ts +0 -44
- package/dist/ui/navigation.tsx +0 -29
- package/dist/ui/positioning.ts +0 -90
- package/dist/ui/presented.tsx +0 -119
- package/dist/ui/provider.tsx +0 -184
- package/dist/ui/render-loop.ts +0 -133
- package/dist/ui/roving-focus.ts +0 -161
- package/dist/ui/screens.ts +0 -141
- package/dist/ui/scroll-lock.ts +0 -28
- package/dist/ui/series.ts +0 -97
- package/dist/ui/signals.ts +0 -386
- package/dist/ui/styleguide.ts +0 -231
- package/dist/ui/styleguides.ts +0 -374
- package/dist/ui/themes.ts +0 -22
- package/dist/ui/token.ts +0 -78
- package/dist/ui/tokens/shadow.ts +0 -25
- package/dist/ui/tokens.ts +0 -234
- package/dist/ui/validators.ts +0 -232
- package/dist/ui/variant.ts +0 -349
- package/dist/ui/variants/var_avatar-round.ts +0 -14
- package/dist/ui/variants/var_bubble-me.ts +0 -14
- package/dist/ui/variants/var_bubble-them.ts +0 -13
- package/dist/ui/variants/var_button-border.ts +0 -76
- package/dist/ui/variants/var_button-cta.ts +0 -76
- package/dist/ui/variants/var_button-destructive-ghost.ts +0 -72
- package/dist/ui/variants/var_button-destructive.ts +0 -76
- package/dist/ui/variants/var_button-fill.ts +0 -76
- package/dist/ui/variants/var_button-ghost.ts +0 -72
- package/dist/ui/variants/var_button-glass.ts +0 -55
- package/dist/ui/variants/var_button-normal.ts +0 -76
- package/dist/ui/variants/var_button-quiet.ts +0 -74
- package/dist/ui/variants/var_card.ts +0 -17
- package/dist/ui/variants/var_chip.ts +0 -13
- package/dist/ui/variants/var_choice.ts +0 -15
- package/dist/ui/variants/var_framed.ts +0 -10
- package/dist/ui/variants/var_glyph-plain.ts +0 -11
- package/dist/ui/variants/var_input.ts +0 -43
- package/dist/ui/variants/var_link-inline.ts +0 -29
- package/dist/ui/variants/var_list-row.ts +0 -34
- package/dist/ui/variants/var_rule.ts +0 -10
- package/dist/ui/variants/var_skeleton-block.ts +0 -12
- package/dist/ui/variants/var_spinner-turning.ts +0 -12
- package/dist/ui/variants/var_stat-tile.ts +0 -13
- package/dist/ui/variants/var_tab-bar.ts +0 -15
- package/dist/ui/variants/var_tap-target.ts +0 -25
- package/dist/ui/variants.ts +0 -64
- package/dist/ui/wrappers.tsx +0 -429
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
import { useId, useState, type ReactNode } from 'react'
|
|
2
|
-
|
|
3
|
-
import type { Row } from '../charts.tsx'
|
|
4
|
-
import type { Surface } from '../door.ts'
|
|
5
|
-
import type { AccordionProps } from './accordion.tsx'
|
|
6
|
-
|
|
7
|
-
type Kept = {
|
|
8
|
-
readonly base: string
|
|
9
|
-
readonly open: readonly string[]
|
|
10
|
-
readonly toggle: (id: string) => void
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export function uses(props: AccordionProps): {
|
|
14
|
-
readonly holds?: readonly string[]
|
|
15
|
-
readonly animates?: boolean
|
|
16
|
-
readonly on?: Readonly<Record<string, unknown>>
|
|
17
|
-
readonly base: string
|
|
18
|
-
readonly open: readonly string[]
|
|
19
|
-
readonly toggle: (id: string) => void
|
|
20
|
-
} {
|
|
21
|
-
const base = useId()
|
|
22
|
-
const [open, setOpen] = useState<readonly string[]>(props.initial ?? [])
|
|
23
|
-
return {
|
|
24
|
-
base,
|
|
25
|
-
open,
|
|
26
|
-
toggle: (id: string): void => {
|
|
27
|
-
const next = open.includes(id)
|
|
28
|
-
? open.filter((one) => one !== id)
|
|
29
|
-
: props.exclusive === true
|
|
30
|
-
? [id]
|
|
31
|
-
: [...open, id]
|
|
32
|
-
setOpen(next)
|
|
33
|
-
props.onChange?.(next)
|
|
34
|
-
},
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
export function section(_props: AccordionProps, kept: Kept, row: Row, _at: number): Readonly<Record<string, unknown>> {
|
|
39
|
-
return { 'data-open': kept.open.includes(String(row['id'])) }
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export function header(_props: AccordionProps, kept: Kept, row: Row, _at: number): Readonly<Record<string, unknown>> {
|
|
43
|
-
const id = String(row['id'])
|
|
44
|
-
return {
|
|
45
|
-
type: 'button',
|
|
46
|
-
id: `${kept.base}-header-${id}`,
|
|
47
|
-
'aria-controls': `${kept.base}-region-${id}`,
|
|
48
|
-
'aria-expanded': kept.open.includes(id),
|
|
49
|
-
disabled: row['disabled'] === true,
|
|
50
|
-
onClick: (): void => kept.toggle(id),
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
export function region(_props: AccordionProps, kept: Kept, row: Row, _at: number): Readonly<Record<string, unknown>> {
|
|
55
|
-
const id = String(row['id'])
|
|
56
|
-
return {
|
|
57
|
-
role: 'region',
|
|
58
|
-
id: `${kept.base}-region-${id}`,
|
|
59
|
-
'aria-labelledby': `${kept.base}-header-${id}`,
|
|
60
|
-
hidden: !kept.open.includes(id),
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
export function shown(_props: AccordionProps, row: Row, surface: Surface, _kept: unknown): Readonly<Record<string, ReactNode>> {
|
|
65
|
-
return { label: surface.text(String(row['labelKey'])), inside: row['content'] as ReactNode }
|
|
66
|
-
}
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
'use client'
|
|
2
|
-
|
|
3
|
-
import type { ReactNode } from 'react'
|
|
4
|
-
|
|
5
|
-
import type { Dispatching } from '../checked.ts'
|
|
6
|
-
import { type Element, element, useSurface } from '../wrappers.tsx'
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
export interface AspectRatioProps {
|
|
10
|
-
readonly children: ReactNode
|
|
11
|
-
readonly ratio: number
|
|
12
|
-
readonly dispatch?: keyof Dispatching
|
|
13
|
-
readonly input?: Readonly<Record<string, unknown>>
|
|
14
|
-
readonly invokeOn?: 'press' | 'shown'
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export const AspectRatio: Element<'AspectRatio', AspectRatioProps> = element(
|
|
18
|
-
'AspectRatio',
|
|
19
|
-
(props: AspectRatioProps, className) => {
|
|
20
|
-
const surface = useSurface({ className,
|
|
21
|
-
invokes: { ...(props.dispatch === undefined ? {} : { dispatch: props.dispatch }), ...(props.input === undefined ? {} : { input: props.input }), ...(props.invokeOn === undefined ? {} : { on: props.invokeOn }) },
|
|
22
|
-
measures: { "ratio": String(props.ratio ?? '') }, })
|
|
23
|
-
return (
|
|
24
|
-
<div className={surface.className} {...surface.marks} {...surface.invokes} {...surface.a11y} style={surface.measures}>
|
|
25
|
-
{props.children}
|
|
26
|
-
</div>
|
|
27
|
-
)
|
|
28
|
-
},
|
|
29
|
-
'e-aspect-ratio',
|
|
30
|
-
{"framed":"thread-framed"},
|
|
31
|
-
)
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
'use client'
|
|
2
|
-
|
|
3
|
-
import type { MessageKey } from '../content.tsx'
|
|
4
|
-
import { roleClass } from '../fonts.ts'
|
|
5
|
-
|
|
6
|
-
import type { Dispatching } from '../checked.ts'
|
|
7
|
-
import { type Element, element, useSurface } from '../wrappers.tsx'
|
|
8
|
-
import { shown } from './avatar.works.ts'
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
export interface AvatarProps {
|
|
12
|
-
readonly labelKey: MessageKey
|
|
13
|
-
readonly src?: string
|
|
14
|
-
readonly initials?: string
|
|
15
|
-
readonly dispatch?: keyof Dispatching
|
|
16
|
-
readonly input?: Readonly<Record<string, unknown>>
|
|
17
|
-
readonly invokeOn?: 'press' | 'shown'
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export const Avatar: Element<'Avatar', AvatarProps> = element(
|
|
21
|
-
'Avatar',
|
|
22
|
-
(props: AvatarProps, className) => {
|
|
23
|
-
const surface = useSurface({ className: roleClass(undefined, className),
|
|
24
|
-
invokes: { ...(props.dispatch === undefined ? {} : { dispatch: props.dispatch }), ...(props.input === undefined ? {} : { input: props.input }), ...(props.invokeOn === undefined ? {} : { on: props.invokeOn }) }, })
|
|
25
|
-
return (
|
|
26
|
-
<span className={surface.className} {...surface.marks} {...surface.invokes} {...surface.a11y} role="img" aria-label={surface.text(props.labelKey)}>
|
|
27
|
-
{props.src === undefined ? null : <img src={props.src} alt="" />}
|
|
28
|
-
<span>{shown(props, surface).lettering}</span>
|
|
29
|
-
</span>
|
|
30
|
-
)
|
|
31
|
-
},
|
|
32
|
-
'e-avatar',
|
|
33
|
-
{"avatarRound":"thread-avatar-round"},
|
|
34
|
-
)
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import type { AvatarProps } from './avatar.tsx'
|
|
2
|
-
|
|
3
|
-
export function shown(props: AvatarProps, surface: { readonly text: (key: AvatarProps['labelKey']) => string }): Readonly<Record<string, string | null>> {
|
|
4
|
-
if (props.src !== undefined) return { lettering: null }
|
|
5
|
-
const said = props.initials
|
|
6
|
-
if (said !== undefined) return { lettering: said }
|
|
7
|
-
return {
|
|
8
|
-
lettering: surface
|
|
9
|
-
.text(props.labelKey)
|
|
10
|
-
.split(/\s+/)
|
|
11
|
-
.filter(Boolean)
|
|
12
|
-
.slice(0, 2)
|
|
13
|
-
.map((part) => part.charAt(0).toUpperCase())
|
|
14
|
-
.join(''),
|
|
15
|
-
}
|
|
16
|
-
}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
'use client'
|
|
2
|
-
|
|
3
|
-
import type { MessageKey } from '../content.tsx'
|
|
4
|
-
import { roleClass } from '../fonts.ts'
|
|
5
|
-
|
|
6
|
-
import type { Dispatching } from '../checked.ts'
|
|
7
|
-
import { type Element, element, useSurface } from '../wrappers.tsx'
|
|
8
|
-
import { shows } from './badge.works.ts'
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
export interface BadgeProps {
|
|
12
|
-
readonly labelKey: MessageKey
|
|
13
|
-
readonly count?: number
|
|
14
|
-
readonly max?: number
|
|
15
|
-
readonly dispatch?: keyof Dispatching
|
|
16
|
-
readonly input?: Readonly<Record<string, unknown>>
|
|
17
|
-
readonly invokeOn?: 'press' | 'shown'
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export const Badge: Element<'Badge', BadgeProps> = element(
|
|
21
|
-
'Badge',
|
|
22
|
-
(props: BadgeProps, className) => {
|
|
23
|
-
const surface = useSurface({ className: roleClass(undefined, className),
|
|
24
|
-
invokes: { ...(props.dispatch === undefined ? {} : { dispatch: props.dispatch }), ...(props.input === undefined ? {} : { input: props.input }), ...(props.invokeOn === undefined ? {} : { on: props.invokeOn }) }, })
|
|
25
|
-
return (
|
|
26
|
-
<span className={surface.className} {...surface.marks} {...surface.invokes} {...surface.a11y}>
|
|
27
|
-
{shows(props, surface)}
|
|
28
|
-
</span>
|
|
29
|
-
)
|
|
30
|
-
},
|
|
31
|
-
'e-badge',
|
|
32
|
-
{"chip":"thread-chip"},
|
|
33
|
-
)
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import type { ReactNode } from 'react'
|
|
2
|
-
|
|
3
|
-
import type { BadgeProps } from './badge.tsx'
|
|
4
|
-
|
|
5
|
-
export function shows(props: BadgeProps, surface: { readonly text: (key: BadgeProps['labelKey']) => string }): ReactNode {
|
|
6
|
-
const max = props.max ?? 99
|
|
7
|
-
if (props.count === undefined) return surface.text(props.labelKey)
|
|
8
|
-
return props.count > max ? `${max}+` : String(props.count)
|
|
9
|
-
}
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
'use client'
|
|
2
|
-
|
|
3
|
-
import type { MessageKey } from '../content.tsx'
|
|
4
|
-
import type { Row } from '../charts.tsx'
|
|
5
|
-
import { roleClass } from '../fonts.ts'
|
|
6
|
-
import { measured as marking } from '../charts.tsx'
|
|
7
|
-
|
|
8
|
-
import type { Dispatching } from '../checked.ts'
|
|
9
|
-
import { type Element, element, useSurface } from '../wrappers.tsx'
|
|
10
|
-
import { Each } from '../elements/each.tsx'
|
|
11
|
-
import { shown, sized, uses } from './bars.works.ts'
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
export interface BarsProps {
|
|
15
|
-
readonly rows: readonly Row[]
|
|
16
|
-
readonly by: string
|
|
17
|
-
readonly value: string
|
|
18
|
-
readonly format?: string
|
|
19
|
-
readonly titleKey?: MessageKey
|
|
20
|
-
readonly dispatch?: keyof Dispatching
|
|
21
|
-
readonly input?: Readonly<Record<string, unknown>>
|
|
22
|
-
readonly invokeOn?: 'press' | 'shown'
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export const Bars: Element<'Bars', BarsProps> = element(
|
|
26
|
-
'Bars',
|
|
27
|
-
(props: BarsProps, className) => {
|
|
28
|
-
const kept = uses(props)
|
|
29
|
-
const surface = useSurface({ className: roleClass(undefined, className),
|
|
30
|
-
invokes: { ...(props.dispatch === undefined ? {} : { dispatch: props.dispatch }), ...(props.input === undefined ? {} : { input: props.input }), ...(props.invokeOn === undefined ? {} : { on: props.invokeOn }) },
|
|
31
|
-
holds: [
|
|
32
|
-
...(kept.holds ?? []),
|
|
33
|
-
],
|
|
34
|
-
...(kept.animates === undefined ? {} : { animates: kept.animates }), })
|
|
35
|
-
return (
|
|
36
|
-
<div className={surface.className} {...surface.marks} {...surface.invokes} {...surface.a11y} {...(kept.on ?? {})} role="img" {...(props.titleKey === undefined ? {} : { 'aria-label': surface.text(props.titleKey) })}>
|
|
37
|
-
<Each rows={props.rows} by={props.by}>
|
|
38
|
-
{(each0, at) => (
|
|
39
|
-
<span style={marking(sized(props, kept, each0, at))}>
|
|
40
|
-
<span>{shown(props, each0, surface, kept).label}</span>
|
|
41
|
-
<span>{shown(props, each0, surface, kept).amount}</span>
|
|
42
|
-
</span>
|
|
43
|
-
)}
|
|
44
|
-
</Each>
|
|
45
|
-
</div>
|
|
46
|
-
)
|
|
47
|
-
},
|
|
48
|
-
'e-bars',
|
|
49
|
-
{"card":"thread-card"},
|
|
50
|
-
)
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { formatValue } from '../validators.ts'
|
|
2
|
-
import { seriesColour } from '../series.ts'
|
|
3
|
-
import { num, str, useRamp, type Row } from '../charts.tsx'
|
|
4
|
-
import type { BarsProps } from './bars.tsx'
|
|
5
|
-
|
|
6
|
-
export function uses(props: BarsProps): {
|
|
7
|
-
readonly holds?: readonly string[]
|
|
8
|
-
readonly animates?: boolean
|
|
9
|
-
readonly on?: Readonly<Record<string, unknown>>
|
|
10
|
-
readonly ramp: readonly string[]
|
|
11
|
-
} {
|
|
12
|
-
const ramp = useRamp(props.rows.length)
|
|
13
|
-
return { ...(props.rows.length === 0 ? { holds: ['empty'] as const } : {}), ramp }
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export function sized(props: BarsProps, kept: { readonly ramp: readonly string[] }, row: Row, at: number): Readonly<Record<string, string | number>> {
|
|
17
|
-
const most = Math.max(...props.rows.map((one: Row) => num(one, props.value)), 0) || 1
|
|
18
|
-
return {
|
|
19
|
-
series: seriesColour(kept.ramp, at),
|
|
20
|
-
fraction: `${((num(row, props.value) / most) * 100).toFixed(1)}%`,
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export function shown(props: BarsProps, row: Row, _surface: unknown, _kept?: unknown): Readonly<Record<string, string>> {
|
|
25
|
-
return {
|
|
26
|
-
label: str(row, props.by),
|
|
27
|
-
amount: String(formatValue(props.format ?? 'number', num(row, props.value))),
|
|
28
|
-
}
|
|
29
|
-
}
|
package/dist/ui/elements/box.tsx
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
'use client'
|
|
2
|
-
|
|
3
|
-
import type { ReactNode } from 'react'
|
|
4
|
-
import type { MessageKey } from '../content.tsx'
|
|
5
|
-
|
|
6
|
-
import type { Dispatching } from '../checked.ts'
|
|
7
|
-
import { type Element, element, useSurface } from '../wrappers.tsx'
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
export interface BoxProps {
|
|
11
|
-
readonly children: ReactNode
|
|
12
|
-
readonly labelKey?: MessageKey
|
|
13
|
-
readonly scrolling?: boolean
|
|
14
|
-
readonly dispatch?: keyof Dispatching
|
|
15
|
-
readonly input?: Readonly<Record<string, unknown>>
|
|
16
|
-
readonly invokeOn?: 'press' | 'shown'
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export const Box: Element<'Box', BoxProps> = element(
|
|
20
|
-
'Box',
|
|
21
|
-
(props: BoxProps, className) => {
|
|
22
|
-
const surface = useSurface({ className,
|
|
23
|
-
invokes: { ...(props.dispatch === undefined ? {} : { dispatch: props.dispatch }), ...(props.input === undefined ? {} : { input: props.input }), ...(props.invokeOn === undefined ? {} : { on: props.invokeOn }) },
|
|
24
|
-
holds: [
|
|
25
|
-
...(props.scrolling === true ? ['scrolling' as const] : []),
|
|
26
|
-
],
|
|
27
|
-
raises: ['scrolling' as const], })
|
|
28
|
-
return (
|
|
29
|
-
<div className={surface.className} {...surface.marks} {...surface.invokes} {...surface.a11y} {...(props.labelKey === undefined ? {} : { role: 'group' as const })} {...(props.labelKey === undefined ? {} : { 'aria-label': surface.text(props.labelKey) })}>
|
|
30
|
-
{props.children}
|
|
31
|
-
</div>
|
|
32
|
-
)
|
|
33
|
-
},
|
|
34
|
-
'e-box',
|
|
35
|
-
{"card":"thread-card","listRow":"thread-list-row","bubbleThem":"thread-bubble-them","bubbleMe":"thread-bubble-me"},
|
|
36
|
-
)
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
'use client'
|
|
2
|
-
|
|
3
|
-
import { roleClass } from '../fonts.ts'
|
|
4
|
-
import type { MapIsland } from '../islands/map.ts'
|
|
5
|
-
import { Link } from './link.tsx'
|
|
6
|
-
|
|
7
|
-
import type { Dispatching } from '../checked.ts'
|
|
8
|
-
import { type Element, element, useSurface } from '../wrappers.tsx'
|
|
9
|
-
import { Each } from '../elements/each.tsx'
|
|
10
|
-
import { crumb, steps } from './breadcrumb.works.ts'
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
export interface BreadcrumbProps {
|
|
14
|
-
readonly map: MapIsland
|
|
15
|
-
readonly current: string
|
|
16
|
-
readonly dispatch?: keyof Dispatching
|
|
17
|
-
readonly input?: Readonly<Record<string, unknown>>
|
|
18
|
-
readonly invokeOn?: 'press' | 'shown'
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export const Breadcrumb: Element<'Breadcrumb', BreadcrumbProps> = element(
|
|
22
|
-
'Breadcrumb',
|
|
23
|
-
(props: BreadcrumbProps, className) => {
|
|
24
|
-
const surface = useSurface({ className: roleClass(undefined, className),
|
|
25
|
-
invokes: { ...(props.dispatch === undefined ? {} : { dispatch: props.dispatch }), ...(props.input === undefined ? {} : { input: props.input }), ...(props.invokeOn === undefined ? {} : { on: props.invokeOn }) }, })
|
|
26
|
-
return (
|
|
27
|
-
<nav className={surface.className} {...surface.marks} {...surface.invokes} {...surface.a11y} aria-label={surface.text('nav.breadcrumb')}>
|
|
28
|
-
<Each rows={steps(props)} by={'id'}>
|
|
29
|
-
{(each0, at) => (
|
|
30
|
-
<Link.linkInline {...crumb(props, each0, at)}></Link.linkInline>
|
|
31
|
-
)}
|
|
32
|
-
</Each>
|
|
33
|
-
</nav>
|
|
34
|
-
)
|
|
35
|
-
},
|
|
36
|
-
'e-breadcrumb',
|
|
37
|
-
{"tabBar":"thread-tab-bar"},
|
|
38
|
-
)
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { trailTo } from '../navigation.tsx'
|
|
2
|
-
import type { Row } from '../charts.tsx'
|
|
3
|
-
import type { BreadcrumbProps } from './breadcrumb.tsx'
|
|
4
|
-
import type { LinkProps } from './link.tsx'
|
|
5
|
-
|
|
6
|
-
export function steps(props: BreadcrumbProps): readonly Row[] {
|
|
7
|
-
const known = new Map(props.map.screens.map((one) => [one.id, one]))
|
|
8
|
-
if (!known.has(props.current)) return []
|
|
9
|
-
const trail = trailTo(props.map, props.current)
|
|
10
|
-
return trail.flatMap((id, at) => {
|
|
11
|
-
const screen = known.get(id)
|
|
12
|
-
if (screen === undefined) return []
|
|
13
|
-
return [{ id, nameKey: screen.nameKey, here: at === trail.length - 1 }]
|
|
14
|
-
})
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export function crumb(_props: BreadcrumbProps, row: Row, _at: number): LinkProps & { readonly 'aria-current'?: 'page' } {
|
|
18
|
-
return {
|
|
19
|
-
navigateTo: String(row['id']),
|
|
20
|
-
labelKey: String(row['nameKey']),
|
|
21
|
-
is: 'label',
|
|
22
|
-
...(row['here'] === true ? ({ 'aria-current': 'page' } as const) : {}),
|
|
23
|
-
}
|
|
24
|
-
}
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
'use client'
|
|
2
|
-
|
|
3
|
-
import type { MessageKey } from '../content.tsx'
|
|
4
|
-
import { roleClass } from '../fonts.ts'
|
|
5
|
-
|
|
6
|
-
import type { Dispatching } from '../checked.ts'
|
|
7
|
-
import { type Element, element, useSurface } from '../wrappers.tsx'
|
|
8
|
-
import { shown, iconed, worded, uses, wires } from './button.works.tsx'
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
export interface ButtonProps {
|
|
12
|
-
readonly label: MessageKey
|
|
13
|
-
readonly with?: Readonly<Record<string, unknown>>
|
|
14
|
-
readonly icon?: string
|
|
15
|
-
readonly shows?: string
|
|
16
|
-
readonly type?: string
|
|
17
|
-
readonly disabled?: boolean
|
|
18
|
-
readonly loading?: boolean
|
|
19
|
-
readonly input?: Readonly<Record<string, unknown>>
|
|
20
|
-
readonly navigateTo?: string
|
|
21
|
-
readonly onPress?: () => void
|
|
22
|
-
readonly dispatch?: keyof Dispatching
|
|
23
|
-
readonly invokeOn?: 'press' | 'shown'
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export const Button: Element<'Button', ButtonProps> = element(
|
|
27
|
-
'Button',
|
|
28
|
-
(props: ButtonProps, className) => {
|
|
29
|
-
const kept = uses(props)
|
|
30
|
-
const surface = useSurface({ className: roleClass(undefined, className),
|
|
31
|
-
invokes: { ...(props.dispatch === undefined ? {} : { dispatch: props.dispatch }), ...(props.input === undefined ? {} : { input: props.input }), ...(props.invokeOn === undefined ? {} : { on: props.invokeOn }) },
|
|
32
|
-
holds: [
|
|
33
|
-
...(kept.holds ?? []),
|
|
34
|
-
],
|
|
35
|
-
...(kept.animates === undefined ? {} : { animates: kept.animates }), })
|
|
36
|
-
const wired = wires(props, kept, surface)
|
|
37
|
-
return (
|
|
38
|
-
<button className={surface.className} {...surface.marks} {...surface.invokes} {...surface.a11y} {...(kept.on ?? {})} {...(wired.on ?? {})}>
|
|
39
|
-
{!iconed(props, kept) ? null : <span className="e-button-symbol">{shown(props, surface, kept, wired).symbol}</span>}
|
|
40
|
-
{!worded(props, kept) ? null : <span>{shown(props, surface, kept, wired).wording}</span>}
|
|
41
|
-
</button>
|
|
42
|
-
)
|
|
43
|
-
},
|
|
44
|
-
'e-button',
|
|
45
|
-
{"buttonFill":"thread-button-fill","buttonNormal":"thread-button-normal","buttonGhost":"thread-button-ghost","buttonBorder":"thread-button-border","buttonDestructive":"thread-button-destructive","buttonDestructiveGhost":"thread-button-destructive-ghost","buttonCta":"thread-button-cta","buttonQuiet":"thread-button-quiet","buttonGlass":"thread-button-glass"},
|
|
46
|
-
)
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
import type { ReactNode } from 'react'
|
|
2
|
-
|
|
3
|
-
import { pressOf, usePress } from '../wrappers.tsx'
|
|
4
|
-
import type { Surface } from '../door.ts'
|
|
5
|
-
import { drawn } from './glyph.works.tsx'
|
|
6
|
-
import type { ButtonProps } from './button.tsx'
|
|
7
|
-
|
|
8
|
-
export function uses(props: ButtonProps): {
|
|
9
|
-
readonly holds?: readonly string[]
|
|
10
|
-
readonly animates?: boolean
|
|
11
|
-
readonly on?: Readonly<Record<string, unknown>>
|
|
12
|
-
readonly press: (() => void) | undefined
|
|
13
|
-
} {
|
|
14
|
-
return {
|
|
15
|
-
holds: [
|
|
16
|
-
...(props.disabled === true ? (['disabled'] as const) : []),
|
|
17
|
-
...(props.loading === true ? (['loading'] as const) : []),
|
|
18
|
-
],
|
|
19
|
-
press: usePress(pressOf(props), { element: 'Button', name: props.label }),
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export function wires(
|
|
24
|
-
props: ButtonProps,
|
|
25
|
-
kept: { readonly press: (() => void) | undefined },
|
|
26
|
-
surface: Surface,
|
|
27
|
-
): { readonly on: Readonly<Record<string, unknown>> } {
|
|
28
|
-
const inert = surface.marked('disabled') || surface.marked('loading')
|
|
29
|
-
return {
|
|
30
|
-
on: {
|
|
31
|
-
type: props.type ?? 'button',
|
|
32
|
-
disabled: inert,
|
|
33
|
-
...(props.shows === 'icon' ? { 'aria-label': surface.text(props.label, props.with) } : {}),
|
|
34
|
-
onClick: inert ? undefined : kept.press,
|
|
35
|
-
},
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export function iconed(props: ButtonProps, _kept?: unknown): boolean {
|
|
40
|
-
return props.icon !== undefined
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export function worded(props: ButtonProps, _kept?: unknown): boolean {
|
|
44
|
-
return props.shows !== 'icon'
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
export function shown(props: ButtonProps, surface: Surface, _kept: unknown, _wired?: unknown): Readonly<Record<string, ReactNode>> {
|
|
48
|
-
return {
|
|
49
|
-
symbol: props.icon === undefined ? null : drawn(props.icon, { 'aria-hidden': true }),
|
|
50
|
-
wording: props.shows === 'icon' ? null : surface.text(props.label, props.with),
|
|
51
|
-
}
|
|
52
|
-
}
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
'use client'
|
|
2
|
-
|
|
3
|
-
import type { ReactNode } from 'react'
|
|
4
|
-
|
|
5
|
-
import type { Dispatching } from '../checked.ts'
|
|
6
|
-
import { type Element, element, useSurface } from '../wrappers.tsx'
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
export interface ColumnProps {
|
|
10
|
-
readonly children: ReactNode
|
|
11
|
-
readonly dispatch?: keyof Dispatching
|
|
12
|
-
readonly input?: Readonly<Record<string, unknown>>
|
|
13
|
-
readonly invokeOn?: 'press' | 'shown'
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export const Column: Element<'Column', ColumnProps> = element(
|
|
17
|
-
'Column',
|
|
18
|
-
(props: ColumnProps, className) => {
|
|
19
|
-
const surface = useSurface({ className,
|
|
20
|
-
invokes: { ...(props.dispatch === undefined ? {} : { dispatch: props.dispatch }), ...(props.input === undefined ? {} : { input: props.input }), ...(props.invokeOn === undefined ? {} : { on: props.invokeOn }) }, })
|
|
21
|
-
return (
|
|
22
|
-
<div className={surface.className} {...surface.marks} {...surface.invokes} {...surface.a11y}>
|
|
23
|
-
{props.children}
|
|
24
|
-
</div>
|
|
25
|
-
)
|
|
26
|
-
},
|
|
27
|
-
'e-column',
|
|
28
|
-
{},
|
|
29
|
-
)
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
'use client'
|
|
2
|
-
|
|
3
|
-
import type { MessageKey } from '../content.tsx'
|
|
4
|
-
import { roleClass } from '../fonts.ts'
|
|
5
|
-
import type { ConsentDecision } from '../consent.ts'
|
|
6
|
-
import { Box } from './box.tsx'
|
|
7
|
-
import { Column } from './column.tsx'
|
|
8
|
-
import { Text } from './text.tsx'
|
|
9
|
-
import { Toggle } from './toggle.tsx'
|
|
10
|
-
import { Button } from './button.tsx'
|
|
11
|
-
|
|
12
|
-
import type { Dispatching } from '../checked.ts'
|
|
13
|
-
import { type Element, element, useSurface } from '../wrappers.tsx'
|
|
14
|
-
import { Each } from '../elements/each.tsx'
|
|
15
|
-
import { title, policy, hasPolicy, categories, label, describe, chooser, optional, fixed, required, withdraw, withdrawable, decline, accept, acceptAll, uses } from './consent.works.tsx'
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
export interface ConsentProps {
|
|
19
|
-
readonly decision?: ConsentDecision
|
|
20
|
-
readonly onDecide: (said: ConsentDecision) => void
|
|
21
|
-
readonly policyKey?: MessageKey
|
|
22
|
-
readonly preselected: readonly string[]
|
|
23
|
-
readonly dispatch?: keyof Dispatching
|
|
24
|
-
readonly input?: Readonly<Record<string, unknown>>
|
|
25
|
-
readonly invokeOn?: 'press' | 'shown'
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export const Consent: Element<'Consent', ConsentProps> = element(
|
|
29
|
-
'Consent',
|
|
30
|
-
(props: ConsentProps, className) => {
|
|
31
|
-
const kept = uses(props)
|
|
32
|
-
useSurface({ className: roleClass(undefined, className),
|
|
33
|
-
invokes: { ...(props.dispatch === undefined ? {} : { dispatch: props.dispatch }), ...(props.input === undefined ? {} : { input: props.input }), ...(props.invokeOn === undefined ? {} : { on: props.invokeOn }) },
|
|
34
|
-
holds: [
|
|
35
|
-
...(kept.holds ?? []),
|
|
36
|
-
],
|
|
37
|
-
...(kept.animates === undefined ? {} : { animates: kept.animates }), })
|
|
38
|
-
return (
|
|
39
|
-
<>
|
|
40
|
-
<Box.card>
|
|
41
|
-
<Column>
|
|
42
|
-
<Text {...title(props, kept)}></Text>
|
|
43
|
-
{!hasPolicy(props, kept) ? null : <Text {...policy(props, kept)}></Text>}
|
|
44
|
-
<Column>
|
|
45
|
-
<Each rows={categories(props, kept)} by={'id'}>
|
|
46
|
-
{(each0, at) => (
|
|
47
|
-
<Box>
|
|
48
|
-
<Column>
|
|
49
|
-
<Text {...label(props, kept, each0, at)}></Text>
|
|
50
|
-
<Text {...describe(props, kept, each0, at)}></Text>
|
|
51
|
-
</Column>
|
|
52
|
-
{!optional(props, kept, each0) ? null : <Toggle.input {...chooser(props, kept, each0, at)}></Toggle.input>}
|
|
53
|
-
{!required(props, kept, each0) ? null : <Text {...fixed(props, kept, each0, at)}></Text>}
|
|
54
|
-
</Box>
|
|
55
|
-
)}
|
|
56
|
-
</Each>
|
|
57
|
-
</Column>
|
|
58
|
-
<Box>
|
|
59
|
-
{!withdrawable(props, kept) ? null : <Button.buttonQuiet {...withdraw(props, kept)}></Button.buttonQuiet>}
|
|
60
|
-
<Button.buttonBorder {...decline(props, kept)}></Button.buttonBorder>
|
|
61
|
-
<Button.buttonBorder {...accept(props, kept)}></Button.buttonBorder>
|
|
62
|
-
<Button.buttonFill {...acceptAll(props, kept)}></Button.buttonFill>
|
|
63
|
-
</Box>
|
|
64
|
-
</Column>
|
|
65
|
-
</Box.card>
|
|
66
|
-
</>
|
|
67
|
-
)
|
|
68
|
-
},
|
|
69
|
-
'e-consent',
|
|
70
|
-
{},
|
|
71
|
-
)
|