@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.
Files changed (209) hide show
  1. package/CHANGELOG.md +375 -0
  2. package/dist/ui/attach.js +6 -7
  3. package/dist/ui/compositions.d.ts +0 -8
  4. package/dist/ui/compositions.js +3 -166
  5. package/dist/ui/generators/routes.js +1 -0
  6. package/package.json +2 -2
  7. package/dist/ui/animations/anm_appear.ts +0 -13
  8. package/dist/ui/animations/anm_blur_in.ts +0 -19
  9. package/dist/ui/animations/anm_blur_out.ts +0 -18
  10. package/dist/ui/animations/anm_dismiss.ts +0 -18
  11. package/dist/ui/animations/anm_drop.ts +0 -19
  12. package/dist/ui/animations/anm_fall.ts +0 -18
  13. package/dist/ui/animations/anm_flash.ts +0 -18
  14. package/dist/ui/animations/anm_glow.ts +0 -16
  15. package/dist/ui/animations/anm_lift.ts +0 -16
  16. package/dist/ui/animations/anm_nudge.ts +0 -16
  17. package/dist/ui/animations/anm_pop_in.ts +0 -23
  18. package/dist/ui/animations/anm_pop_out.ts +0 -22
  19. package/dist/ui/animations/anm_press.ts +0 -12
  20. package/dist/ui/animations/anm_pulse.ts +0 -13
  21. package/dist/ui/animations/anm_rise.ts +0 -19
  22. package/dist/ui/animations/anm_shake.ts +0 -13
  23. package/dist/ui/animations/anm_slide_in_left.ts +0 -19
  24. package/dist/ui/animations/anm_slide_in_right.ts +0 -19
  25. package/dist/ui/animations/anm_slide_out_left.ts +0 -18
  26. package/dist/ui/animations/anm_slide_out_right.ts +0 -18
  27. package/dist/ui/animations/anm_spin.ts +0 -12
  28. package/dist/ui/animations/anm_swell.ts +0 -16
  29. package/dist/ui/animations/anm_wobble.ts +0 -24
  30. package/dist/ui/animations/anm_zoom_in.ts +0 -19
  31. package/dist/ui/animations/anm_zoom_out.ts +0 -18
  32. package/dist/ui/animations.ts +0 -308
  33. package/dist/ui/attach.ts +0 -553
  34. package/dist/ui/charts.tsx +0 -69
  35. package/dist/ui/checked.ts +0 -32
  36. package/dist/ui/collector.ts +0 -140
  37. package/dist/ui/compositions.ts +0 -613
  38. package/dist/ui/consent.ts +0 -55
  39. package/dist/ui/content.tsx +0 -27
  40. package/dist/ui/contrast.ts +0 -27
  41. package/dist/ui/controls.tsx +0 -25
  42. package/dist/ui/disclosure.tsx +0 -20
  43. package/dist/ui/dismiss-layer.ts +0 -87
  44. package/dist/ui/door.ts +0 -140
  45. package/dist/ui/drag.ts +0 -316
  46. package/dist/ui/elements/accordion.tsx +0 -47
  47. package/dist/ui/elements/accordion.works.ts +0 -66
  48. package/dist/ui/elements/aspect-ratio.tsx +0 -31
  49. package/dist/ui/elements/aspect-ratio.works.ts +0 -5
  50. package/dist/ui/elements/avatar.tsx +0 -34
  51. package/dist/ui/elements/avatar.works.ts +0 -16
  52. package/dist/ui/elements/badge.tsx +0 -33
  53. package/dist/ui/elements/badge.works.ts +0 -9
  54. package/dist/ui/elements/bars.tsx +0 -50
  55. package/dist/ui/elements/bars.works.ts +0 -29
  56. package/dist/ui/elements/box.tsx +0 -36
  57. package/dist/ui/elements/breadcrumb.tsx +0 -38
  58. package/dist/ui/elements/breadcrumb.works.ts +0 -24
  59. package/dist/ui/elements/button.tsx +0 -46
  60. package/dist/ui/elements/button.works.tsx +0 -52
  61. package/dist/ui/elements/column.tsx +0 -29
  62. package/dist/ui/elements/consent.tsx +0 -71
  63. package/dist/ui/elements/consent.works.tsx +0 -132
  64. package/dist/ui/elements/donut.tsx +0 -45
  65. package/dist/ui/elements/donut.works.ts +0 -42
  66. package/dist/ui/elements/each.tsx +0 -34
  67. package/dist/ui/elements/each.works.tsx +0 -82
  68. package/dist/ui/elements/empty.tsx +0 -33
  69. package/dist/ui/elements/field.tsx +0 -45
  70. package/dist/ui/elements/field.works.ts +0 -65
  71. package/dist/ui/elements/funnel.tsx +0 -50
  72. package/dist/ui/elements/funnel.works.ts +0 -37
  73. package/dist/ui/elements/gauge.tsx +0 -40
  74. package/dist/ui/elements/gauge.works.ts +0 -42
  75. package/dist/ui/elements/glyph.tsx +0 -30
  76. package/dist/ui/elements/glyph.works.tsx +0 -42
  77. package/dist/ui/elements/grid.tsx +0 -29
  78. package/dist/ui/elements/heatmap.tsx +0 -48
  79. package/dist/ui/elements/heatmap.works.ts +0 -24
  80. package/dist/ui/elements/hit-box.tsx +0 -47
  81. package/dist/ui/elements/hit-box.works.tsx +0 -576
  82. package/dist/ui/elements/image.tsx +0 -29
  83. package/dist/ui/elements/line-chart.tsx +0 -45
  84. package/dist/ui/elements/line-chart.works.ts +0 -41
  85. package/dist/ui/elements/link.tsx +0 -38
  86. package/dist/ui/elements/link.works.ts +0 -25
  87. package/dist/ui/elements/media.tsx +0 -57
  88. package/dist/ui/elements/menu.tsx +0 -51
  89. package/dist/ui/elements/menu.works.tsx +0 -154
  90. package/dist/ui/elements/money.tsx +0 -36
  91. package/dist/ui/elements/money.works.ts +0 -9
  92. package/dist/ui/elements/pagination.tsx +0 -39
  93. package/dist/ui/elements/pagination.works.ts +0 -20
  94. package/dist/ui/elements/progress.tsx +0 -34
  95. package/dist/ui/elements/progress.works.ts +0 -8
  96. package/dist/ui/elements/radio-group.tsx +0 -50
  97. package/dist/ui/elements/radio-group.works.ts +0 -33
  98. package/dist/ui/elements/row.tsx +0 -29
  99. package/dist/ui/elements/scatter.tsx +0 -42
  100. package/dist/ui/elements/scatter.works.ts +0 -38
  101. package/dist/ui/elements/select.tsx +0 -43
  102. package/dist/ui/elements/select.works.ts +0 -5
  103. package/dist/ui/elements/separator.tsx +0 -31
  104. package/dist/ui/elements/skeleton.tsx +0 -31
  105. package/dist/ui/elements/slider.tsx +0 -34
  106. package/dist/ui/elements/slider.works.ts +0 -5
  107. package/dist/ui/elements/sparkline.tsx +0 -37
  108. package/dist/ui/elements/sparkline.works.ts +0 -32
  109. package/dist/ui/elements/spinner.tsx +0 -33
  110. package/dist/ui/elements/stack.tsx +0 -29
  111. package/dist/ui/elements/stat.tsx +0 -36
  112. package/dist/ui/elements/stat.works.ts +0 -14
  113. package/dist/ui/elements/surface.tsx +0 -36
  114. package/dist/ui/elements/surface.works.ts +0 -9
  115. package/dist/ui/elements/table.tsx +0 -62
  116. package/dist/ui/elements/table.works.ts +0 -30
  117. package/dist/ui/elements/tabs.tsx +0 -47
  118. package/dist/ui/elements/tabs.works.ts +0 -84
  119. package/dist/ui/elements/text.tsx +0 -33
  120. package/dist/ui/elements/textarea.tsx +0 -38
  121. package/dist/ui/elements/textarea.works.ts +0 -5
  122. package/dist/ui/elements/time.tsx +0 -40
  123. package/dist/ui/elements/time.works.ts +0 -29
  124. package/dist/ui/elements/toggle.tsx +0 -34
  125. package/dist/ui/elements/toggle.works.ts +0 -5
  126. package/dist/ui/elements/tooltip.tsx +0 -40
  127. package/dist/ui/elements/tooltip.works.ts +0 -77
  128. package/dist/ui/elements/value.tsx +0 -38
  129. package/dist/ui/elements/value.works.ts +0 -9
  130. package/dist/ui/elements.ts +0 -127
  131. package/dist/ui/focus-scope.ts +0 -121
  132. package/dist/ui/fonts.ts +0 -355
  133. package/dist/ui/generators/dev.d.ts +0 -1
  134. package/dist/ui/generators/dev.js +0 -62
  135. package/dist/ui/generators/dev.ts +0 -75
  136. package/dist/ui/generators/elements.ts +0 -796
  137. package/dist/ui/generators/i18n.ts +0 -283
  138. package/dist/ui/generators/icons.ts +0 -207
  139. package/dist/ui/generators/react.ts +0 -267
  140. package/dist/ui/generators/routes.ts +0 -847
  141. package/dist/ui/generators/show.ts +0 -261
  142. package/dist/ui/generators/styles.ts +0 -677
  143. package/dist/ui/generators/variants.ts +0 -196
  144. package/dist/ui/i18n/catalogs/en.ts +0 -191
  145. package/dist/ui/i18n/format.ts +0 -221
  146. package/dist/ui/i18n/locales.ts +0 -33
  147. package/dist/ui/i18n/parse.ts +0 -315
  148. package/dist/ui/i18n/translator.ts +0 -31
  149. package/dist/ui/i18n/types.ts +0 -96
  150. package/dist/ui/icons.ts +0 -331
  151. package/dist/ui/islands/map.ts +0 -58
  152. package/dist/ui/localizations.ts +0 -75
  153. package/dist/ui/material.ts +0 -236
  154. package/dist/ui/materials/mat_bordered.ts +0 -13
  155. package/dist/ui/materials/mat_ceramic.ts +0 -13
  156. package/dist/ui/materials/mat_clay.ts +0 -13
  157. package/dist/ui/materials/mat_elevated.ts +0 -24
  158. package/dist/ui/materials/mat_flat.ts +0 -34
  159. package/dist/ui/materials/mat_glass.ts +0 -20
  160. package/dist/ui/materials/mat_lit.ts +0 -13
  161. package/dist/ui/materials/mat_moulded.ts +0 -11
  162. package/dist/ui/materials.ts +0 -197
  163. package/dist/ui/modes.ts +0 -44
  164. package/dist/ui/navigation.tsx +0 -29
  165. package/dist/ui/positioning.ts +0 -90
  166. package/dist/ui/presented.tsx +0 -119
  167. package/dist/ui/provider.tsx +0 -184
  168. package/dist/ui/render-loop.ts +0 -133
  169. package/dist/ui/roving-focus.ts +0 -161
  170. package/dist/ui/screens.ts +0 -141
  171. package/dist/ui/scroll-lock.ts +0 -28
  172. package/dist/ui/series.ts +0 -97
  173. package/dist/ui/signals.ts +0 -386
  174. package/dist/ui/styleguide.ts +0 -231
  175. package/dist/ui/styleguides.ts +0 -374
  176. package/dist/ui/themes.ts +0 -22
  177. package/dist/ui/token.ts +0 -78
  178. package/dist/ui/tokens/shadow.ts +0 -25
  179. package/dist/ui/tokens.ts +0 -234
  180. package/dist/ui/validators.ts +0 -232
  181. package/dist/ui/variant.ts +0 -349
  182. package/dist/ui/variants/var_avatar-round.ts +0 -14
  183. package/dist/ui/variants/var_bubble-me.ts +0 -14
  184. package/dist/ui/variants/var_bubble-them.ts +0 -13
  185. package/dist/ui/variants/var_button-border.ts +0 -76
  186. package/dist/ui/variants/var_button-cta.ts +0 -76
  187. package/dist/ui/variants/var_button-destructive-ghost.ts +0 -72
  188. package/dist/ui/variants/var_button-destructive.ts +0 -76
  189. package/dist/ui/variants/var_button-fill.ts +0 -76
  190. package/dist/ui/variants/var_button-ghost.ts +0 -72
  191. package/dist/ui/variants/var_button-glass.ts +0 -55
  192. package/dist/ui/variants/var_button-normal.ts +0 -76
  193. package/dist/ui/variants/var_button-quiet.ts +0 -74
  194. package/dist/ui/variants/var_card.ts +0 -17
  195. package/dist/ui/variants/var_chip.ts +0 -13
  196. package/dist/ui/variants/var_choice.ts +0 -15
  197. package/dist/ui/variants/var_framed.ts +0 -10
  198. package/dist/ui/variants/var_glyph-plain.ts +0 -11
  199. package/dist/ui/variants/var_input.ts +0 -43
  200. package/dist/ui/variants/var_link-inline.ts +0 -29
  201. package/dist/ui/variants/var_list-row.ts +0 -34
  202. package/dist/ui/variants/var_rule.ts +0 -10
  203. package/dist/ui/variants/var_skeleton-block.ts +0 -12
  204. package/dist/ui/variants/var_spinner-turning.ts +0 -12
  205. package/dist/ui/variants/var_stat-tile.ts +0 -13
  206. package/dist/ui/variants/var_tab-bar.ts +0 -15
  207. package/dist/ui/variants/var_tap-target.ts +0 -25
  208. package/dist/ui/variants.ts +0 -64
  209. package/dist/ui/wrappers.tsx +0 -429
