@vectoriox/iox-ui 5.65.0 → 5.66.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.
@@ -2335,6 +2335,22 @@ declare function rankStylePresets(input: RankInput, presets?: ReadonlyArray<Styl
2335
2335
  * proper name); a type's or the owner's advice and the shared-moods line are English in the contract yet.
2336
2336
  */
2337
2337
  declare function presetReason(ranked: RankedPreset, preset: StylePreset | undefined, locale: string | null | undefined): string;
2338
+ /** One flavor's styles in Design ▸ Look: its presets in ranking order. */
2339
+ interface PresetFlavorGroup {
2340
+ flavorId: string;
2341
+ presets: RankedPreset[];
2342
+ }
2343
+ /**
2344
+ * Design ▸ Look's grid (decided 2026-10-28, Doron: "All 24, grouped by flavor" — reverses Q7 and the wizard's best 6):
2345
+ * every ranked style under its flavor, the flavors in catalogue order (Crisp · Linen · Midnight · Glass · Bloom · Pop),
2346
+ * each flavor's styles best-ranked first. A ranking with no basis (no business, no moods) is catalogue order, so the
2347
+ * groups are too. One rule for both hosts.
2348
+ */
2349
+ declare function presetsByFlavor(ranked: ReadonlyArray<RankedPreset>, presets?: ReadonlyArray<StylePreset>, flavors?: ReadonlyArray<{
2350
+ id: string;
2351
+ }>): PresetFlavorGroup[];
2352
+ /** The style the ranking puts first — only when it had something to rank by (a positive score); else none is "best". */
2353
+ declare function bestRankedPreset(ranked: ReadonlyArray<RankedPreset>): string | null;
2338
2354
  declare enum StyleReadSourceKind {
2339
2355
  Image = "image",
2340
2356
  Site = "site"
@@ -2994,5 +3010,5 @@ type SiteAuditView = SiteAudit & {
2994
3010
  advice: LintFinding[];
2995
3011
  };
2996
3012
 
2997
- export { ANIMATE_ADVICE_STEPS, AnalysisIssueCode, AnalysisLocale, AvoidCheck, BUSINESS_TYPES, BUSINESS_TYPE_IDS, BookingNeed, COPY_LENGTH_ORDER, CopyLength, GENERATION_LIMITS, HARNESS_SOURCE, LITTLE_MOVEMENT_AVOID, LITTLE_MOVEMENT_CAP, LintKind, MAX_ANALYSIS_MOODS, MAX_PIXEL_SAMPLES, MAX_READ_PICTURES, NEEDS, NEED_IDS, NeedSource, PALETTE_SIZE, PALETTE_THRESHOLDS, PictureRole, PlanChangeOutcome, PresetFit, RANK_WEIGHTS, READING_SHAPE, READ_ANIMATE, READ_WEIGHTS, RankReason, ReaderState, ReadingIssueCode, SITE_ANALYSIS_SCHEMA_NAME, SITE_READING_SCHEMA_NAME, SPEC_ANALYSIS_SHAPE, SPEC_BUSINESS_TYPES, SPEC_HARNESS_EXAMPLES, SPEC_HARNESS_SOURCE, SPEC_NEEDS, SPEC_STRUCTURES, SPEC_USER_AVOIDS, STRUCTURES, SiteReadRefusal, StyleReadGround, StyleReadHeadings, StyleReadMotion, StyleReadSourceKind, USER_AVOID_IDS, VoiceFormality, VoicePerson, addressesIn, analysisFromWire, analysisPromptContext, analysisToWire, businessTypeById, calmerChoice, decodeSiteReading, inferNeeds, isLookRule, lintDesign, lookMatches, mapStyleRead, matchBusinessType, matchBusinessTypes, measurePalette, mergeStyleReads, motionAdvice, motionFor, normalizeAddress, oklchHue, paletteBrand, paletteGround, paletteSamples, pictureStyleRead, pixelSamples, presetDesign, presetHasSerifHeadings, presetLook, presetReason, rankStylePresets, rankWithReferences, readPalette, referenceSeed, seedPassesPreset, siteAnalysisJsonSchema, siteReadingJsonSchema, startingDesign, structureFor, userAvoidRule, validateSiteAnalysis, validateSiteReading, withoutAddress };
2998
- export type { AiGenerationView, AnalysisContext, AnalysisIssue, AnalysisValidation, AvoidRule, BusinessType, BusinessTypeMatch, CheckRule, ColourSample, FactRead, GenerationFileView, GenerationReadersView, GenerationStartRequest, GoodFit, LintFinding, LintSite, LookCondition, LookDesign, LookRule, MeasuredPicture, MotionBasis, MotionInput, MotionStart, NeedDef, NeedId, PaletteColour, PaletteReading, PictureStyle, PlanRevisionView, PromptContext, PromptContextOptions, PromptSection, RankInput, RankedPreset, ReadingIssue, ReferenceSeed, SiteAnalysis, SiteAuditView, SiteNeed, SiteReaderView, SiteReading, StartingDesign, StructureChoice, StructureId, StyleHints, StyleRead, UserAvoidId };
3013
+ export { ANIMATE_ADVICE_STEPS, AnalysisIssueCode, AnalysisLocale, AvoidCheck, BUSINESS_TYPES, BUSINESS_TYPE_IDS, BookingNeed, COPY_LENGTH_ORDER, CopyLength, GENERATION_LIMITS, HARNESS_SOURCE, LITTLE_MOVEMENT_AVOID, LITTLE_MOVEMENT_CAP, LintKind, MAX_ANALYSIS_MOODS, MAX_PIXEL_SAMPLES, MAX_READ_PICTURES, NEEDS, NEED_IDS, NeedSource, PALETTE_SIZE, PALETTE_THRESHOLDS, PictureRole, PlanChangeOutcome, PresetFit, RANK_WEIGHTS, READING_SHAPE, READ_ANIMATE, READ_WEIGHTS, RankReason, ReaderState, ReadingIssueCode, SITE_ANALYSIS_SCHEMA_NAME, SITE_READING_SCHEMA_NAME, SPEC_ANALYSIS_SHAPE, SPEC_BUSINESS_TYPES, SPEC_HARNESS_EXAMPLES, SPEC_HARNESS_SOURCE, SPEC_NEEDS, SPEC_STRUCTURES, SPEC_USER_AVOIDS, STRUCTURES, SiteReadRefusal, StyleReadGround, StyleReadHeadings, StyleReadMotion, StyleReadSourceKind, USER_AVOID_IDS, VoiceFormality, VoicePerson, addressesIn, analysisFromWire, analysisPromptContext, analysisToWire, bestRankedPreset, businessTypeById, calmerChoice, decodeSiteReading, inferNeeds, isLookRule, lintDesign, lookMatches, mapStyleRead, matchBusinessType, matchBusinessTypes, measurePalette, mergeStyleReads, motionAdvice, motionFor, normalizeAddress, oklchHue, paletteBrand, paletteGround, paletteSamples, pictureStyleRead, pixelSamples, presetDesign, presetHasSerifHeadings, presetLook, presetReason, presetsByFlavor, rankStylePresets, rankWithReferences, readPalette, referenceSeed, seedPassesPreset, siteAnalysisJsonSchema, siteReadingJsonSchema, startingDesign, structureFor, userAvoidRule, validateSiteAnalysis, validateSiteReading, withoutAddress };
3014
+ export type { AiGenerationView, AnalysisContext, AnalysisIssue, AnalysisValidation, AvoidRule, BusinessType, BusinessTypeMatch, CheckRule, ColourSample, FactRead, GenerationFileView, GenerationReadersView, GenerationStartRequest, GoodFit, LintFinding, LintSite, LookCondition, LookDesign, LookRule, MeasuredPicture, MotionBasis, MotionInput, MotionStart, NeedDef, NeedId, PaletteColour, PaletteReading, PictureStyle, PlanRevisionView, PresetFlavorGroup, PromptContext, PromptContextOptions, PromptSection, RankInput, RankedPreset, ReadingIssue, ReferenceSeed, SiteAnalysis, SiteAuditView, SiteNeed, SiteReaderView, SiteReading, StartingDesign, StructureChoice, StructureId, StyleHints, StyleRead, UserAvoidId };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vectoriox/iox-ui",
3
- "version": "5.65.0",
3
+ "version": "5.66.0",
4
4
  "peerDependencies": {
5
5
  "@angular/common": ">=20.0.0",
6
6
  "@angular/core": ">=20.0.0",
@@ -72,3 +72,16 @@ export function presetChoices(id: string, mode?: DesignMode): DesignChoices | nu
72
72
  motion: preset.motion, pillButtons: preset.pillButtons, mode: wear, tint: preset.tint, ...preset.moves,
73
73
  });
