@vectoriox/iox-ui 5.50.0 → 5.52.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.
@@ -1695,6 +1695,7 @@ export const SPEC_STYLE_PRESETS = [
1695
1695
  "Minimalism & Swiss Style"
1696
1696
  ],
1697
1697
  "blurb": "Clean, light and easy to read. Says \"you are in good hands\".",
1698
+ "blurbHe": "נקי, בהיר וקל לקריאה. אומר \"אתם בידיים טובות\".",
1698
1699
  "slice": true
1699
1700
  },
1700
1701
  {
@@ -1727,6 +1728,7 @@ export const SPEC_STYLE_PRESETS = [
1727
1728
  "Swiss Modernism 2.0"
1728
1729
  ],
1729
1730
  "blurb": "Black on white, a strict grid, nothing extra.",
1731
+ "blurbHe": "שחור על לבן, גריד קפדני, בלי שום תוספות.",
1730
1732
  "slice": true
1731
1733
  },
1732
1734
  {
@@ -1757,6 +1759,7 @@ export const SPEC_STYLE_PRESETS = [
1757
1759
  "Trust & Authority (landing)"
1758
1760
  ],
1759
1761
  "blurb": "Navy, plain type, firm edges. Serious without being cold.",
1762
+ "blurbHe": "כחול כהה, אותיות פשוטות ופינות חדות. רציני, אבל לא קר.",
1760
1763
  "slice": true
1761
1764
  },
1762
1765
  {
@@ -1788,6 +1791,7 @@ export const SPEC_STYLE_PRESETS = [
1788
1791
  "Accessible & Ethical"
1789
1792
  ],
1790
1793
  "blurb": "Bright, soft and reassuring, with rounded buttons.",
1794
+ "blurbHe": "בהיר, רך ומרגיע, עם כפתורים מעוגלים.",
1791
1795
  "slice": false
1792
1796
  },
1793
1797
  {
@@ -1820,6 +1824,7 @@ export const SPEC_STYLE_PRESETS = [
1820
1824
  "Editorial Grid / Magazine"
1821
1825
  ],
1822
1826
  "blurb": "White walls and a quiet serif. The work does the talking.",
1827
+ "blurbHe": "קירות לבנים וסריף שקט. העבודות מדברות בעד עצמן.",
1823
1828
  "slice": true
1824
1829
  },
1825
1830
  {
@@ -1851,6 +1856,7 @@ export const SPEC_STYLE_PRESETS = [
1851
1856
  "Nature Distilled"
1852
1857
  ],
1853
1858
  "blurb": "Cream paper, terracotta and a soft serif, like a good magazine.",
1859
+ "blurbHe": "נייר בצבע שמנת, טרקוטה וסריף רך, כמו מגזין טוב.",
1854
1860
  "slice": true
1855
1861
  },
1856
1862
  {
@@ -1882,6 +1888,7 @@ export const SPEC_STYLE_PRESETS = [
1882
1888
  "Nature Distilled"
1883
1889
  ],
1884
1890
  "blurb": "Rose-tinted cream, a fine serif and slow, gentle motion.",
1891
+ "blurbHe": "שמנת בגוון ורוד, סריף עדין ותנועה איטית ורכה.",
1885
1892
  "slice": true
1886
1893
  },
1887
1894
  {
@@ -1914,6 +1921,7 @@ export const SPEC_STYLE_PRESETS = [
1914
1921
  "Liquid Glass (luxury rows, without the glass)"
1915
1922
  ],
1916
1923
  "blurb": "Bronze on warm white. Expensive, never loud.",
1924
+ "blurbHe": "ברונזה על לבן חם. יוקרתי, אבל אף פעם לא צעקני.",
1917
1925
  "slice": false
1918
1926
  },
1919
1927
  {
@@ -1945,6 +1953,7 @@ export const SPEC_STYLE_PRESETS = [
1945
1953
  "Vibrant & Block-based"
1946
1954
  ],
1947
1955
  "blurb": "A night out: dark rooms, one bright colour, lively motion.",
1956
+ "blurbHe": "יציאה בלילה: חללים כהים, צבע בוהק אחד ותנועה תוססת.",
1948
1957
  "slice": false
1949
1958
  },
1950
1959
  {
@@ -1976,6 +1985,7 @@ export const SPEC_STYLE_PRESETS = [
1976
1985
  "Brutalism"
1977
1986
  ],
1978
1987
  "blurb": "Black, sharp and orange. A shop with attitude.",
1988
+ "blurbHe": "שחור, חד וכתום. עסק עם אופי.",
1979
1989
  "slice": false
1980
1990
  },