@@ -1,43 +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
-
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 { does } from './select.works.ts'
11
-
12
-
13
- export interface SelectProps {
14
- readonly labelKey: MessageKey
15
- readonly options: readonly Row[]
16
- readonly value?: string
17
- readonly onValue?: (said: string) => void
18
- readonly dispatch?: keyof Dispatching
19
- readonly input?: Readonly<Record<string, unknown>>
20
- readonly invokeOn?: 'press' | 'shown'
21
- }
22
-
23
- export const Select: Element<'Select', SelectProps> = element(
24
- 'Select',
25
- (props: SelectProps, className) => {
26
- const surface = useSurface({ className: roleClass(undefined, className),
27
- invokes: { ...(props.dispatch === undefined ? {} : { dispatch: props.dispatch }), ...(props.input === undefined ? {} : { input: props.input }), ...(props.invokeOn === undefined ? {} : { on: props.invokeOn }) }, })
28
- return (
29
- <label className={surface.className} {...surface.marks} {...surface.invokes} {...surface.a11y}>
30
- <span>{surface.text(props.labelKey)}</span>
31
- {props.value === undefined ? null : <select disabled={surface.marked('disabled')} value={props.value ?? ''} onChange={(event) => does(props).chose(event.target.value)}>
32
- <Each rows={props.options} by={props.value}>
33
- {(each0, at) => (
34
- <option value={String(each0.value)}>{surface.text(String(each0.labelKey))}</option>
35
- )}
36
- </Each>
37
- </select>}
38
- </label>
39
- )
40
- },
41
- 'e-select',
42
- {"input":"thread-input"},
43
- )
@@ -1,5 +0,0 @@
1
- import type { SelectProps } from './select.tsx'
2
-
3
- export function does(props: SelectProps): { readonly chose: (value: string) => void } {
4
- return { chose: (value: string) => props.onValue?.(value) }
5
- }
@@ -1,31 +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
-
9
-
10
- export interface SeparatorProps {
11
- readonly labelKey?: MessageKey
12
- readonly orientation?: string
13
- readonly dispatch?: keyof Dispatching
14
- readonly input?: Readonly<Record<string, unknown>>
15
- readonly invokeOn?: 'press' | 'shown'
16
- }
17
-
18
- export const Separator: Element<'Separator', SeparatorProps> = element(
19
- 'Separator',
20
- (props: SeparatorProps, className) => {
21
- const surface = useSurface({ className: roleClass(undefined, className),
22
- invokes: { ...(props.dispatch === undefined ? {} : { dispatch: props.dispatch }), ...(props.input === undefined ? {} : { input: props.input }), ...(props.invokeOn === undefined ? {} : { on: props.invokeOn }) }, })
23
- return (
24
- <div className={surface.className} {...surface.marks} {...surface.invokes} {...surface.a11y} role="separator" aria-orientation={props.orientation === 'vertical' ? 'vertical' : 'horizontal'}>
25
- {props.labelKey === undefined ? null : <span>{surface.text(props.labelKey)}</span>}
26
- </div>
27
- )
28
- },
29
- 'e-separator',
30
- {"rule":"thread-rule"},
31
- )
@@ -1,31 +0,0 @@
1
- 'use client'
2
-
3
- import { roleClass } from '../fonts.ts'
4
-
5
- import type { Dispatching } from '../checked.ts'
6
- import { type Element, element, useSurface } from '../wrappers.tsx'
7
-
8
-
9
- export interface SkeletonProps {
10
- readonly lines?: number
11
- readonly dispatch?: keyof Dispatching
12
- readonly input?: Readonly<Record<string, unknown>>
13
- readonly invokeOn?: 'press' | 'shown'
14
- }
15
-
16
- export const Skeleton: Element<'Skeleton', SkeletonProps> = element(
17
- 'Skeleton',
18
- (props: SkeletonProps, className) => {
19
- const surface = useSurface({ className: roleClass(undefined, className),
20
- invokes: { ...(props.dispatch === undefined ? {} : { dispatch: props.dispatch }), ...(props.input === undefined ? {} : { input: props.input }), ...(props.invokeOn === undefined ? {} : { on: props.invokeOn }) }, })
21
- return (
22
- <span className={surface.className} {...surface.marks} {...surface.invokes} {...surface.a11y} aria-hidden="true">
23
- {Array.from({ length: Math.max(1, props.lines ?? 1) }, (_, at) => (
24
- <span></span>
25
- ))}
26
- </span>
27
- )
28
- },
29
- 'e-skeleton',
30
- {"skeletonBlock":"thread-skeleton-block"},
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 { does } from './slider.works.ts'
9
-
10
-
11
- export interface SliderProps {
12
- readonly labelKey: MessageKey
13
- readonly value?: number
14
- readonly min?: number
15
- readonly max?: number
16
- readonly step?: number
17
- readonly onValue?: (said: number) => void
18
- readonly dispatch?: keyof Dispatching
19
- readonly input?: Readonly<Record<string, unknown>>
20
- readonly invokeOn?: 'press' | 'shown'
21
- }
22
-
23
- export const Slider: Element<'Slider', SliderProps> = element(
24
- 'Slider',
25
- (props: SliderProps, className) => {
26
- const surface = useSurface({ className: roleClass(undefined, className),
27
- invokes: { ...(props.dispatch === undefined ? {} : { dispatch: props.dispatch }), ...(props.input === undefined ? {} : { input: props.input }), ...(props.invokeOn === undefined ? {} : { on: props.invokeOn }) }, })
28
- return (
29
- <input className={surface.className} {...surface.marks} {...surface.invokes} {...surface.a11y} type="range" disabled={surface.marked('disabled')} value={props.value ?? 0} onChange={(event) => does(props).moved(Number(event.target.value))} min={props.min} max={props.max} step={props.step ?? 1} aria-label={surface.text(props.labelKey)} />
30
- )
31
- },
32
- 'e-slider',
33
- {"input":"thread-input"},
34
- )
@@ -1,5 +0,0 @@
1
- import type { SliderProps } from './slider.tsx'
2
-
3
- export function does(props: SliderProps): { readonly moved: (to: number) => void } {
4
- return { moved: (to: number) => props.onValue?.(to) }
5
- }
@@ -1,37 +0,0 @@
1
- 'use client'
2
-
3
- import type { Row } from '../charts.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 { drawing, uses } from './sparkline.works.ts'
9
-
10
-
11
- export interface SparklineProps {
12
- readonly rows: readonly Row[]
13
- readonly value: string
14
- readonly dispatch?: keyof Dispatching
15
- readonly input?: Readonly<Record<string, unknown>>
16
- readonly invokeOn?: 'press' | 'shown'
17
- }
18
-
19
- export const Sparkline: Element<'Sparkline', SparklineProps> = element(
20
- 'Sparkline',
21
- (props: SparklineProps, className) => {
22
- const kept = uses(props)
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
- holds: [
26
- ...(kept.holds ?? []),
27
- ],
28
- ...(kept.animates === undefined ? {} : { animates: kept.animates }), })
29
- return (
30
- <svg className={surface.className} {...surface.marks} {...surface.invokes} {...surface.a11y} {...(kept.on ?? {})} aria-hidden="true">
31
- <polyline {...drawing(props, kept)}></polyline>
32
- </svg>
33
- )
34
- },
35
- 'e-sparkline',
36
- {"card":"thread-card"},
37
- )
@@ -1,32 +0,0 @@
1
- import { num, polyline, useRamp } from '../charts.tsx'
2
- import type { Row } from '../charts.tsx'
3
- import type { SparklineProps } from './sparkline.tsx'
4
-
5
- const WIDE = 100
6
- const TALL = 24
7
-
8
- export function uses(props: SparklineProps): {
9
- readonly holds?: readonly string[]
10
- readonly animates?: boolean
11
- readonly on?: Readonly<Record<string, unknown>>
12
- readonly ramp: readonly string[]
13
- } {
14
- const ramp = useRamp(1)
15
- return {
16
- ...(props.rows.length === 0 ? { holds: ['empty'] as const } : {}),
17
- on: { viewBox: `0 0 ${String(WIDE)} ${String(TALL)}` },
18
- ramp,
19
- }
20
- }
21
-
22
- export function drawing(
23
- props: SparklineProps,
24
- kept: { readonly ramp: readonly string[] },
25
- ): Readonly<Record<string, string | number>> {
26
- return {
27
- points: polyline(props.rows.map((one: Row) => num(one, props.value)), WIDE, TALL),
28
- fill: 'none',
29
- stroke: kept.ramp[0] ?? 'currentColor',
30
- strokeWidth: 2,
31
- }
32
- }
@@ -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
-
9
-
10
- export interface SpinnerProps {
11
- readonly labelKey: MessageKey
12
- readonly dispatch?: keyof Dispatching
13
- readonly input?: Readonly<Record<string, unknown>>
14
- readonly invokeOn?: 'press' | 'shown'
15
- }
16
-
17
- export const Spinner: Element<'Spinner', SpinnerProps> = element(
18
- 'Spinner',
19
- (props: SpinnerProps, className) => {
20
- const surface = useSurface({ className: roleClass(undefined, className),
21
- invokes: { ...(props.dispatch === undefined ? {} : { dispatch: props.dispatch }), ...(props.input === undefined ? {} : { input: props.input }), ...(props.invokeOn === undefined ? {} : { on: props.invokeOn }) },
22
- holds: [
23
- 'spinner' as const,
24
- ], })
25
- return (
26
- <span className={surface.className} {...surface.marks} {...surface.invokes} {...surface.a11y} aria-label={surface.text(props.labelKey)}>
27
- {null}
28
- </span>
29
- )
30
- },
31
- 'e-spinner',
32
- {"spinnerTurning":"thread-spinner-turning"},
33
- )
@@ -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 StackProps {
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 Stack: Element<'Stack', StackProps> = element(
17
- 'Stack',
18
- (props: StackProps, 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-stack',
28
- {},
29
- )
@@ -1,36 +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 './stat.works.ts'
9
-
10
-
11
- export interface StatProps {
12
- readonly labelKey: MessageKey
13
- readonly value?: unknown
14
- readonly compare?: number
15
- readonly format?: string
16
- readonly dispatch?: keyof Dispatching
17
- readonly input?: Readonly<Record<string, unknown>>
18
- readonly invokeOn?: 'press' | 'shown'
19
- }
20
-
21
- export const Stat: Element<'Stat', StatProps> = element(
22
- 'Stat',
23
- (props: StatProps, 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
- <figure className={surface.className} {...surface.marks} {...surface.invokes} {...surface.a11y}>
28
- <span>{shown(props, surface).figure}</span>
29
- <figcaption>{surface.text(props.labelKey)}</figcaption>
30
- <span>{shown(props, surface).delta}</span>
31
- </figure>
32
- )
33
- },
34
- 'e-stat',
35
- {"statTile":"thread-stat-tile"},
36
- )
@@ -1,14 +0,0 @@
1
- import type { ReactNode } from 'react'
2
-
3
- import { formatValue } from '../validators.ts'
4
- import type { StatProps } from './stat.tsx'
5
-
6
- export function shown(props: StatProps, _surface: unknown): Readonly<Record<string, ReactNode>> {
7
- const current = typeof props.value === 'number' ? props.value : Number(props.value ?? 0)
8
- const against = props.compare
9
- const moved = against === undefined || against === 0 ? null : (current - against) / Math.abs(against)
10
- return {
11
- figure: formatValue(props.format ?? 'number', props.value),
12
- delta: moved === null ? null : formatValue('percent', Math.round(moved * 1000) / 10),
13
- }
14
- }
@@ -1,36 +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
- import { uses } from './surface.works.ts'
8
-
9
-
10
- export interface SurfaceProps {
11
- readonly children: ReactNode
12
- readonly dispatch?: keyof Dispatching
13
- readonly input?: Readonly<Record<string, unknown>>
14
- readonly invokeOn?: 'press' | 'shown'
15
- }
16
-
17
- export const Surface: Element<'Surface', SurfaceProps> = element(
18
- 'Surface',
19
- (props: SurfaceProps, className) => {
20
- const kept = uses(props)
21
- const surface = useSurface({ className,
22
- invokes: { ...(props.dispatch === undefined ? {} : { dispatch: props.dispatch }), ...(props.input === undefined ? {} : { input: props.input }), ...(props.invokeOn === undefined ? {} : { on: props.invokeOn }) },
23
- holds: [
24
- ...(kept.holds ?? []),
25
- ],
26
- animates: true,
27
- ...(kept.animates === undefined ? {} : { animates: kept.animates }), })
28
- return (
29
- <div className={surface.className} {...surface.marks} {...surface.invokes} {...surface.a11y} {...(kept.on ?? {})}>
30
- {props.children}
31
- </div>
32
- )
33
- },
34
- 'e-surface',
35
- {"card":"thread-card"},
36
- )
@@ -1,9 +0,0 @@
1
- import { useVisibility } from '../wrappers.tsx'
2
-
3
- export function uses(_props: unknown): {
4
- readonly holds?: readonly string[]
5
- readonly animates?: boolean
6
- readonly on: { readonly ref: (node: HTMLElement | null) => void }
7
- } {
8
- return { on: { ref: useVisibility(true) } }
9
- }
@@ -1,62 +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
-
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 { shown, heading, uses } from './table.works.ts'
11
-
12
-
13
- export interface TableProps {
14
- readonly rows: readonly Row[]
15
- readonly columns: readonly Row[]
16
- readonly by: string
17
- readonly titleKey?: MessageKey
18
- readonly dispatch?: keyof Dispatching
19
- readonly input?: Readonly<Record<string, unknown>>
20
- readonly invokeOn?: 'press' | 'shown'
21
- }
22
-
23
- export const Table: Element<'Table', TableProps> = element(
24
- 'Table',
25
- (props: TableProps, className) => {
26
- const kept = uses(props)
27
- const surface = useSurface({ className: roleClass(undefined, className),
28
- invokes: { ...(props.dispatch === undefined ? {} : { dispatch: props.dispatch }), ...(props.input === undefined ? {} : { input: props.input }), ...(props.invokeOn === undefined ? {} : { on: props.invokeOn }) },
29
- holds: [
30
- ...(kept.holds ?? []),
31
- ],
32
- ...(kept.animates === undefined ? {} : { animates: kept.animates }), })
33
- return (
34
- <table className={surface.className} {...surface.marks} {...surface.invokes} {...surface.a11y} {...(kept.on ?? {})} {...(props.titleKey === undefined ? {} : { 'aria-label': surface.text(props.titleKey) })}>
35
- <thead>
36
- <tr>
37
- <Each rows={props.columns} by={'field'}>
38
- {(each0, at) => (
39
- <th {...heading(props, kept, each0, at)}>{shown(props, each0, surface, kept).heading}</th>
40
- )}
41
- </Each>
42
- </tr>
43
- </thead>
44
- <tbody>
45
- <Each rows={props.rows} by={props.by}>
46
- {(each0, at) => (
47
- <tr>
48
- <Each rows={props.columns} by={'field'}>
49
- {(each1, at) => (
50
- <td>{shown(props, each0, each1, surface, kept).cell}</td>
51
- )}
52
- </Each>
53
- </tr>
54
- )}
55
- </Each>
56
- </tbody>
57
- </table>
58
- )
59
- },
60
- 'e-table',
61
- {"card":"thread-card"},
62
- )
@@ -1,30 +0,0 @@
1
- import { formatValue } from '../validators.ts'
2
- import type { ReactNode } from 'react'
3
-
4
- import type { Row } from '../charts.tsx'
5
- import type { Surface } from '../door.ts'
6
- import type { TableProps } from './table.tsx'
7
-
8
- export function uses(props: TableProps): {
9
- readonly holds?: readonly string[]
10
- readonly animates?: boolean
11
- readonly on?: Readonly<Record<string, unknown>>
12
- } {
13
- return props.rows.length === 0 ? { holds: ['empty'] } : {}
14
- }
15
-
16
- export function shown(
17
- _props: TableProps,
18
- ...rest: readonly [Row, Surface, unknown] | readonly [Row, Row, Surface, unknown]
19
- ): Readonly<Record<string, ReactNode>> {
20
- if (rest.length === 3) {
21
- const [column, surface] = rest
22
- return { heading: surface.text(String(column['labelKey'])) }
23
- }
24
- const [row, column] = rest
25
- return { cell: formatValue(String(column['format'] ?? 'text'), row[String(column['field'])]) }
26
- }
27
-
28
- export function heading(_props: TableProps, _kept: unknown, _column: Row, _at: number): Readonly<Record<string, string>> {
29
- return { scope: 'col' }
30
- }
@@ -1,47 +0,0 @@
1
- 'use client'
2
-
3
- import { roleClass } from '../fonts.ts'
4
- import type { TabItem } from '../disclosure.tsx'
5
-
6
- import type { Dispatching } from '../checked.ts'
7
- import { type Element, element, useSurface } from '../wrappers.tsx'
8
- import { Each } from '../elements/each.tsx'
9
- import { shown, strip, tab, panel, opened, uses } from './tabs.works.ts'
10
-
11
-
12
- export interface TabsProps {
13
- readonly items: readonly TabItem[]
14
- readonly initial?: string
15
- readonly onChange?: (said: string) => void
16
- readonly orientation?: string
17
- readonly dispatch?: keyof Dispatching
18
- readonly input?: Readonly<Record<string, unknown>>
19
- readonly invokeOn?: 'press' | 'shown'
20
- }
21
-
22
- export const Tabs: Element<'Tabs', TabsProps> = element(
23
- 'Tabs',
24
- (props: TabsProps, className) => {
25
- const kept = uses(props)
26
- const surface = useSurface({ className: roleClass(undefined, className),
27
- invokes: { ...(props.dispatch === undefined ? {} : { dispatch: props.dispatch }), ...(props.input === undefined ? {} : { input: props.input }), ...(props.invokeOn === undefined ? {} : { on: props.invokeOn }) },
28
- holds: [
29
- ...(kept.holds ?? []),
30
- ],
31
- ...(kept.animates === undefined ? {} : { animates: kept.animates }), })
32
- return (
33
- <div {...surface.marks} {...surface.invokes} {...surface.a11y} {...(kept.on ?? {})}>
34
- <div className={`e-tabs-strip ${surface.className ?? ''}`} {...strip(props, kept)}>
35
- <Each rows={props.items} by={'id'}>
36
- {(each0, at) => (
37
- <button className="e-tabs-tab" {...tab(props, kept, each0, at)}>{shown(props, each0, surface, kept).label}</button>
38
- )}
39
- </Each>
40
- </div>
41
- {!opened(props, kept) ? null : <div {...panel(props, kept)}>{shown(props, surface, kept).inside}</div>}
42
- </div>
43
- )
44
- },
45
- 'e-tabs',
46
- {"tabBar":"thread-tab-bar"},
47
- )
@@ -1,84 +0,0 @@
1
- import { useId, useRef, useState } from 'react'
2
-
3
- import { ITEM_ATTR, useRovingFocus } from '../roving-focus.ts'
4
- import type { ReactNode, RefObject } from 'react'
5
-
6
- import type { Row } from '../charts.tsx'
7
- import type { Surface } from '../door.ts'
8
- import type { TabsProps } from './tabs.tsx'
9
-
10
- type Kept = {
11
- readonly list: RefObject<HTMLDivElement | null>
12
- readonly base: string
13
- readonly open: string | undefined
14
- readonly choose: (id: string) => void
15
- }
16
-
17
- export function uses(props: TabsProps): {
18
- readonly holds?: readonly string[]
19
- readonly animates?: boolean
20
- readonly on?: Readonly<Record<string, unknown>>
21
- readonly list: RefObject<HTMLDivElement | null>
22
- readonly base: string
23
- readonly open: string | undefined
24
- readonly choose: (id: string) => void
25
- } {
26
- const list = useRef<HTMLDivElement>(null)
27
- const base = useId()
28
- const first = props.items.find((one) => one.disabled !== true)?.id
29
- const [active, setActive] = useState<string | undefined>(props.initial ?? first)
30
- useRovingFocus(list, { orientation: props.orientation === 'vertical' ? 'vertical' : 'horizontal' })
31
-
32
- const open = props.items.find((one) => one.id === active) ?? props.items.find((one) => one.disabled !== true)
33
- return {
34
- list,
35
- base,
36
- open: open?.id,
37
- choose: (id: string): void => {
38
- setActive(id)
39
- props.onChange?.(id)
40
- },
41
- }
42
- }
43
-
44
- export function strip(props: TabsProps, kept: Kept): Readonly<Record<string, unknown>> {
45
- return { ref: kept.list, role: 'tablist', 'aria-orientation': props.orientation === 'vertical' ? 'vertical' : 'horizontal' }
46
- }
47
-
48
- export function tab(_props: TabsProps, kept: Kept, row: Row, _at: number): Readonly<Record<string, unknown>> {
49
- const id = String(row['id'])
50
- return {
51
- ...{ [ITEM_ATTR]: '' },
52
- type: 'button',
53
- role: 'tab',
54
- id: `${kept.base}-tab-${id}`,
55
- 'aria-controls': `${kept.base}-panel-${id}`,
56
- 'aria-selected': id === kept.open,
57
- disabled: row['disabled'] === true,
58
- onClick: (): void => kept.choose(id),
59
- }
60
- }
61
-
62
- export function opened(_props: TabsProps, kept: Kept): boolean {
63
- return kept.open !== undefined
64
- }
65
-
66
- export function panel(_props: TabsProps, kept: Kept): Readonly<Record<string, unknown>> {
67
- return {
68
- role: 'tabpanel',
69
- id: `${kept.base}-panel-${String(kept.open)}`,
70
- 'aria-labelledby': `${kept.base}-tab-${String(kept.open)}`,
71
- }
72
- }
73
-
74
- export function shown(
75
- props: TabsProps,
76
- ...rest: readonly [Surface, Kept] | readonly [Row, Surface, Kept]
77
- ): Readonly<Record<string, ReactNode>> {
78
- if (rest.length === 3) {
79
- const [row, surface] = rest
80
- return { label: surface.text(String(row['labelKey'])) }
81
- }
82
- const [, kept] = rest
83
- return { inside: props.items.find((one) => one.id === kept.open)?.content ?? null }
84
- }
@@ -1,33 +0,0 @@
1
- 'use client'
2
-
3
- import type { MessageKey } from '../content.tsx'
4
- import { roleClass, type FontRoleId } from '../fonts.ts'
5
-
6
- import type { Dispatching } from '../checked.ts'
7
- import { type Element, element, useSurface } from '../wrappers.tsx'
8
-
9
-
10
- export interface TextProps {
11
- readonly k: MessageKey
12
- readonly with?: Readonly<Record<string, unknown>>
13
- readonly is?: FontRoleId
14
- readonly announce?: 'alert' | 'status'
15
- readonly dispatch?: keyof Dispatching
16
- readonly input?: Readonly<Record<string, unknown>>
17
- readonly invokeOn?: 'press' | 'shown'
18
- }
19
-
20
- export const Text: Element<'Text', TextProps> = element(
21
- 'Text',
22
- (props: TextProps, className) => {
23
- const surface = useSurface({ className: roleClass(props.is, 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={props.announce}>
27
- {surface.text(props.k, props.with)}
28
- </span>
29
- )
30
- },
31
- 'e-text',
32
- {},
33
- )