74
74
  }
75
+
76
+ /**
77
+ * The preset a set of choices IS (Design ▸ Look's "Current", 2026-10-28): its look — flavor, colour, tint, pairing,
78
+ * shape, spacing, pill buttons — in a mode it offers. Motion, speed and font overrides are the site's, not the
79
+ * style's, so they never unmark it; a colour or a corner changed by hand does: the look is then its flavor's, customised.
80
+ */
81
+ export function stylePresetOfChoices(choices: DesignChoices | null | undefined): StylePreset | undefined {
82
+ if (!choices) return undefined;
83
+ const c = resolveDesignChoices(choices);
84
+ return STYLE_PRESETS.find(p => p.flavorId === c.flavorId && p.seed.toLowerCase() === c.seed.toLowerCase() && p.tint === c.tint
85
+ && p.pairId === c.pairId && p.shape === c.shape && p.density === c.density && p.pillButtons === c.pillButtons
86
+ && presetModes(p).includes(c.mode));
87
+ }
@@ -1,5 +1,5 @@
1
1
  import {
2
- DensityId, flavorPackById, MOOD_LABELS, MoodId, parseFontFamilies, ShapeId, STYLE_PRESETS, StylePreset, TintId,
2
+ DensityId, flavorPackById, MOOD_LABELS, MoodId, parseFontFamilies, ShapeId, SPEC_FLAVORS, STYLE_PRESETS, StylePreset, TintId,
3
3
  } from '@vectoriox/iox-ui/design-core';
