@prestack/thread-ui 0.0.1 → 0.1.0
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 +177 -0
- package/dist/ui/animations/anm_appear.ts +13 -0
- package/dist/ui/animations/anm_blur_in.ts +19 -0
- package/dist/ui/animations/anm_blur_out.ts +18 -0
- package/dist/ui/animations/anm_dismiss.ts +18 -0
- package/dist/ui/animations/anm_drop.ts +19 -0
- package/dist/ui/animations/anm_fall.ts +18 -0
- package/dist/ui/animations/anm_flash.ts +18 -0
- package/dist/ui/animations/anm_glow.ts +16 -0
- package/dist/ui/animations/anm_lift.ts +16 -0
- package/dist/ui/animations/anm_nudge.ts +16 -0
- package/dist/ui/animations/anm_pop_in.ts +23 -0
- package/dist/ui/animations/anm_pop_out.ts +22 -0
- package/dist/ui/animations/anm_press.ts +12 -0
- package/dist/ui/animations/anm_pulse.ts +13 -0
- package/dist/ui/animations/anm_rise.ts +19 -0
- package/dist/ui/animations/anm_shake.ts +13 -0
- package/dist/ui/animations/anm_slide_in_left.ts +19 -0
- package/dist/ui/animations/anm_slide_in_right.ts +19 -0
- package/dist/ui/animations/anm_slide_out_left.ts +18 -0
- package/dist/ui/animations/anm_slide_out_right.ts +18 -0
- package/dist/ui/animations/anm_spin.ts +12 -0
- package/dist/ui/animations/anm_swell.ts +16 -0
- package/dist/ui/animations/anm_wobble.ts +24 -0
- package/dist/ui/animations/anm_zoom_in.ts +19 -0
- package/dist/ui/animations/anm_zoom_out.ts +18 -0
- package/dist/ui/animations.js +2 -3
- package/dist/ui/animations.ts +316 -0
- package/dist/ui/attach.js +13 -10
- package/dist/ui/attach.ts +607 -0
- package/dist/ui/charts.tsx +74 -0
- package/dist/ui/checked.d.ts +2 -2
- package/dist/ui/checked.ts +32 -0
- package/dist/ui/collector.ts +140 -0
- package/dist/ui/compositions.d.ts +11 -2
- package/dist/ui/compositions.js +283 -59
- package/dist/ui/compositions.ts +633 -0
- package/dist/ui/consent.ts +55 -0
- package/dist/ui/content.tsx +39 -0
- package/dist/ui/contrast.ts +27 -0
- package/dist/ui/controls.tsx +30 -0
- package/dist/ui/disclosure.tsx +22 -0
- package/dist/ui/dismiss-layer.ts +87 -0
- package/dist/ui/door.ts +140 -0
- package/dist/ui/drag.ts +316 -0
- package/dist/ui/elements/accordion.js +2 -2
- package/dist/ui/elements/accordion.tsx +47 -0
- package/dist/ui/elements/accordion.works.ts +66 -0
- package/dist/ui/elements/aspect-ratio.js +1 -1
- package/dist/ui/elements/aspect-ratio.tsx +30 -0
- package/dist/ui/elements/aspect-ratio.works.ts +5 -0
- package/dist/ui/elements/avatar.js +1 -1
- package/dist/ui/elements/avatar.tsx +33 -0
- package/dist/ui/elements/avatar.works.ts +16 -0
- package/dist/ui/elements/badge.js +1 -1
- package/dist/ui/elements/badge.tsx +32 -0
- package/dist/ui/elements/badge.works.ts +9 -0
- package/dist/ui/elements/bars.js +2 -2
- package/dist/ui/elements/bars.tsx +49 -0
- package/dist/ui/elements/bars.works.ts +29 -0
- package/dist/ui/elements/box.js +3 -2
- package/dist/ui/elements/box.tsx +35 -0
- package/dist/ui/elements/breadcrumb.js +2 -2
- package/dist/ui/elements/breadcrumb.tsx +37 -0
- package/dist/ui/elements/breadcrumb.works.ts +24 -0
- package/dist/ui/elements/button.js +1 -1
- package/dist/ui/elements/button.tsx +45 -0
- package/dist/ui/elements/button.works.tsx +52 -0
- package/dist/ui/elements/column.js +1 -1
- package/dist/ui/elements/column.tsx +28 -0
- package/dist/ui/elements/consent.js +2 -2
- package/dist/ui/elements/consent.tsx +70 -0
- package/dist/ui/elements/consent.works.tsx +132 -0
- package/dist/ui/elements/donut.js +2 -2
- package/dist/ui/elements/donut.tsx +44 -0
- package/dist/ui/elements/donut.works.ts +42 -0
- package/dist/ui/elements/each.js +1 -1
- package/dist/ui/elements/each.tsx +33 -0
- package/dist/ui/elements/each.works.tsx +82 -0
- package/dist/ui/elements/empty.js +1 -1
- package/dist/ui/elements/empty.tsx +32 -0
- package/dist/ui/elements/field.js +1 -1
- package/dist/ui/elements/field.tsx +44 -0
- package/dist/ui/elements/field.works.ts +65 -0
- package/dist/ui/elements/funnel.js +2 -2
- package/dist/ui/elements/funnel.tsx +49 -0
- package/dist/ui/elements/funnel.works.ts +37 -0
- package/dist/ui/elements/gauge.js +1 -1
- package/dist/ui/elements/gauge.tsx +39 -0
- package/dist/ui/elements/gauge.works.ts +42 -0
- package/dist/ui/elements/glyph.js +1 -1
- package/dist/ui/elements/glyph.tsx +29 -0
- package/dist/ui/elements/glyph.works.tsx +42 -0
- package/dist/ui/elements/grid.js +1 -1
- package/dist/ui/elements/grid.tsx +28 -0
- package/dist/ui/elements/heatmap.js +2 -2
- package/dist/ui/elements/heatmap.tsx +47 -0
- package/dist/ui/elements/heatmap.works.ts +24 -0
- package/dist/ui/elements/hit-box.js +1 -1
- package/dist/ui/elements/hit-box.tsx +46 -0
- package/dist/ui/elements/hit-box.works.tsx +576 -0
- package/dist/ui/elements/image.js +1 -1
- package/dist/ui/elements/image.tsx +28 -0
- package/dist/ui/elements/line-chart.js +2 -2
- package/dist/ui/elements/line-chart.tsx +44 -0
- package/dist/ui/elements/line-chart.works.ts +41 -0
- package/dist/ui/elements/link.js +1 -1
- package/dist/ui/elements/link.tsx +37 -0
- package/dist/ui/elements/link.works.ts +25 -0
- package/dist/ui/elements/media.js +1 -1
- package/dist/ui/elements/media.tsx +56 -0
- package/dist/ui/elements/menu.js +2 -2
- package/dist/ui/elements/menu.tsx +50 -0
- package/dist/ui/elements/menu.works.tsx +153 -0
- package/dist/ui/elements/money.js +1 -1
- package/dist/ui/elements/money.tsx +28 -0
- package/dist/ui/elements/money.works.ts +9 -0
- package/dist/ui/elements/pagination.js +2 -2
- package/dist/ui/elements/pagination.tsx +38 -0
- package/dist/ui/elements/pagination.works.ts +20 -0
- package/dist/ui/elements/progress.js +1 -1
- package/dist/ui/elements/progress.tsx +33 -0
- package/dist/ui/elements/progress.works.ts +8 -0
- package/dist/ui/elements/radio-group.js +2 -2
- package/dist/ui/elements/radio-group.tsx +49 -0
- package/dist/ui/elements/radio-group.works.ts +33 -0
- package/dist/ui/elements/row.js +1 -1
- package/dist/ui/elements/row.tsx +28 -0
- package/dist/ui/elements/scatter.js +1 -1
- package/dist/ui/elements/scatter.tsx +41 -0
- package/dist/ui/elements/scatter.works.ts +38 -0
- package/dist/ui/elements/select.js +2 -2
- package/dist/ui/elements/select.tsx +42 -0
- package/dist/ui/elements/select.works.ts +5 -0
- package/dist/ui/elements/separator.js +1 -1
- package/dist/ui/elements/separator.tsx +30 -0
- package/dist/ui/elements/skeleton.js +1 -1
- package/dist/ui/elements/skeleton.tsx +30 -0
- package/dist/ui/elements/slider.js +1 -1
- package/dist/ui/elements/slider.tsx +33 -0
- package/dist/ui/elements/slider.works.ts +5 -0
- package/dist/ui/elements/sparkline.js +1 -1
- package/dist/ui/elements/sparkline.tsx +36 -0
- package/dist/ui/elements/sparkline.works.ts +32 -0
- package/dist/ui/elements/spinner.js +1 -1
- package/dist/ui/elements/spinner.tsx +32 -0
- package/dist/ui/elements/stack.js +1 -1
- package/dist/ui/elements/stack.tsx +28 -0
- package/dist/ui/elements/stat.js +1 -1
- package/dist/ui/elements/stat.tsx +35 -0
- package/dist/ui/elements/stat.works.ts +14 -0
- package/dist/ui/elements/surface.js +1 -1
- package/dist/ui/elements/surface.tsx +35 -0
- package/dist/ui/elements/surface.works.ts +9 -0
- package/dist/ui/elements/table.js +2 -2
- package/dist/ui/elements/table.tsx +61 -0
- package/dist/ui/elements/table.works.ts +30 -0
- package/dist/ui/elements/tabs.js +2 -2
- package/dist/ui/elements/tabs.tsx +47 -0
- package/dist/ui/elements/tabs.works.ts +84 -0
- package/dist/ui/elements/text.js +1 -1
- package/dist/ui/elements/text.tsx +32 -0
- package/dist/ui/elements/textarea.js +1 -1
- package/dist/ui/elements/textarea.tsx +37 -0
- package/dist/ui/elements/textarea.works.ts +5 -0
- package/dist/ui/elements/time.js +1 -1
- package/dist/ui/elements/time.tsx +34 -0
- package/dist/ui/elements/time.works.ts +25 -0
- package/dist/ui/elements/toggle.js +1 -1
- package/dist/ui/elements/toggle.tsx +33 -0
- package/dist/ui/elements/toggle.works.ts +5 -0
- package/dist/ui/elements/tooltip.js +1 -1
- package/dist/ui/elements/tooltip.tsx +39 -0
- package/dist/ui/elements/tooltip.works.ts +77 -0
- package/dist/ui/elements/value.js +1 -1
- package/dist/ui/elements/value.tsx +30 -0
- package/dist/ui/elements/value.works.ts +9 -0
- package/dist/ui/elements.ts +127 -0
- package/dist/ui/focus-scope.ts +121 -0
- package/dist/ui/fonts.ts +355 -0
- package/dist/ui/generators/dev.js +2 -1
- package/dist/ui/generators/dev.ts +80 -0
- package/dist/ui/generators/elements.d.ts +1 -11
- package/dist/ui/generators/elements.js +44 -14
- package/dist/ui/generators/elements.ts +794 -0
- package/dist/ui/generators/i18n.js +2 -3
- package/dist/ui/generators/i18n.ts +300 -0
- package/dist/ui/generators/icons.js +3 -12
- package/dist/ui/generators/icons.ts +214 -0
- package/dist/ui/generators/react.js +13 -5
- package/dist/ui/generators/react.ts +269 -0
- package/dist/ui/generators/routes.d.ts +1 -0
- package/dist/ui/generators/routes.js +99 -83
- package/dist/ui/generators/routes.ts +743 -0
- package/dist/ui/generators/show.js +4 -12
- package/dist/ui/generators/show.ts +260 -0
- package/dist/ui/generators/styles.js +3 -4
- package/dist/ui/generators/styles.ts +669 -0
- package/dist/ui/generators/variants.js +2 -3
- package/dist/ui/generators/variants.ts +204 -0
- package/dist/ui/i18n/catalogs/en.ts +191 -0
- package/dist/ui/i18n/format.ts +221 -0
- package/dist/ui/i18n/locales.ts +33 -0
- package/dist/ui/i18n/parse.ts +315 -0
- package/dist/ui/i18n/translator.ts +31 -0
- package/dist/ui/i18n/types.ts +96 -0
- package/dist/ui/icons.ts +331 -0
- package/dist/ui/islands/map.ts +58 -0
- package/dist/ui/localizations.ts +75 -0
- package/dist/ui/material.ts +236 -0
- package/dist/ui/materials/mat_bordered.ts +13 -0
- package/dist/ui/materials/mat_ceramic.ts +13 -0
- package/dist/ui/materials/mat_clay.ts +13 -0
- package/dist/ui/materials/mat_elevated.ts +24 -0
- package/dist/ui/materials/mat_flat.ts +34 -0
- package/dist/ui/materials/mat_glass.ts +20 -0
- package/dist/ui/materials/mat_lit.ts +13 -0
- package/dist/ui/materials/mat_moulded.ts +11 -0
- package/dist/ui/materials.js +2 -3
- package/dist/ui/materials.ts +205 -0
- package/dist/ui/modes.ts +44 -0
- package/dist/ui/navigation.tsx +32 -0
- package/dist/ui/positioning.ts +90 -0
- package/dist/ui/presented.tsx +119 -0
- package/dist/ui/provider.d.ts +2 -0
- package/dist/ui/provider.js +7 -1
- package/dist/ui/provider.tsx +182 -0
- package/dist/ui/render-loop.ts +133 -0
- package/dist/ui/roving-focus.ts +161 -0
- package/dist/ui/screens.js +22 -22
- package/dist/ui/screens.ts +141 -0
- package/dist/ui/scroll-lock.ts +28 -0
- package/dist/ui/series.ts +97 -0
- package/dist/ui/signals.ts +386 -0
- package/dist/ui/styleguide.ts +231 -0
- package/dist/ui/styleguides.ts +374 -0
- package/dist/ui/themes.ts +22 -0
- package/dist/ui/token.js +1 -1
- package/dist/ui/token.ts +78 -0
- package/dist/ui/tokens/shadow.ts +25 -0
- package/dist/ui/tokens.js +1 -2
- package/dist/ui/tokens.ts +234 -0
- package/dist/ui/validators.ts +232 -0
- package/dist/ui/variant.d.ts +1 -0
- package/dist/ui/variant.js +3 -0
- package/dist/ui/variant.ts +352 -0
- package/dist/ui/variants/var_avatar-round.ts +14 -0
- package/dist/ui/variants/var_bubble-me.ts +14 -0
- package/dist/ui/variants/var_bubble-them.ts +13 -0
- package/dist/ui/variants/var_button-border.ts +76 -0
- package/dist/ui/variants/var_button-cta.ts +76 -0
- package/dist/ui/variants/var_button-destructive-ghost.ts +72 -0
- package/dist/ui/variants/var_button-destructive.ts +76 -0
- package/dist/ui/variants/var_button-fill.ts +76 -0
- package/dist/ui/variants/var_button-ghost.ts +72 -0
- package/dist/ui/variants/var_button-glass.ts +55 -0
- package/dist/ui/variants/var_button-normal.ts +76 -0
- package/dist/ui/variants/var_button-quiet.ts +74 -0
- package/dist/ui/variants/var_card.ts +17 -0
- package/dist/ui/variants/var_chip.ts +13 -0
- package/dist/ui/variants/var_choice.ts +15 -0
- package/dist/ui/variants/var_framed.ts +10 -0
- package/dist/ui/variants/var_glyph-plain.ts +11 -0
- package/dist/ui/variants/var_input.ts +43 -0
- package/dist/ui/variants/var_link-inline.ts +29 -0
- package/dist/ui/variants/var_list-row.ts +34 -0
- package/dist/ui/variants/var_rule.ts +10 -0
- package/dist/ui/variants/var_skeleton-block.ts +12 -0
- package/dist/ui/variants/var_spinner-turning.ts +12 -0
- package/dist/ui/variants/var_stat-tile.ts +13 -0
- package/dist/ui/variants/var_tab-bar.ts +15 -0
- package/dist/ui/variants/var_tap-target.ts +25 -0
- package/dist/ui/variants.ts +64 -0
- package/dist/ui/wrappers.d.ts +4 -1
- package/dist/ui/wrappers.js +60 -20
- package/dist/ui/wrappers.tsx +426 -0
- package/package.json +8 -2
- package/dist/ui/makers/message.d.ts +0 -1
- package/dist/ui/makers/message.js +0 -230
|
@@ -0,0 +1,352 @@
|
|
|
1
|
+
import { BOUND as MATERIAL_BOUND, compose, composed, FREE, type Material, type Setting } from './material.ts'
|
|
2
|
+
import type { MATERIALS } from './materials.ts'
|
|
3
|
+
import type { Holds, Token, Wearing } from './token.ts'
|
|
4
|
+
import { coexist, holds, isSignal, selectorOf, signalNames } from './signals.ts'
|
|
5
|
+
|
|
6
|
+
interface Stateful {
|
|
7
|
+
readonly id: string
|
|
8
|
+
|
|
9
|
+
readonly states?: readonly {
|
|
10
|
+
readonly when: readonly string[]
|
|
11
|
+
readonly sets: readonly Setting[]
|
|
12
|
+
}[]
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
type SignalId = (typeof holds)[number]['id'] | (string & {})
|
|
16
|
+
|
|
17
|
+
type MaterialId = (typeof MATERIALS)['declares'][number]['id'] | (string & {})
|
|
18
|
+
|
|
19
|
+
const BOUND = {
|
|
20
|
+
background: ['colour', 'gradient', 'texture', 'noise', 'img'],
|
|
21
|
+
borderColor: ['colour'],
|
|
22
|
+
color: ['colour'],
|
|
23
|
+
borderRadius: ['radius'],
|
|
24
|
+
borderWidth: ['edge'],
|
|
25
|
+
|
|
26
|
+
borderStyle: ['line'],
|
|
27
|
+
boxShadow: ['shadow'],
|
|
28
|
+
cursor: ['cursor'],
|
|
29
|
+
gap: ['space'],
|
|
30
|
+
padding: ['space'],
|
|
31
|
+
outlineOffset: ['space'],
|
|
32
|
+
minHeight: ['control', 'space'],
|
|
33
|
+
minWidth: ['space'],
|
|
34
|
+
maxWidth: ['space'],
|
|
35
|
+
opacity: ['opacity'],
|
|
36
|
+
transform: ['transform'],
|
|
37
|
+
animation: ['animation'],
|
|
38
|
+
width: ['icon'],
|
|
39
|
+
height: ['control', 'icon'],
|
|
40
|
+
|
|
41
|
+
display: ['layout'],
|
|
42
|
+
flexDirection: ['flow'],
|
|
43
|
+
alignItems: ['align'],
|
|
44
|
+
justifyContent: ['align'],
|
|
45
|
+
flexWrap: ['wrap'],
|
|
46
|
+
|
|
47
|
+
position: ['position'],
|
|
48
|
+
visibility: ['visibility'],
|
|
49
|
+
pointerEvents: ['reach'],
|
|
50
|
+
userSelect: ['picking'],
|
|
51
|
+
touchAction: ['touch'],
|
|
52
|
+
willChange: ['readying'],
|
|
53
|
+
transformOrigin: ['origin'],
|
|
54
|
+
overflow: ['overflow'],
|
|
55
|
+
zIndex: ['layer'],
|
|
56
|
+
top: ['space'],
|
|
57
|
+
left: ['space'],
|
|
58
|
+
aspectRatio: ['ratio'],
|
|
59
|
+
} as const
|
|
60
|
+
|
|
61
|
+
type Property = keyof typeof BOUND
|
|
62
|
+
|
|
63
|
+
type BoundSettingFor<P extends Property> = {
|
|
64
|
+
readonly property: P
|
|
65
|
+
|
|
66
|
+
readonly is?: string
|
|
67
|
+
|
|
68
|
+
readonly token?: (typeof BOUND)[P][number]
|
|
69
|
+
|
|
70
|
+
readonly asks?: Readonly<Record<string, string | number>>
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
type FreeProperty = (typeof FREE)[number]
|
|
74
|
+
|
|
75
|
+
type FreeSettingFor<P extends FreeProperty> = {
|
|
76
|
+
readonly property: P
|
|
77
|
+
|
|
78
|
+
readonly is: string
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
type VariantSetting =
|
|
82
|
+
| { [P in Property]: BoundSettingFor<P> }[Property]
|
|
83
|
+
| { [P in FreeProperty]: FreeSettingFor<P> }[FreeProperty]
|
|
84
|
+
|
|
85
|
+
export interface Variant {
|
|
86
|
+
readonly id: string
|
|
87
|
+
|
|
88
|
+
readonly version?: number
|
|
89
|
+
|
|
90
|
+
readonly material?: MaterialId
|
|
91
|
+
|
|
92
|
+
readonly type?: string
|
|
93
|
+
|
|
94
|
+
readonly icon?: string
|
|
95
|
+
|
|
96
|
+
readonly sets: readonly VariantSetting[]
|
|
97
|
+
|
|
98
|
+
readonly states?: readonly {
|
|
99
|
+
readonly when: readonly SignalId[]
|
|
100
|
+
readonly sets: readonly VariantSetting[]
|
|
101
|
+
}[]
|
|
102
|
+
|
|
103
|
+
readonly reacts: readonly SignalId[]
|
|
104
|
+
|
|
105
|
+
readonly plays?: {
|
|
106
|
+
readonly in?: string
|
|
107
|
+
readonly out?: string
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export function propertiesHeld(): Readonly<Record<string, readonly string[]>> {
|
|
112
|
+
return BOUND
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export function freeHeld(): readonly string[] {
|
|
116
|
+
return FREE
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export const structural = new Set(['tag', 'shows', 'reads', 'holds', 'each', 'by', 'takes', 'marks', 'gives', 'keyed', 'when'])
|
|
120
|
+
|
|
121
|
+
export function looking(made: Readonly<Record<string, string>>): boolean {
|
|
122
|
+
return Object.keys(made).some((key) => !structural.has(key))
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export const variant = <const T extends Variant>(
|
|
126
|
+
one: T & {
|
|
127
|
+
readonly sets: {
|
|
128
|
+
readonly [I in keyof T['sets']]: T['sets'][I] extends { readonly is: infer Said }
|
|
129
|
+
? { readonly is: Wearing<Said & string> }
|
|
130
|
+
: unknown
|
|
131
|
+
}
|
|
132
|
+
} & (T extends { readonly states: infer States }
|
|
133
|
+
? {
|
|
134
|
+
readonly states: {
|
|
135
|
+
readonly [S in keyof States]: States[S] extends { readonly sets: infer Sets }
|
|
136
|
+
? {
|
|
137
|
+
readonly sets: {
|
|
138
|
+
readonly [I in keyof Sets]: Sets[I] extends { readonly is: infer Said }
|
|
139
|
+
? { readonly is: Wearing<Said & string> }
|
|
140
|
+
: unknown
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
: unknown
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
: unknown),
|
|
147
|
+
): T => one
|
|
148
|
+
|
|
149
|
+
export function boundHeld(): Readonly<Record<string, readonly string[]>> {
|
|
150
|
+
return BOUND
|
|
151
|
+
}
|
|
152
|
+
export function camel(id: string): string {
|
|
153
|
+
return id.replace(/-([a-z0-9])/g, (_, one: string) => one.toUpperCase())
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
export function classOf(id: string): string {
|
|
157
|
+
return `thread-${id}`
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
export function classOfElement(id: string): string {
|
|
161
|
+
return `e-${id}`
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
export function classOfComposition(id: string): string {
|
|
165
|
+
return `c-${id}`
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
export function classOfScreen(id: string): string {
|
|
169
|
+
return `s-${id}`
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
export function unreacted(
|
|
173
|
+
variant: Variant,
|
|
174
|
+
materials: Readonly<Record<string, Material>>,
|
|
175
|
+
): readonly string[] {
|
|
176
|
+
const whole = statesOf(variant, materials)
|
|
177
|
+
const described = new Set((whole.states ?? []).flatMap((one) => one.when))
|
|
178
|
+
const claimed = new Set<string>(variant.reacts)
|
|
179
|
+
const missing: string[] = []
|
|
180
|
+
|
|
181
|
+
for (const name of [...described].sort()) {
|
|
182
|
+
if (claimed.has(name)) continue
|
|
183
|
+
missing.push(
|
|
184
|
+
`\`${variant.id}\` looks different under "${name}" and does not say it reacts to it. A ` +
|
|
185
|
+
'variant states what it answers to, so reading one tells you without opening its material.',
|
|
186
|
+
)
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
for (const name of [...claimed].sort()) {
|
|
190
|
+
if (!isSignal(name)) {
|
|
191
|
+
missing.push(
|
|
192
|
+
`\`${variant.id}\` says it reacts to "${name}", and no signal by that name is declared. ` +
|
|
193
|
+
`Declared: ${signalNames().join(' · ')}.`,
|
|
194
|
+
)
|
|
195
|
+
continue
|
|
196
|
+
}
|
|
197
|
+
if (described.has(name)) continue
|
|
198
|
+
missing.push(
|
|
199
|
+
`\`${variant.id}\` says it reacts to "${name}" and never says how it looks under it, so it ` +
|
|
200
|
+
'reacts to nothing.',
|
|
201
|
+
)
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
return missing
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
export function complete(
|
|
208
|
+
variant: Variant,
|
|
209
|
+
materials: Readonly<Record<string, Material>>,
|
|
210
|
+
named: ReadonlySet<string>,
|
|
211
|
+
tokens: Readonly<Record<string, Token>>,
|
|
212
|
+
kinds: Readonly<Record<string, string>>,
|
|
213
|
+
): Readonly<Record<string, Holds>> {
|
|
214
|
+
const made: Record<string, Holds> = {}
|
|
215
|
+
|
|
216
|
+
if (variant.material !== undefined) {
|
|
217
|
+
const material = materials[variant.material]
|
|
218
|
+
if (material === undefined) {
|
|
219
|
+
throw new Error(
|
|
220
|
+
`\`${variant.id}\` is made of \`${variant.material}\`, and no material by that name is ` +
|
|
221
|
+
'declared. A variant is material plus the rest, so without the material there is no rest.',
|
|
222
|
+
)
|
|
223
|
+
}
|
|
224
|
+
Object.assign(made, compose(material, named, tokens, kinds))
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
Object.assign(
|
|
228
|
+
made,
|
|
229
|
+
composed(variant.sets, named, tokens, variant.id, kinds, { ...MATERIAL_BOUND, ...BOUND }),
|
|
230
|
+
)
|
|
231
|
+
|
|
232
|
+
return made
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
export function statesOf(
|
|
236
|
+
variant: Variant,
|
|
237
|
+
materials: Readonly<Record<string, Material>>,
|
|
238
|
+
): Stateful {
|
|
239
|
+
const material = variant.material === undefined ? undefined : materials[variant.material]
|
|
240
|
+
const merged = new Map<string, { when: readonly string[]; sets: Setting[] }>()
|
|
241
|
+
|
|
242
|
+
for (const state of [...(material?.states ?? []), ...(variant.states ?? [])]) {
|
|
243
|
+
const at = [...state.when].sort((a, b) => (a < b ? -1 : a > b ? 1 : 0)).join('+')
|
|
244
|
+
const already = merged.get(at)
|
|
245
|
+
if (already === undefined) merged.set(at, { when: state.when, sets: [...state.sets] })
|
|
246
|
+
else already.sets.push(...state.sets)
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
return { id: variant.id, states: [...merged.values()] }
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
function marked(when: readonly string[]): string {
|
|
253
|
+
return [...when]
|
|
254
|
+
.sort((a, b) => (a < b ? -1 : a > b ? 1 : 0))
|
|
255
|
+
.map((one) => selectorOf(one) ?? '')
|
|
256
|
+
.join('')
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
export function under(
|
|
260
|
+
variant: Stateful,
|
|
261
|
+
named: ReadonlySet<string>,
|
|
262
|
+
tokens: Readonly<Record<string, Token>>,
|
|
263
|
+
kinds: Readonly<Record<string, string>>,
|
|
264
|
+
): readonly { readonly marks: string; readonly made: Readonly<Record<string, Holds>> }[] {
|
|
265
|
+
const found: { marks: string; made: Readonly<Record<string, Holds>> }[] = []
|
|
266
|
+
|
|
267
|
+
for (const state of variant.states ?? []) {
|
|
268
|
+
if (state.when.length === 0) {
|
|
269
|
+
throw new Error(
|
|
270
|
+
`\`${variant.id}\` declares a state that names no signal. A state is the set of truths it ` +
|
|
271
|
+
'holds under, and the empty set is the resting look, which is already declared.',
|
|
272
|
+
)
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
for (const name of state.when) {
|
|
276
|
+
if (isSignal(name)) continue
|
|
277
|
+
throw new Error(
|
|
278
|
+
`\`${variant.id}\` declares a state under \`${name}\`, and no signal by that name is ` +
|
|
279
|
+
`declared. Declared: ${signalNames().join(' · ')}.`,
|
|
280
|
+
)
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
found.push({
|
|
284
|
+
marks: marked(state.when),
|
|
285
|
+
made: composed(state.sets, named, tokens, variant.id, kinds, { ...MATERIAL_BOUND, ...BOUND }),
|
|
286
|
+
})
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
return found
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
const key = (when: readonly string[]): string =>
|
|
293
|
+
[...when].sort((a, b) => (a < b ? -1 : a > b ? 1 : 0)).join('+')
|
|
294
|
+
|
|
295
|
+
function sized(all: readonly string[], size: number): readonly (readonly string[])[] {
|
|
296
|
+
if (size === 0) return [[]]
|
|
297
|
+
const found: (readonly string[])[] = []
|
|
298
|
+
for (let at = 0; at <= all.length - size; at += 1) {
|
|
299
|
+
const head = all[at]
|
|
300
|
+
if (head === undefined) continue
|
|
301
|
+
for (const rest of sized(all.slice(at + 1), size - 1)) found.push([head, ...rest])
|
|
302
|
+
}
|
|
303
|
+
return found
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
function together(all: readonly string[]): boolean {
|
|
307
|
+
for (let i = 0; i < all.length; i += 1) {
|
|
308
|
+
for (let j = i + 1; j < all.length; j += 1) {
|
|
309
|
+
if (!coexist(all[i] ?? '', all[j] ?? '')) return false
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
return true
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
export function undeclaredStates(variant: Stateful): readonly string[] {
|
|
316
|
+
const states = variant.states ?? []
|
|
317
|
+
const declared = new Set(states.map((one) => key(one.when)))
|
|
318
|
+
const named = [...new Set(states.flatMap((one) => one.when))].sort((a, b) => (a < b ? -1 : a > b ? 1 : 0))
|
|
319
|
+
const missing: string[] = []
|
|
320
|
+
|
|
321
|
+
for (let size = 2; size <= named.length; size += 1) {
|
|
322
|
+
for (const combination of sized(named, size)) {
|
|
323
|
+
if (!together(combination)) continue
|
|
324
|
+
if (declared.has(key(combination))) continue
|
|
325
|
+
|
|
326
|
+
const applying = states.filter((one) => one.when.every((name) => combination.includes(name)))
|
|
327
|
+
const deepest = new Map<string, number>()
|
|
328
|
+
const tied = new Map<string, number>()
|
|
329
|
+
for (const state of applying) {
|
|
330
|
+
for (const property of new Set(state.sets.map((set) => set.property))) {
|
|
331
|
+
const depth = deepest.get(property) ?? 0
|
|
332
|
+
if (state.when.length > depth) {
|
|
333
|
+
deepest.set(property, state.when.length)
|
|
334
|
+
tied.set(property, 1)
|
|
335
|
+
} else if (state.when.length === depth) {
|
|
336
|
+
tied.set(property, (tied.get(property) ?? 0) + 1)
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
const clash = new Set([...tied.entries()].filter(([, held]) => held > 1).map(([property]) => property))
|
|
341
|
+
if (clash.size === 0) continue
|
|
342
|
+
|
|
343
|
+
missing.push(
|
|
344
|
+
`${combination.map((one) => `"${one}"`).join(' and ')} can all hold at once and they all ` +
|
|
345
|
+
`set ${[...clash].sort().join(', ')}, so which one wins would be an accident of file ` +
|
|
346
|
+
`order. "${key(combination)}" is not declared — declare it, or say the signals cannot coexist`,
|
|
347
|
+
)
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
return missing
|
|
352
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { variant } from '../variant.ts'
|
|
2
|
+
|
|
3
|
+
export const AVATAR_ROUND = variant({
|
|
4
|
+
id: 'avatar-round',
|
|
5
|
+
sets: [
|
|
6
|
+
{ property: 'width', is: 'icon-lg' },
|
|
7
|
+
{ property: 'height', is: 'icon-lg' },
|
|
8
|
+
{ property: 'borderRadius', is: 'radius-pill' },
|
|
9
|
+
{ property: 'background', is: 'colour-sunken' },
|
|
10
|
+
{ property: 'display', is: 'layout-flex' },
|
|
11
|
+
{ property: 'alignItems', is: 'align-centre' },
|
|
12
|
+
],
|
|
13
|
+
reacts: [],
|
|
14
|
+
} as const)
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { variant } from '../variant.ts'
|
|
2
|
+
|
|
3
|
+
export const BUBBLE_ME = variant({
|
|
4
|
+
id: 'bubble-me',
|
|
5
|
+
material: 'flat',
|
|
6
|
+
sets: [
|
|
7
|
+
{ property: 'background', is: 'colour-accent' },
|
|
8
|
+
{ property: 'color', is: 'colour-on-accent' },
|
|
9
|
+
{ property: 'borderRadius', is: 'radius-lg' },
|
|
10
|
+
{ property: 'padding', is: 'space-3 space-4' },
|
|
11
|
+
{ property: 'gap', is: 'space-2' },
|
|
12
|
+
],
|
|
13
|
+
reacts: ['focus', 'hover'],
|
|
14
|
+
} as const)
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { variant } from '../variant.ts'
|
|
2
|
+
|
|
3
|
+
export const BUBBLE_THEM = variant({
|
|
4
|
+
id: 'bubble-them',
|
|
5
|
+
material: 'flat',
|
|
6
|
+
sets: [
|
|
7
|
+
{ property: 'color', is: 'colour-ink' },
|
|
8
|
+
{ property: 'borderRadius', is: 'radius-lg' },
|
|
9
|
+
{ property: 'padding', is: 'space-3 space-4' },
|
|
10
|
+
{ property: 'gap', is: 'space-2' },
|
|
11
|
+
],
|
|
12
|
+
reacts: ['focus', 'hover'],
|
|
13
|
+
} as const)
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { variant } from '../variant.ts'
|
|
2
|
+
|
|
3
|
+
export const BUTTON_BORDER = variant({
|
|
4
|
+
id: 'button-border',
|
|
5
|
+
type: 'label',
|
|
6
|
+
icon: 'md',
|
|
7
|
+
sets: [
|
|
8
|
+
{ property: 'display', is: 'layout-flex' },
|
|
9
|
+
{ property: 'alignItems', is: 'align-centre' },
|
|
10
|
+
{ property: 'justifyContent', is: 'align-centre' },
|
|
11
|
+
{ property: 'borderRadius', is: 'control-radius' },
|
|
12
|
+
{ property: 'height', is: 'control-md' },
|
|
13
|
+
{ property: 'padding', is: 'control-pad-y control-pad-x' },
|
|
14
|
+
{ property: 'gap', is: 'control-gap' },
|
|
15
|
+
{ property: 'cursor', is: 'cursor-press' },
|
|
16
|
+
{ property: 'transition', is: 'motion-quick ease-out' },
|
|
17
|
+
{ property: 'background', is: 'colour-clear' },
|
|
18
|
+
{ property: 'color', is: 'colour-accent' },
|
|
19
|
+
{ property: 'borderWidth', is: 'control-edge' },
|
|
20
|
+
{ property: 'borderStyle', is: 'line-solid' },
|
|
21
|
+
{ property: 'borderColor', is: 'colour-accent' },
|
|
22
|
+
{ property: 'boxShadow', is: 'shadow-0' },
|
|
23
|
+
],
|
|
24
|
+
states: [
|
|
25
|
+
{
|
|
26
|
+
when: ['hover'],
|
|
27
|
+
sets: [
|
|
28
|
+
{ property: 'background', is: 'colour-surface-lit' },
|
|
29
|
+
{ property: 'transform', is: 'transform-lift' },
|
|
30
|
+
],
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
when: ['active'],
|
|
34
|
+
sets: [
|
|
35
|
+
{ property: 'background', is: 'colour-surface-lit' },
|
|
36
|
+
{ property: 'transform', is: 'transform-press' },
|
|
37
|
+
],
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
when: ['active', 'hover'],
|
|
41
|
+
sets: [
|
|
42
|
+
{ property: 'background', is: 'colour-surface-lit' },
|
|
43
|
+
{ property: 'transform', is: 'transform-press' },
|
|
44
|
+
],
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
when: ['focus'],
|
|
48
|
+
sets: [
|
|
49
|
+
{ property: 'outline', is: 'control-ring line-solid colour-accent' },
|
|
50
|
+
{ property: 'outlineOffset', is: 'control-ring-offset' },
|
|
51
|
+
],
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
when: ['loading'],
|
|
55
|
+
sets: [
|
|
56
|
+
{ property: 'opacity', is: 'opacity-muted' },
|
|
57
|
+
],
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
when: ['disabled'],
|
|
61
|
+
sets: [
|
|
62
|
+
{ property: 'cursor', is: 'cursor-refuse' },
|
|
63
|
+
{ property: 'borderColor', is: 'colour-edge' },
|
|
64
|
+
{ property: 'color', is: 'colour-ink-faint' },
|
|
65
|
+
],
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
when: ['disabled', 'hover'],
|
|
69
|
+
sets: [
|
|
70
|
+
{ property: 'background', is: 'colour-clear' },
|
|
71
|
+
{ property: 'transform', is: 'transform-rest' },
|
|
72
|
+
],
|
|
73
|
+
},
|
|
74
|
+
],
|
|
75
|
+
reacts: ['active', 'disabled', 'focus', 'hover', 'loading'],
|
|
76
|
+
} as const)
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { variant } from '../variant.ts'
|
|
2
|
+
|
|
3
|
+
export const BUTTON_CTA = variant({
|
|
4
|
+
id: 'button-cta',
|
|
5
|
+
type: 'body',
|
|
6
|
+
icon: 'md',
|
|
7
|
+
sets: [
|
|
8
|
+
{ property: 'display', is: 'layout-flex' },
|
|
9
|
+
{ property: 'alignItems', is: 'align-centre' },
|
|
10
|
+
{ property: 'justifyContent', is: 'align-centre' },
|
|
11
|
+
{ property: 'borderRadius', is: 'control-radius' },
|
|
12
|
+
{ property: 'height', is: 'control-lg' },
|
|
13
|
+
{ property: 'padding', is: 'control-pad-y control-pad-x' },
|
|
14
|
+
{ property: 'gap', is: 'control-gap' },
|
|
15
|
+
{ property: 'cursor', is: 'cursor-press' },
|
|
16
|
+
{ property: 'transition', is: 'motion-quick ease-out' },
|
|
17
|
+
{ property: 'background', is: 'colour-accent' },
|
|
18
|
+
{ property: 'color', is: 'colour-on-accent' },
|
|
19
|
+
{ property: 'borderWidth', is: 'edge-hair' },
|
|
20
|
+
{ property: 'borderStyle', is: 'line-off' },
|
|
21
|
+
{ property: 'borderColor', is: 'colour-clear' },
|
|
22
|
+
{ property: 'boxShadow', is: 'shadow-2' },
|
|
23
|
+
],
|
|
24
|
+
states: [
|
|
25
|
+
{
|
|
26
|
+
when: ['hover'],
|
|
27
|
+
sets: [
|
|
28
|
+
{ property: 'background', is: 'colour-accent-hover' },
|
|
29
|
+
{ property: 'transform', is: 'transform-lift' },
|
|
30
|
+
],
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
when: ['active'],
|
|
34
|
+
sets: [
|
|
35
|
+
{ property: 'background', is: 'colour-accent-press' },
|
|
36
|
+
{ property: 'transform', is: 'transform-press' },
|
|
37
|
+
],
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
when: ['active', 'hover'],
|
|
41
|
+
sets: [
|
|
42
|
+
{ property: 'background', is: 'colour-accent-press' },
|
|
43
|
+
{ property: 'transform', is: 'transform-press' },
|
|
44
|
+
],
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
when: ['focus'],
|
|
48
|
+
sets: [
|
|
49
|
+
{ property: 'outline', is: 'control-ring line-solid colour-accent' },
|
|
50
|
+
{ property: 'outlineOffset', is: 'control-ring-offset' },
|
|
51
|
+
],
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
when: ['loading'],
|
|
55
|
+
sets: [
|
|
56
|
+
{ property: 'opacity', is: 'opacity-muted' },
|
|
57
|
+
],
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
when: ['disabled'],
|
|
61
|
+
sets: [
|
|
62
|
+
{ property: 'cursor', is: 'cursor-refuse' },
|
|
63
|
+
{ property: 'background', is: 'colour-sunken' },
|
|
64
|
+
{ property: 'color', is: 'colour-ink-faint' },
|
|
65
|
+
],
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
when: ['disabled', 'hover'],
|
|
69
|
+
sets: [
|
|
70
|
+
{ property: 'background', is: 'colour-sunken' },
|
|
71
|
+
{ property: 'transform', is: 'transform-rest' },
|
|
72
|
+
],
|
|
73
|
+
},
|
|
74
|
+
],
|
|
75
|
+
reacts: ['active', 'disabled', 'focus', 'hover', 'loading'],
|
|
76
|
+
} as const)
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { variant } from '../variant.ts'
|
|
2
|
+
|
|
3
|
+
export const BUTTON_DESTRUCTIVE_GHOST = variant({
|
|
4
|
+
id: 'button-destructive-ghost',
|
|
5
|
+
type: 'label',
|
|
6
|
+
icon: 'md',
|
|
7
|
+
sets: [
|
|
8
|
+
{ property: 'display', is: 'layout-flex' },
|
|
9
|
+
{ property: 'alignItems', is: 'align-centre' },
|
|
10
|
+
{ property: 'justifyContent', is: 'align-centre' },
|
|
11
|
+
{ property: 'borderRadius', is: 'control-radius' },
|
|
12
|
+
{ property: 'height', is: 'control-md' },
|
|
13
|
+
{ property: 'padding', is: 'control-pad-y control-pad-x' },
|
|
14
|
+
{ property: 'gap', is: 'control-gap' },
|
|
15
|
+
{ property: 'cursor', is: 'cursor-press' },
|
|
16
|
+
{ property: 'transition', is: 'motion-quick ease-out' },
|
|
17
|
+
{ property: 'background', is: 'colour-clear' },
|
|
18
|
+
{ property: 'color', is: 'colour-negative' },
|
|
19
|
+
{ property: 'borderWidth', is: 'edge-hair' },
|
|
20
|
+
{ property: 'borderStyle', is: 'line-off' },
|
|
21
|
+
{ property: 'borderColor', is: 'colour-clear' },
|
|
22
|
+
{ property: 'boxShadow', is: 'shadow-0' },
|
|
23
|
+
],
|
|
24
|
+
states: [
|
|
25
|
+
{
|
|
26
|
+
when: ['hover'],
|
|
27
|
+
sets: [
|
|
28
|
+
{ property: 'background', is: 'colour-surface-alert' },
|
|
29
|
+
{ property: 'transform', is: 'transform-lift' },
|
|
30
|
+
],
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
when: ['active'],
|
|
34
|
+
sets: [
|
|
35
|
+
{ property: 'background', is: 'colour-surface-alert' },
|
|
36
|
+
{ property: 'transform', is: 'transform-press' },
|
|
37
|
+
],
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
when: ['active', 'hover'],
|
|
41
|
+
sets: [
|
|
42
|
+
{ property: 'background', is: 'colour-surface-alert' },
|
|
43
|
+
{ property: 'transform', is: 'transform-press' },
|
|
44
|
+
],
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
when: ['focus'],
|
|
48
|
+
sets: [
|
|
49
|
+
{ property: 'outline', is: 'control-ring line-solid colour-negative' },
|
|
50
|
+
{ property: 'outlineOffset', is: 'control-ring-offset' },
|
|
51
|
+
],
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
when: ['loading'],
|
|
55
|
+
sets: [
|
|
56
|
+
{ property: 'opacity', is: 'opacity-muted' },
|
|
57
|
+
],
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
when: ['disabled'],
|
|
61
|
+
sets: [{ property: 'color', is: 'colour-ink-faint' }, { property: 'cursor', is: 'cursor-refuse' }],
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
when: ['disabled', 'hover'],
|
|
65
|
+
sets: [
|
|
66
|
+
{ property: 'background', is: 'colour-clear' },
|
|
67
|
+
{ property: 'transform', is: 'transform-rest' },
|
|
68
|
+
],
|
|
69
|
+
},
|
|
70
|
+
],
|
|
71
|
+
reacts: ['active', 'disabled', 'focus', 'hover', 'loading'],
|
|
72
|
+
} as const)
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { variant } from '../variant.ts'
|
|
2
|
+
|
|
3
|
+
export const BUTTON_DESTRUCTIVE = variant({
|
|
4
|
+
id: 'button-destructive',
|
|
5
|
+
type: 'label',
|
|
6
|
+
icon: 'md',
|
|
7
|
+
sets: [
|
|
8
|
+
{ property: 'display', is: 'layout-flex' },
|
|
9
|
+
{ property: 'alignItems', is: 'align-centre' },
|
|
10
|
+
{ property: 'justifyContent', is: 'align-centre' },
|
|
11
|
+
{ property: 'borderRadius', is: 'control-radius' },
|
|
12
|
+
{ property: 'height', is: 'control-md' },
|
|
13
|
+
{ property: 'padding', is: 'control-pad-y control-pad-x' },
|
|
14
|
+
{ property: 'gap', is: 'control-gap' },
|
|
15
|
+
{ property: 'cursor', is: 'cursor-press' },
|
|
16
|
+
{ property: 'transition', is: 'motion-quick ease-out' },
|
|
17
|
+
{ property: 'background', is: 'colour-negative' },
|
|
18
|
+
{ property: 'color', is: 'colour-on-negative' },
|
|
19
|
+
{ property: 'borderWidth', is: 'edge-hair' },
|
|
20
|
+
{ property: 'borderStyle', is: 'line-off' },
|
|
21
|
+
{ property: 'borderColor', is: 'colour-clear' },
|
|
22
|
+
{ property: 'boxShadow', is: 'shadow-0' },
|
|
23
|
+
],
|
|
24
|
+
states: [
|
|
25
|
+
{
|
|
26
|
+
when: ['hover'],
|
|
27
|
+
sets: [
|
|
28
|
+
{ property: 'background', is: 'colour-negative-hover' },
|
|
29
|
+
{ property: 'transform', is: 'transform-lift' },
|
|
30
|
+
],
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
when: ['active'],
|
|
34
|
+
sets: [
|
|
35
|
+
{ property: 'background', is: 'colour-negative-press' },
|
|
36
|
+
{ property: 'transform', is: 'transform-press' },
|
|
37
|
+
],
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
when: ['active', 'hover'],
|
|
41
|
+
sets: [
|
|
42
|
+
{ property: 'background', is: 'colour-negative-press' },
|
|
43
|
+
{ property: 'transform', is: 'transform-press' },
|
|
44
|
+
],
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
when: ['focus'],
|
|
48
|
+
sets: [
|
|
49
|
+
{ property: 'outline', is: 'control-ring line-solid colour-negative' },
|
|
50
|
+
{ property: 'outlineOffset', is: 'control-ring-offset' },
|
|
51
|
+
],
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
when: ['loading'],
|
|
55
|
+
sets: [
|
|
56
|
+
{ property: 'opacity', is: 'opacity-muted' },
|
|
57
|
+
],
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
when: ['disabled'],
|
|
61
|
+
sets: [
|
|
62
|
+
{ property: 'cursor', is: 'cursor-refuse' },
|
|
63
|
+
{ property: 'background', is: 'colour-sunken' },
|
|
64
|
+
{ property: 'color', is: 'colour-ink-faint' },
|
|
65
|
+
],
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
when: ['disabled', 'hover'],
|
|
69
|
+
sets: [
|
|
70
|
+
{ property: 'background', is: 'colour-sunken' },
|
|
71
|
+
{ property: 'transform', is: 'transform-rest' },
|
|
72
|
+
],
|
|
73
|
+
},
|
|
74
|
+
],
|
|
75
|
+
reacts: ['active', 'disabled', 'focus', 'hover', 'loading'],
|
|
76
|
+
} as const)
|