1981
1991
  {
@@ -2008,6 +2018,7 @@ export const SPEC_STYLE_PRESETS = [
2008
2018
  "Minimalism & Swiss Style"
2009
2019
  ],
2010
2020
  "blurb": "Pictures on black, like a darkened gallery.",
2021
+ "blurbHe": "תמונות על רקע שחור, כמו בגלריה חשוכה.",
2011
2022
  "slice": true
2012
2023
  },
2013
2024
  {
@@ -2040,6 +2051,7 @@ export const SPEC_STYLE_PRESETS = [
2040
2051
  "Minimalism & Swiss Style"
2041
2052
  ],
2042
2053
  "blurb": "Dark, precise and modern, for people who build things.",
2054
+ "blurbHe": "כהה, מדויק ועכשווי, לאנשים שבונים דברים.",
2043
2055
  "slice": false
2044
2056
  },
2045
2057
  {
@@ -2071,6 +2083,7 @@ export const SPEC_STYLE_PRESETS = [
2071
2083
  "Soft UI Evolution"
2072
2084
  ],
2073
2085
  "blurb": "Frosted panels over a soft teal light. Fresh and calm.",
2086
+ "blurbHe": "משטחי זכוכית חלבית על אור טורקיז רך. רענן ורגוע.",
2074
2087
  "slice": true
2075
2088
  },
2076
2089
  {
@@ -2101,6 +2114,7 @@ export const SPEC_STYLE_PRESETS = [
2101
2114
  "Glassmorphism"
2102
2115
  ],
2103
2116
  "blurb": "Sea-blue glass and big photos. Makes people want to go.",
2117
+ "blurbHe": "זכוכית בכחול של ים ותמונות גדולות. מעורר חשק לנסוע.",
2104
2118
  "slice": false
2105
2119
  },
2106
2120
  {
@@ -2132,6 +2146,7 @@ export const SPEC_STYLE_PRESETS = [
2132
2146
  "Spatial UI (VisionOS)"
2133
2147
  ],
2134
2148
  "blurb": "Grey glass and lots of space around your pictures.",
2149
+ "blurbHe": "זכוכית אפורה והרבה מרחב סביב התמונות שלכם.",
2135
2150
  "slice": true
2136
2151
  },
2137
2152
  {
@@ -2162,6 +2177,7 @@ export const SPEC_STYLE_PRESETS = [
2162
2177
  "Vibrant & Block-based"
2163
2178
  ],
2164
2179
  "blurb": "Warm coral and bouncy buttons. Full of energy.",
2180
+ "blurbHe": "אלמוג חם וכפתורים קופצניים. מלא אנרגיה.",
2165
2181
  "slice": false
2166
2182
  },
2167
2183
  {
@@ -2193,6 +2209,7 @@ export const SPEC_STYLE_PRESETS = [
2193
2209
  "Soft UI Evolution"
2194
2210
  ],
2195
2211
  "blurb": "Berry red, round shapes, a cheerful headline face.",
2212
+ "blurbHe": "אדום פירות יער, צורות עגולות ופונט כותרות עליז.",
2196
2213
  "slice": true
2197
2214
  },
2198
2215
  {
@@ -2224,6 +2241,7 @@ export const SPEC_STYLE_PRESETS = [
2224
2241
  "Organic Biophilic"
2225
2242
  ],
2226
2243
  "blurb": "Leaf green and soft, open shapes. Welcoming to everyone.",
2244
+ "blurbHe": "ירוק עלים וצורות רכות ופתוחות. מזמין את כולם.",
2227
2245
  "slice": false
2228
2246
  },
2229
2247
  {
@@ -2254,6 +2272,7 @@ export const SPEC_STYLE_PRESETS = [
2254
2272
  "Vibrant & Block-based"
2255
2273
  ],
2256
2274
  "blurb": "Teal, chunky and playful. Made for families.",
2275
+ "blurbHe": "טורקיז, צורות שמנמנות והרבה שובבות. נועד למשפחות.",
2257
2276
  "slice": false
2258
2277
  },
2259
2278
  {
@@ -2285,6 +2304,7 @@ export const SPEC_STYLE_PRESETS = [
2285
2304
  "Organic Biophilic"
2286
2305
  ],
2287
2306
  "blurb": "Dusty rose and soft lavender light. A celebration.",
2307
+ "blurbHe": "ורוד עתיק ואור לבנדר רך. תחושה של חגיגה.",
2288
2308
  "slice": true
2289
2309
  },