4
4
  import type { AnimateId } from '@vectoriox/iox-ui/design-core';
5
5
 
@@ -133,6 +133,35 @@ export function presetReason(ranked: RankedPreset, preset: StylePreset | undefin
133
133
  return (hebrew ? preset?.blurbHe : preset?.blurb) ?? '';
134
134
  }
135
135
 
136
+ /** One flavor's styles in Design ▸ Look: its presets in ranking order. */
137
+ export interface PresetFlavorGroup {
138
+ flavorId: string;
139
+ presets: RankedPreset[];
140
+ }
141
+
142
+ /**
143
+ * Design ▸ Look's grid (decided 2026-10-28, Doron: "All 24, grouped by flavor" — reverses Q7 and the wizard's best 6):
144
+ * every ranked style under its flavor, the flavors in catalogue order (Crisp · Linen · Midnight · Glass · Bloom · Pop),
145
+ * each flavor's styles best-ranked first. A ranking with no basis (no business, no moods) is catalogue order, so the
146
+ * groups are too. One rule for both hosts.
147
+ */
148
+ export function presetsByFlavor(
149
+ ranked: ReadonlyArray<RankedPreset>,
150
+ presets: ReadonlyArray<StylePreset> = STYLE_PRESETS,
151
+ flavors: ReadonlyArray<{ id: string }> = SPEC_FLAVORS,
152
+ ): PresetFlavorGroup[] {
153
+ const flavorOf = new Map(presets.map(p => [p.id, p.flavorId]));
154
+ return flavors
155
+ .map(f => ({ flavorId: f.id, presets: ranked.filter(r => flavorOf.get(r.id) === f.id) }))
156
+ .filter(g => g.presets.length > 0);
157
+ }
158
+
159
+ /** The style the ranking puts first — only when it had something to rank by (a positive score); else none is "best". */
160
+ export function bestRankedPreset(ranked: ReadonlyArray<RankedPreset>): string | null {
161
+ const top = ranked[0];
162
+ return top && top.score > 0 ? top.id : null;
163
+ }
164
+
136
165
  // ── References: a reading of pictures or a site, as style (plan §3k, R4) ─────────────────────────────────
137
166
  export enum StyleReadSourceKind {
138
167
  Image = 'image',