openuispec 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/LICENSE +21 -0
- package/README.md +214 -0
- package/cli/index.ts +49 -0
- package/cli/init.ts +390 -0
- package/drift/index.ts +398 -0
- package/examples/taskflow/README.md +103 -0
- package/examples/taskflow/contracts/README.md +18 -0
- package/examples/taskflow/contracts/action_trigger.yaml +7 -0
- package/examples/taskflow/contracts/collection.yaml +7 -0
- package/examples/taskflow/contracts/data_display.yaml +7 -0
- package/examples/taskflow/contracts/feedback.yaml +7 -0
- package/examples/taskflow/contracts/input_field.yaml +7 -0
- package/examples/taskflow/contracts/nav_container.yaml +7 -0
- package/examples/taskflow/contracts/surface.yaml +7 -0
- package/examples/taskflow/contracts/x_media_player.yaml +185 -0
- package/examples/taskflow/flows/create_task.yaml +171 -0
- package/examples/taskflow/flows/edit_task.yaml +131 -0
- package/examples/taskflow/locales/en.json +158 -0
- package/examples/taskflow/openuispec.yaml +144 -0
- package/examples/taskflow/platform/android.yaml +32 -0
- package/examples/taskflow/platform/ios.yaml +39 -0
- package/examples/taskflow/platform/web.yaml +35 -0
- package/examples/taskflow/screens/calendar.yaml +23 -0
- package/examples/taskflow/screens/home.yaml +220 -0
- package/examples/taskflow/screens/profile_edit.yaml +70 -0
- package/examples/taskflow/screens/project_detail.yaml +65 -0
- package/examples/taskflow/screens/projects.yaml +142 -0
- package/examples/taskflow/screens/settings.yaml +178 -0
- package/examples/taskflow/screens/task_detail.yaml +317 -0
- package/examples/taskflow/tokens/color.yaml +88 -0
- package/examples/taskflow/tokens/elevation.yaml +27 -0
- package/examples/taskflow/tokens/icons.yaml +189 -0
- package/examples/taskflow/tokens/layout.yaml +156 -0
- package/examples/taskflow/tokens/motion.yaml +41 -0
- package/examples/taskflow/tokens/spacing.yaml +23 -0
- package/examples/taskflow/tokens/themes.yaml +34 -0
- package/examples/taskflow/tokens/typography.yaml +61 -0
- package/package.json +43 -0
- package/schema/custom-contract.schema.json +257 -0
- package/schema/defs/action.schema.json +272 -0
- package/schema/defs/adaptive.schema.json +13 -0
- package/schema/defs/common.schema.json +330 -0
- package/schema/defs/data-binding.schema.json +119 -0
- package/schema/defs/validation.schema.json +121 -0
- package/schema/flow.schema.json +164 -0
- package/schema/locale.schema.json +26 -0
- package/schema/openuispec.schema.json +287 -0
- package/schema/platform.schema.json +95 -0
- package/schema/screen.schema.json +346 -0
- package/schema/tokens/color.schema.json +104 -0
- package/schema/tokens/elevation.schema.json +84 -0
- package/schema/tokens/icons.schema.json +149 -0
- package/schema/tokens/layout.schema.json +170 -0
- package/schema/tokens/motion.schema.json +83 -0
- package/schema/tokens/spacing.schema.json +93 -0
- package/schema/tokens/themes.schema.json +92 -0
- package/schema/tokens/typography.schema.json +106 -0
- package/schema/validate.ts +258 -0
- package/spec/openuispec-v0.1.md +3677 -0
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# TaskFlow — Color Tokens
|
|
2
|
+
# Brand: warm indigo + coral accent, neutral warm grays
|
|
3
|
+
|
|
4
|
+
color:
|
|
5
|
+
brand:
|
|
6
|
+
primary:
|
|
7
|
+
semantic: "Main brand identity — actions, selected states, key UI"
|
|
8
|
+
reference: "#5B4FE8"
|
|
9
|
+
range:
|
|
10
|
+
hue: [240, 250]
|
|
11
|
+
saturation: [65, 80]
|
|
12
|
+
lightness: [50, 60]
|
|
13
|
+
on_color:
|
|
14
|
+
reference: "#FFFFFF"
|
|
15
|
+
contrast_min: 4.5
|
|
16
|
+
|
|
17
|
+
secondary:
|
|
18
|
+
semantic: "Accent for highlights, badges, urgency"
|
|
19
|
+
reference: "#E8634F"
|
|
20
|
+
range:
|
|
21
|
+
hue: [10, 18]
|
|
22
|
+
saturation: [70, 85]
|
|
23
|
+
lightness: [50, 60]
|
|
24
|
+
on_color:
|
|
25
|
+
reference: "#FFFFFF"
|
|
26
|
+
contrast_min: 4.5
|
|
27
|
+
|
|
28
|
+
surface:
|
|
29
|
+
primary:
|
|
30
|
+
semantic: "Main content background"
|
|
31
|
+
reference: "#FFFFFF"
|
|
32
|
+
secondary:
|
|
33
|
+
semantic: "Card and grouped backgrounds"
|
|
34
|
+
reference: "#F7F6F3"
|
|
35
|
+
tertiary:
|
|
36
|
+
semantic: "Page canvas behind content"
|
|
37
|
+
reference: "#EFEEE8"
|
|
38
|
+
|
|
39
|
+
text:
|
|
40
|
+
primary:
|
|
41
|
+
semantic: "Headings, body text, high emphasis"
|
|
42
|
+
reference: "#1C1B1A"
|
|
43
|
+
contrast_min: 7.0
|
|
44
|
+
secondary:
|
|
45
|
+
semantic: "Supporting text, descriptions"
|
|
46
|
+
reference: "#6B6966"
|
|
47
|
+
contrast_min: 4.5
|
|
48
|
+
tertiary:
|
|
49
|
+
semantic: "Placeholders, hints, timestamps"
|
|
50
|
+
reference: "#9C9A94"
|
|
51
|
+
contrast_min: 3.0
|
|
52
|
+
disabled:
|
|
53
|
+
semantic: "Non-interactive labels"
|
|
54
|
+
reference: "#C8C6C1"
|
|
55
|
+
|
|
56
|
+
semantic:
|
|
57
|
+
success:
|
|
58
|
+
reference: "#2D9D5E"
|
|
59
|
+
range: { hue: [145, 155], saturation: [55, 70], lightness: [35, 45] }
|
|
60
|
+
on_color: { reference: "#FFFFFF", contrast_min: 4.5 }
|
|
61
|
+
warning:
|
|
62
|
+
reference: "#D4920E"
|
|
63
|
+
range: { hue: [38, 45], saturation: [85, 95], lightness: [40, 50] }
|
|
64
|
+
on_color: { reference: "#FFFFFF", contrast_min: 3.0 }
|
|
65
|
+
danger:
|
|
66
|
+
reference: "#D43B3B"
|
|
67
|
+
range: { hue: [0, 8], saturation: [65, 80], lightness: [45, 55] }
|
|
68
|
+
on_color: { reference: "#FFFFFF", contrast_min: 4.5 }
|
|
69
|
+
info:
|
|
70
|
+
reference: "#3B82D4"
|
|
71
|
+
range: { hue: [210, 220], saturation: [60, 75], lightness: [45, 55] }
|
|
72
|
+
on_color: { reference: "#FFFFFF", contrast_min: 4.5 }
|
|
73
|
+
|
|
74
|
+
border:
|
|
75
|
+
default: { reference: "#E5E3DE", opacity: 0.15 }
|
|
76
|
+
emphasis: { reference: "#D1CFCA", opacity: 0.3 }
|
|
77
|
+
|
|
78
|
+
# App-specific semantic colors
|
|
79
|
+
priority:
|
|
80
|
+
low: { reference: "#9CA3AF", semantic: "Low priority indicator" }
|
|
81
|
+
medium: { reference: "#3B82D4", semantic: "Medium priority indicator" }
|
|
82
|
+
high: { reference: "#D4920E", semantic: "High priority indicator" }
|
|
83
|
+
urgent: { reference: "#D43B3B", semantic: "Urgent priority indicator" }
|
|
84
|
+
|
|
85
|
+
status:
|
|
86
|
+
todo: { reference: "#9CA3AF", semantic: "Not started" }
|
|
87
|
+
in_progress: { reference: "#5B4FE8", semantic: "Currently active" }
|
|
88
|
+
done: { reference: "#2D9D5E", semantic: "Completed" }
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# TaskFlow — Elevation Tokens
|
|
2
|
+
|
|
3
|
+
elevation:
|
|
4
|
+
none:
|
|
5
|
+
semantic: "Flat, no shadow"
|
|
6
|
+
value: "none"
|
|
7
|
+
|
|
8
|
+
sm:
|
|
9
|
+
semantic: "Subtle lift for hover states, input focus"
|
|
10
|
+
platform:
|
|
11
|
+
ios: { shadow: { color: "black", opacity: 0.04, radius: 2, y: 1 } }
|
|
12
|
+
android: { elevation: 1 }
|
|
13
|
+
web: { box_shadow: "0 1px 2px rgba(0,0,0,0.04)" }
|
|
14
|
+
|
|
15
|
+
md:
|
|
16
|
+
semantic: "Cards, toasts, popovers"
|
|
17
|
+
platform:
|
|
18
|
+
ios: { shadow: { color: "black", opacity: 0.08, radius: 8, y: 2 } }
|
|
19
|
+
android: { elevation: 3 }
|
|
20
|
+
web: { box_shadow: "0 2px 8px rgba(0,0,0,0.08)" }
|
|
21
|
+
|
|
22
|
+
lg:
|
|
23
|
+
semantic: "FABs, modals, sheets"
|
|
24
|
+
platform:
|
|
25
|
+
ios: { shadow: { color: "black", opacity: 0.12, radius: 16, y: 4 } }
|
|
26
|
+
android: { elevation: 6 }
|
|
27
|
+
web: { box_shadow: "0 4px 16px rgba(0,0,0,0.12)" }
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
# TaskFlow — Icon Tokens
|
|
2
|
+
|
|
3
|
+
icons:
|
|
4
|
+
sizes:
|
|
5
|
+
sm:
|
|
6
|
+
semantic: "Inline indicators, badge icons"
|
|
7
|
+
value: 16
|
|
8
|
+
md:
|
|
9
|
+
semantic: "Default icon size for actions and list items"
|
|
10
|
+
value: 20
|
|
11
|
+
lg:
|
|
12
|
+
semantic: "Prominent icons, empty states, section headers"
|
|
13
|
+
value: 24
|
|
14
|
+
xl:
|
|
15
|
+
semantic: "Hero icons, onboarding illustrations"
|
|
16
|
+
value: 32
|
|
17
|
+
|
|
18
|
+
variants:
|
|
19
|
+
default: "outline"
|
|
20
|
+
suffixes:
|
|
21
|
+
_fill: "Filled/solid variant — used for selected or active states"
|
|
22
|
+
|
|
23
|
+
fallback:
|
|
24
|
+
strategy: "name_passthrough"
|
|
25
|
+
missing_icon: "questionmark_circle"
|
|
26
|
+
|
|
27
|
+
registry:
|
|
28
|
+
navigation:
|
|
29
|
+
chevron_right:
|
|
30
|
+
semantic: "Navigate forward, disclosure indicator"
|
|
31
|
+
platform:
|
|
32
|
+
ios: "chevron.right"
|
|
33
|
+
android: "chevron_right"
|
|
34
|
+
web: "chevron-right"
|
|
35
|
+
chevron_left:
|
|
36
|
+
semantic: "Navigate back"
|
|
37
|
+
platform:
|
|
38
|
+
ios: "chevron.left"
|
|
39
|
+
android: "chevron_left"
|
|
40
|
+
web: "chevron-left"
|
|
41
|
+
arrow_uturn_left:
|
|
42
|
+
semantic: "Undo, revert to previous state"
|
|
43
|
+
platform:
|
|
44
|
+
ios: "arrow.uturn.left"
|
|
45
|
+
android: "undo"
|
|
46
|
+
web: "undo-2"
|
|
47
|
+
|
|
48
|
+
actions:
|
|
49
|
+
plus:
|
|
50
|
+
semantic: "Create new item"
|
|
51
|
+
variants: ["circle"]
|
|
52
|
+
platform:
|
|
53
|
+
ios: "plus"
|
|
54
|
+
android: "add"
|
|
55
|
+
web: "plus"
|
|
56
|
+
pencil:
|
|
57
|
+
semantic: "Edit, modify content"
|
|
58
|
+
platform:
|
|
59
|
+
ios: "pencil"
|
|
60
|
+
android: "edit"
|
|
61
|
+
web: "pencil"
|
|
62
|
+
trash:
|
|
63
|
+
semantic: "Delete, remove item"
|
|
64
|
+
platform:
|
|
65
|
+
ios: "trash"
|
|
66
|
+
android: "delete"
|
|
67
|
+
web: "trash-2"
|
|
68
|
+
search:
|
|
69
|
+
semantic: "Search, find content"
|
|
70
|
+
platform:
|
|
71
|
+
ios: "magnifyingglass"
|
|
72
|
+
android: "search"
|
|
73
|
+
web: "search"
|
|
74
|
+
checkmark:
|
|
75
|
+
semantic: "Confirm, complete, done"
|
|
76
|
+
variants: ["circle", "circle_fill", "list"]
|
|
77
|
+
platform:
|
|
78
|
+
ios: "checkmark"
|
|
79
|
+
android: "check"
|
|
80
|
+
web: "check"
|
|
81
|
+
square_arrow_up:
|
|
82
|
+
semantic: "Share, export content"
|
|
83
|
+
platform:
|
|
84
|
+
ios: "square.and.arrow.up"
|
|
85
|
+
android: "share"
|
|
86
|
+
web: "share"
|
|
87
|
+
|
|
88
|
+
status:
|
|
89
|
+
flag:
|
|
90
|
+
semantic: "Priority indicator, flagged item"
|
|
91
|
+
variants: ["fill"]
|
|
92
|
+
platform:
|
|
93
|
+
ios: "flag"
|
|
94
|
+
android: "flag"
|
|
95
|
+
web: "flag"
|
|
96
|
+
circle_fill:
|
|
97
|
+
semantic: "Status dot, filled indicator"
|
|
98
|
+
platform:
|
|
99
|
+
ios: "circle.fill"
|
|
100
|
+
android: "circle"
|
|
101
|
+
web: "circle"
|
|
102
|
+
exclamationmark_triangle:
|
|
103
|
+
semantic: "Warning, caution, attention needed"
|
|
104
|
+
platform:
|
|
105
|
+
ios: "exclamationmark.triangle"
|
|
106
|
+
android: "warning"
|
|
107
|
+
web: "alert-triangle"
|
|
108
|
+
|
|
109
|
+
objects:
|
|
110
|
+
folder:
|
|
111
|
+
semantic: "Project, collection, file group"
|
|
112
|
+
variants: ["fill"]
|
|
113
|
+
platform:
|
|
114
|
+
ios: "folder"
|
|
115
|
+
android: "folder"
|
|
116
|
+
web: "folder"
|
|
117
|
+
calendar:
|
|
118
|
+
semantic: "Date, schedule, due date"
|
|
119
|
+
variants: ["fill"]
|
|
120
|
+
platform:
|
|
121
|
+
ios: "calendar"
|
|
122
|
+
android: "calendar_today"
|
|
123
|
+
web: "calendar"
|
|
124
|
+
clock:
|
|
125
|
+
semantic: "Time, duration, recent"
|
|
126
|
+
platform:
|
|
127
|
+
ios: "clock"
|
|
128
|
+
android: "schedule"
|
|
129
|
+
web: "clock"
|
|
130
|
+
tag:
|
|
131
|
+
semantic: "Label, category, classification"
|
|
132
|
+
platform:
|
|
133
|
+
ios: "tag"
|
|
134
|
+
android: "label"
|
|
135
|
+
web: "tag"
|
|
136
|
+
gear:
|
|
137
|
+
semantic: "Settings, configuration, preferences"
|
|
138
|
+
variants: ["fill"]
|
|
139
|
+
platform:
|
|
140
|
+
ios: "gear"
|
|
141
|
+
android: "settings"
|
|
142
|
+
web: "settings"
|
|
143
|
+
person:
|
|
144
|
+
semantic: "User, profile, assignee"
|
|
145
|
+
platform:
|
|
146
|
+
ios: "person"
|
|
147
|
+
android: "person"
|
|
148
|
+
web: "user"
|
|
149
|
+
|
|
150
|
+
content:
|
|
151
|
+
briefcase:
|
|
152
|
+
semantic: "Work, professional context"
|
|
153
|
+
platform:
|
|
154
|
+
ios: "briefcase"
|
|
155
|
+
android: "work"
|
|
156
|
+
web: "briefcase"
|
|
157
|
+
rocket:
|
|
158
|
+
semantic: "Launch, progress, momentum"
|
|
159
|
+
platform:
|
|
160
|
+
ios: "rocket"
|
|
161
|
+
android: "rocket_launch"
|
|
162
|
+
web: "rocket"
|
|
163
|
+
star:
|
|
164
|
+
semantic: "Favorite, important, featured"
|
|
165
|
+
platform:
|
|
166
|
+
ios: "star"
|
|
167
|
+
android: "star"
|
|
168
|
+
web: "star"
|
|
169
|
+
heart:
|
|
170
|
+
semantic: "Like, love, health"
|
|
171
|
+
platform:
|
|
172
|
+
ios: "heart"
|
|
173
|
+
android: "favorite"
|
|
174
|
+
web: "heart"
|
|
175
|
+
lightbulb:
|
|
176
|
+
semantic: "Idea, tip, suggestion"
|
|
177
|
+
platform:
|
|
178
|
+
ios: "lightbulb"
|
|
179
|
+
android: "lightbulb"
|
|
180
|
+
web: "lightbulb"
|
|
181
|
+
|
|
182
|
+
custom:
|
|
183
|
+
taskflow:
|
|
184
|
+
checkmark_list:
|
|
185
|
+
semantic: "Task list, todo checklist"
|
|
186
|
+
platform:
|
|
187
|
+
ios: "checklist"
|
|
188
|
+
android: "checklist"
|
|
189
|
+
web: "list-checks"
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
# TaskFlow — Layout Tokens
|
|
2
|
+
# Defines size classes, layout primitives, and adaptive rules
|
|
3
|
+
|
|
4
|
+
layout:
|
|
5
|
+
# ============================================================
|
|
6
|
+
# Size classes — the universal breakpoint vocabulary
|
|
7
|
+
# ============================================================
|
|
8
|
+
# Every platform maps to these same semantic classes.
|
|
9
|
+
# Screens and sections reference size classes by name,
|
|
10
|
+
# never by pixel value.
|
|
11
|
+
# ============================================================
|
|
12
|
+
size_classes:
|
|
13
|
+
compact:
|
|
14
|
+
semantic: "Single-column, phone-first layout"
|
|
15
|
+
width: { max: 600 }
|
|
16
|
+
columns: 4
|
|
17
|
+
margin: "spacing.md"
|
|
18
|
+
content_max_width: null # full width
|
|
19
|
+
examples: "iPhone portrait, small Android phones"
|
|
20
|
+
|
|
21
|
+
regular:
|
|
22
|
+
semantic: "Two-column capable, tablet and large phone layouts"
|
|
23
|
+
width: { min: 601, max: 1024 }
|
|
24
|
+
columns: 8
|
|
25
|
+
margin: "spacing.lg"
|
|
26
|
+
content_max_width: 840
|
|
27
|
+
examples: "iPad portrait, large phones landscape, small tablets"
|
|
28
|
+
|
|
29
|
+
expanded:
|
|
30
|
+
semantic: "Multi-column, desktop and large tablet layouts"
|
|
31
|
+
width: { min: 1025 }
|
|
32
|
+
columns: 12
|
|
33
|
+
margin: "spacing.xl"
|
|
34
|
+
content_max_width: 1200
|
|
35
|
+
examples: "iPad landscape, desktop browsers, large tablets"
|
|
36
|
+
|
|
37
|
+
# How each platform resolves size classes
|
|
38
|
+
platform_mapping:
|
|
39
|
+
ios:
|
|
40
|
+
uses: "UIUserInterfaceSizeClass"
|
|
41
|
+
compact: ".compact horizontal"
|
|
42
|
+
regular: ".regular horizontal"
|
|
43
|
+
expanded: ".regular horizontal + width > 1024"
|
|
44
|
+
android:
|
|
45
|
+
uses: "WindowSizeClass"
|
|
46
|
+
compact: "WindowWidthSizeClass.Compact"
|
|
47
|
+
regular: "WindowWidthSizeClass.Medium"
|
|
48
|
+
expanded: "WindowWidthSizeClass.Expanded"
|
|
49
|
+
web:
|
|
50
|
+
uses: "media queries"
|
|
51
|
+
compact: "@media (max-width: 600px)"
|
|
52
|
+
regular: "@media (min-width: 601px) and (max-width: 1024px)"
|
|
53
|
+
expanded: "@media (min-width: 1025px)"
|
|
54
|
+
|
|
55
|
+
# ============================================================
|
|
56
|
+
# Layout primitives — the building blocks
|
|
57
|
+
# ============================================================
|
|
58
|
+
primitives:
|
|
59
|
+
stack:
|
|
60
|
+
semantic: "Vertical arrangement, items flow top to bottom"
|
|
61
|
+
props:
|
|
62
|
+
spacing: { type: token_ref, default: "spacing.md" }
|
|
63
|
+
align: { type: enum, values: [leading, center, trailing, stretch], default: stretch }
|
|
64
|
+
padding: { type: token_ref, required: false }
|
|
65
|
+
platform_mapping:
|
|
66
|
+
ios: "VStack"
|
|
67
|
+
android: "Column"
|
|
68
|
+
web: "flex-direction: column"
|
|
69
|
+
|
|
70
|
+
row:
|
|
71
|
+
semantic: "Horizontal arrangement, items flow leading to trailing"
|
|
72
|
+
props:
|
|
73
|
+
spacing: { type: token_ref, default: "spacing.sm" }
|
|
74
|
+
align: { type: enum, values: [top, center, bottom, baseline, stretch], default: center }
|
|
75
|
+
justify: { type: enum, values: [start, center, end, space-between, space-around], default: start }
|
|
76
|
+
wrap: { type: bool, default: false }
|
|
77
|
+
platform_mapping:
|
|
78
|
+
ios: "HStack"
|
|
79
|
+
android: "Row"
|
|
80
|
+
web: "flex-direction: row"
|
|
81
|
+
|
|
82
|
+
grid:
|
|
83
|
+
semantic: "2D grid with defined columns"
|
|
84
|
+
props:
|
|
85
|
+
columns: { type: "int or adaptive_map", default: 2 }
|
|
86
|
+
gap: { type: token_ref, default: "spacing.md" }
|
|
87
|
+
item_min_width: { type: int, required: false }
|
|
88
|
+
platform_mapping:
|
|
89
|
+
ios: "LazyVGrid"
|
|
90
|
+
android: "LazyVerticalGrid"
|
|
91
|
+
web: "display: grid"
|
|
92
|
+
|
|
93
|
+
scroll_vertical:
|
|
94
|
+
semantic: "Vertically scrollable content area"
|
|
95
|
+
props:
|
|
96
|
+
safe_area: { type: bool, default: true }
|
|
97
|
+
padding: { type: token_ref, required: false }
|
|
98
|
+
refresh: { type: bool, default: false }
|
|
99
|
+
platform_mapping:
|
|
100
|
+
ios: "ScrollView(.vertical)"
|
|
101
|
+
android: "LazyColumn or verticalScroll"
|
|
102
|
+
web: "overflow-y: auto"
|
|
103
|
+
|
|
104
|
+
split_view:
|
|
105
|
+
semantic: "Side-by-side panes for master-detail layouts"
|
|
106
|
+
props:
|
|
107
|
+
primary_width: { type: "fraction or token_ref", default: 0.35 }
|
|
108
|
+
divider: { type: bool, default: true }
|
|
109
|
+
collapse_at: { type: size_class, default: "compact" }
|
|
110
|
+
platform_mapping:
|
|
111
|
+
ios: "NavigationSplitView"
|
|
112
|
+
android: "ListDetailPaneScaffold"
|
|
113
|
+
web: "CSS Grid with two columns"
|
|
114
|
+
|
|
115
|
+
adaptive:
|
|
116
|
+
semantic: "Changes arrangement based on size class"
|
|
117
|
+
props:
|
|
118
|
+
compact: { type: layout_ref, required: true }
|
|
119
|
+
regular: { type: layout_ref, required: false }
|
|
120
|
+
expanded: { type: layout_ref, required: false }
|
|
121
|
+
behavior: "Falls back to nearest smaller class if not specified"
|
|
122
|
+
|
|
123
|
+
# ============================================================
|
|
124
|
+
# Content reflow rules
|
|
125
|
+
# ============================================================
|
|
126
|
+
# These define how content behaves when crossing size class
|
|
127
|
+
# boundaries. AI generators should apply these automatically.
|
|
128
|
+
# ============================================================
|
|
129
|
+
reflow_rules:
|
|
130
|
+
# Full-width buttons become inline on larger screens
|
|
131
|
+
action_trigger:
|
|
132
|
+
compact: { full_width: true }
|
|
133
|
+
regular: { full_width: false }
|
|
134
|
+
|
|
135
|
+
# Single column becomes multi-column
|
|
136
|
+
collection_grid:
|
|
137
|
+
compact: { columns: 1 }
|
|
138
|
+
regular: { columns: 2 }
|
|
139
|
+
expanded: { columns: 3 }
|
|
140
|
+
|
|
141
|
+
# Stacked stat cards become horizontal row
|
|
142
|
+
stat_group:
|
|
143
|
+
compact: { layout: stack, max_per_row: 2 }
|
|
144
|
+
regular: { layout: row }
|
|
145
|
+
expanded: { layout: row }
|
|
146
|
+
|
|
147
|
+
# Navigation adapts
|
|
148
|
+
nav_container:
|
|
149
|
+
compact: { variant: "tab_bar" }
|
|
150
|
+
regular: { variant: "rail" }
|
|
151
|
+
expanded: { variant: "sidebar" }
|
|
152
|
+
|
|
153
|
+
# Sheets become side panels on larger screens
|
|
154
|
+
surface_sheet:
|
|
155
|
+
compact: { variant: "sheet" }
|
|
156
|
+
expanded: { variant: "panel" }
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# TaskFlow — Motion Tokens
|
|
2
|
+
|
|
3
|
+
motion:
|
|
4
|
+
duration:
|
|
5
|
+
instant: 100
|
|
6
|
+
quick: 200
|
|
7
|
+
normal: 300
|
|
8
|
+
slow: 500
|
|
9
|
+
|
|
10
|
+
easing:
|
|
11
|
+
default: "ease-out"
|
|
12
|
+
enter: "ease-out"
|
|
13
|
+
exit: "ease-in"
|
|
14
|
+
emphasis: "cubic-bezier(0.2, 0, 0, 1)"
|
|
15
|
+
|
|
16
|
+
reduced_motion: "remove-animation"
|
|
17
|
+
|
|
18
|
+
patterns:
|
|
19
|
+
press_feedback:
|
|
20
|
+
duration: "instant"
|
|
21
|
+
property: "scale"
|
|
22
|
+
value: 0.97
|
|
23
|
+
state_change:
|
|
24
|
+
duration: "quick"
|
|
25
|
+
property: "opacity, background"
|
|
26
|
+
screen_enter:
|
|
27
|
+
duration: "normal"
|
|
28
|
+
easing: "enter"
|
|
29
|
+
pattern: "slide-from-trailing"
|
|
30
|
+
screen_exit:
|
|
31
|
+
duration: "quick"
|
|
32
|
+
easing: "exit"
|
|
33
|
+
pattern: "slide-to-leading"
|
|
34
|
+
checkbox_check:
|
|
35
|
+
duration: "quick"
|
|
36
|
+
easing: "emphasis"
|
|
37
|
+
pattern: "scale-bounce"
|
|
38
|
+
list_reorder:
|
|
39
|
+
duration: "normal"
|
|
40
|
+
easing: "emphasis"
|
|
41
|
+
pattern: "layout-shift"
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# TaskFlow — Spacing Tokens
|
|
2
|
+
|
|
3
|
+
spacing:
|
|
4
|
+
base_unit: 4
|
|
5
|
+
platform_flex: 0.15
|
|
6
|
+
|
|
7
|
+
scale:
|
|
8
|
+
none: 0
|
|
9
|
+
xxs: 2
|
|
10
|
+
xs: 4
|
|
11
|
+
sm: 8
|
|
12
|
+
md: { base: 16, range: [12, 16] }
|
|
13
|
+
lg: { base: 24, range: [20, 24] }
|
|
14
|
+
xl: 32
|
|
15
|
+
xxl: 48
|
|
16
|
+
xxxl: 64
|
|
17
|
+
|
|
18
|
+
aliases:
|
|
19
|
+
page_margin: { horizontal: md, vertical: md }
|
|
20
|
+
card_padding: { all: md }
|
|
21
|
+
section_gap: lg
|
|
22
|
+
inline_gap: sm
|
|
23
|
+
stack_gap: md
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# TaskFlow — Themes
|
|
2
|
+
|
|
3
|
+
themes:
|
|
4
|
+
default: "light"
|
|
5
|
+
|
|
6
|
+
variants:
|
|
7
|
+
light:
|
|
8
|
+
surface.primary: { lightness: [98, 100] }
|
|
9
|
+
surface.secondary: { lightness: [94, 97] }
|
|
10
|
+
surface.tertiary: { lightness: [90, 93] }
|
|
11
|
+
text.primary: { lightness: [5, 12] }
|
|
12
|
+
text.secondary: { lightness: [38, 45] }
|
|
13
|
+
text.tertiary: { lightness: [58, 64] }
|
|
14
|
+
border.default: { opacity: 0.12 }
|
|
15
|
+
|
|
16
|
+
dark:
|
|
17
|
+
surface.primary: { lightness: [10, 14] }
|
|
18
|
+
surface.secondary: { lightness: [14, 19] }
|
|
19
|
+
surface.tertiary: { lightness: [7, 11] }
|
|
20
|
+
text.primary: { lightness: [88, 95] }
|
|
21
|
+
text.secondary: { lightness: [58, 66] }
|
|
22
|
+
text.tertiary: { lightness: [42, 50] }
|
|
23
|
+
border.default: { opacity: 0.18 }
|
|
24
|
+
|
|
25
|
+
# Warm-tinted brand variant
|
|
26
|
+
warm:
|
|
27
|
+
extends: "light"
|
|
28
|
+
surface.primary: { hue: 38, saturation: [4, 8], lightness: [96, 99] }
|
|
29
|
+
surface.secondary: { hue: 38, saturation: [4, 8], lightness: [92, 96] }
|
|
30
|
+
|
|
31
|
+
platform:
|
|
32
|
+
ios: { supports_dynamic: true, system_materials: true }
|
|
33
|
+
android: { material_you: true, dynamic_color: true }
|
|
34
|
+
web: { prefers_color_scheme: true, css_custom_properties: true }
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# TaskFlow — Typography Tokens
|
|
2
|
+
|
|
3
|
+
typography:
|
|
4
|
+
font_family:
|
|
5
|
+
primary:
|
|
6
|
+
semantic: "All UI text"
|
|
7
|
+
value: "DM Sans"
|
|
8
|
+
fallback_strategy: "geometric-sans"
|
|
9
|
+
platform:
|
|
10
|
+
ios: { system_alternative: "SF Pro" }
|
|
11
|
+
android: { system_alternative: "Google Sans" }
|
|
12
|
+
web: { load_strategy: "swap", source: "google_fonts" }
|
|
13
|
+
|
|
14
|
+
scale:
|
|
15
|
+
display:
|
|
16
|
+
semantic: "Onboarding hero, empty states"
|
|
17
|
+
size: { base: 32, range: [28, 36] }
|
|
18
|
+
weight: 700
|
|
19
|
+
tracking: -0.02
|
|
20
|
+
line_height: 1.2
|
|
21
|
+
heading_lg:
|
|
22
|
+
semantic: "Screen titles"
|
|
23
|
+
size: { base: 24, range: [22, 26] }
|
|
24
|
+
weight: 600
|
|
25
|
+
tracking: -0.015
|
|
26
|
+
line_height: 1.3
|
|
27
|
+
heading:
|
|
28
|
+
semantic: "Section headers"
|
|
29
|
+
size: { base: 20, range: [18, 22] }
|
|
30
|
+
weight: 600
|
|
31
|
+
tracking: -0.01
|
|
32
|
+
line_height: 1.35
|
|
33
|
+
heading_sm:
|
|
34
|
+
semantic: "Card titles, list group headers"
|
|
35
|
+
size: { base: 16, range: [15, 17] }
|
|
36
|
+
weight: 600
|
|
37
|
+
line_height: 1.4
|
|
38
|
+
body:
|
|
39
|
+
semantic: "Primary readable text"
|
|
40
|
+
size: { base: 16, range: [14, 16] }
|
|
41
|
+
weight: 400
|
|
42
|
+
line_height: 1.5
|
|
43
|
+
body_sm:
|
|
44
|
+
semantic: "Secondary text, descriptions"
|
|
45
|
+
size: { base: 14, range: [13, 15] }
|
|
46
|
+
weight: 400
|
|
47
|
+
tracking: 0.005
|
|
48
|
+
line_height: 1.45
|
|
49
|
+
caption:
|
|
50
|
+
semantic: "Labels, timestamps, metadata"
|
|
51
|
+
size: { base: 12, range: [11, 13] }
|
|
52
|
+
weight: 400
|
|
53
|
+
tracking: 0.02
|
|
54
|
+
line_height: 1.35
|
|
55
|
+
overline:
|
|
56
|
+
semantic: "Section tags, category labels"
|
|
57
|
+
size: { base: 11, range: [10, 12] }
|
|
58
|
+
weight: 600
|
|
59
|
+
tracking: 0.08
|
|
60
|
+
transform: uppercase
|
|
61
|
+
line_height: 1.3
|
package/package.json
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "openuispec",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "A semantic UI specification format for AI-native, platform-native app development",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "https://github.com/rsktash/openuispec.git"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"cli/",
|
|
12
|
+
"drift/",
|
|
13
|
+
"schema/",
|
|
14
|
+
"spec/",
|
|
15
|
+
"examples/",
|
|
16
|
+
"README.md",
|
|
17
|
+
"LICENSE"
|
|
18
|
+
],
|
|
19
|
+
"bin": {
|
|
20
|
+
"openuispec": "./cli/index.ts"
|
|
21
|
+
},
|
|
22
|
+
"scripts": {
|
|
23
|
+
"validate": "tsx schema/validate.ts",
|
|
24
|
+
"validate:manifest": "tsx schema/validate.ts manifest",
|
|
25
|
+
"validate:tokens": "tsx schema/validate.ts tokens",
|
|
26
|
+
"validate:screens": "tsx schema/validate.ts screens",
|
|
27
|
+
"validate:flows": "tsx schema/validate.ts flows",
|
|
28
|
+
"validate:platform": "tsx schema/validate.ts platform",
|
|
29
|
+
"validate:locales": "tsx schema/validate.ts locales",
|
|
30
|
+
"drift": "tsx drift/index.ts",
|
|
31
|
+
"drift:snapshot": "tsx drift/index.ts --snapshot --target"
|
|
32
|
+
},
|
|
33
|
+
"dependencies": {
|
|
34
|
+
"tsx": "^4.19.4",
|
|
35
|
+
"yaml": "^2.7.1"
|
|
36
|
+
},
|
|
37
|
+
"devDependencies": {
|
|
38
|
+
"@types/node": "^25.5.0",
|
|
39
|
+
"ajv": "^8.17.1",
|
|
40
|
+
"ajv-formats": "^3.0.1",
|
|
41
|
+
"typescript": "^5.8.3"
|
|
42
|
+
}
|
|
43
|
+
}
|