2290
2310
  {
@@ -2316,6 +2336,7 @@ export const SPEC_STYLE_PRESETS = [
2316
2336
  "Vibrant & Block-based"
2317
2337
  ],
2318
2338
  "blurb": "Thick outlines and orange. Proud of what you make.",
2339
+ "blurbHe": "קווי מתאר עבים וכתום. גאים במה שאתם יוצרים.",
2319
2340
  "slice": true
2320
2341
  },
2321
2342
  {
@@ -2348,6 +2369,7 @@ export const SPEC_STYLE_PRESETS = [
2348
2369
  "Vibrant & Block-based"
2349
2370
  ],
2350
2371
  "blurb": "Pink, heavy type, poster energy.",
2372
+ "blurbHe": "ורוד, אותיות כבדות, אנרגיה של פוסטר.",
2351
2373
  "slice": false
2352
2374
  },
2353
2375
  {
@@ -2379,6 +2401,7 @@ export const SPEC_STYLE_PRESETS = [
2379
2401
  "Anti-Polish / Raw Aesthetic"
2380
2402
  ],
2381
2403
  "blurb": "Electric blue and an odd, wide face. Made by hand, on purpose.",
2404
+ "blurbHe": "כחול חשמלי ופונט רחב ומשונה. נראה כמו עבודת יד, ובכוונה.",
2382
2405
  "slice": false
2383
2406
  },
2384
2407
  {
@@ -2410,6 +2433,7 @@ export const SPEC_STYLE_PRESETS = [
2410
2433
  "Flat Design"
2411
2434
  ],
2412
2435
  "blurb": "Green and bright, like a market stall in the morning.",
2436
+ "blurbHe": "ירוק ובהיר, כמו דוכן בשוק בבוקר.",
2413
2437
  "slice": false
2414
2438
  }
2415
2439
  ] as const;
@@ -21,8 +21,11 @@ export type PresetMode = Exclude<DesignMode, 'auto'>;
21
21
 
