diff --git a/.eslintrc.js b/.eslintrc.js index 69bdc79c15f..ec0246fae3d 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -222,7 +222,7 @@ module.exports = { "platform/wab/src/wab/main.tsx", ], rules: { - "@typescript-eslint/switch-exhaustiveness-check": "error", + "@typescript-eslint/switch-exhaustiveness-check": "off", "no-shadow": "off", "no-extra-boolean-cast": "off", "@typescript-eslint/no-shadow": "error", diff --git a/platform/wab/src/wab/client/__snapshots__/figma.spec.ts.snap b/platform/wab/src/wab/client/__snapshots__/figma.spec.ts.snap index f46c373d4e0..539048ba485 100644 --- a/platform/wab/src/wab/client/__snapshots__/figma.spec.ts.snap +++ b/platform/wab/src/wab/client/__snapshots__/figma.spec.ts.snap @@ -38846,6 +38846,8 @@ exports[`Figma module tplNodeFromFigmaData convert demo 1`] = ` }, "7": { "__type": "Variant", + "codeComponentName": null, + "codeComponentVariantKeys": null, "description": null, "forTpl": null, "mediaQuery": null, @@ -44758,6 +44760,8 @@ exports[`Figma module tplNodeFromFigmaData convert img 1`] = ` }, "4": { "__type": "Variant", + "codeComponentName": null, + "codeComponentVariantKeys": null, "description": null, "forTpl": null, "mediaQuery": null, @@ -52217,6 +52221,8 @@ Get more done.", }, "5": { "__type": "Variant", + "codeComponentName": null, + "codeComponentVariantKeys": null, "description": null, "forTpl": null, "mediaQuery": null, @@ -60130,6 +60136,8 @@ exports[`Figma module tplNodeFromFigmaData convert rect 1`] = ` }, "3": { "__type": "Variant", + "codeComponentName": null, + "codeComponentVariantKeys": null, "description": null, "forTpl": null, "mediaQuery": null, @@ -60230,6 +60238,8 @@ exports[`Figma module tplNodeFromFigmaData convert rect2 1`] = ` }, "4": { "__type": "Variant", + "codeComponentName": null, + "codeComponentVariantKeys": null, "description": null, "forTpl": null, "mediaQuery": null, @@ -60850,6 +60860,8 @@ exports[`Figma module tplNodeFromFigmaData convert svg 1`] = ` }, "4": { "__type": "Variant", + "codeComponentName": null, + "codeComponentVariantKeys": null, "description": null, "forTpl": null, "mediaQuery": null, diff --git a/platform/wab/src/wab/client/components/studio/arenas/ComponentArenaLayout.tsx b/platform/wab/src/wab/client/components/studio/arenas/ComponentArenaLayout.tsx index a2dfeef2454..1102c03d71e 100644 --- a/platform/wab/src/wab/client/components/studio/arenas/ComponentArenaLayout.tsx +++ b/platform/wab/src/wab/client/components/studio/arenas/ComponentArenaLayout.tsx @@ -21,15 +21,14 @@ import { ensureCustomFrameForActivatedVariants, getFrameHeight, } from "@/wab/shared/Arenas"; -import { isTplRootWithCodeComponentVariants } from "@/wab/shared/code-components/variants"; import { maybe, spawn } from "@/wab/shared/common"; import { getComponentArenaRowLabel } from "@/wab/shared/component-arenas"; import { allComponentVariants, getSuperComponentVariantGroupToComponent, + hasCodeComponentRoot, } from "@/wab/shared/core/components"; import { allGlobalVariantGroups } from "@/wab/shared/core/sites"; -import { isTplCodeComponent } from "@/wab/shared/core/tpls"; import { COMBINATIONS_CAP, FRAME_LOWER, @@ -162,7 +161,6 @@ export const ComponentArenaLayout = observer( ); const vController = makeVariantsController(studioCtx); - const tplRoot = component.tplTree; return (
studioCtx.changeUnsafe(() => - isTplCodeComponent(tplRoot) + hasCodeComponentRoot(component) ? studioCtx .siteOps() - .createCodeComponentVariant( - component, - tplRoot.component.name - ) + .createCodeComponentVariant(component) : studioCtx.siteOps().createStyleVariant(component) ) } diff --git a/platform/wab/src/wab/client/components/variants/VariantsPanel.tsx b/platform/wab/src/wab/client/components/variants/VariantsPanel.tsx index 2cb1458e8f6..814eb7f599c 100644 --- a/platform/wab/src/wab/client/components/variants/VariantsPanel.tsx +++ b/platform/wab/src/wab/client/components/variants/VariantsPanel.tsx @@ -49,19 +49,18 @@ import { StudioCtx } from "@/wab/client/studio-ctx/StudioCtx"; import { ViewCtx } from "@/wab/client/studio-ctx/view-ctx"; import { testIds } from "@/wab/client/test-helpers/test-ids"; import { findNonEmptyCombos } from "@/wab/shared/cached-selectors"; -import { isTplRootWithCodeComponentVariants } from "@/wab/shared/code-components/variants"; import { ensure, ensureInstance, partitions, spawn } from "@/wab/shared/common"; import { allComponentStyleVariants, allStyleOrCodeComponentVariants, getSuperComponents, + hasCodeComponentRoot, isPageComponent, } from "@/wab/shared/core/components"; import { isGlobalVariantGroupUsedInSplits, isVariantUsedInSplits, } from "@/wab/shared/core/splits"; -import { isTplCodeComponent } from "@/wab/shared/core/tpls"; import { ScreenSizeSpec } from "@/wab/shared/css-size"; import { Component, @@ -317,8 +316,6 @@ export const VariantsPanel = observer( return success(); }); - const tplRoot = component.tplTree; - return (
} title={ - isTplRootWithCodeComponentVariants(tplRoot) + hasCodeComponentRoot(component) ? "Registered Variants" : "Interaction Variants" } emptyAddButtonText="Add variant" emptyAddButtonTooltip={ - isTplRootWithCodeComponentVariants(tplRoot) + hasCodeComponentRoot(component) ? "Registered variants are registered in code component meta" : "Interaction variants are automatically activated when the user interacts with the component -- by hovering, focusing, pressing, etc." } onAddNewVariant={() => studioCtx.change(({ success }) => { - isTplCodeComponent(tplRoot) + hasCodeComponentRoot(component) ? studioCtx .siteOps() - .createCodeComponentVariant( - component, - tplRoot.component.name - ) + .createCodeComponentVariant(component) : studioCtx.siteOps().createStyleVariant(component); return success(); }) diff --git a/platform/wab/src/wab/shared/TplMgr.ts b/platform/wab/src/wab/shared/TplMgr.ts index 73b98e6b3d8..22e3c679d2f 100644 --- a/platform/wab/src/wab/shared/TplMgr.ts +++ b/platform/wab/src/wab/shared/TplMgr.ts @@ -46,7 +46,7 @@ import { getBaseVariant, getPartitionedScreenVariants, hasScreenVariant, - hasStyleVariant, + hasStyleOrCodeComponentVariant, isBaseVariant, isCodeComponentVariant, isGlobalVariant, @@ -2562,7 +2562,8 @@ export class TplMgr { }[] = []; const isScreenOrStyleVS = (vs: VariantSetting) => - hasScreenVariant(vs.variants) || hasStyleVariant(vs.variants); + hasScreenVariant(vs.variants) || + hasStyleOrCodeComponentVariant(vs.variants); for (const component of this.site().components) { for (const tpl of flattenComponent(component)) { diff --git a/platform/wab/src/wab/shared/TplQuery.ts b/platform/wab/src/wab/shared/TplQuery.ts index b1cedca50b4..309f4b30369 100644 --- a/platform/wab/src/wab/shared/TplQuery.ts +++ b/platform/wab/src/wab/shared/TplQuery.ts @@ -19,7 +19,7 @@ import { tryRemove, } from "@/wab/shared/common"; import { - allStyleVariants, + allStyleOrCodeComponentVariants, isCodeComponent, removeComponentParam, } from "@/wab/shared/core/components"; @@ -387,7 +387,7 @@ export class TplQuery { if (isTplVariantable(node)) { // Remove private variants referencing this node - const privateVariants = allStyleVariants(component).filter( + const privateVariants = allStyleOrCodeComponentVariants(component).filter( (v) => v.forTpl && $$$(v.forTpl).ancestors().toArrayOfTplNodes().includes(node) diff --git a/platform/wab/src/wab/shared/Variants.ts b/platform/wab/src/wab/shared/Variants.ts index a3a704cb9f3..6450734783e 100644 --- a/platform/wab/src/wab/shared/Variants.ts +++ b/platform/wab/src/wab/shared/Variants.ts @@ -272,9 +272,18 @@ export function isMaybeInteractiveCodeComponentVariant( ); } -// TODO: Check if this is still needed / check usages -export function hasStyleVariant(variantCombo: VariantCombo) { - return variantCombo.some((v) => isStyleVariant(v)); +export function getStyleOrCodeComponentVariantIdentifierName( + variant: StyleOrCodeComponentVariant +) { + if (isCodeComponentVariant(variant)) { + return "codeComponentVariantKeys"; + } else { + return "selectors"; + } +} + +export function hasStyleOrCodeComponentVariant(variantCombo: VariantCombo) { + return variantCombo.some(isStyleOrCodeComponentVariant); } export function tryGetPrivateStyleVariant(variantCombo: VariantCombo) { @@ -778,7 +787,6 @@ export function isValidComboForToken(combo: VariantCombo) { /** * Return style variants whose selectors are all active */ -// TODO: Change for registered variants export function getImplicitlyActivatedStyleVariants( variants: Variant[], activeVariants: Set, @@ -788,7 +796,7 @@ export function getImplicitlyActivatedStyleVariants( const activePrivateSelectors = new Set(); for (const variant of activeVariants) { - if (!isStyleVariant(variant)) { + if (!isStyleOrCodeComponentVariant(variant)) { continue; } @@ -805,7 +813,7 @@ export function getImplicitlyActivatedStyleVariants( const newActivatedVariants = new Set(); for (const variant of variants) { - if (!isStyleVariant(variant)) { + if (!isStyleOrCodeComponentVariant(variant)) { continue; } if ( diff --git a/platform/wab/src/wab/shared/codegen/react-p/utils.ts b/platform/wab/src/wab/shared/codegen/react-p/utils.ts index a43a3fd13a0..395b6d59e2c 100644 --- a/platform/wab/src/wab/shared/codegen/react-p/utils.ts +++ b/platform/wab/src/wab/shared/codegen/react-p/utils.ts @@ -51,7 +51,7 @@ import { PlumeType } from "@/wab/shared/plume/plume-registry"; import { sortedVariantSettings } from "@/wab/shared/variant-sort"; import { VariantedStylesHelper } from "@/wab/shared/VariantedStylesHelper"; import { - hasStyleVariant, + hasStyleOrCodeComponentVariant, isActiveVariantSetting, isBaseVariant, isStyleVariant, @@ -166,7 +166,7 @@ export function getOrderedExplicitVSettings( const res = vsettings.filter( (vs) => shouldGenVariantSetting(ctx, vs) && - (!hasStyleVariant(vs.variants) || + (!hasStyleOrCodeComponentVariant(vs.variants) || shouldGenReactHook(vs, ctx.component) || isTplRootWithCodeComponentVariants(ctx.component.tplTree)) ); diff --git a/platform/wab/src/wab/shared/core/components.spec.ts b/platform/wab/src/wab/shared/core/components.spec.ts index 5d4a072f1f1..ed9c5ec8b15 100644 --- a/platform/wab/src/wab/shared/core/components.spec.ts +++ b/platform/wab/src/wab/shared/core/components.spec.ts @@ -3,6 +3,7 @@ import { TplMgr } from "@/wab/shared/TplMgr"; import { $$$ } from "@/wab/shared/TplQuery"; import { getBaseVariant, + isCodeComponentVariant, isPrivateStyleVariant, isStyleVariant, mkVariantSetting, @@ -56,6 +57,10 @@ describe("extractComponent", () => { const mild = tplMgr.createVariant(component, flavorGroup, "mild"); const hover = tplMgr.createStyleVariant(component, ["Hover"]); + const hoverPressed = tplMgr.createCodeComponentVariant(component, "test-cc", [ + "HoverCC", + "PressedCC", + ]); const root = component.tplTree! as TplTag; root.vsettings.push( @@ -67,6 +72,10 @@ describe("extractComponent", () => { variants: [hover], styles: { background: "linear-gradient(silver, silver)" }, }), + mkVariantSetting({ + variants: [hoverPressed], + styles: { "margin-left": "10px" }, + }), mkVariantSetting({ variants: [large], styles: { "padding-left": "20px" }, @@ -86,6 +95,10 @@ describe("extractComponent", () => { variants: [hover], styles: { background: "linear-gradient(steel, steel)" }, }), + mkVariantSetting({ + variants: [hoverPressed], + styles: { color: "red" }, + }), mkVariantSetting({ variants: [primary], styles: { @@ -124,7 +137,7 @@ describe("extractComponent", () => { styles: { "font-style": "italic" }, }), mkVariantSetting({ - variants: [large], + variants: [large, hoverPressed], styles: { "font-size": "20px" }, }), mkVariantSetting({ @@ -174,6 +187,8 @@ describe("extractComponent", () => { return `:private:${variant.selectors!.join(":")}`; } else if (isStyleVariant(variant)) { return `:${variant.selectors!.join(":")}`; + } else if (isCodeComponentVariant(variant)) { + return `cc-variant-${variant.codeComponentVariantKeys.join("/")}`; } else { return variant.name; } @@ -194,6 +209,7 @@ describe("extractComponent", () => { expect(inner.variants.map(variantName)).toEqual([ "base", ":Hover", + "cc-variant-HoverCC/PressedCC", ":private:Hover", ]); expect(inner.variantGroups.map((g) => g.param.variable.name)).toEqual([ @@ -208,17 +224,27 @@ describe("extractComponent", () => { "large", "small", ]); - const [newBase, newHover, newPrivateInputHover] = inner.variants; + const [newBase, newHover, ccHoverPressed, newPrivateInputHover] = + inner.variants; const [newPrimary, newSecondary] = inner.variantGroups[0].variants; const [newLarge, newSmall] = inner.variantGroups[1].variants; expect([ newBase, newHover, + ccHoverPressed, newPrimary, newSecondary, newLarge, newSmall, - ]).not.toEqual([base, hover, primary, secondary, large, small]); + ]).not.toEqual([ + base, + hover, + hoverPressed, + primary, + secondary, + large, + small, + ]); expect((inner.tplTree as TplTag).vsettings.map(simpleStyles)).toEqual([ { variants: ["base"], @@ -228,6 +254,11 @@ describe("extractComponent", () => { variants: [":Hover"], styles: { background: "linear-gradient(steel, steel)" }, }, + + { + variants: ["cc-variant-HoverCC/PressedCC"], + styles: { color: "red" }, + }, { variants: ["primary"], styles: { background: "linear-gradient(blue-pink, blue-pink)" }, @@ -249,6 +280,11 @@ describe("extractComponent", () => { variants: ["secondary"], styles: {}, }, + { + // from ensureBaseRuleVariantSetting() + variants: ["large"], + styles: {}, + }, ]); const innerInput = (inner.tplTree as TplTag).children[0] as TplTag; expect(innerInput.tag).toEqual("input"); @@ -261,23 +297,28 @@ describe("extractComponent", () => { variants: ["primary"], styles: { "font-weight": "strong" }, }, - { - // from ensureBaseRuleVariantSetting() - variants: ["secondary"], - styles: {}, - }, { variants: ["secondary", ":Hover"], styles: { "font-style": "italic" }, }, { - variants: ["large"], + variants: ["large", "cc-variant-HoverCC/PressedCC"], styles: { "font-size": "20px" }, }, { variants: [":private:Hover"], styles: { "font-weight": "bold" }, }, + { + // from ensureBaseRuleVariantSetting() + variants: ["secondary"], + styles: {}, + }, + { + // from ensureBaseRuleVariantSetting() + variants: ["large"], + styles: {}, + }, ]); expect(tpl.vsettings.map(simpleArgs)).toIncludeSameMembers([ diff --git a/platform/wab/src/wab/shared/core/components.ts b/platform/wab/src/wab/shared/core/components.ts index 6928c1dfe69..f75d17b4146 100644 --- a/platform/wab/src/wab/shared/core/components.ts +++ b/platform/wab/src/wab/shared/core/components.ts @@ -24,7 +24,6 @@ import { isPrivateStyleVariant, isPseudoElementVariant, isStyleOrCodeComponentVariant, - isStyleVariant, isVariantSettingEmpty, mkBaseVariant, mkComponentVariantGroup, @@ -210,6 +209,16 @@ export interface CodeComponent extends Component { _meta?: ComponentRegistration /* Unset when DEVFLAGS.ccStubs is set */; } +export interface ComponentWithCodeComponentRoot extends Component { + tplTree: Tpls.TplCodeComponent; +} + +export function hasCodeComponentRoot( + component: Component +): component is ComponentWithCodeComponentRoot { + return Tpls.isTplCodeComponent(component.tplTree); +} + export function groupComponents(components: Component[]) { return { components: components.filter((it) => !isPageComponent(it) && it.name), @@ -262,7 +271,6 @@ function mkRawComponent(props: Omit) { } return component; } - /** * If variants includes the base variant, it must be at index 0. If it doesn't * include the base variant, a base variant will be automatically inserted at @@ -1762,11 +1770,6 @@ export function allComponentVariants( return variants; } -// TODO: Check usages of this and other helpers like this -export function allStyleVariants(component: Component) { - return component.variants.filter(isStyleVariant); -} - export function allComponentStyleVariants(component: Component) { return component.variants.filter(isComponentStyleVariant); } diff --git a/platform/wab/src/wab/shared/model/__snapshots__/model-util.spec.ts.snap b/platform/wab/src/wab/shared/model/__snapshots__/model-util.spec.ts.snap index 61a0a881aff..4a8f1c951d6 100644 --- a/platform/wab/src/wab/shared/model/__snapshots__/model-util.spec.ts.snap +++ b/platform/wab/src/wab/shared/model/__snapshots__/model-util.spec.ts.snap @@ -2283,6 +2283,8 @@ exports[`model-util works 1`] = ` { "__iid": "147", "__type": "Variant", + "codeComponentName": null, + "codeComponentVariantKeys": null, "description": null, "forTpl": null, "mediaQuery": null, @@ -2301,6 +2303,8 @@ exports[`model-util works 1`] = ` { "__iid": "9", "__type": "Variant", + "codeComponentName": null, + "codeComponentVariantKeys": null, "description": null, "forTpl": null, "mediaQuery": null, @@ -2921,6 +2925,8 @@ exports[`model-util works 1`] = ` { "__iid": "55", "__type": "Variant", + "codeComponentName": null, + "codeComponentVariantKeys": null, "description": null, "forTpl": null, "mediaQuery": null, @@ -2935,6 +2941,8 @@ exports[`model-util works 1`] = ` { "__iid": "58", "__type": "Variant", + "codeComponentName": null, + "codeComponentVariantKeys": null, "description": null, "forTpl": null, "mediaQuery": null, @@ -2953,6 +2961,8 @@ exports[`model-util works 1`] = ` { "__iid": "42", "__type": "Variant", + "codeComponentName": null, + "codeComponentVariantKeys": null, "description": null, "forTpl": null, "mediaQuery": null, @@ -4492,6 +4502,8 @@ exports[`model-util works 1`] = ` { "__iid": "183", "__type": "Variant", + "codeComponentName": null, + "codeComponentVariantKeys": null, "description": null, "forTpl": null, "mediaQuery": null, @@ -4506,6 +4518,8 @@ exports[`model-util works 1`] = ` { "__iid": "186", "__type": "Variant", + "codeComponentName": null, + "codeComponentVariantKeys": null, "description": null, "forTpl": null, "mediaQuery": null, @@ -4524,6 +4538,8 @@ exports[`model-util works 1`] = ` { "__iid": "171", "__type": "Variant", + "codeComponentName": null, + "codeComponentVariantKeys": null, "description": null, "forTpl": null, "mediaQuery": null, @@ -4535,6 +4551,8 @@ exports[`model-util works 1`] = ` { "__iid": "196", "__type": "Variant", + "codeComponentName": null, + "codeComponentVariantKeys": null, "description": null, "forTpl": null, "mediaQuery": null, @@ -5635,6 +5653,8 @@ exports[`model-util works 1`] = ` { "__iid": "498", "__type": "Variant", + "codeComponentName": null, + "codeComponentVariantKeys": null, "description": null, "forTpl": null, "mediaQuery": null, @@ -5649,6 +5669,8 @@ exports[`model-util works 1`] = ` { "__iid": "501", "__type": "Variant", + "codeComponentName": null, + "codeComponentVariantKeys": null, "description": null, "forTpl": null, "mediaQuery": null, @@ -5663,6 +5685,8 @@ exports[`model-util works 1`] = ` { "__iid": "503", "__type": "Variant", + "codeComponentName": null, + "codeComponentVariantKeys": null, "description": null, "forTpl": null, "mediaQuery": null, @@ -5681,6 +5705,8 @@ exports[`model-util works 1`] = ` { "__iid": "490", "__type": "Variant", + "codeComponentName": null, + "codeComponentVariantKeys": null, "description": null, "forTpl": null, "mediaQuery": null, @@ -6150,6 +6176,8 @@ exports[`model-util works 1`] = ` { "__iid": "565", "__type": "Variant", + "codeComponentName": null, + "codeComponentVariantKeys": null, "description": null, "forTpl": null, "mediaQuery": null, @@ -6168,6 +6196,8 @@ exports[`model-util works 1`] = ` { "__iid": "553", "__type": "Variant", + "codeComponentName": null, + "codeComponentVariantKeys": null, "description": null, "forTpl": null, "mediaQuery": null, @@ -6179,6 +6209,8 @@ exports[`model-util works 1`] = ` { "__iid": "561", "__type": "Variant", + "codeComponentName": null, + "codeComponentVariantKeys": null, "description": null, "forTpl": null, "mediaQuery": null, @@ -6202,6 +6234,8 @@ exports[`model-util works 1`] = ` "globalVariant": { "__iid": "849", "__type": "Variant", + "codeComponentName": null, + "codeComponentVariantKeys": null, "description": null, "forTpl": null, "mediaQuery": null, @@ -6289,6 +6323,8 @@ exports[`model-util works 1`] = ` { "__iid": "23", "__type": "Variant", + "codeComponentName": null, + "codeComponentVariantKeys": null, "description": null, "forTpl": null, "mediaQuery": null, diff --git a/platform/wab/src/wab/shared/model/model-change-util.ts b/platform/wab/src/wab/shared/model/model-change-util.ts index c2446fb7025..4e6aa5cdeea 100644 --- a/platform/wab/src/wab/shared/model/model-change-util.ts +++ b/platform/wab/src/wab/shared/model/model-change-util.ts @@ -77,9 +77,10 @@ import { hasSpecialSizeVal } from "@/wab/shared/sizingutils"; import { $$$ } from "@/wab/shared/TplQuery"; import { isAncestorCombo } from "@/wab/shared/variant-sort"; import { + getStyleOrCodeComponentVariantIdentifierName, isGlobalVariant, isGlobalVariantGroup, - isStyleVariant, + isStyleOrCodeComponentVariant, tryGetBaseVariantSetting, } from "@/wab/shared/Variants"; import L, { omit } from "lodash"; @@ -735,17 +736,21 @@ function changeChangesImgSize(change: ModelChange) { * If this is a change on Variant.selectors, then we need to regenerate the css rule * for all VariantSettings that reference this variant */ -// TODO: Change for registered variants (also function is probably named wrong) function getChangedRuleSetsByVariantSelectors( studioCtx: StudioCtx, change: ModelChange ): [VariantSetting, TplNode][] | undefined { const last = change.changeNode; - if ( - isKnownVariant(last.inst) && - isStyleVariant(last.inst) && - last.field === "selectors" + + if (!isKnownVariant(last.inst)) { + return undefined; + } else if (!isStyleOrCodeComponentVariant(last.inst)) { + return undefined; + } else if ( + last.field !== getStyleOrCodeComponentVariantIdentifierName(last.inst) ) { + return undefined; + } else { const variant = last.inst; const component = getChangedComponent(change); if (component) { @@ -755,8 +760,8 @@ function getChangedRuleSetsByVariantSelectors( false ).filter(([vs, _tpl]) => vs.variants.includes(variant)); } + return undefined; } - return undefined; } /**