22
22
  export interface StylePreset {
23
23
  readonly id: string;
24
+ /** A proper name — never translated. */
24
25
  readonly name: string;
25
26
  readonly blurb: string;
27
+ /** The blurb in Hebrew (2026-10-25). */
28
+ readonly blurbHe: string;
26
29
  readonly flavorId: string;
27
30
  readonly seed: string;
28
31
  readonly tint: TintId;
@@ -48,6 +48,8 @@ export enum StepState {
48
48
  /** What a build creates, as Undo walks it. */
49
49
  export enum CreatedKind {
50
50
  ContentType = 'content-type',
51
+ /** Fields the build added to a content type it found (types are shared by every organization of a studio). */
52
+ ContentTypeFields = 'content-type-fields',
51
53
  SampleImage = 'sample-image',
52
54
  Item = 'item',
53
55
  DataSource = 'data-source',
@@ -61,6 +63,8 @@ export enum KeptReason {
61
63
  Edited = 'edited',
62
64
  Published = 'published',
63
65
  InUse = 'in-use',
66
+ /** Added to a content type every organization shares: removing a field is the studio owner's change. */
67
+ Shared = 'shared',
64
68
  }
65
69
 
66
70
  export interface BuildStepError {
@@ -88,6 +92,8 @@ export interface CreatedRecord {
88
92
  contentType?: string;
89
93
  /** A sample image's public URL — what items and pages reference. */
90
94
  url?: string;
95
+ /** `content-type-fields`: the fields the build added. */
96
+ fields?: string[];
91
97
  }
92
98
 
93
99
  export interface UndoKept {
@@ -112,6 +118,8 @@ export interface UndoRecord {
112
118
  export enum BuildNoticeCode {
113
119
  /** Storage is not configured: sample items get the empty image box, and the run says so. */
114
120
  NoStorage = 'no-storage',
121
+ /** A content type the build reuses is not public in this studio: the site will not show its items. */
122
+ ContentTypeNotPublic = 'content-type-not-public',
115
123
  }
116
124
 
117
125
  export interface BuildNotice {
@@ -153,12 +161,13 @@ export enum PreflightRefusalCode {
153
161
  InvalidPlan = 'invalid-plan',
154
162
  /** A route the plan wants is already a page of this organization. */
155
163
  RouteTaken = 'route-taken',
156
- /** A content type of that name exists in this instance (content types are instance-wide). */
157
- ContentTypeTaken = 'content-type-taken',
164
+ /** The studio's content type of that name stores a field the plan needs differently (type or control) —
165
+ * types are shared by every organization, so the build reuses one it finds and adds what it lacks. */
166
+ ContentTypeConflict = 'content-type-conflict',
158
167
  /** The name may not be a content type (a platform collection, or not a valid name). */
159
168
  ContentTypeName = 'content-type-name',
160
- /** Content types act on the whole instance: only the instance owner may create them (SEC1). */
161
- ContentTypesNeedInstanceOwner = 'content-types-need-instance-owner',
169
+ /** The plan creates a content type or adds fields to one, and the caller may not (an org owner/admin — schema_all). */
170
+ ContentTypesNeedPermission = 'content-types-need-permission',
162
171
  /** The org library holds the alias with a different definition. */
163
172
  DataSourceConflict = 'data-source-conflict',
164
173
  /** The studio has pages AND a header/footer: replace or keep them is the caller's choice (D7). */
@@ -183,6 +192,7 @@ export interface PreflightRefusal {
183
192
  */
184
193
  export const buildKeys = {
185
194
  contentType: (name: string) => `schema:${name}`,
195
+ contentTypeFields: (name: string) => `schema-fields:${name}`,
186
196
  item: (contentType: string, n: number) => `item:${contentType}:${n}`,
187
197
  sampleImage: (n: number) => `sample-image:${n}`,
188
198
  dataSource: (alias: string) => `data-source:${alias}`,
@@ -209,10 +219,21 @@ export function isActiveBuild(run: Pick<SiteBuildRun, 'status'> | null | undefin
209
219
  return !!run && ACTIVE_BUILD_STATUSES.includes(run.status);
210
220
  }
211
221
 
212
- /** What each step of a build of `plan` will make — the progress rows' words, from the plan alone. */
222
+ /** What a build does with each content type its plan names (the preflight's `summary.contentTypes[].action`): content
223
+ * types are shared by every organization of a studio, so one the studio already has is reused, or extended with the
224
+ * fields it lacks — never created twice. */
225
+ export enum ContentTypeAction {
226
+ Create = 'create',
227
+ Reuse = 'reuse',
228
+ Extend = 'extend',
229
+ }
230
+
231
+ /** What each step of a build of `plan` will make — the progress rows' words, from the plan (+ the preflight's actions). */
213
232
  export interface BuildStepFacts {
214
- /** Content types to create: their labels. */
233
+ /** The plan's content types: their labels (created, reused or extended — see `contentTypeActions`). */
215
234
  contentTypes: string[];
235
+ /** Per label, what the build does with it — known only once the preflight said so (absent = not known). */
236
+ contentTypeActions: Partial<Record<ContentTypeAction, string[]>>;
216
237
  /** Sample items, all types together. */
217
238
  items: number;
218
239
  /** Pages (template pages included) and their routes. */
@@ -224,9 +245,15 @@ export interface BuildStepFacts {
224
245
  flavorId: string;
225
246
  }
226
247
 
227
- export function buildStepFacts(plan: SitePlan): BuildStepFacts {
248
+ export function buildStepFacts(plan: SitePlan, actions: Readonly<Record<string, `${ContentTypeAction}`>> = {}): BuildStepFacts {
249
+ const contentTypeActions: Partial<Record<ContentTypeAction, string[]>> = {};
250
+ for (const t of plan.contentTypes) {
251
+ const action = actions[t.name] as ContentTypeAction | undefined;
252
+ if (action) (contentTypeActions[action] ??= []).push(t.label);
253
+ }
228
254
  return {
229
255
  contentTypes: plan.contentTypes.map(t => t.label),
256
+ contentTypeActions,
230
257
  items: plan.contentTypes.reduce((n, t) => n + (t.seed?.count ?? 0), 0),
231
258
  pages: plan.pages.length,
232
259
  routes: plan.pages.map(p => p.route),
@@ -90,6 +90,8 @@ export const isLookRule = (rule: AvoidRule): rule is LookRule => 'when' in rule;
90
90
  export interface GoodFit {
91
91
  readonly preset: string;
92
92
  readonly reason: string;
93
+ /** The reason in Hebrew (2026-10-25). */
94
+ readonly reasonHe: string;
93
95
  }
94
96
 
95
97
  export interface BusinessType {