efficient-web-builder 0.10.0 → 2.0.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 +50 -367
- package/README.md +108 -261
- package/dist/components/AddBlockRow.d.ts +1 -0
- package/dist/components/AddBlockRow.js +1 -0
- package/dist/components/AddChildRow.d.ts +1 -0
- package/dist/components/AddChildRow.js +1 -0
- package/dist/components/AddSidePanel.d.ts +2 -0
- package/dist/components/AddSidePanel.js +1 -0
- package/dist/components/AnimatedStat.d.ts +6 -0
- package/dist/components/AnimatedStat.js +1 -0
- package/dist/components/ApplyCornersToSiblings.d.ts +9 -0
- package/dist/components/ApplyCornersToSiblings.js +1 -0
- package/dist/components/Banner.d.ts +12 -0
- package/dist/components/Banner.js +1 -0
- package/dist/components/BlockFrame.d.ts +15 -0
- package/dist/components/BlockFrame.js +1 -0
- package/dist/components/BlockGapField.d.ts +5 -0
- package/dist/components/BlockGapField.js +1 -0
- package/dist/components/BlogPostSource.d.ts +14 -0
- package/dist/components/BlogPostSource.js +1 -0
- package/dist/components/BoxSurfaceContext.d.ts +7 -0
- package/dist/components/BoxSurfaceContext.js +1 -0
- package/dist/components/BoxTabs.d.ts +6 -0
- package/dist/components/BoxTabs.js +1 -0
- package/dist/components/Breadcrumb.d.ts +10 -0
- package/dist/components/Breadcrumb.js +1 -0
- package/dist/components/Btn.d.ts +22 -0
- package/dist/components/Btn.js +1 -0
- package/dist/components/ButtonBlock.d.ts +13 -0
- package/dist/components/ButtonBlock.js +1 -0
- package/dist/components/CardShadowField.d.ts +6 -0
- package/dist/components/CardShadowField.js +1 -0
- package/dist/components/Cards.d.ts +15 -0
- package/dist/components/Cards.js +1 -0
- package/dist/components/CategoryBar.d.ts +16 -0
- package/dist/components/CategoryBar.js +1 -0
- package/dist/components/ChartSection.d.ts +16 -0
- package/dist/components/ChartSection.js +1 -0
- package/dist/components/ChatSettingsPanel.d.ts +1 -0
- package/dist/components/ChatSettingsPanel.js +1 -0
- package/dist/components/ClearColoursDialog.d.ts +5 -0
- package/dist/components/ClearColoursDialog.js +1 -0
- package/dist/components/ContactLocations.d.ts +17 -0
- package/dist/components/ContactLocations.js +73 -0
- package/dist/components/CornersField.d.ts +6 -0
- package/dist/components/CornersField.js +1 -0
- package/dist/components/CountUpText.d.ts +3 -0
- package/dist/components/CountUpText.js +1 -0
- package/dist/components/Divider.d.ts +9 -0
- package/dist/components/Divider.js +1 -0
- package/dist/components/DocBody.d.ts +13 -0
- package/dist/components/DocBody.js +7 -0
- package/dist/components/DocMasthead.d.ts +13 -0
- package/dist/components/DocMasthead.js +1 -0
- package/dist/components/DocMetaCards.d.ts +10 -0
- package/dist/components/DocMetaCards.js +1 -0
- package/dist/components/DocTabs.d.ts +12 -0
- package/dist/components/DocTabs.js +1 -0
- package/dist/components/DuplicateToPageMenu.d.ts +12 -0
- package/dist/components/DuplicateToPageMenu.js +1 -0
- package/dist/components/EditorScreenMount.d.ts +1 -0
- package/dist/components/EditorScreenMount.js +1 -0
- package/dist/components/EditorStoreProvider.d.ts +1 -0
- package/dist/components/EditorStoreProvider.js +1 -0
- package/dist/components/EditorialSectionHead.d.ts +11 -0
- package/dist/components/EditorialSectionHead.js +1 -0
- package/dist/components/Eyebrow.d.ts +9 -0
- package/dist/components/Eyebrow.js +1 -0
- package/dist/components/FAQ.d.ts +20 -0
- package/dist/components/FAQ.js +1 -0
- package/dist/components/FeaturedCover.d.ts +13 -0
- package/dist/components/FeaturedCover.js +1 -0
- package/dist/components/FieldGlyph.d.ts +12 -0
- package/dist/components/FieldGlyph.js +1 -0
- package/dist/components/Flex.d.ts +32 -0
- package/dist/components/Flex.js +1 -0
- package/dist/components/Footprint.d.ts +16 -0
- package/dist/components/Footprint.js +27 -0
- package/dist/components/Grid.d.ts +11 -0
- package/dist/components/Grid.js +1 -0
- package/dist/components/Heading.d.ts +11 -0
- package/dist/components/Heading.js +1 -0
- package/dist/components/HeadingAudit.d.ts +1 -0
- package/dist/components/HeadingAudit.js +1 -0
- package/dist/components/HeroArrows.d.ts +8 -0
- package/dist/components/HeroArrows.js +1 -0
- package/dist/components/HeroGroup.d.ts +20 -0
- package/dist/components/HeroGroup.js +1 -0
- package/dist/components/HeroHeldFrame.d.ts +8 -0
- package/dist/components/HeroHeldFrame.js +1 -0
- package/dist/components/HeroImageField.d.ts +6 -0
- package/dist/components/HeroImageField.js +1 -0
- package/dist/components/HeroPoster.d.ts +10 -0
- package/dist/components/HeroPoster.js +1 -0
- package/dist/components/HeroSection.d.ts +35 -0
- package/dist/components/HeroSection.js +11 -0
- package/dist/components/HeroSingle.d.ts +17 -0
- package/dist/components/HeroSingle.js +1 -0
- package/dist/components/HeroSlide.d.ts +30 -0
- package/dist/components/HeroSlide.js +1 -0
- package/dist/components/HoverEffectField.d.ts +6 -0
- package/dist/components/HoverEffectField.js +1 -0
- package/dist/components/ImageBlock.d.ts +18 -0
- package/dist/components/ImageBlock.js +1 -0
- package/dist/components/ImageFocusRow.d.ts +7 -0
- package/dist/components/ImageFocusRow.js +1 -0
- package/dist/components/IntegrationsSection.d.ts +14 -0
- package/dist/components/IntegrationsSection.js +1 -0
- package/dist/components/IntroBleed.d.ts +32 -0
- package/dist/components/IntroBleed.js +1 -0
- package/dist/components/KeepHint.d.ts +5 -0
- package/dist/components/KeepHint.js +1 -0
- package/dist/components/KeyFeatures.d.ts +14 -0
- package/dist/components/KeyFeatures.js +1 -0
- package/dist/components/LocationGroupHeader.d.ts +5 -0
- package/dist/components/LocationGroupHeader.js +1 -0
- package/dist/components/LocationsGroupedField.d.ts +5 -0
- package/dist/components/LocationsGroupedField.js +1 -0
- package/dist/components/LocationsTreeContext.d.ts +2 -0
- package/dist/components/LocationsTreeContext.js +1 -0
- package/dist/components/Logo.d.ts +27 -0
- package/dist/components/Logo.js +1 -0
- package/dist/components/LogoBlock.d.ts +8 -0
- package/dist/components/LogoBlock.js +1 -0
- package/dist/components/Logos.d.ts +15 -0
- package/dist/components/Logos.js +1 -0
- package/dist/components/LongRead.d.ts +20 -0
- package/dist/components/LongRead.js +1 -0
- package/dist/components/Manifesto.d.ts +14 -0
- package/dist/components/Manifesto.js +1 -0
- package/dist/components/Masthead.d.ts +16 -0
- package/dist/components/Masthead.js +1 -0
- package/dist/components/MediaSidePanel.d.ts +1 -0
- package/dist/components/MediaSidePanel.js +1 -0
- package/dist/components/MediaUploadField.d.ts +9 -0
- package/dist/components/MediaUploadField.js +1 -0
- package/dist/components/MockupSection.d.ts +59 -0
- package/dist/components/MockupSection.js +1 -0
- package/dist/components/MultiSelectField.d.ts +19 -0
- package/dist/components/MultiSelectField.js +1 -0
- package/dist/components/NodeContextMenu.d.ts +2 -0
- package/dist/components/NodeContextMenu.js +1 -0
- package/dist/components/OrderSummary.d.ts +17 -0
- package/dist/components/OrderSummary.js +1 -0
- package/dist/components/PageEditGuardNotices.d.ts +1 -0
- package/dist/components/PageEditGuardNotices.js +1 -0
- package/dist/components/PagesPanel.d.ts +8 -0
- package/dist/components/PagesPanel.js +1 -0
- package/dist/components/PanelToggleIcon.d.ts +1 -0
- package/dist/components/PanelToggleIcon.js +1 -0
- package/dist/components/ParagraphsA.d.ts +15 -0
- package/dist/components/ParagraphsA.js +1 -0
- package/dist/components/PartGlyphs.d.ts +7 -0
- package/dist/components/PartGlyphs.js +1 -0
- package/dist/components/PartInkControl.d.ts +7 -0
- package/dist/components/PartInkControl.js +1 -0
- package/dist/components/PartResetDot.d.ts +5 -0
- package/dist/components/PartResetDot.js +1 -0
- package/dist/components/PartSettingsPanel.d.ts +68 -0
- package/dist/components/PartSettingsPanel.js +1 -0
- package/dist/components/PartStyledText.d.ts +5 -0
- package/dist/components/PartStyledText.js +1 -0
- package/dist/components/PartTextBox.d.ts +20 -0
- package/dist/components/PartTextBox.js +1 -0
- package/dist/components/PaymentBadges.d.ts +14 -0
- package/dist/components/PaymentBadges.js +1 -0
- package/dist/components/PhoneMenuTools.d.ts +12 -0
- package/dist/components/PhoneMenuTools.js +1 -0
- package/dist/components/PhotographyField.d.ts +6 -0
- package/dist/components/PhotographyField.js +1 -0
- package/dist/components/Placeholder.d.ts +18 -0
- package/dist/components/Placeholder.js +1 -0
- package/dist/components/PostCard.d.ts +37 -0
- package/dist/components/PostCard.js +1 -0
- package/dist/components/PreviewChatContext.d.ts +23 -0
- package/dist/components/PreviewChatContext.js +1 -0
- package/dist/components/PreviewDeviceContext.d.ts +2 -0
- package/dist/components/PreviewDeviceContext.js +1 -0
- package/dist/components/PreviewFocusContext.d.ts +15 -0
- package/dist/components/PreviewFocusContext.js +1 -0
- package/dist/components/PreviewFooterContext.d.ts +17 -0
- package/dist/components/PreviewFooterContext.js +1 -0
- package/dist/components/PreviewHeaderContext.d.ts +97 -0
- package/dist/components/PreviewHeaderContext.js +1 -0
- package/dist/components/PreviewLocationPartContext.d.ts +10 -0
- package/dist/components/PreviewLocationPartContext.js +1 -0
- package/dist/components/PreviewPartAnchors.d.ts +16 -0
- package/dist/components/PreviewPartAnchors.js +1 -0
- package/dist/components/PreviewPartStyleContext.d.ts +21 -0
- package/dist/components/PreviewPartStyleContext.js +1 -0
- package/dist/components/PreviewPartsContext.d.ts +1 -0
- package/dist/components/PreviewPartsContext.js +1 -0
- package/dist/components/PreviewSocialContext.d.ts +30 -0
- package/dist/components/PreviewSocialContext.js +1 -0
- package/dist/components/PreviewSurfaceContext.d.ts +10 -0
- package/dist/components/PreviewSurfaceContext.js +1 -0
- package/dist/components/PreviewThemeFrame.d.ts +6 -0
- package/dist/components/PreviewThemeFrame.js +11 -0
- package/dist/components/PreviewTickerContext.d.ts +4 -0
- package/dist/components/PreviewTickerContext.js +1 -0
- package/dist/components/ProcessSteps.d.ts +32 -0
- package/dist/components/ProcessSteps.js +1 -0
- package/dist/components/Prose.d.ts +9 -0
- package/dist/components/Prose.js +1 -0
- package/dist/components/PublishedFooterContext.d.ts +11 -0
- package/dist/components/PublishedFooterContext.js +1 -0
- package/dist/components/PublishedPartStylesContext.d.ts +15 -0
- package/dist/components/PublishedPartStylesContext.js +1 -0
- package/dist/components/RMark.d.ts +6 -0
- package/dist/components/RMark.js +1 -0
- package/dist/components/Reel.d.ts +15 -0
- package/dist/components/Reel.js +1 -0
- package/dist/components/RuleLine.d.ts +1 -0
- package/dist/components/RuleLine.js +1 -0
- package/dist/components/SearchSelectField.d.ts +22 -0
- package/dist/components/SearchSelectField.js +1 -0
- package/dist/components/SectionAnimation.d.ts +7 -0
- package/dist/components/SectionAnimation.js +1 -0
- package/dist/components/SectionEditor.d.ts +63 -0
- package/dist/components/SectionEditor.js +1 -0
- package/dist/components/SectionEditorShell.d.ts +1 -0
- package/dist/components/SectionEditorShell.js +1 -0
- package/dist/components/SectionEyebrow.d.ts +10 -0
- package/dist/components/SectionEyebrow.js +1 -0
- package/dist/components/SectionHeader.d.ts +29 -0
- package/dist/components/SectionHeader.js +1 -0
- package/dist/components/SectionIcon.d.ts +5 -0
- package/dist/components/SectionIcon.js +1 -0
- package/dist/components/SectionTextEntries.d.ts +5 -0
- package/dist/components/SectionTextEntries.js +1 -0
- package/dist/components/SectionTextPartBridge.d.ts +6 -0
- package/dist/components/SectionTextPartBridge.js +1 -0
- package/dist/components/SectionThemePicker.d.ts +25 -0
- package/dist/components/SectionThemePicker.js +1 -0
- package/dist/components/SectionThumbnail.d.ts +3 -0
- package/dist/components/SectionThumbnail.js +1 -0
- package/dist/components/Series.d.ts +19 -0
- package/dist/components/Series.js +1 -0
- package/dist/components/ShadowColourField.d.ts +5 -0
- package/dist/components/ShadowColourField.js +1 -0
- package/dist/components/SidePanelHead.d.ts +1 -0
- package/dist/components/SidePanelHead.js +1 -0
- package/dist/components/SideSpaceField.d.ts +7 -0
- package/dist/components/SideSpaceField.js +1 -0
- package/dist/components/SiteEditorProvider.d.ts +3 -0
- package/dist/components/SiteEditorProvider.js +1 -0
- package/dist/components/SiteFields.d.ts +6 -0
- package/dist/components/SiteFields.js +1 -0
- package/dist/components/SiteGutterFrame.d.ts +9 -0
- package/dist/components/SiteGutterFrame.js +1 -0
- package/dist/components/SiteLogoContext.d.ts +25 -0
- package/dist/components/SiteLogoContext.js +1 -0
- package/dist/components/SitePhotographyContext.d.ts +8 -0
- package/dist/components/SitePhotographyContext.js +1 -0
- package/dist/components/SiteStyleUnset.d.ts +1 -0
- package/dist/components/SiteStyleUnset.js +1 -0
- package/dist/components/SiteWidthField.d.ts +7 -0
- package/dist/components/SiteWidthField.js +1 -0
- package/dist/components/SlotChildActionsContext.d.ts +2 -0
- package/dist/components/SlotChildActionsContext.js +1 -0
- package/dist/components/SlotChildRows.d.ts +16 -0
- package/dist/components/SlotChildRows.js +1 -0
- package/dist/components/SocialLinksPanel.d.ts +3 -0
- package/dist/components/SocialLinksPanel.js +1 -0
- package/dist/components/SourceStatus.d.ts +14 -0
- package/dist/components/SourceStatus.js +1 -0
- package/dist/components/Spacer.d.ts +6 -0
- package/dist/components/Spacer.js +1 -0
- package/dist/components/SpecStrip.d.ts +10 -0
- package/dist/components/SpecStrip.js +1 -0
- package/dist/components/Split.d.ts +33 -0
- package/dist/components/Split.js +1 -0
- package/dist/components/StandaloneSectionEditor.d.ts +19 -0
- package/dist/components/StandaloneSectionEditor.js +1 -0
- package/dist/components/Stats.d.ts +14 -0
- package/dist/components/Stats.js +1 -0
- package/dist/components/StatsParagraph.d.ts +21 -0
- package/dist/components/StatsParagraph.js +1 -0
- package/dist/components/StorefrontDocumentContext.d.ts +2 -0
- package/dist/components/StorefrontDocumentContext.js +1 -0
- package/dist/components/StorefrontEditor.d.ts +19 -0
- package/dist/components/StorefrontEditor.js +1 -0
- package/dist/components/StorefrontEditorChrome.d.ts +1 -0
- package/dist/components/StorefrontEditorChrome.js +1 -0
- package/dist/components/StorefrontLinkField.d.ts +19 -0
- package/dist/components/StorefrontLinkField.js +1 -0
- package/dist/components/StylesPanel.d.ts +11 -0
- package/dist/components/StylesPanel.js +1 -0
- package/dist/components/SwitchToBoxFooter.d.ts +1 -0
- package/dist/components/SwitchToBoxFooter.js +1 -0
- package/dist/components/TemplateGlyph.d.ts +6 -0
- package/dist/components/TemplateGlyph.js +1 -0
- package/dist/components/Testimonials.d.ts +16 -0
- package/dist/components/Testimonials.js +1 -0
- package/dist/components/Text.d.ts +11 -0
- package/dist/components/Text.js +1 -0
- package/dist/components/TextStyleRow.d.ts +13 -0
- package/dist/components/TextStyleRow.js +1 -0
- package/dist/components/TextStylesField.d.ts +17 -0
- package/dist/components/TextStylesField.js +1 -0
- package/dist/components/ThemeCard.d.ts +40 -0
- package/dist/components/ThemeCard.js +1 -0
- package/dist/components/ThemeColourField.d.ts +5 -0
- package/dist/components/ThemeColourField.js +1 -0
- package/dist/components/ThemeField.d.ts +8 -0
- package/dist/components/ThemeField.js +1 -0
- package/dist/components/Ticker.d.ts +18 -0
- package/dist/components/Ticker.js +1 -0
- package/dist/components/TickerSection.d.ts +18 -0
- package/dist/components/TickerSection.js +1 -0
- package/dist/components/TickerSettingsPanel.d.ts +3 -0
- package/dist/components/TickerSettingsPanel.js +1 -0
- package/dist/components/Timeline.d.ts +24 -0
- package/dist/components/Timeline.js +1 -0
- package/dist/components/TimelineTrack.d.ts +22 -0
- package/dist/components/TimelineTrack.js +1 -0
- package/dist/components/TitleWithButtons.d.ts +14 -0
- package/dist/components/TitleWithButtons.js +1 -0
- package/dist/components/UiIcon.d.ts +2 -0
- package/dist/components/UiIcon.js +1 -0
- package/dist/components/WebsiteScreenParts.d.ts +2 -0
- package/dist/components/WebsiteScreenParts.js +1 -0
- package/dist/components/WebsiteSettingsPanel.d.ts +46 -0
- package/dist/components/WebsiteSettingsPanel.js +1 -0
- package/dist/components/WidthFollowField.d.ts +10 -0
- package/dist/components/WidthFollowField.js +1 -0
- package/dist/components/cartGlyph.d.ts +1 -0
- package/dist/components/cartGlyph.js +1 -0
- package/dist/components/floating-editor/tokens.d.ts +27 -0
- package/dist/components/floating-editor/tokens.js +1 -0
- package/dist/components/goldPhrases.d.ts +7 -0
- package/dist/components/goldPhrases.js +2 -0
- package/dist/components/integrationIcons.d.ts +2 -0
- package/dist/components/integrationIcons.js +1 -0
- package/dist/components/panel-widths.d.ts +2 -0
- package/dist/components/panel-widths.js +1 -0
- package/dist/components/preview-devices.d.ts +3 -0
- package/dist/components/preview-devices.js +1 -0
- package/dist/components/socialIcons.d.ts +8 -0
- package/dist/components/socialIcons.js +1 -0
- package/dist/components/storefront-editor.css +4870 -0
- package/dist/components/useCountUp.d.ts +10 -0
- package/dist/components/useCountUp.js +1 -0
- package/dist/components/useFooterFocus.d.ts +2 -0
- package/dist/components/useFooterFocus.js +1 -0
- package/dist/components/useLocationsTree.d.ts +6 -0
- package/dist/components/useLocationsTree.js +1 -0
- package/dist/components/usePartBridge.d.ts +1 -0
- package/dist/components/usePartBridge.js +1 -0
- package/dist/components/usePinnedChromeSeed.d.ts +2 -0
- package/dist/components/usePinnedChromeSeed.js +1 -0
- package/dist/components/usePreviewHref.d.ts +5 -0
- package/dist/components/usePreviewHref.js +1 -0
- package/dist/components/useReducedMotion.d.ts +4 -0
- package/dist/components/useReducedMotion.js +1 -0
- package/dist/components/useSnapshotSource.d.ts +17 -0
- package/dist/components/useSnapshotSource.js +1 -0
- package/dist/components/useSocialSettings.d.ts +14 -0
- package/dist/components/useSocialSettings.js +1 -0
- package/dist/components/useStorefrontBlogPosts.d.ts +2 -0
- package/dist/components/useStorefrontBlogPosts.js +1 -0
- package/dist/lib/client-only.d.ts +1 -0
- package/dist/lib/client-only.js +1 -0
- package/dist/lib/content/authored-props.d.ts +4 -0
- package/dist/lib/content/authored-props.js +1 -0
- package/dist/lib/content/box-background.d.ts +31 -0
- package/dist/lib/content/box-background.js +1 -0
- package/dist/lib/content/box-layout.d.ts +78 -0
- package/dist/lib/content/box-layout.js +1 -0
- package/dist/lib/content/button-arrow.d.ts +2 -0
- package/dist/lib/content/button-arrow.js +1 -0
- package/dist/lib/content/card-corners.d.ts +12 -0
- package/dist/lib/content/card-corners.js +1 -0
- package/dist/lib/content/card-image-background.d.ts +11 -0
- package/dist/lib/content/card-image-background.js +1 -0
- package/dist/lib/content/card-image-shape.d.ts +5 -0
- package/dist/lib/content/card-image-shape.js +1 -0
- package/dist/lib/content/cart-drawer.d.ts +20 -0
- package/dist/lib/content/cart-drawer.js +1 -0
- package/dist/lib/content/contact.d.ts +79 -0
- package/dist/lib/content/contact.js +3 -0
- package/dist/lib/content/container-direction.d.ts +14 -0
- package/dist/lib/content/container-direction.js +1 -0
- package/dist/lib/content/container-gap.d.ts +31 -0
- package/dist/lib/content/container-gap.js +1 -0
- package/dist/lib/content/footer.d.ts +30 -0
- package/dist/lib/content/footer.js +1 -0
- package/dist/lib/content/footprint.d.ts +22 -0
- package/dist/lib/content/footprint.js +1 -0
- package/dist/lib/content/gallery-card-layout.d.ts +7 -0
- package/dist/lib/content/gallery-card-layout.js +1 -0
- package/dist/lib/content/gallery-layout.d.ts +154 -0
- package/dist/lib/content/gallery-layout.js +1 -0
- package/dist/lib/content/grid-span.d.ts +15 -0
- package/dist/lib/content/grid-span.js +1 -0
- package/dist/lib/content/image-corners.d.ts +7 -0
- package/dist/lib/content/image-corners.js +1 -0
- package/dist/lib/content/image-fit.d.ts +11 -0
- package/dist/lib/content/image-fit.js +1 -0
- package/dist/lib/content/image-treatment.d.ts +20 -0
- package/dist/lib/content/image-treatment.js +1 -0
- package/dist/lib/content/image-width.d.ts +9 -0
- package/dist/lib/content/image-width.js +1 -0
- package/dist/lib/content/page-background.d.ts +4 -0
- package/dist/lib/content/page-background.js +1 -0
- package/dist/lib/content/page-width.d.ts +63 -0
- package/dist/lib/content/page-width.js +1 -0
- package/dist/lib/content/product-page.d.ts +11 -0
- package/dist/lib/content/product-page.js +1 -0
- package/dist/lib/content/section-animation.d.ts +13 -0
- package/dist/lib/content/section-animation.js +1 -0
- package/dist/lib/content/section-background.d.ts +7 -0
- package/dist/lib/content/section-background.js +1 -0
- package/dist/lib/content/section-corners.d.ts +16 -0
- package/dist/lib/content/section-corners.js +1 -0
- package/dist/lib/content/section-height.d.ts +9 -0
- package/dist/lib/content/section-height.js +1 -0
- package/dist/lib/content/section-min-height.d.ts +60 -0
- package/dist/lib/content/section-min-height.js +1 -0
- package/dist/lib/content/section-padding.d.ts +33 -0
- package/dist/lib/content/section-padding.js +1 -0
- package/dist/lib/content/section-surface.d.ts +13 -0
- package/dist/lib/content/section-surface.js +1 -0
- package/dist/lib/content/section-type-size.d.ts +7 -0
- package/dist/lib/content/section-type-size.js +1 -0
- package/dist/lib/content/section-width.d.ts +19 -0
- package/dist/lib/content/section-width.js +1 -0
- package/dist/lib/content/site-gutter.d.ts +2 -0
- package/dist/lib/content/site-gutter.js +1 -0
- package/dist/lib/content/site-name.d.ts +2 -0
- package/dist/lib/content/site-name.js +1 -0
- package/dist/lib/content/social-links.d.ts +12 -0
- package/dist/lib/content/social-links.js +1 -0
- package/dist/lib/content/subscribe.d.ts +76 -0
- package/dist/lib/content/subscribe.js +2 -0
- package/dist/lib/content/view-tiers.d.ts +2 -0
- package/dist/lib/content/view-tiers.js +1 -0
- package/dist/lib/editor/preview-href.d.ts +6 -0
- package/dist/lib/editor/preview-href.js +1 -0
- package/dist/lib/editor-admin-bridge.d.ts +2 -0
- package/dist/lib/editor-admin-bridge.js +1 -0
- package/dist/lib/editor-auth.d.ts +3 -0
- package/dist/lib/editor-auth.js +1 -0
- package/dist/lib/editor-backend-error.d.ts +2 -0
- package/dist/lib/editor-backend-error.js +1 -0
- package/dist/lib/editor-block-metadata.d.ts +6 -0
- package/dist/lib/editor-block-metadata.js +1 -0
- package/dist/lib/editor-blocks.d.ts +20 -0
- package/dist/lib/editor-blocks.js +1 -0
- package/dist/lib/editor-canvas-styles.d.ts +12 -0
- package/dist/lib/editor-canvas-styles.js +1 -0
- package/dist/lib/editor-chrome.d.ts +2 -0
- package/dist/lib/editor-chrome.js +1 -0
- package/dist/lib/editor-document-adapter.d.ts +7 -0
- package/dist/lib/editor-document-adapter.js +1 -0
- package/dist/lib/editor-document-addressing.d.ts +2 -0
- package/dist/lib/editor-document-addressing.js +1 -0
- package/dist/lib/editor-document-contract.d.ts +1 -0
- package/dist/lib/editor-document-contract.js +0 -0
- package/dist/lib/editor-document-hooks.d.ts +1 -0
- package/dist/lib/editor-document-hooks.js +0 -0
- package/dist/lib/editor-document-switch.d.ts +2 -0
- package/dist/lib/editor-document-switch.js +1 -0
- package/dist/lib/editor-events.d.ts +8 -0
- package/dist/lib/editor-events.js +1 -0
- package/dist/lib/editor-failure.d.ts +1 -0
- package/dist/lib/editor-failure.js +1 -0
- package/dist/lib/editor-form-window.d.ts +21 -0
- package/dist/lib/editor-form-window.js +1 -0
- package/dist/lib/editor-host-inbound.d.ts +1 -0
- package/dist/lib/editor-host-inbound.js +1 -0
- package/dist/lib/editor-host.d.ts +2 -0
- package/dist/lib/editor-host.js +1 -0
- package/dist/lib/editor-key-scope.d.ts +1 -0
- package/dist/lib/editor-key-scope.js +1 -0
- package/dist/lib/editor-load-error.d.ts +1 -0
- package/dist/lib/editor-load-error.js +1 -0
- package/dist/lib/editor-media-panel.d.ts +2 -0
- package/dist/lib/editor-media-panel.js +1 -0
- package/dist/lib/editor-media-picker.d.ts +2 -0
- package/dist/lib/editor-media-picker.js +1 -0
- package/dist/lib/editor-page-lock.d.ts +1 -0
- package/dist/lib/editor-page-lock.js +1 -0
- package/dist/lib/editor-page-rows.d.ts +16 -0
- package/dist/lib/editor-page-rows.js +1 -0
- package/dist/lib/editor-screen.d.ts +2 -0
- package/dist/lib/editor-screen.js +1 -0
- package/dist/lib/editor-section-templates.d.ts +1 -0
- package/dist/lib/editor-section-templates.js +1 -0
- package/dist/lib/editor-session-context.d.ts +1 -0
- package/dist/lib/editor-session-context.js +1 -0
- package/dist/lib/editor-session-loader.d.ts +4 -0
- package/dist/lib/editor-session-loader.js +1 -0
- package/dist/lib/editor-session.d.ts +2 -0
- package/dist/lib/editor-session.js +1 -0
- package/dist/lib/editor-site-slug.d.ts +2 -0
- package/dist/lib/editor-site-slug.js +1 -0
- package/dist/lib/editor-site.d.ts +3 -0
- package/dist/lib/editor-site.js +1 -0
- package/dist/lib/editor-theme.d.ts +1 -0
- package/dist/lib/editor-theme.js +1 -0
- package/dist/lib/fit-words.d.ts +3 -0
- package/dist/lib/fit-words.js +220 -0
- package/dist/lib/fonts.d.ts +32 -0
- package/dist/lib/fonts.js +1 -0
- package/dist/lib/geocode.d.ts +6 -0
- package/dist/lib/geocode.js +1 -0
- package/dist/lib/hero-arrows.d.ts +23 -0
- package/dist/lib/hero-arrows.js +1 -0
- package/dist/lib/hero-group-placement.d.ts +46 -0
- package/dist/lib/hero-group-placement.js +1 -0
- package/dist/lib/hero-overlay-anchor.d.ts +6 -0
- package/dist/lib/hero-overlay-anchor.js +1 -0
- package/dist/lib/hero-phone-stack.d.ts +27 -0
- package/dist/lib/hero-phone-stack.js +1 -0
- package/dist/lib/hero-swipe.d.ts +16 -0
- package/dist/lib/hero-swipe.js +1 -0
- package/dist/lib/hero-texture.d.ts +4 -0
- package/dist/lib/hero-texture.js +1 -0
- package/dist/lib/hero-video-control.d.ts +13 -0
- package/dist/lib/hero-video-control.js +1 -0
- package/dist/lib/image-focus.d.ts +16 -0
- package/dist/lib/image-focus.js +1 -0
- package/dist/lib/links/link-filters.d.ts +1 -0
- package/dist/lib/links/link-filters.js +0 -0
- package/dist/lib/links/link-picker-setup.d.ts +29 -0
- package/dist/lib/links/link-picker-setup.js +1 -0
- package/dist/lib/links/page-link-rules.d.ts +22 -0
- package/dist/lib/links/page-link-rules.js +1 -0
- package/dist/lib/locations-grid.d.ts +10 -0
- package/dist/lib/locations-grid.js +1 -0
- package/dist/lib/logo/analyze-logo-client.d.ts +3 -0
- package/dist/lib/logo/analyze-logo-client.js +1 -0
- package/dist/lib/logo/reverse-svg.d.ts +9 -0
- package/dist/lib/logo/reverse-svg.js +1 -0
- package/dist/lib/map-styles.d.ts +30 -0
- package/dist/lib/map-styles.js +1 -0
- package/dist/lib/maps-config.d.ts +16 -0
- package/dist/lib/maps-config.js +1 -0
- package/dist/lib/maps-loader.d.ts +3 -0
- package/dist/lib/maps-loader.js +1 -0
- package/dist/lib/markup.d.ts +38 -0
- package/dist/lib/markup.js +2 -0
- package/dist/lib/media.d.ts +10 -0
- package/dist/lib/media.js +1 -0
- package/dist/lib/parse-option.d.ts +3 -0
- package/dist/lib/parse-option.js +1 -0
- package/dist/lib/popup/text-kinds.d.ts +11 -0
- package/dist/lib/popup/text-kinds.js +1 -0
- package/dist/lib/preview-header-settings.d.ts +39 -0
- package/dist/lib/preview-header-settings.js +0 -0
- package/dist/lib/puck/ColourControl.d.ts +11 -0
- package/dist/lib/puck/ColourControl.js +1 -0
- package/dist/lib/puck/MarkupToolbar.d.ts +13 -0
- package/dist/lib/puck/MarkupToolbar.js +1 -0
- package/dist/lib/puck/add-palette.d.ts +14 -0
- package/dist/lib/puck/add-palette.js +1 -0
- package/dist/lib/puck/add-target-types.d.ts +1 -0
- package/dist/lib/puck/add-target-types.js +0 -0
- package/dist/lib/puck/add-target.d.ts +3 -0
- package/dist/lib/puck/add-target.js +1 -0
- package/dist/lib/puck/apply-card-corners.d.ts +21 -0
- package/dist/lib/puck/apply-card-corners.js +1 -0
- package/dist/lib/puck/block-choice.d.ts +2 -0
- package/dist/lib/puck/block-choice.js +1 -0
- package/dist/lib/puck/block-offer.d.ts +10 -0
- package/dist/lib/puck/block-offer.js +1 -0
- package/dist/lib/puck/block-types-in.d.ts +1 -0
- package/dist/lib/puck/block-types-in.js +1 -0
- package/dist/lib/puck/blocks/block-types.d.ts +12 -0
- package/dist/lib/puck/blocks/block-types.js +1 -0
- package/dist/lib/puck/blocks/general/Banner/fields.d.ts +2 -0
- package/dist/lib/puck/blocks/general/Banner/fields.js +1 -0
- package/dist/lib/puck/blocks/general/Banner/render.d.ts +2 -0
- package/dist/lib/puck/blocks/general/Banner/render.js +1 -0
- package/dist/lib/puck/blocks/general/Breadcrumb/fields.d.ts +2 -0
- package/dist/lib/puck/blocks/general/Breadcrumb/fields.js +1 -0
- package/dist/lib/puck/blocks/general/Breadcrumb/render.d.ts +5 -0
- package/dist/lib/puck/blocks/general/Breadcrumb/render.js +1 -0
- package/dist/lib/puck/blocks/general/ButtonBlock/fields.d.ts +2 -0
- package/dist/lib/puck/blocks/general/ButtonBlock/fields.js +1 -0
- package/dist/lib/puck/blocks/general/ButtonBlock/render.d.ts +2 -0
- package/dist/lib/puck/blocks/general/ButtonBlock/render.js +1 -0
- package/dist/lib/puck/blocks/general/Cards/fields.d.ts +2 -0
- package/dist/lib/puck/blocks/general/Cards/fields.js +1 -0
- package/dist/lib/puck/blocks/general/Cards/render.d.ts +6 -0
- package/dist/lib/puck/blocks/general/Cards/render.js +1 -0
- package/dist/lib/puck/blocks/general/CategoryBar/fields.d.ts +2 -0
- package/dist/lib/puck/blocks/general/CategoryBar/fields.js +1 -0
- package/dist/lib/puck/blocks/general/CategoryBar/render.d.ts +2 -0
- package/dist/lib/puck/blocks/general/CategoryBar/render.js +1 -0
- package/dist/lib/puck/blocks/general/Chart/fields.d.ts +2 -0
- package/dist/lib/puck/blocks/general/Chart/fields.js +1 -0
- package/dist/lib/puck/blocks/general/Chart/render.d.ts +6 -0
- package/dist/lib/puck/blocks/general/Chart/render.js +2 -0
- package/dist/lib/puck/blocks/general/ContactLocations/fields.d.ts +2 -0
- package/dist/lib/puck/blocks/general/ContactLocations/fields.js +1 -0
- package/dist/lib/puck/blocks/general/ContactLocations/render.d.ts +2 -0
- package/dist/lib/puck/blocks/general/ContactLocations/render.js +1 -0
- package/dist/lib/puck/blocks/general/CustomHTML/fields.d.ts +2 -0
- package/dist/lib/puck/blocks/general/CustomHTML/fields.js +1 -0
- package/dist/lib/puck/blocks/general/CustomHTML/render.d.ts +2 -0
- package/dist/lib/puck/blocks/general/CustomHTML/render.js +3 -0
- package/dist/lib/puck/blocks/general/Divider/fields.d.ts +2 -0
- package/dist/lib/puck/blocks/general/Divider/fields.js +1 -0
- package/dist/lib/puck/blocks/general/Divider/render.d.ts +2 -0
- package/dist/lib/puck/blocks/general/Divider/render.js +1 -0
- package/dist/lib/puck/blocks/general/DocBody/fields.d.ts +2 -0
- package/dist/lib/puck/blocks/general/DocBody/fields.js +1 -0
- package/dist/lib/puck/blocks/general/DocBody/render.d.ts +5 -0
- package/dist/lib/puck/blocks/general/DocBody/render.js +1 -0
- package/dist/lib/puck/blocks/general/DocMasthead/fields.d.ts +2 -0
- package/dist/lib/puck/blocks/general/DocMasthead/fields.js +1 -0
- package/dist/lib/puck/blocks/general/DocMasthead/render.d.ts +7 -0
- package/dist/lib/puck/blocks/general/DocMasthead/render.js +1 -0
- package/dist/lib/puck/blocks/general/DocMetaCards/fields.d.ts +2 -0
- package/dist/lib/puck/blocks/general/DocMetaCards/fields.js +1 -0
- package/dist/lib/puck/blocks/general/DocMetaCards/render.d.ts +4 -0
- package/dist/lib/puck/blocks/general/DocMetaCards/render.js +1 -0
- package/dist/lib/puck/blocks/general/DocTabs/fields.d.ts +2 -0
- package/dist/lib/puck/blocks/general/DocTabs/fields.js +1 -0
- package/dist/lib/puck/blocks/general/DocTabs/render.d.ts +6 -0
- package/dist/lib/puck/blocks/general/DocTabs/render.js +1 -0
- package/dist/lib/puck/blocks/general/Eyebrow/fields.d.ts +2 -0
- package/dist/lib/puck/blocks/general/Eyebrow/fields.js +1 -0
- package/dist/lib/puck/blocks/general/Eyebrow/render.d.ts +2 -0
- package/dist/lib/puck/blocks/general/Eyebrow/render.js +1 -0
- package/dist/lib/puck/blocks/general/FAQ/fields.d.ts +2 -0
- package/dist/lib/puck/blocks/general/FAQ/fields.js +1 -0
- package/dist/lib/puck/blocks/general/FAQ/render.d.ts +7 -0
- package/dist/lib/puck/blocks/general/FAQ/render.js +1 -0
- package/dist/lib/puck/blocks/general/FeaturedCover/fields.d.ts +2 -0
- package/dist/lib/puck/blocks/general/FeaturedCover/fields.js +1 -0
- package/dist/lib/puck/blocks/general/FeaturedCover/render.d.ts +13 -0
- package/dist/lib/puck/blocks/general/FeaturedCover/render.js +1 -0
- package/dist/lib/puck/blocks/general/Flex/fields.d.ts +2 -0
- package/dist/lib/puck/blocks/general/Flex/fields.js +1 -0
- package/dist/lib/puck/blocks/general/Flex/render.d.ts +7 -0
- package/dist/lib/puck/blocks/general/Flex/render.js +1 -0
- package/dist/lib/puck/blocks/general/Footprint/fields.d.ts +2 -0
- package/dist/lib/puck/blocks/general/Footprint/fields.js +1 -0
- package/dist/lib/puck/blocks/general/Footprint/render.d.ts +7 -0
- package/dist/lib/puck/blocks/general/Footprint/render.js +2 -0
- package/dist/lib/puck/blocks/general/Grid/fields.d.ts +2 -0
- package/dist/lib/puck/blocks/general/Grid/fields.js +1 -0
- package/dist/lib/puck/blocks/general/Grid/render.d.ts +7 -0
- package/dist/lib/puck/blocks/general/Grid/render.js +1 -0
- package/dist/lib/puck/blocks/general/Heading/fields.d.ts +2 -0
- package/dist/lib/puck/blocks/general/Heading/fields.js +1 -0
- package/dist/lib/puck/blocks/general/Heading/render.d.ts +2 -0
- package/dist/lib/puck/blocks/general/Heading/render.js +1 -0
- package/dist/lib/puck/blocks/general/Hero/fields.d.ts +2 -0
- package/dist/lib/puck/blocks/general/Hero/fields.js +1 -0
- package/dist/lib/puck/blocks/general/Hero/render.d.ts +7 -0
- package/dist/lib/puck/blocks/general/Hero/render.js +1 -0
- package/dist/lib/puck/blocks/general/HeroGroup/fields.d.ts +2 -0
- package/dist/lib/puck/blocks/general/HeroGroup/fields.js +1 -0
- package/dist/lib/puck/blocks/general/HeroGroup/render.d.ts +8 -0
- package/dist/lib/puck/blocks/general/HeroGroup/render.js +1 -0
- package/dist/lib/puck/blocks/general/HeroSingle/fields.d.ts +2 -0
- package/dist/lib/puck/blocks/general/HeroSingle/fields.js +1 -0
- package/dist/lib/puck/blocks/general/HeroSingle/render.d.ts +8 -0
- package/dist/lib/puck/blocks/general/HeroSingle/render.js +1 -0
- package/dist/lib/puck/blocks/general/HeroSlide/fields.d.ts +2 -0
- package/dist/lib/puck/blocks/general/HeroSlide/fields.js +1 -0
- package/dist/lib/puck/blocks/general/HeroSlide/render.d.ts +8 -0
- package/dist/lib/puck/blocks/general/HeroSlide/render.js +1 -0
- package/dist/lib/puck/blocks/general/ImageBlock/fields.d.ts +2 -0
- package/dist/lib/puck/blocks/general/ImageBlock/fields.js +1 -0
- package/dist/lib/puck/blocks/general/ImageBlock/render.d.ts +2 -0
- package/dist/lib/puck/blocks/general/ImageBlock/render.js +1 -0
- package/dist/lib/puck/blocks/general/Integrations/fields.d.ts +2 -0
- package/dist/lib/puck/blocks/general/Integrations/fields.js +2 -0
- package/dist/lib/puck/blocks/general/Integrations/render.d.ts +2 -0
- package/dist/lib/puck/blocks/general/Integrations/render.js +2 -0
- package/dist/lib/puck/blocks/general/IntroBleed/fields.d.ts +2 -0
- package/dist/lib/puck/blocks/general/IntroBleed/fields.js +1 -0
- package/dist/lib/puck/blocks/general/IntroBleed/render.d.ts +7 -0
- package/dist/lib/puck/blocks/general/IntroBleed/render.js +2 -0
- package/dist/lib/puck/blocks/general/KeyFeatures/fields.d.ts +2 -0
- package/dist/lib/puck/blocks/general/KeyFeatures/fields.js +1 -0
- package/dist/lib/puck/blocks/general/KeyFeatures/render.d.ts +6 -0
- package/dist/lib/puck/blocks/general/KeyFeatures/render.js +1 -0
- package/dist/lib/puck/blocks/general/LogoBlock/fields.d.ts +2 -0
- package/dist/lib/puck/blocks/general/LogoBlock/fields.js +1 -0
- package/dist/lib/puck/blocks/general/LogoBlock/render.d.ts +2 -0
- package/dist/lib/puck/blocks/general/LogoBlock/render.js +1 -0
- package/dist/lib/puck/blocks/general/Logos/fields.d.ts +2 -0
- package/dist/lib/puck/blocks/general/Logos/fields.js +1 -0
- package/dist/lib/puck/blocks/general/Logos/render.d.ts +2 -0
- package/dist/lib/puck/blocks/general/Logos/render.js +1 -0
- package/dist/lib/puck/blocks/general/LongRead/fields.d.ts +2 -0
- package/dist/lib/puck/blocks/general/LongRead/fields.js +1 -0
- package/dist/lib/puck/blocks/general/LongRead/render.d.ts +19 -0
- package/dist/lib/puck/blocks/general/LongRead/render.js +1 -0
- package/dist/lib/puck/blocks/general/Manifesto/fields.d.ts +2 -0
- package/dist/lib/puck/blocks/general/Manifesto/fields.js +2 -0
- package/dist/lib/puck/blocks/general/Manifesto/render.d.ts +2 -0
- package/dist/lib/puck/blocks/general/Manifesto/render.js +1 -0
- package/dist/lib/puck/blocks/general/Masthead/fields.d.ts +2 -0
- package/dist/lib/puck/blocks/general/Masthead/fields.js +1 -0
- package/dist/lib/puck/blocks/general/Masthead/render.d.ts +8 -0
- package/dist/lib/puck/blocks/general/Masthead/render.js +1 -0
- package/dist/lib/puck/blocks/general/Mockup/fields.d.ts +2 -0
- package/dist/lib/puck/blocks/general/Mockup/fields.js +2 -0
- package/dist/lib/puck/blocks/general/Mockup/render.d.ts +2 -0
- package/dist/lib/puck/blocks/general/Mockup/render.js +2 -0
- package/dist/lib/puck/blocks/general/OrderSummary/fields.d.ts +2 -0
- package/dist/lib/puck/blocks/general/OrderSummary/fields.js +1 -0
- package/dist/lib/puck/blocks/general/OrderSummary/render.d.ts +6 -0
- package/dist/lib/puck/blocks/general/OrderSummary/render.js +1 -0
- package/dist/lib/puck/blocks/general/ParagraphsA/fields.d.ts +2 -0
- package/dist/lib/puck/blocks/general/ParagraphsA/fields.js +1 -0
- package/dist/lib/puck/blocks/general/ParagraphsA/render.d.ts +9 -0
- package/dist/lib/puck/blocks/general/ParagraphsA/render.js +1 -0
- package/dist/lib/puck/blocks/general/PaymentBadges/fields.d.ts +2 -0
- package/dist/lib/puck/blocks/general/PaymentBadges/fields.js +1 -0
- package/dist/lib/puck/blocks/general/PaymentBadges/render.d.ts +5 -0
- package/dist/lib/puck/blocks/general/PaymentBadges/render.js +1 -0
- package/dist/lib/puck/blocks/general/PostCard/fields.d.ts +2 -0
- package/dist/lib/puck/blocks/general/PostCard/fields.js +1 -0
- package/dist/lib/puck/blocks/general/PostCard/render.d.ts +9 -0
- package/dist/lib/puck/blocks/general/PostCard/render.js +1 -0
- package/dist/lib/puck/blocks/general/ProcessSteps/fields.d.ts +2 -0
- package/dist/lib/puck/blocks/general/ProcessSteps/fields.js +1 -0
- package/dist/lib/puck/blocks/general/ProcessSteps/render.d.ts +13 -0
- package/dist/lib/puck/blocks/general/ProcessSteps/render.js +1 -0
- package/dist/lib/puck/blocks/general/Prose/fields.d.ts +2 -0
- package/dist/lib/puck/blocks/general/Prose/fields.js +1 -0
- package/dist/lib/puck/blocks/general/Prose/render.d.ts +7 -0
- package/dist/lib/puck/blocks/general/Prose/render.js +1 -0
- package/dist/lib/puck/blocks/general/SectionHeader/fields.d.ts +2 -0
- package/dist/lib/puck/blocks/general/SectionHeader/fields.js +1 -0
- package/dist/lib/puck/blocks/general/SectionHeader/render.d.ts +2 -0
- package/dist/lib/puck/blocks/general/SectionHeader/render.js +1 -0
- package/dist/lib/puck/blocks/general/Series/fields.d.ts +2 -0
- package/dist/lib/puck/blocks/general/Series/fields.js +1 -0
- package/dist/lib/puck/blocks/general/Series/render.d.ts +8 -0
- package/dist/lib/puck/blocks/general/Series/render.js +1 -0
- package/dist/lib/puck/blocks/general/Spacer/fields.d.ts +2 -0
- package/dist/lib/puck/blocks/general/Spacer/fields.js +1 -0
- package/dist/lib/puck/blocks/general/Spacer/render.d.ts +2 -0
- package/dist/lib/puck/blocks/general/Spacer/render.js +1 -0
- package/dist/lib/puck/blocks/general/SpecStrip/fields.d.ts +2 -0
- package/dist/lib/puck/blocks/general/SpecStrip/fields.js +1 -0
- package/dist/lib/puck/blocks/general/SpecStrip/render.d.ts +2 -0
- package/dist/lib/puck/blocks/general/SpecStrip/render.js +1 -0
- package/dist/lib/puck/blocks/general/Split/fields.d.ts +2 -0
- package/dist/lib/puck/blocks/general/Split/fields.js +1 -0
- package/dist/lib/puck/blocks/general/Split/render.d.ts +10 -0
- package/dist/lib/puck/blocks/general/Split/render.js +2 -0
- package/dist/lib/puck/blocks/general/Stats/fields.d.ts +2 -0
- package/dist/lib/puck/blocks/general/Stats/fields.js +1 -0
- package/dist/lib/puck/blocks/general/Stats/render.d.ts +2 -0
- package/dist/lib/puck/blocks/general/Stats/render.js +1 -0
- package/dist/lib/puck/blocks/general/StatsParagraph/fields.d.ts +2 -0
- package/dist/lib/puck/blocks/general/StatsParagraph/fields.js +1 -0
- package/dist/lib/puck/blocks/general/StatsParagraph/render.d.ts +7 -0
- package/dist/lib/puck/blocks/general/StatsParagraph/render.js +1 -0
- package/dist/lib/puck/blocks/general/Testimonials/fields.d.ts +2 -0
- package/dist/lib/puck/blocks/general/Testimonials/fields.js +1 -0
- package/dist/lib/puck/blocks/general/Testimonials/render.d.ts +6 -0
- package/dist/lib/puck/blocks/general/Testimonials/render.js +1 -0
- package/dist/lib/puck/blocks/general/Text/fields.d.ts +2 -0
- package/dist/lib/puck/blocks/general/Text/fields.js +1 -0
- package/dist/lib/puck/blocks/general/Text/render.d.ts +2 -0
- package/dist/lib/puck/blocks/general/Text/render.js +1 -0
- package/dist/lib/puck/blocks/general/Ticker/fields.d.ts +2 -0
- package/dist/lib/puck/blocks/general/Ticker/fields.js +1 -0
- package/dist/lib/puck/blocks/general/Ticker/render.d.ts +5 -0
- package/dist/lib/puck/blocks/general/Ticker/render.js +1 -0
- package/dist/lib/puck/blocks/general/Timeline/fields.d.ts +2 -0
- package/dist/lib/puck/blocks/general/Timeline/fields.js +1 -0
- package/dist/lib/puck/blocks/general/Timeline/render.d.ts +10 -0
- package/dist/lib/puck/blocks/general/Timeline/render.js +2 -0
- package/dist/lib/puck/blocks/general/TimelineTrack/fields.d.ts +2 -0
- package/dist/lib/puck/blocks/general/TimelineTrack/fields.js +1 -0
- package/dist/lib/puck/blocks/general/TimelineTrack/render.d.ts +8 -0
- package/dist/lib/puck/blocks/general/TimelineTrack/render.js +1 -0
- package/dist/lib/puck/blocks/general/TitleWithButtons/fields.d.ts +2 -0
- package/dist/lib/puck/blocks/general/TitleWithButtons/fields.js +1 -0
- package/dist/lib/puck/blocks/general/TitleWithButtons/render.d.ts +5 -0
- package/dist/lib/puck/blocks/general/TitleWithButtons/render.js +2 -0
- package/dist/lib/puck/blocks/general/index.d.ts +2 -0
- package/dist/lib/puck/blocks/general/index.js +1 -0
- package/dist/lib/puck/blocks/general/renders.d.ts +57 -0
- package/dist/lib/puck/blocks/general/renders.js +1 -0
- package/dist/lib/puck/blocks/general/section-bg-built-in.d.ts +6 -0
- package/dist/lib/puck/blocks/general/section-bg-built-in.js +1 -0
- package/dist/lib/puck/blocks/placeholders.d.ts +25 -0
- package/dist/lib/puck/blocks/placeholders.js +1 -0
- package/dist/lib/puck/blocks/scaffold.d.ts +22 -0
- package/dist/lib/puck/blocks/scaffold.js +1 -0
- package/dist/lib/puck/blocks/shared-fields.d.ts +14 -0
- package/dist/lib/puck/blocks/shared-fields.js +1 -0
- package/dist/lib/puck/booking-preview.d.ts +3 -0
- package/dist/lib/puck/booking-preview.js +1 -0
- package/dist/lib/puck/box-footer.d.ts +9 -0
- package/dist/lib/puck/box-footer.js +1 -0
- package/dist/lib/puck/build-config.d.ts +3 -0
- package/dist/lib/puck/build-config.js +1 -0
- package/dist/lib/puck/cap-hero-groups.d.ts +1 -0
- package/dist/lib/puck/cap-hero-groups.js +1 -0
- package/dist/lib/puck/container-blocks.d.ts +10 -0
- package/dist/lib/puck/container-blocks.js +1 -0
- package/dist/lib/puck/content-tree.d.ts +2 -0
- package/dist/lib/puck/content-tree.js +1 -0
- package/dist/lib/puck/controls.d.ts +335 -0
- package/dist/lib/puck/controls.js +1 -0
- package/dist/lib/puck/device-fields.d.ts +2 -0
- package/dist/lib/puck/device-fields.js +1 -0
- package/dist/lib/puck/editor-page-context.d.ts +6 -0
- package/dist/lib/puck/editor-page-context.js +1 -0
- package/dist/lib/puck/enclosing-section.d.ts +1 -0
- package/dist/lib/puck/enclosing-section.js +1 -0
- package/dist/lib/puck/field-buckets.d.ts +2 -0
- package/dist/lib/puck/field-buckets.js +1 -0
- package/dist/lib/puck/field-groups.d.ts +23 -0
- package/dist/lib/puck/field-groups.js +1 -0
- package/dist/lib/puck/field-markers.d.ts +2 -0
- package/dist/lib/puck/field-markers.js +1 -0
- package/dist/lib/puck/field-noun.d.ts +3 -0
- package/dist/lib/puck/field-noun.js +1 -0
- package/dist/lib/puck/footer-block-row-name.d.ts +4 -0
- package/dist/lib/puck/footer-block-row-name.js +1 -0
- package/dist/lib/puck/footer-blocks.d.ts +11 -0
- package/dist/lib/puck/footer-blocks.js +1 -0
- package/dist/lib/puck/footer-return.d.ts +3 -0
- package/dist/lib/puck/footer-return.js +1 -0
- package/dist/lib/puck/general-registry.d.ts +4 -0
- package/dist/lib/puck/general-registry.js +1 -0
- package/dist/lib/puck/geocode-resolve.d.ts +14 -0
- package/dist/lib/puck/geocode-resolve.js +1 -0
- package/dist/lib/puck/header-clearance.d.ts +49 -0
- package/dist/lib/puck/header-clearance.js +1 -0
- package/dist/lib/puck/header-ink.d.ts +16 -0
- package/dist/lib/puck/header-ink.js +1 -0
- package/dist/lib/puck/heading-outline.d.ts +7 -0
- package/dist/lib/puck/heading-outline.js +1 -0
- package/dist/lib/puck/hidable.d.ts +2 -0
- package/dist/lib/puck/hidable.js +1 -0
- package/dist/lib/puck/home-page.d.ts +1 -0
- package/dist/lib/puck/home-page.js +1 -0
- package/dist/lib/puck/left-view.d.ts +5 -0
- package/dist/lib/puck/left-view.js +1 -0
- package/dist/lib/puck/locations-focus.d.ts +22 -0
- package/dist/lib/puck/locations-focus.js +1 -0
- package/dist/lib/puck/locations-tree.d.ts +23 -0
- package/dist/lib/puck/locations-tree.js +2 -0
- package/dist/lib/puck/locked-blocks.d.ts +2 -0
- package/dist/lib/puck/locked-blocks.js +1 -0
- package/dist/lib/puck/media-manifest.json +138 -0
- package/dist/lib/puck/migrate-legacy.d.ts +2 -0
- package/dist/lib/puck/migrate-legacy.js +1 -0
- package/dist/lib/puck/mockup-variant-fields.d.ts +10 -0
- package/dist/lib/puck/mockup-variant-fields.js +1 -0
- package/dist/lib/puck/neutralization-contracts.d.ts +43 -0
- package/dist/lib/puck/neutralization-contracts.js +1 -0
- package/dist/lib/puck/one-h1.d.ts +3 -0
- package/dist/lib/puck/one-h1.js +1 -0
- package/dist/lib/puck/overlay-portal.d.ts +2 -0
- package/dist/lib/puck/overlay-portal.js +1 -0
- package/dist/lib/puck/overrides.d.ts +2 -0
- package/dist/lib/puck/overrides.js +1 -0
- package/dist/lib/puck/page-render.d.ts +5 -0
- package/dist/lib/puck/page-render.js +1 -0
- package/dist/lib/puck/page-root-fields.d.ts +29 -0
- package/dist/lib/puck/page-root-fields.js +1 -0
- package/dist/lib/puck/page-root.d.ts +55 -0
- package/dist/lib/puck/page-root.js +1 -0
- package/dist/lib/puck/palette-sections.d.ts +2 -0
- package/dist/lib/puck/palette-sections.js +1 -0
- package/dist/lib/puck/panel-drop-empty-headings.d.ts +3 -0
- package/dist/lib/puck/panel-drop-empty-headings.js +1 -0
- package/dist/lib/puck/panel-fields.d.ts +2 -0
- package/dist/lib/puck/panel-fields.js +1 -0
- package/dist/lib/puck/panel-heading-scope.d.ts +8 -0
- package/dist/lib/puck/panel-heading-scope.js +1 -0
- package/dist/lib/puck/panel-no-control-mark.d.ts +2 -0
- package/dist/lib/puck/panel-no-control-mark.js +1 -0
- package/dist/lib/puck/part-anchors.d.ts +23 -0
- package/dist/lib/puck/part-anchors.js +1 -0
- package/dist/lib/puck/part-id.d.ts +1 -0
- package/dist/lib/puck/part-id.js +1 -0
- package/dist/lib/puck/part-inks.d.ts +9 -0
- package/dist/lib/puck/part-inks.js +1 -0
- package/dist/lib/puck/part-key.d.ts +9 -0
- package/dist/lib/puck/part-key.js +1 -0
- package/dist/lib/puck/part-row-field.d.ts +2 -0
- package/dist/lib/puck/part-row-field.js +1 -0
- package/dist/lib/puck/part-rows.d.ts +15 -0
- package/dist/lib/puck/part-rows.js +1 -0
- package/dist/lib/puck/part-styles.d.ts +133 -0
- package/dist/lib/puck/part-styles.js +2 -0
- package/dist/lib/puck/part-text.d.ts +12 -0
- package/dist/lib/puck/part-text.js +1 -0
- package/dist/lib/puck/part-typing.d.ts +11 -0
- package/dist/lib/puck/part-typing.js +1 -0
- package/dist/lib/puck/passes/catalogue-labels.d.ts +2 -0
- package/dist/lib/puck/passes/catalogue-labels.js +1 -0
- package/dist/lib/puck/passes/cell-width.d.ts +2 -0
- package/dist/lib/puck/passes/cell-width.js +1 -0
- package/dist/lib/puck/passes/clickable-parts.d.ts +2 -0
- package/dist/lib/puck/passes/clickable-parts.js +1 -0
- package/dist/lib/puck/passes/corners.d.ts +3 -0
- package/dist/lib/puck/passes/corners.js +1 -0
- package/dist/lib/puck/passes/document-position.d.ts +16 -0
- package/dist/lib/puck/passes/document-position.js +1 -0
- package/dist/lib/puck/passes/empty-headings.d.ts +2 -0
- package/dist/lib/puck/passes/empty-headings.js +1 -0
- package/dist/lib/puck/passes/hidden-nodes.d.ts +2 -0
- package/dist/lib/puck/passes/hidden-nodes.js +1 -0
- package/dist/lib/puck/passes/index.d.ts +5 -0
- package/dist/lib/puck/passes/index.js +1 -0
- package/dist/lib/puck/passes/inspector.d.ts +2 -0
- package/dist/lib/puck/passes/inspector.js +1 -0
- package/dist/lib/puck/passes/registry-context.d.ts +2 -0
- package/dist/lib/puck/passes/registry-context.js +1 -0
- package/dist/lib/puck/passes/section-anchor.d.ts +2 -0
- package/dist/lib/puck/passes/section-anchor.js +1 -0
- package/dist/lib/puck/passes/section-animation.d.ts +2 -0
- package/dist/lib/puck/passes/section-animation.js +1 -0
- package/dist/lib/puck/passes/section-height.d.ts +2 -0
- package/dist/lib/puck/passes/section-height.js +1 -0
- package/dist/lib/puck/passes/section-padding.d.ts +8 -0
- package/dist/lib/puck/passes/section-padding.js +1 -0
- package/dist/lib/puck/passes/section-theme.d.ts +3 -0
- package/dist/lib/puck/passes/section-theme.js +1 -0
- package/dist/lib/puck/passes/section-width.d.ts +10 -0
- package/dist/lib/puck/passes/section-width.js +1 -0
- package/dist/lib/puck/passes/settings-groups.d.ts +3 -0
- package/dist/lib/puck/passes/settings-groups.js +1 -0
- package/dist/lib/puck/passes/slot-rules.d.ts +4 -0
- package/dist/lib/puck/passes/slot-rules.js +1 -0
- package/dist/lib/puck/passes/types.d.ts +51 -0
- package/dist/lib/puck/passes/types.js +0 -0
- package/dist/lib/puck/phone-override.d.ts +4 -0
- package/dist/lib/puck/phone-override.js +1 -0
- package/dist/lib/puck/pinned-seed-gate.d.ts +7 -0
- package/dist/lib/puck/pinned-seed-gate.js +1 -0
- package/dist/lib/puck/preview-click.d.ts +1 -0
- package/dist/lib/puck/preview-click.js +1 -0
- package/dist/lib/puck/preview-dom.d.ts +1 -0
- package/dist/lib/puck/preview-dom.js +1 -0
- package/dist/lib/puck/preview-events.d.ts +2 -0
- package/dist/lib/puck/preview-events.js +1 -0
- package/dist/lib/puck/preview-selection-context.d.ts +2 -0
- package/dist/lib/puck/preview-selection-context.js +1 -0
- package/dist/lib/puck/registry.d.ts +3 -0
- package/dist/lib/puck/registry.js +1 -0
- package/dist/lib/puck/renamed-props.d.ts +2 -0
- package/dist/lib/puck/renamed-props.js +1 -0
- package/dist/lib/puck/sanitize.d.ts +1 -0
- package/dist/lib/puck/sanitize.js +1 -0
- package/dist/lib/puck/section-catalog.d.ts +36 -0
- package/dist/lib/puck/section-catalog.js +1 -0
- package/dist/lib/puck/section-descriptions.d.ts +1 -0
- package/dist/lib/puck/section-descriptions.js +1 -0
- package/dist/lib/puck/section-doc.d.ts +1 -0
- package/dist/lib/puck/section-doc.js +1 -0
- package/dist/lib/puck/section-groups.d.ts +21 -0
- package/dist/lib/puck/section-groups.js +1 -0
- package/dist/lib/puck/section-text-suppress.d.ts +9 -0
- package/dist/lib/puck/section-text-suppress.js +1 -0
- package/dist/lib/puck/site-gap-fields.d.ts +2 -0
- package/dist/lib/puck/site-gap-fields.js +1 -0
- package/dist/lib/puck/slider-typing.d.ts +9 -0
- package/dist/lib/puck/slider-typing.js +1 -0
- package/dist/lib/puck/slot-child-name.d.ts +2 -0
- package/dist/lib/puck/slot-child-name.js +1 -0
- package/dist/lib/puck/slot-heal.d.ts +1 -0
- package/dist/lib/puck/slot-heal.js +1 -0
- package/dist/lib/puck/slot-section-spec.d.ts +1 -0
- package/dist/lib/puck/slot-section-spec.js +0 -0
- package/dist/lib/puck/slot-specs.d.ts +9 -0
- package/dist/lib/puck/slot-specs.js +1 -0
- package/dist/lib/puck/snapshot-contracts.d.ts +4 -0
- package/dist/lib/puck/snapshot-contracts.js +1 -0
- package/dist/lib/puck/source-bound-parts.d.ts +12 -0
- package/dist/lib/puck/source-bound-parts.js +1 -0
- package/dist/lib/puck/style-clipboard.d.ts +1 -0
- package/dist/lib/puck/style-clipboard.js +1 -0
- package/dist/lib/puck/templateFields.d.ts +2 -0
- package/dist/lib/puck/templateFields.js +1 -0
- package/dist/lib/puck/text-control-kinds.d.ts +2 -0
- package/dist/lib/puck/text-control-kinds.js +1 -0
- package/dist/lib/puck/text-parts.d.ts +30 -0
- package/dist/lib/puck/text-parts.js +1 -0
- package/dist/lib/puck/theme-swatches.d.ts +3 -0
- package/dist/lib/puck/theme-swatches.js +1 -0
- package/dist/lib/puck/tree-reveal.d.ts +1 -0
- package/dist/lib/puck/tree-reveal.js +1 -0
- package/dist/lib/puck/use-section-ops.d.ts +2 -0
- package/dist/lib/puck/use-section-ops.js +1 -0
- package/dist/lib/reel.d.ts +33 -0
- package/dist/lib/reel.js +1 -0
- package/dist/lib/safe-storage.d.ts +10 -0
- package/dist/lib/safe-storage.js +1 -0
- package/dist/lib/save-as-template-action.d.ts +29 -0
- package/dist/lib/save-as-template-action.js +1 -0
- package/dist/lib/section-template-types.d.ts +1 -0
- package/dist/lib/section-template-types.js +0 -0
- package/dist/lib/sections/card-cover-index.d.ts +7 -0
- package/dist/lib/sections/card-cover-index.js +1 -0
- package/dist/lib/sections/collection-card-text-regions.d.ts +4 -0
- package/dist/lib/sections/collection-card-text-regions.js +1 -0
- package/dist/lib/sections/divider-style.d.ts +12 -0
- package/dist/lib/sections/divider-style.js +1 -0
- package/dist/lib/sections/faq-text-regions.d.ts +4 -0
- package/dist/lib/sections/faq-text-regions.js +1 -0
- package/dist/lib/sections/hero-overlay.d.ts +10 -0
- package/dist/lib/sections/hero-overlay.js +1 -0
- package/dist/lib/sections/intro-bleed-layout.d.ts +15 -0
- package/dist/lib/sections/intro-bleed-layout.js +1 -0
- package/dist/lib/sections/new-section-node.d.ts +2 -0
- package/dist/lib/sections/new-section-node.js +1 -0
- package/dist/lib/sections/product-card-style.d.ts +18 -0
- package/dist/lib/sections/product-card-style.js +1 -0
- package/dist/lib/sections/section-eyebrow-look.d.ts +11 -0
- package/dist/lib/sections/section-eyebrow-look.js +1 -0
- package/dist/lib/sections/section-head-placement.d.ts +31 -0
- package/dist/lib/sections/section-head-placement.js +1 -0
- package/dist/lib/sections/section-head-style.d.ts +16 -0
- package/dist/lib/sections/section-head-style.js +1 -0
- package/dist/lib/sections/section-number-style.d.ts +10 -0
- package/dist/lib/sections/section-number-style.js +1 -0
- package/dist/lib/sections/section-presets.d.ts +9 -0
- package/dist/lib/sections/section-presets.js +1 -0
- package/dist/lib/sections/section-text-kinds.d.ts +8 -0
- package/dist/lib/sections/section-text-kinds.js +1 -0
- package/dist/lib/sections/section-text-regions.d.ts +3 -0
- package/dist/lib/sections/section-text-regions.js +1 -0
- package/dist/lib/sections/spec-table-regions.d.ts +11 -0
- package/dist/lib/sections/spec-table-regions.js +1 -0
- package/dist/lib/sections/text-regions.d.ts +21 -0
- package/dist/lib/sections/text-regions.js +1 -0
- package/dist/lib/sections/ticker-join.d.ts +9 -0
- package/dist/lib/sections/ticker-join.js +1 -0
- package/dist/lib/sections/ticker-scroll.d.ts +11 -0
- package/dist/lib/sections/ticker-scroll.js +1 -0
- package/dist/lib/sections/ticker-style.d.ts +17 -0
- package/dist/lib/sections/ticker-style.js +1 -0
- package/dist/lib/site-runtime.d.ts +28 -0
- package/dist/lib/site-runtime.js +1 -0
- package/dist/lib/site-theme-row.d.ts +52 -0
- package/dist/lib/site-theme-row.js +0 -0
- package/dist/lib/slugify.d.ts +1 -0
- package/dist/lib/slugify.js +1 -0
- package/dist/lib/source-rules/accent-token-name.d.ts +20 -0
- package/dist/lib/source-rules/accent-token-name.js +4 -0
- package/dist/lib/source-rules/button-corners.d.ts +13 -0
- package/dist/lib/source-rules/button-corners.js +2 -0
- package/dist/lib/source-rules/editor-chrome-note.d.ts +16 -0
- package/dist/lib/source-rules/editor-chrome-note.js +13 -0
- package/dist/lib/source-rules/editor-context-menu.d.ts +5 -0
- package/dist/lib/source-rules/editor-context-menu.js +4 -0
- package/dist/lib/source-rules/editor-puck-drag-off.d.ts +8 -0
- package/dist/lib/source-rules/editor-puck-drag-off.js +4 -0
- package/dist/lib/source-rules/efficient-easel-version.d.ts +9 -0
- package/dist/lib/source-rules/efficient-easel-version.js +2 -0
- package/dist/lib/source-rules/every-button-follows-the-button-colour.d.ts +12 -0
- package/dist/lib/source-rules/every-button-follows-the-button-colour.js +7 -0
- package/dist/lib/source-rules/flat-theme-palette.d.ts +10 -0
- package/dist/lib/source-rules/flat-theme-palette.js +8 -0
- package/dist/lib/source-rules/full-width-means-full.d.ts +8 -0
- package/dist/lib/source-rules/full-width-means-full.js +2 -0
- package/dist/lib/source-rules/heading-ceiling-sweep.d.ts +11 -0
- package/dist/lib/source-rules/heading-ceiling-sweep.js +8 -0
- package/dist/lib/source-rules/label-hints.d.ts +7 -0
- package/dist/lib/source-rules/label-hints.js +5 -0
- package/dist/lib/source-rules/label-vocabulary.d.ts +14 -0
- package/dist/lib/source-rules/label-vocabulary.js +5 -0
- package/dist/lib/source-rules/mirrored-rows-agree.d.ts +19 -0
- package/dist/lib/source-rules/mirrored-rows-agree.js +10 -0
- package/dist/lib/source-rules/no-comment-in-jsx.d.ts +9 -0
- package/dist/lib/source-rules/no-comment-in-jsx.js +7 -0
- package/dist/lib/source-rules/no-glyph-rows.d.ts +15 -0
- package/dist/lib/source-rules/no-glyph-rows.js +4 -0
- package/dist/lib/source-rules/one-colour-control.d.ts +7 -0
- package/dist/lib/source-rules/one-colour-control.js +2 -0
- package/dist/lib/source-rules/one-dropdown.d.ts +10 -0
- package/dist/lib/source-rules/one-dropdown.js +4 -0
- package/dist/lib/source-rules/one-editable-list.d.ts +16 -0
- package/dist/lib/source-rules/one-editable-list.js +6 -0
- package/dist/lib/source-rules/one-editor-list.d.ts +7 -0
- package/dist/lib/source-rules/one-editor-list.js +3 -0
- package/dist/lib/source-rules/one-right-click.d.ts +10 -0
- package/dist/lib/source-rules/one-right-click.js +2 -0
- package/dist/lib/source-rules/one-switch.d.ts +9 -0
- package/dist/lib/source-rules/one-switch.js +7 -0
- package/dist/lib/source-rules/one-up-level-link.d.ts +16 -0
- package/dist/lib/source-rules/one-up-level-link.js +18 -0
- package/dist/lib/source-rules/panel-colour-tokens.d.ts +48 -0
- package/dist/lib/source-rules/panel-colour-tokens.js +20 -0
- package/dist/lib/source-rules/panel-no-divider-lines.d.ts +14 -0
- package/dist/lib/source-rules/panel-no-divider-lines.js +10 -0
- package/dist/lib/source-rules/panel-one-arrow.d.ts +21 -0
- package/dist/lib/source-rules/panel-one-arrow.js +1 -0
- package/dist/lib/source-rules/panel-one-hover.d.ts +8 -0
- package/dist/lib/source-rules/panel-one-hover.js +2 -0
- package/dist/lib/source-rules/panel-rows-use-the-shared-row.d.ts +23 -0
- package/dist/lib/source-rules/panel-rows-use-the-shared-row.js +22 -0
- package/dist/lib/source-rules/part-slider-fills-row.d.ts +11 -0
- package/dist/lib/source-rules/part-slider-fills-row.js +29 -0
- package/dist/lib/source-rules/part-style-naming.d.ts +10 -0
- package/dist/lib/source-rules/part-style-naming.js +2 -0
- package/dist/lib/source-rules/puck-document-surfaces.d.ts +16 -0
- package/dist/lib/source-rules/puck-document-surfaces.js +8 -0
- package/dist/lib/source-rules/reduced-motion.d.ts +26 -0
- package/dist/lib/source-rules/reduced-motion.js +9 -0
- package/dist/lib/source-rules/route-content-width.d.ts +22 -0
- package/dist/lib/source-rules/route-content-width.js +5 -0
- package/dist/lib/source-rules/rule.d.ts +21 -0
- package/dist/lib/source-rules/rule.js +1 -0
- package/dist/lib/source-rules/section-theme-preview.d.ts +9 -0
- package/dist/lib/source-rules/section-theme-preview.js +8 -0
- package/dist/lib/source-rules/site-gutter.d.ts +6 -0
- package/dist/lib/source-rules/site-gutter.js +4 -0
- package/dist/lib/source-rules/site-square-by-default.d.ts +17 -0
- package/dist/lib/source-rules/site-square-by-default.js +3 -0
- package/dist/lib/source-rules/site-width.d.ts +11 -0
- package/dist/lib/source-rules/site-width.js +7 -0
- package/dist/lib/source-rules/size-token-paints.d.ts +8 -0
- package/dist/lib/source-rules/size-token-paints.js +11 -0
- package/dist/lib/source-rules/social-icons-import.d.ts +6 -0
- package/dist/lib/source-rules/social-icons-import.js +6 -0
- package/dist/lib/source-rules/source-status-is-shared.d.ts +7 -0
- package/dist/lib/source-rules/source-status-is-shared.js +1 -0
- package/dist/lib/source-rules/style-face-matches-size.d.ts +10 -0
- package/dist/lib/source-rules/style-face-matches-size.js +4 -0
- package/dist/lib/source-rules/support/accent-rename-bytes.d.ts +5 -0
- package/dist/lib/source-rules/support/accent-rename-bytes.js +1 -0
- package/dist/lib/source-rules/support/css-box-model.d.ts +5 -0
- package/dist/lib/source-rules/support/css-box-model.js +1 -0
- package/dist/lib/source-rules/support/css-length.d.ts +2 -0
- package/dist/lib/source-rules/support/css-length.js +1 -0
- package/dist/lib/source-rules/support/css-rules.d.ts +12 -0
- package/dist/lib/source-rules/support/css-rules.js +1 -0
- package/dist/lib/source-rules/support/css-source.d.ts +2 -0
- package/dist/lib/source-rules/support/css-source.js +3 -0
- package/dist/lib/source-rules/support/label-extraction.d.ts +14 -0
- package/dist/lib/source-rules/support/label-extraction.js +5 -0
- package/dist/lib/source-rules/support/panel-select-cascade.d.ts +72 -0
- package/dist/lib/source-rules/support/panel-select-cascade.js +2 -0
- package/dist/lib/source-rules/support/part-slider-call-sites.d.ts +9 -0
- package/dist/lib/source-rules/support/part-slider-call-sites.js +17 -0
- package/dist/lib/source-rules/support/registry-source.d.ts +14 -0
- package/dist/lib/source-rules/support/registry-source.js +3 -0
- package/dist/lib/source-rules/support/ts-source.d.ts +2 -0
- package/dist/lib/source-rules/support/ts-source.js +3 -0
- package/dist/lib/source-rules/theme-mode-controls-gone.d.ts +10 -0
- package/dist/lib/source-rules/theme-mode-controls-gone.js +5 -0
- package/dist/lib/source-rules/upload-intake-guard.d.ts +11 -0
- package/dist/lib/source-rules/upload-intake-guard.js +6 -0
- package/dist/lib/source-rules/word-styles.d.ts +8 -0
- package/dist/lib/source-rules/word-styles.js +4 -0
- package/dist/lib/theme-dom.d.ts +14 -0
- package/dist/lib/theme-dom.js +1 -0
- package/dist/lib/theme-row-persist.d.ts +34 -0
- package/dist/lib/theme-row-persist.js +1 -0
- package/dist/lib/theme-save-message.d.ts +6 -0
- package/dist/lib/theme-save-message.js +1 -0
- package/dist/lib/theme.d.ts +177 -0
- package/dist/lib/theme.js +18 -0
- package/dist/lib/use-host-products.d.ts +2 -0
- package/dist/lib/use-host-products.js +1 -0
- package/dist/lib/web-backend.d.ts +138 -0
- package/dist/lib/web-backend.js +1 -0
- package/dist/lib/web-runtime.d.ts +7 -0
- package/dist/lib/web-runtime.js +1 -0
- package/dist/lib/website-document-addressing.d.ts +2 -0
- package/dist/lib/website-document-addressing.js +1 -0
- package/dist/lib/website-host-inbound.d.ts +1 -0
- package/dist/lib/website-host-inbound.js +1 -0
- package/dist/lib/website-session.d.ts +5 -0
- package/dist/lib/website-session.js +1 -0
- package/dist/lib/word-styles.d.ts +54 -0
- package/dist/lib/word-styles.js +1 -0
- package/package.json +50 -36
- package/dist/chunks/EditorPreviewCheckout-5KOAA2SK.js +0 -4
- package/dist/chunks/PreviewFooter-H6XJUR5S.js +0 -1
- package/dist/chunks/SectionEditorShell-EEZR7KFE.js +0 -1
- package/dist/chunks/SiteEditorProvider-ECGZVKLG.js +0 -1
- package/dist/chunks/StorefrontEditorChrome-4TFS62GY.js +0 -1
- package/dist/chunks/chunk-6CP4D6VJ.js +0 -1
- package/dist/chunks/chunk-7QXLVNFD.js +0 -1
- package/dist/chunks/chunk-BJOS4Y35.js +0 -15
- package/dist/chunks/chunk-BJOS4Y35.js.LEGAL.txt +0 -27
- package/dist/chunks/chunk-EIXUXJQ5.js +0 -153
- package/dist/chunks/chunk-EIXUXJQ5.js.LEGAL.txt +0 -4
- package/dist/chunks/chunk-H7O6ZYX6.js +0 -1
- package/dist/chunks/chunk-HVOO2GNE.js +0 -1
- package/dist/chunks/chunk-IFRGL3GL.js +0 -1
- package/dist/chunks/chunk-ML2AR222.js +0 -1
- package/dist/chunks/chunk-RRHBLOH4.js +0 -1
- package/dist/chunks/chunk-S6SXIMIG.js +0 -2
- package/dist/chunks/chunk-SNH7IFTZ.js +0 -1
- package/dist/chunks/chunk-Y4CZD2YY.js +0 -230
- package/dist/chunks/chunk-Y6SLVHK3.js +0 -1
- package/dist/chunks/chunk-YVQUISDX.js +0 -1
- package/dist/chunks/fitment-data-6NXSKODX.js +0 -1
- package/dist/chunks/gallery-builds-data-SWA6XKFF.js +0 -1
- package/dist/chunks/headers-3CAQXQEY.js +0 -1
- package/dist/chunks/render-client-YGYDU3K2.js +0 -1
- package/dist/contract.d.ts +0 -48
- package/dist/contract.js +0 -1
- package/dist/editor.css +0 -1
- package/dist/index.d.ts +0 -721
- package/dist/index.js +0 -11058
- package/dist/links.d.ts +0 -86
- package/dist/links.js +0 -1
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type RuleReport, type SourceFile } from "./rule.js";
|
|
2
|
+
export type EfficientEaselVersionOptions = {
|
|
3
|
+
readonly packageJson: string;
|
|
4
|
+
readonly resolve: (specifier: string) => string;
|
|
5
|
+
readonly readText: (path: string) => string | undefined;
|
|
6
|
+
};
|
|
7
|
+
export declare function satisfiesCaret(version: string, range: string): boolean;
|
|
8
|
+
export declare function importedSubpaths(files: readonly SourceFile[]): string[];
|
|
9
|
+
export declare function efficientEaselVersion(files: readonly SourceFile[], options: EfficientEaselVersionOptions): RuleReport;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{ruleChecks as b}from"./rule.js";const p=n=>JSON.stringify(n),t="efficient-easel",u=`${t}/panel.css`;function m(n,r){const s=/^\^(\d+)\.(\d+)\.(\d+)$/.exec(r.trim());if(!s)throw new Error(`only \`^x.y.z\` pins are understood here, got "${r}"`);const a=/^(\d+)\.(\d+)\.(\d+)/.exec(n.trim());if(!a)throw new Error(`"${n}" is not a version this can read`);const[i,c,h]=s.slice(1).map(Number),[e,o,l]=a.slice(1).map(Number);return!(e!==i||i===0&&o!==c||o<c||o===c&&l<h)}const $=n=>{const r=Math.max(n.lastIndexOf("/"),n.lastIndexOf("\\"));return r<=0?n.slice(0,r+1)||n:n.slice(0,r)};function g(n,r){const s=n(u);let a=$(s);for(let i=0;i<12;i++){const c=r(`${a}/package.json`);if(c!==void 0)try{const e=JSON.parse(c);if(e.name===t){if(!e.version)throw new Error(`${t} resolved but its package.json carries no version`);return e.version}}catch(e){if(!(e instanceof SyntaxError))throw e}const h=$(a);if(h===a)break;a=h}throw new Error(`resolved ${u} to ${s} but found no ${t} package.json above it`)}function v(n){const r=new Set;for(const s of n)if(/\.(ts|tsx|mts|mjs|js|jsx)$/.test(s.path))for(const a of s.text.matchAll(/(?:\bfrom\s*|\bimport\s*\(?\s*|\brequire\s*\(\s*)["'](efficient-easel\/[A-Za-z0-9._/-]+)["']/g))r.add(a[1]);return[...r].sort()}const k=n=>n.code??"threw";function x(n,r){const{check:s,report:a}=b(`${t} version`);{const e=(f,w)=>{try{return m(f,w)}catch{return"threw"}};s("the caret reading is right about 0.x, where the minor is part of the lock",e("0.10.0","^0.10.1")===!1&&e("0.10.1","^0.10.1")===!0&&e("0.11.0","^0.11.0")===!0&&e("0.11.0","^0.10.1")===!1&&e("0.10.1","^0.11.0")===!1&&e("0.11.4","^0.11.0")===!0&&e("0.11.4","~0.11.0")==="threw","a stale patch is caught; 0.x carets cross no minor and go no backwards; patches above the pin pass; only ^x.y.z is read");const o={"/s/node_modules/.pnpm/efficient-easel@1.2.3/node_modules/efficient-easel/package.json":JSON.stringify({name:t,version:"1.2.3"}),"/s/node_modules/.pnpm/efficient-easel@1.2.3/node_modules/efficient-easel/dist/package.json":"{ not json"};let l="";try{l=g(()=>"/s/node_modules/.pnpm/efficient-easel@1.2.3/node_modules/efficient-easel/dist/css/panel.css",f=>o[f])}catch(f){l=f.message}s("the manifest walk climbs past an unreadable manifest to the package's own",l==="1.2.3",l);const d=v([{path:"fixture.ts",text:[`import { A } from ${p(t+"/menu")};`,`// see ${t}/edit-lock`,`const m = await import(${p(t+"/icons")});`,`const s = ${p(t+"/not-an-import")};`].join(`
|
|
2
|
+
`)}]);s("only import syntax counts as an import, never prose or a string",d.join()===`${t}/icons,${t}/menu`,JSON.stringify(d))}let i;try{const e=JSON.parse(r.packageJson);i=e.dependencies?.[t]??e.devDependencies?.[t]}catch(e){s("package.json reads as JSON",!1,e.message)}if(s(`package.json declares a dependency on ${t}`,i!==void 0)){let e;try{e=g(r.resolve,r.readText)}catch(o){s(`${t} resolves from the install`,!1,o.message)}if(e!==void 0){let o,l;try{o=m(e,i)}catch(d){o=!1,l=d.message}s(`the resolved ${t} satisfies the declared pin (declared ${i}, resolved ${e})`,o,l??`this tree resolves ${t} ${e}, which does not satisfy the declared ${i}. The install is stale \u2014 what you are looking at is not what this repository says it is. Refresh it with \`pnpm install\`, and inside Docker remember that a node_modules VOLUME outlives the container: it keeps whatever was installed into it until something installs again.`)}}const c=v(n);if(s(`found the ${t} imports (${c.length} subpaths)`,c.length>0,"the search is broken, not the code")){const e=[];for(const o of c)try{r.resolve(o)}catch(l){e.push(`${o} (${k(l)})`)}s(`every ${t} subpath this tree imports resolves from the install \u2014 ${c.join(", ")}`,e.length===0,`the installed package does not export: ${e.join(", ")}. The pin resolves and the lockfile is valid \u2014 the SUBPATH is missing, which means the pin points at a release published before it existed. Move the pin to the release that carries it.`)}let h=!1;try{r.resolve(`${t}/a-subpath-that-was-never-exported`)}catch{h=!0}return s(`the resolver refuses a ${t} subpath that does not exist`,h,"it resolved one \u2014 this check cannot fail"),a()}export{x as efficientEaselVersion,v as importedSubpaths,m as satisfiesCaret};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type RuleReport, type SourceFile } from "./rule.js";
|
|
2
|
+
export type EveryButtonOptions = {
|
|
3
|
+
readonly buttonFiles: readonly (readonly [string, number, number])[];
|
|
4
|
+
readonly exclude?: readonly string[];
|
|
5
|
+
readonly accentFillsThatStay: number;
|
|
6
|
+
readonly buttonFills: number;
|
|
7
|
+
readonly buttonSites: number;
|
|
8
|
+
readonly hoverFgKeepers: number;
|
|
9
|
+
readonly chips?: readonly string[];
|
|
10
|
+
readonly runtimeFallbacks?: string;
|
|
11
|
+
};
|
|
12
|
+
export declare function everyButtonFollowsTheButtonColour(files: readonly SourceFile[], options: EveryButtonOptions): RuleReport;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import{ruleChecks as F}from"./rule.js";const h=/[-a-zA-Z0-9:/.[\]]*bg-accent[-a-zA-Z0-9:/.[\]]*/g,u=/[-a-zA-Z0-9:/.[\]]*bg-btn[-a-zA-Z0-9:/.[\]]*/g;function N(o){const t=o.trim();return t.startsWith("//")||t.startsWith("*")||t.startsWith("/*")}function f(o,t){const n=[];for(const r of o)r.text.split(`
|
|
2
|
+
`).forEach((l,i)=>{t.lastIndex=0,!(!t.test(l)||N(l))&&n.push({file:r.path,line:i+1,text:l})});return n}function g(o,t){const n=new Map;for(const r of o){const l=r.text.match(t)?.length??0;l&&n.set(r.file,(n.get(r.file)??0)+l)}return n}const d=o=>[...o.values()].reduce((t,n)=>t+n,0);function $(o){const t=/(?<![-:\w])text-bg\b/.test(o),n=/\btext-black\b/.test(o),r=/\bhover:text-bg\b/.test(o)&&/\bhover:bg-btn\b/.test(o);return t||n||r}const w=o=>/\bhover:bg-fg\b/.test(o)&&/\bhover:text-bg\b/.test(o);function B(o,t){const{check:n,report:r}=F("every button follows the button colour");{const e={path:"fixture.tsx",text:['<button className="bg-btn text-btn-ink hover:bg-btn/90" />','// <button className="bg-accent" /> \u2014 a comment is not paint','<span className={on ? "bg-accent text-bg" : "bg-fg/10"} />','<button className="bg-btn text-bg" />','<button className="bg-btn hover:bg-fg hover:text-bg" />'].join(`
|
|
3
|
+
`)},a=f([e],u);n("the readers count fills per occurrence and drop comment lines",d(g(a,u))===4&&d(g(f([e],h),h))===1),n("\xA74's reader flags page ink on a button and keeps the --fg hover's ink",a.filter(s=>$(s.text)).map(s=>s.line).join()==="4"&&a.filter(s=>w(s.text)).map(s=>s.line).join()==="5")}const l=o.filter(e=>/\.(tsx?|css)$/.test(e.path)),i=new Set(t.exclude??[]);for(const e of i)n(`the excluded file is still real: ${e}`,l.some(a=>a.path===e),"remove the stale entry");const b=l.filter(e=>!i.has(e.path));n(`read the .ts, .tsx and .css files (${b.length})`,b.length>0,"the population is empty \u2014 this rule is measuring nothing");const y=f(b,h),c=f(b,u),m=g(y,h),p=g(c,u);{const e=[];for(const[a,s,k]of t.buttonFiles){const v=p.get(a)??0,x=m.get(a)??0;v!==s&&e.push(`${a}: ${v} bg-btn, expected ${s}`),x!==k&&e.push(`${a}: ${x} bg-accent left, expected ${k}`)}n(`\xA71 every ruled button paints the button token, and its file's markers do not (${t.buttonFiles.length} files)`,e.length===0,`a ruled button still paints --accent, or a marker was swept along with it:
|
|
4
|
+
`+e.join(`
|
|
5
|
+
`))}{const e=d(m);n(`\xA72 ${t.accentFillsThatStay} bg-accent fills stay (found ${e})`,e===t.accentFillsThatStay,"either a marker was swept (too few) or new accent paint arrived (too many) \u2014 this count is derived from the tree, so a new call site has to come past it.");const a=d(p);n(`\xA72 ${t.buttonFills} bg-btn fills (found ${a})`,a===t.buttonFills)}for(const e of t.chips??[])n(`\xA73 ${e} still paints bg-accent`,(m.get(e)??0)>0,"a filter chip is not a button, and a sweep that repaints it has swept too far");{n(`\xA74 ${t.buttonSites} sites paint bg-btn (found ${c.length})`,c.length===t.buttonSites,"\xA74 cannot say anything about ink until the fills have actually moved");const e=c.filter(s=>$(s.text)).map(s=>`${s.file}:${s.line}`);n("\xA74 no button inks a bg-btn state with the page background or a literal",e.length===0,`a merchant's button colour moves the fill and leaves the ink behind:
|
|
6
|
+
`+e.join(`
|
|
7
|
+
`));const a=c.filter(s=>w(s.text)).length;n(`\xA74 ${t.hoverFgKeepers} buttons still pair hover:bg-fg with hover:text-bg (found ${a})`,a===t.hoverFgKeepers,"a sweep that moved those to --btn-ink has put the button's ink on a foreground-coloured fill")}if(t.runtimeFallbacks!==void 0){const e=o.find(a=>a.path===t.runtimeFallbacks);if(n(`\xA75 read ${t.runtimeFallbacks}`,!!e)){const a=[...e.text.matchAll(/const (btnBg|btnFg) = \w+ \|\| "([^"]+)";/g)].map(s=>[s[1],s[2]]);n(`\xA75 found the 2 button-colour fallbacks (found ${a.length})`,a.length===2,"if the shape changed, this rule stopped reading the thing it names"),n("\xA75 the UNSET button falls back to --btn and --btn-ink",JSON.stringify(Object.fromEntries(a))===JSON.stringify({btnBg:"var(--btn)",btnFg:"var(--btn-ink)"}),"it falls back to the accent or to a literal again. Unset is the majority case, and on hartes-metal that painted #C0392B under a hard-coded black \u2014 card 66309's defect on the most prominent button of the page. Only the fallback may move; a merchant's own colour short-circuits it.")}}return r()}export{B as everyButtonFollowsTheButtonColour};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type * as Theme from "../theme.js";
|
|
2
|
+
import { type RuleReport, type SourceFile } from "./rule.js";
|
|
3
|
+
export type FlatThemeModule = Pick<typeof Theme, "ACCENT_DARKEN_STEPS" | "contrastRatio" | "darkerAccents" | "DEFAULT_THEMES" | "gradeContrast" | "normalizeThemeColors" | "READABILITY_AA" | "READABILITY_AA_LARGE" | "themeAccentStyle" | "themeColorStyle">;
|
|
4
|
+
export type FlatThemePaletteOptions = {
|
|
5
|
+
readonly minFiles: number;
|
|
6
|
+
readonly editorAccentCarriers: number;
|
|
7
|
+
readonly liveAccentCarrier?: string;
|
|
8
|
+
readonly theme?: FlatThemeModule;
|
|
9
|
+
};
|
|
10
|
+
export declare function flatThemePalette(files: readonly SourceFile[], options: FlatThemePaletteOptions): RuleReport;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import{isRuleSource as y,ruleChecks as S}from"./rule.js";import{registryFiles as T,registryText as C}from"./support/registry-source.js";const k=/\.(ts|tsx|js|jsx|css|json)$/,x=["accentLight","backgroundLight","surfaceLight","lineLight","mutedLight","textLight"],_=["lightSurfaces"],R=["usesLightSurfaces","setLightSurfaces","lightPageBackground"],b=["accentForMode","isAccentLinked","linkAccent","unlinkAccent"],N=["--theme-fg-light","--theme-bg-light","--theme-surface-light","--theme-surface-2-light","--theme-line-light","--theme-muted-light","--theme-accent-light","--theme-accent-light-2"],v=[...x,"lightSurfaces"],I=["text","accent","background","surface","line","muted"];function u(c,a){const t=[];for(const d of c)d.text.split(`
|
|
2
|
+
`).forEach((l,f)=>{a.test(l)&&t.push(`${d.path}:${f+1} ${l.trim().slice(0,100)}`)});return t}const A=c=>new RegExp(`\\b${c}\\b`),$=c=>new RegExp(`${c}(?![\\w-])`);function F(c,a){const{check:t,report:d}=S("a theme is one flat palette");{const e=[{path:"fixture.ts",text:`const a = colors.textLight;
|
|
3
|
+
const b = contextLighting;
|
|
4
|
+
`},{path:"fixture.css",text:`.x { color: var(--theme-accent-light-2); }
|
|
5
|
+
.y { color: var(--theme-accent-light); }
|
|
6
|
+
`}],r=u(e,A("textLight"));t("the name reader flags `textLight`, and not `contextLighting`",r.length===1&&r[0].startsWith("fixture.ts:1"),JSON.stringify(r));const n=u(e,$("--theme-accent-light"));t("the token reader flags `--theme-accent-light`, and not `--theme-accent-light-2`",n.length===1&&n[0].startsWith("fixture.css:2"),JSON.stringify(n))}const l=c.filter(e=>k.test(e.path)&&!y(e.path));t(`read the shipped source (${l.length} files, at least ${a.minFiles})`,l.length>=a.minFiles,"every check below asserts an absence, and a read of nothing satisfies an absence");const f=(e,r,n)=>{const s=u(l,r);t(`${e} is gone`,s.length===0,`\`${e}\` still lives in ${s.length} place(s) \u2014 ${n} (66238):
|
|
7
|
+
${s.join(`
|
|
8
|
+
`)}`)};for(const e of x)f(e,A(e),"a theme is ONE flat palette");for(const e of[..._,...R,...b])f(e,A(e),"a theme is ONE flat palette");for(const e of N)f(e,$(e),"the keys and the tokens are ONE mechanism");if(a.theme){const e=a.theme;e.DEFAULT_THEMES.forEach((n,s)=>{const g=n,o=I.filter(h=>typeof g[h]!="string");t(`preset ${s} still states all six base colours`,o.length===0,`lost ${o.join(", ")} \u2014 66238 removes a duplicated HALF, never a colour`);const i=v.filter(h=>h in g);t(`preset ${s} carries no key 66238 deleted`,i.length===0,`still carries ${i.join(", ")}`)}),t(`read the presets (${e.DEFAULT_THEMES.length})`,e.DEFAULT_THEMES.length>0);const r={selected:0,themes:[e.DEFAULT_THEMES[0]]};for(const[n,s]of[["themeAccentStyle",e.themeAccentStyle(r)],["themeColorStyle",e.themeColorStyle(r)]])t(`${n} does not set --accent or --accent-2 directly`,!("--accent"in s)&&!("--accent-2"in s));t("the grading bands sit exactly on the WCAG thresholds",e.gradeContrast(e.READABILITY_AA)==="good"&&e.gradeContrast(e.READABILITY_AA+.5)==="good"&&e.gradeContrast(e.READABILITY_AA-.01)==="large-only"&&e.gradeContrast(e.READABILITY_AA_LARGE)==="large-only"&&e.gradeContrast(e.READABILITY_AA_LARGE-.01)==="hard"&&e.gradeContrast(1)==="hard"),t("the contrast ratio is the real WCAG figure, and symmetric",e.contrastRatio("#000000","#ffffff")===21&&e.contrastRatio("#ffffff","#000000")===21&&e.contrastRatio("not a colour","#ffffff")===null);{const n="#c9a461",s=e.normalizeThemeColors({text:"#0a0a0a",accent:n,background:"#f5f1e8"}).background,g=e.darkerAccents(n),o=[];g.length!==e.ACCENT_DARKEN_STEPS.length&&o.push(`${g.length} suggestions for ${e.ACCENT_DARKEN_STEPS.length} steps`);let i=e.contrastRatio(n,s)??0;for(const h of g){/^#[0-9a-f]{6}$/.test(h)||o.push(`${h} is not a plain hex`);const m=e.contrastRatio(h,s)??0;m>i||o.push(`${h} (${m}) does not beat the previous ${i}`),i=m}e.gradeContrast(i)!=="good"&&o.push(`the deepest reads ${e.gradeContrast(i)}, not good`),t("the darker suggestions are the same hue, and actually read better",o.length===0,o.join("; "))}t("a non-hex suggestion list is empty rather than three swatches of black",e.darkerAccents("var(--brand)").length===0)}if(a.liveAccentCarrier){const e=c.find(r=>r.path===a.liveAccentCarrier);t(`read the live site's accent carrier, ${a.liveAccentCarrier}`,!!e),t("the live site's accent carrier wears sf-theme-accent",!!e&&/className="contents sf-theme-accent"/.test(e.text))}const E=T(c),p=C(c);t(`read this repository's share of the block registry (${E.length} files)`,E.length>0);const L=[...p.matchAll(/className="[^"]*sf-theme-accent/g)].length;return t(`the registry's editor accent carriers wear sf-theme-accent (found ${L}, expected exactly ${a.editorAccentCarriers})`,L===a.editorAccentCarriers),t("the editor preview emits --theme-accent via themeAccentStyle, not a hand-rolled --accent",!/\["--accent"\]:/.test(p)),d()}export{F as flatThemePalette};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type RuleReport, type SourceFile } from "./rule.js";
|
|
2
|
+
export type FullWidthMeansFullOptions = {
|
|
3
|
+
readonly converted: readonly string[];
|
|
4
|
+
readonly carrierFloor: number;
|
|
5
|
+
readonly widthHelper?: string;
|
|
6
|
+
};
|
|
7
|
+
export declare const SITE_CAP = "max-w-[var(--sf-site-width,1600px)]";
|
|
8
|
+
export declare function fullWidthMeansFull(files: readonly SourceFile[], options: FullWidthMeansFullOptions): RuleReport;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{ruleChecks as f}from"./rule.js";const o="max-w-[var(--sf-site-width,1600px)]",p=t=>(t.split("/").pop()??t).replace(/\.tsx$/,"");function a(t){return{asks:t.includes("sectionRunsFullWidth(widthProps)"),column:t.includes(`: "mx-auto ${o}`)||t.includes(`: "relative z-[2] mx-auto ${o}`)||t.includes(`: "mx-auto grid ${o}`)}}function w(t,l){const{check:s,report:c}=f("full width means full");{const e=a(`const full = sectionRunsFullWidth(widthProps);
|
|
2
|
+
<div className={full ? "w-full" : "mx-auto ${o} px-6"} />`),n=a(`<div className="mx-auto ${o} px-6" />`);s("the reader passes a conditional cap",e.asks&&e.column),s("\u2026and fails an unconditional one",!n.asks&&!n.column)}const r=t.filter(e=>e.path.endsWith(".tsx")),i=r.filter(e=>e.text.includes(o));s(`\u2026and it finds the files that carry one (${i.length} of ${r.length} .tsx files, at least ${l.carrierFloor})`,i.length>=l.carrierFloor&&i.length>0,`only ${i.length} files carry ${o}`);for(const e of l.converted){const n=t.find(u=>u.path===e);if(!s(`read ${e}`,!!n,"the converted section is gone \u2014 remove it from the list, or find where it went"))continue;const{asks:d,column:h}=a(n.text);s(`${p(e)} asks whether it runs full width`,d,"its content column is unconditional again \u2014 a merchant choosing Full width would get a capped section, which is the defect this card removed"),s("\u2026and still draws the column when it does not",h,"the other arm lost the cap \u2014 every published page of this type would go edge to edge, which is NOT what this card does")}if(l.widthHelper!==void 0){const e=t.find(n=>n.path===l.widthHelper);s(`read the width helper ${l.widthHelper}`,!!e)&&s("sectionRunsFullWidth resolves absence to the content column, never to full",/resolveWidth\(props as WidthProps, "page"\)/.test(e.text),"absence resolving to `full` sends every published section of these types edge to edge on the day this ships")}return c()}export{o as SITE_CAP,w as fullWidthMeansFull};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type RuleReport, type SourceFile } from "./rule.js";
|
|
2
|
+
export type HeadingCeilingOptions = {
|
|
3
|
+
readonly notSwept?: Readonly<Record<string, string>>;
|
|
4
|
+
readonly reference?: string;
|
|
5
|
+
readonly minSites: number;
|
|
6
|
+
readonly minSwept: number;
|
|
7
|
+
readonly minCapped: number;
|
|
8
|
+
};
|
|
9
|
+
export declare function enclosingLiteral(src: string, at: number): string | null;
|
|
10
|
+
export declare function headingCeilingNotes(files: readonly SourceFile[], options: HeadingCeilingOptions): string[];
|
|
11
|
+
export declare function headingCeilingSweep(files: readonly SourceFile[], options: HeadingCeilingOptions): RuleReport;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import{HEADING_FACE_UTILITIES as _}from"../fonts.js";import{isRuleSource as k,ruleChecks as T}from"./rule.js";import{evalLength as S}from"./support/css-length.js";const j=["app/","components/","lib/"],v="40px",E=["1","1.4"],b=/(?:^|\s)((?:[a-z0-9@_.-]*\[[^\]]*\]:|[a-z0-9@_.-]+:)*)text-\[([^\]]*)\]/g;function L(t){const e=/max-\[(\d+)px\]:/.exec(t);return e?Number(e[1]):1600}function O(t,e){let s=-1,o="";for(let i=e;i>0;i--){const l=t[i-1];if((l==="`"||l==="'"||l==='"')&&t[i-2]!=="\\"){o=l,s=i;break}}if(s===-1)return null;for(let i=e;i<t.length;i++)if(t[i]===o&&t[i-1]!=="\\")return t.slice(s,i);return null}const A=/^(#|rgb|hsl|oklch|color|currentColor|inherit|transparent)/;function y(t){const e=[];for(const s of t){const o=s.text,i=new RegExp(_.join("|"),"g");let l;for(;l=i.exec(o);){const a=O(o,l.index);if(!a)continue;const h=[];b.lastIndex=0;let c;for(;c=b.exec(a);){const p=c[2].replace(/^length:/,"");A.test(p)||h.push({token:c[0].trim(),expr:p,vw:L(c[1])})}h.length!==0&&e.push({file:s.path,line:o.slice(0,l.index).split(`
|
|
2
|
+
`).length,className:a,steps:h})}}return e}function u(t,e){return S(t.expr,t.vw,e)}const C=t=>u(t,{"--scale-heading":"1"})>40;function m(t,e){return t[`${e.file}:${e.line}`]??Object.entries(t).find(([s])=>{const o=s.indexOf("#");return o>0&&s.slice(0,o)===e.file&&e.className.includes(s.slice(o+1))})?.[1]??t[e.file]}const I=t=>t.filter(e=>/\.tsx?$/.test(e.path)&&!k(e.path)&&j.some(s=>e.path.startsWith(s)));function D(t,e){const s=e.notSwept??{},o=y(I(t)).filter(l=>!m(s,l)).flatMap(l=>l.steps.filter(a=>!C(a)&&u(a,{"--sf-heading-max":v,"--scale-heading":"1.4"})>40).map(a=>`${l.file}:${l.line} \xB7 ${a.token}`)),i=[];if(o.length){i.push(` note \u2014 ${o.length} step(s) clear 40px at the default heading scale but not at 1.4; outside this card's census, listed so they are not a silent gap:`);for(const l of o)i.push(` ${l}`)}for(const[l,a]of Object.entries(s))i.push(` note \u2014 not swept: ${l} \u2014 ${a}`);return i}function H(t,e){const{check:s,report:o}=T("heading ceiling sweep"),i=e.notSwept??{},l=I(t),a=y(l);s(`read the source (${l.length} .ts/.tsx files)`,l.length>0,"found no source to sweep \u2014 this rule is not measuring anything"),s(`the scanner finds display headings at all (${a.length}, at least ${e.minSites})`,a.length>=e.minSites,`found ${a.length} heading-face class lists with a text-[\u2026] size`);const h=a.filter(n=>!m(i,n)&&n.steps.some(C));for(const n of Object.keys(i)){const r=n.split(/[:#]/)[0];s(`notSwept["${n}"] still matches a real site`,a.some(f=>f.file===r&&m(i,f)===i[n]))}s(`the census finds the headings a 40px ceiling has to bring down (${h.length}, at least ${e.minSwept})`,h.length>=e.minSwept,`only ${h.length} class lists declare a size above 40px`);const c=[];for(const n of h)for(const r of n.steps)for(const f of E){const d=u(r,{"--sf-heading-max":v,"--scale-heading":f});d>40&&c.push(`${n.file}:${n.line} @scale ${f} \u2192 ${d}px \xB7 ${r.token}`)}s("no swept display heading renders above the site's 40px ceiling",c.length===0,`${c.length} step(s) ignore it:
|
|
3
|
+
${c.join(`
|
|
4
|
+
`)}`);const p=a.flatMap(n=>n.steps.filter(r=>r.expr.includes("--sf-heading-max")).map(r=>({site:n,step:r})));s(`the sweep actually capped headings (${p.length} steps read --sf-heading-max, at least ${e.minCapped})`,p.length>=e.minCapped);const g=[];for(const{site:n,step:r}of p){const f=/^min\((.*),\s*var\(--sf-heading-max,[^)]*\)\)$/.exec(r.expr)?.[1];if(f!==void 0)for(const d of E){const $=S(f,r.vw,{"--scale-heading":d}),w=u(r,{"--scale-heading":d});$!==w&&g.push(`${n.file}:${n.line} @scale ${d}: ${$}px \u2192 ${w}px`)}}if(s("a tenant that sets no ceiling renders exactly what it renders today",g.length===0,`${g.length} step(s) moved:
|
|
5
|
+
${g.join(`
|
|
6
|
+
`)}`),e.reference!==void 0){const n=t.find(r=>r.path===e.reference);s(`the reference component still spells the ceiling the one way (${e.reference})`,!!n&&/var\(--sf-heading-max,\s*9999px\)/.test(n.text),`${e.reference} no longer reads var(--sf-heading-max,9999px)`)}const N=/^var\(--sf-heading-max,/,x=p.filter(({step:n})=>!N.test(n.expr)).filter(({step:n})=>!/^min\(.*,var\(--sf-heading-max,9999px\)\)$/.test(n.expr)).map(({site:n,step:r})=>`${n.file}:${n.line} \xB7 ${r.token}`);return s("every capped step is spelt the reference's way",x.length===0,`${x.length} second spelling(s):
|
|
7
|
+
${x.join(`
|
|
8
|
+
`)}`),o()}export{O as enclosingLiteral,D as headingCeilingNotes,H as headingCeilingSweep};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type RuleReport, type SourceFile } from "./rule.js";
|
|
2
|
+
export type LabelHintsOptions = {
|
|
3
|
+
readonly minLabels: number;
|
|
4
|
+
readonly minJsxLabels: number;
|
|
5
|
+
};
|
|
6
|
+
export declare function hintsIn(label: string): string[];
|
|
7
|
+
export declare function labelHints(files: readonly SourceFile[], options: LabelHintsOptions): RuleReport;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import{ruleChecks as m}from"./rule.js";import{readJsxLabels as $,readLabels as k}from"./support/label-extraction.js";function W(t){const e=[];return t.includes("==")?e.push("shows raw `==` to the merchant"):t.includes("=")&&e.push("carries an `x = y` legend"),/[()]/.test(t)&&e.push("carries a bracket hint"),t.includes(" \u2014 ")&&e.push("carries a ` \u2014 ` hint tail"),e}function j(t){return t.includes("=")?t.includes("==")?["shows raw `==` to the reader"]:["carries an `x = y` legend"]:[]}function x(t){const e=k(t.text),a=[];for(const r of e){const l=W(r.label);l.length&&a.push({where:`${t.path}:${r.line}`,label:r.label,why:l})}return{read:e.length,offenders:a}}function g(t){const e=$(t.text),a=[];for(const{line:r,label:l}of e){const i=j(l);i.length&&a.push({where:`${t.path}:${r}`,label:l,why:i})}return{read:e.length,offenders:a}}const w=t=>`${t.length} label(s) are hints, not names \u2014 the manual does the teaching:
|
|
2
|
+
`+t.map(e=>` ${e.where} ${JSON.stringify(e.label)} \u2014 ${e.why.join(", ")}`).join(`
|
|
3
|
+
`);function L(t,e){const{check:a,report:r}=m("label hints");{const n=x({path:"lib/puck/fixture.tsx",text:['heading: plainText("Heading (new line = break)"),','accent: plainText("Accent ==word=="),','legend: text("Size = px"),','tail: textarea("Body \u2014 one paragraph"),','body: plainText("Body", { placeholder: "A ==word== in the theme colour" }),','layout: { type: "select", label: "Layout",',' options: [{ label: "Split (editorial aside)", value: "split" }] },','defaultProps: { heading: "Our ==new== range" },'].join(`
|
|
4
|
+
`)}),s=y=>n.offenders.filter(h=>h.where.endsWith(`:${y}`)).flatMap(h=>h.why);a("W1 flags a bracket hint (and the `x = y` inside it)",s(1).includes("carries a bracket hint")&&s(1).includes("carries an `x = y` legend")),a("W1 flags raw `==` in a label",s(2).includes("shows raw `==` to the merchant")),a("W1 flags an `x = y` legend",s(3).includes("carries an `x = y` legend")),a("W1 flags a ` \u2014 ` hint tail",s(4).includes("carries a ` \u2014 ` hint tail")),a("W1 passes a placeholder, a select option and a default prop, and reads the labels it should",n.offenders.length===4&&n.read===6,JSON.stringify(n));const o=g({path:"components/Fixture.tsx",text:['<Field label="Accent (==word==)" />','<Field label="Size = px" />','<Field label="Name (optional)" />','<button aria-label="a = b" />'].join(`
|
|
5
|
+
`)});a("W2 flags `==` and `x = y` in a JSX label, leaves a bracket alone, and reads no aria-label",o.offenders.length===2&&o.read===3&&o.offenders[0].why[0]==="shows raw `==` to the reader",JSON.stringify(o))}const l=t.filter(n=>n.path.startsWith("lib/puck/")&&/\.(ts|tsx)$/.test(n.path)),i=t.filter(n=>n.path.startsWith("components/")&&n.path.endsWith(".tsx")),f=l.map(x),u=i.map(g),d=f.reduce((n,s)=>n+s.read,0),c=u.reduce((n,s)=>n+s.read,0),p=f.flatMap(n=>n.offenders),b=u.flatMap(n=>n.offenders);return a(`read >= ${e.minLabels} field labels across ${l.length} files under lib/puck (found ${d})`,d>=e.minLabels,"the reader is broken, not the panel"),a(`read >= ${e.minJsxLabels} JSX label attributes across ${i.length} files under components (found ${c})`,c>=e.minJsxLabels,"the reader is broken, not the panel"),a(`W1 every field label under lib/puck is a plain name (${d} read)`,p.length===0,w(p)),a(`W2 no JSX label under components shows \`=\` (${c} read)`,b.length===0,w(b)),r()}export{W as hintsIn,L as labelHints};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type RuleReport, type SourceFile } from "./rule.js";
|
|
2
|
+
export declare const NEVER_WORDS: readonly string[];
|
|
3
|
+
export type ParkedLabel = {
|
|
4
|
+
readonly file: string;
|
|
5
|
+
readonly label: string;
|
|
6
|
+
readonly why: string;
|
|
7
|
+
};
|
|
8
|
+
export type LabelVocabularyOptions = {
|
|
9
|
+
readonly floors: Readonly<Record<string, number>>;
|
|
10
|
+
readonly minRegistryLabels: number;
|
|
11
|
+
readonly parked: readonly ParkedLabel[];
|
|
12
|
+
};
|
|
13
|
+
export declare function vocabularyBreaches(label: string, item: boolean): string[];
|
|
14
|
+
export declare function labelVocabulary(files: readonly SourceFile[], options: LabelVocabularyOptions): RuleReport;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import{failedChecks as $,ruleChecks as x}from"./rule.js";import{isPanelFile as v,readLabels as w,readPanelLabels as C}from"./support/label-extraction.js";import{registryFiles as T}from"./support/registry-source.js";const p=["kicker","tagline","headline","blurb","description","copy","paragraph","photo","picture","cta","kind","class","grayscale","greyscale","colour","align","align items","text alignment","centre","catalogue","behaviour","labelled","stylised","stack","container","gutter","margin","site width","max width","contained","boxed","header offset","clearance"],j=o=>o.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),R=p.map(o=>({word:o,pattern:new RegExp(`\\b${j(o)}s?\\b`)}));function H(o){return o.split(/\(| — /)[0].trim()}function k(o,c){const t=H(o).toLowerCase(),a=[];for(const{word:d,pattern:l}of R)l.test(t)&&a.push(`N10.1 "${d}"`);/^title\b/.test(t)&&!c&&a.push("N10.2 Title at section level"),/^heading\b/.test(t)&&c&&a.push("N10.2 Heading at item level");const e=/\b(button|link)\s+(text|label|href|url)$/.exec(t);return e&&a.push(`N10.3 "${e[1]} ${e[2]}"`),t==="text"&&a.push("N10.4 bare Text"),a}function N(o,c,t){const a=T(o),e=o.filter(v),d=new Map,l=[],h=(n,s)=>{for(const u of n){const y=s(u.text);d.set(u.path,y.length);for(const m of y)l.push({...m,file:u.path,why:k(m.label,m.item)})}};h(a,w),h(e,C);for(const[n,s]of Object.entries(c.floors)){const u=d.get(n);t(`${n} yields >= ${s} labels (found ${u??"none: not read"})`,u!==void 0&&u>=s,u===void 0?"it has a floor but was not read \u2014 it dropped out of the panels and the registry":"the reader is broken, not the panel")}const r=a.reduce((n,s)=>n+(d.get(s.path)??0),0);t(`the block registry yields >= ${c.minRegistryLabels} labels across ${a.length} files (found ${r})`,r>=c.minRegistryLabels,"the reader is broken, not the panel");const g=l.filter(n=>n.why.length>0),f=n=>c.parked.some(s=>s.file===n.file&&s.label===n.label),i=g.filter(n=>!f(n)),b=l.filter(n=>n.item).length;t(`every field label obeys N10.1\u2013N10.4 (${l.length} read across ${a.length+e.length} files: ${l.length-b} section-level, ${b} item-level)`,i.length===0,`${i.length} break doc/naming.md N10:
|
|
2
|
+
`+i.map(n=>` ${n.file}:${n.line} ${n.item?"[item] ":"[section]"} ${JSON.stringify(n.label)} \u2014 ${n.why.join(", ")}`).join(`
|
|
3
|
+
`));for(const n of c.parked)t(`PARKED ${n.file} ${JSON.stringify(n.label)} still breaks N10 \u2014 ${n.why}`,g.some(s=>s.file===n.file&&s.label===n.label),"it no longer breaks N10 (renamed, or its row deleted) \u2014 take it out of the list");return{read:l,live:i}}function L(o,c){const{check:t,report:a}=x("label vocabulary");t(`N10.1 forbids ${p.length} words, each written once, lower-case and trimmed: ${[...p].sort().join(", ")}`,p.length>0&&new Set(p).size===p.length&&p.every(e=>e===e.trim().toLowerCase()&&e.length>0),JSON.stringify(p));{const e=(l,h=!1)=>k(l,h),d=p.filter(l=>{const h=`N10.1 "${l}"`,r=l[0].toUpperCase()+l.slice(1);return!e(r).includes(h)||!e(`Card ${l}s`).includes(h)});t("N10.1 catches every word on the list, alone and as a qualified plural",d.length===0,d.join(", ")),t("N10.1 \u2026but not inside a longer word",e("Copyright").length===0&&e("Classic layout").length===0&&e("Stacking order").length===0,JSON.stringify([e("Copyright"),e("Classic layout"),e("Stacking order")])),t("N10.2 a section's label may not start Title, an item's may not start Heading",e("Title").includes("N10.2 Title at section level")&&e("Heading",!0).includes("N10.2 Heading at item level")),t("N10.2 \u2026and each is right at its own level",e("Heading").length===0&&e("Title",!0).length===0&&e("Card title").length===0&&e("Section heading",!0).length===0),t("N10.3 nothing follows `button` or `link`",e("Button text").includes('N10.3 "button text"')&&e("Submit button label").includes('N10.3 "button label"')&&e("Link href").includes('N10.3 "link href"')&&e("Archive link URL").includes('N10.3 "link url"')),t("N10.3 \u2026and the pair itself passes",e("Button").length===0&&e("Button link").length===0&&e("Archive link").length===0),t("N10.4 a bare Text fails; Alt text is a name",e("Text").includes("N10.4 bare Text")&&e("Alt text").length===0),t("the name is cut at a hint tail, so a hint cannot corrupt the verdict",e("Body (blank line = new paragraph)").length===0&&e("Copy \u2014 the words under it").includes('N10.1 "copy"'))}{const e=[{path:"lib/puck/config.tsx",text:['heading: plainText("Heading"),','eyebrow: plainText("Kicker"),','title: plainText("Title"),','cards: { type: "array", label: "Cards",'," arrayFields: {",' heading: plainText("Heading"),',' title: plainText("Card title"),'," },","},",'layout: { type: "select", label: "Layout",',' options: [{ label: "Centre", value: "center" }] },'].join(`
|
|
4
|
+
`)},{path:"components/FixturePanel.tsx",text:['import { SettingsField } from "efficient-easel/panel";',"const items = [",' { label: "Copy", onClick: () => copy() },',"];","const rows = [",' { key: "photo", label: "Photo", group: "media" },',"];",'<SettingsField label="Colour" />'].join(`
|
|
5
|
+
`)},{path:"components/HandRolled.tsx",text:'<div className="sf-field"><Row label="Gutter" /></div>'},{path:"components/ShopperForm.tsx",text:'<Field label="Description" />'}],d=x("fixture"),{read:l,live:h}=N(e,{floors:{"components/FixturePanel.tsx":5,"components/HandRolled.tsx":1,"components/Moved.tsx":1},minRegistryLabels:8,parked:[{file:"components/FixturePanel.tsx",label:"Colour",why:"fixture: still breaks"},{file:"lib/puck/config.tsx",label:"Headline",why:"fixture: renamed long ago"}]},d.check),r=$(d.report()).map(i=>i.name),g=i=>r.some(b=>b.startsWith(i)),f=l.map(i=>i.label);t("the fixture reads the registry's fields and the panels' rows, and no option, action or shopper's form",f.join(" \xB7 ")==="Heading \xB7 Kicker \xB7 Title \xB7 Cards \xB7 Heading \xB7 Card title \xB7 Layout \xB7 Photo \xB7 Colour \xB7 Gutter",f.join(" \xB7 ")),t("\u2026and the breaches are the ones it wrote, the parked one waived",h.map(i=>`${i.label}=${i.why.join("+")}`).join(" \xB7 ")==='Kicker=N10.1 "kicker" \xB7 Title=N10.2 Title at section level \xB7 Heading=N10.2 Heading at item level \xB7 Photo=N10.1 "photo" \xB7 Gutter=N10.1 "gutter"',JSON.stringify(h.map(i=>[i.label,i.why]))),t("a file under its floor goes red",g("components/FixturePanel.tsx yields")&&!g("components/HandRolled.tsx yields"),r.join(" | ")),t("a floored file that is not read goes red",g("components/Moved.tsx yields"),r.join(" | ")),t("a registry under its floor goes red",g("the block registry yields"),r.join(" | ")),t("a PARKED label that no longer breaks N10 goes red, and one that still does is waived",g('PARKED lib/puck/config.tsx "Headline"')&&!g('PARKED components/FixturePanel.tsx "Colour"'),r.join(" | ")),t("the verdict goes red on a live breach",g("every field label obeys"),r.join(" | ")),t("\u2026and nothing else did",r.length===5,r.join(" | "))}return N(o,c,t),a()}export{p as NEVER_WORDS,L as labelVocabulary,k as vocabularyBreaches};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type * as TS from "typescript";
|
|
2
|
+
import { type RuleReport, type SourceFile } from "./rule.js";
|
|
3
|
+
export type MirroredPair = {
|
|
4
|
+
readonly row: string;
|
|
5
|
+
readonly constant: string;
|
|
6
|
+
readonly declaredIn: string;
|
|
7
|
+
readonly drawnIn: string;
|
|
8
|
+
};
|
|
9
|
+
export type MirroredRowsOptions = {
|
|
10
|
+
readonly mirrored?: readonly MirroredPair[];
|
|
11
|
+
readonly sameWord?: readonly string[];
|
|
12
|
+
readonly floors: {
|
|
13
|
+
readonly pairs: number;
|
|
14
|
+
readonly labels: number;
|
|
15
|
+
readonly panelRows: number;
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
export declare function glyphOf(text: string): string;
|
|
19
|
+
export declare function mirroredRowsAgree(ts: typeof TS, files: readonly SourceFile[], options: MirroredRowsOptions): RuleReport;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import{ruleChecks as k}from"./rule.js";import{blockSource as E,registryFiles as S}from"./support/registry-source.js";const x="lib/puck/controls.tsx",j=["slider","select","segmented","textList"];function y(c){return/icon=\{<([A-Z][A-Za-z0-9]*Icon)\s*\/>\}/.exec(c)?.[1]??/<([A-Z][A-Za-z0-9]*Icon)\s*\/>/.exec(c)?.[1]??/<FieldGlyph noun="([a-z]+)"/.exec(c)?.[1]??"none"}function I(c){const s=new Map;for(const l of c)l.text.split(`
|
|
2
|
+
`).forEach((t,p)=>{const a=t.trim();if(!(a.startsWith("//")||a.startsWith("*")||a.startsWith("/*")))for(const h of j){if(new RegExp(`^(export )?function ${h}\\(`).test(a))continue;const d=t.match(new RegExp(`(^|[^.\\w])${h}\\(\\s*"([^"]+)"`));d&&s.set(d[2],[...s.get(d[2])??[],{file:l,line:p+1,builder:h}])}});return s}function R(c){const s=[];for(const l of c)l.text.split(`
|
|
3
|
+
`).forEach((t,p)=>{const a=t.match(/<SettingsField\s+label="([^"]+)"/);a&&s.push({file:l.path,line:p+1,label:a[1].trim(),glyph:y(t)})});return s}function W(c,s,l){const{check:t,report:p}=k("mirrored rows agree"),a=l.mirrored??[],h=l.sameWord??[];{const e={path:"fixture.tsx",text:["export function select(label: string) {}",'const a = select("Product", <BoxIcon />, options);','// select("In a comment", <BoxIcon />)','const b = usePreviewParts().select("Not a row");','const c = <SettingsField label="Product" icon={<BoxIcon />}>{x}</SettingsField>;'].join(`
|
|
4
|
+
`)},o=I([e]),n=R([e]);t("the builder-label reader finds a call, and not its declaration, a comment or another object's method",[...o.keys()].join()==="Product"&&o.get("Product")?.[0].line===2,JSON.stringify([...o.keys()])),t("the row reader finds a hand-drawn row and the glyph it wears",n.length===1&&n[0].label==="Product"&&n[0].glyph==="BoxIcon",JSON.stringify(n))}const d=s.find(e=>e.path===x);for(const e of a){const o=d?new RegExp(`export const ${e.constant} = \\{[\\s\\S]*?\\} as const;`).exec(d.text):null;t(`${e.constant} is declared in ${x}`,o!==null),o&&(t("\u2026and carries the label",/label:\s*"/.test(o[0]),o[0].slice(0,120)),t("\u2026and carries the glyph",/icon:\s*</.test(o[0]),o[0].slice(0,120)));let n=null;try{n=E(c,s,e.declaredIn)}catch{n=null}t(`read the ${e.declaredIn} block`,n!==null,`no block "${e.declaredIn}" among the files handed in`);const r=s.find(i=>i.path===e.drawnIn)?.text??null;t(`read ${e.drawnIn}`,r!==null);for(const[i,$]of[[`the ${e.declaredIn} block`,n],[e.drawnIn,r]])$!==null&&(t(`${i} spreads ${e.constant}`,new RegExp(`${e.constant}\\.(label|icon)`).test($)),t(`\u2026and no longer hard-codes "${e.row}"`,!new RegExp(`"${e.row}"`).test($),`${i} still contains the literal`))}t(`the mirrored pairs were checked (${a.length}, at least ${l.floors.pairs}; an empty sweep proves nothing)`,a.length>=l.floors.pairs);const f=I([...S(s),...d?[d]:[]]),w=s.filter(e=>/^components\/[^/]+\.tsx$/.test(e.path)),u=R(w),g=[],m=[];for(const e of u){if(!f.has(e.label))continue;if(h.includes(e.label)){m.push({at:`${e.file}:${e.line}`,label:e.label,glyph:e.glyph});continue}const o=(f.get(e.label)??[]).map(n=>`${n.builder} @ ${n.file.path}:${n.line}`).join(" \xB7 ");g.push(`${e.file}:${e.line} "${e.label}" \u2014 also ${o}`)}t(`the builder-label scan read something (${f.size} labels, at least ${l.floors.labels})`,f.size>=l.floors.labels),t(`the component scan read something (${u.length} hand-drawn rows in ${w.length} component files, at least ${l.floors.panelRows})`,u.length>=l.floors.panelRows),t("no NEW hard-coded mirror",g.length===0,`
|
|
5
|
+
${g.join(`
|
|
6
|
+
`)}`);const b=h.filter(e=>!f.has(e));t("no same-word entry has outlived its subject",b.length===0,b.join(" \xB7 "));for(const e of h){const o=new Set,n=[];for(const r of m.filter(i=>i.label===e))o.add(r.glyph),n.push(`${r.at} \u2192 ${r.glyph}`);for(const r of f.get(e)??[]){const i=y(r.file.text.split(`
|
|
7
|
+
`).slice(r.line-1,r.line+6).join(`
|
|
8
|
+
`));o.add(i),n.push(`${r.file.path}:${r.line} \u2192 ${i}`)}t(`"${e}" draws ONE picture wherever it is declared`,o.size===1,`${o.size} different:
|
|
9
|
+
${n.join(`
|
|
10
|
+
`)}`),t(`\u2026and "${e}" was actually found in both places`,n.length>=2,`${n.length}`)}return p()}export{y as glyphOf,W as mirroredRowsAgree};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type * as TS from "typescript";
|
|
2
|
+
import { type RuleReport, type SourceFile } from "./rule.js";
|
|
3
|
+
export type JsxCommentFinding = {
|
|
4
|
+
readonly file: string;
|
|
5
|
+
readonly line: number;
|
|
6
|
+
readonly text: string;
|
|
7
|
+
};
|
|
8
|
+
export declare function jsxCommentLines(ts: typeof TS, file: SourceFile): JsxCommentFinding[];
|
|
9
|
+
export declare function noCommentInJsx(ts: typeof TS, files: readonly SourceFile[]): RuleReport;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import{ruleChecks as g}from"./rule.js";function h(n,a){const s=n.createSourceFile(a.path,a.text,n.ScriptTarget.Latest,!0,n.ScriptKind.TSX),l=[],o=t=>{if(n.isJsxText(t)){const r=t.getFullText(s),e=t.getFullStart();r.split(`
|
|
2
|
+
`).forEach((m,c)=>{const i=m.trim();if(!(i.startsWith("//")||i.startsWith("/*")||i.startsWith("*/"))||i.startsWith("//")&&/^\/\/[A-Za-z0-9.-]+\.[A-Za-z]{2,}\//.test(i))return;const f=e+r.split(`
|
|
3
|
+
`).slice(0,c).join(`
|
|
4
|
+
`).length+(c>0?1:0),{line:x}=s.getLineAndCharacterOfPosition(f);l.push({file:a.path,line:x+1,text:i.length>90?`${i.slice(0,90)}\u2026`:i})})}n.forEachChild(t,o)};return o(s),l}function d(n,a){const{check:s,report:l}=g("no comment in JSX"),o=h(n,{path:"fixture.tsx",text:["const a = ("," <div>"," // this line is printed on the page"," {/* this one is a comment */}",' <a href="x">//cdn.example.com/x.js</a>'," </div>",");"].join(`
|
|
5
|
+
`)});s("the reader flags a `//` line between tags, and neither a braced comment nor a protocol-relative URL",o.length===1&&o[0].line===3,JSON.stringify(o));const t=a.filter(e=>e.path.endsWith(".tsx"));s(`read the .tsx files (${t.length})`,t.length>0,"found no .tsx files to scan \u2014 this rule is not measuring anything");const r=t.flatMap(e=>h(n,e));return s(`no \`//\` or \`/* */\` comment line sits between JSX tags (${t.length} .tsx files)`,r.length===0,`${r.length} line(s) React renders as TEXT on the page \u2014 wrap them in {/* ... */}:
|
|
6
|
+
`+r.map(e=>` ${e.file}:${e.line} ${e.text}`).join(`
|
|
7
|
+
`)),l()}export{h as jsxCommentLines,d as noCommentInJsx};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type RuleReport, type SourceFile } from "./rule.js";
|
|
2
|
+
export declare const CONTROLS_FILE = "lib/puck/controls.tsx";
|
|
3
|
+
export type NoGlyphRowsOptions = {
|
|
4
|
+
readonly expected: number;
|
|
5
|
+
readonly minChars: number;
|
|
6
|
+
readonly controls?: {
|
|
7
|
+
readonly buildersFloor: number;
|
|
8
|
+
};
|
|
9
|
+
};
|
|
10
|
+
export type NoGlyphRow = {
|
|
11
|
+
readonly at: string;
|
|
12
|
+
readonly reason: string;
|
|
13
|
+
};
|
|
14
|
+
export declare function noGlyphRowsIn(file: SourceFile): NoGlyphRow[];
|
|
15
|
+
export declare function noGlyphRows(files: readonly SourceFile[], options: NoGlyphRowsOptions): RuleReport;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import{isRegistryPath as m,registryFiles as x}from"./support/registry-source.js";import{ruleChecks as y}from"./rule.js";const d="lib/puck/controls.tsx",u=/doc\/naming\.md|N10\.\d|owner|GG|SS seat|editor-shell|\d{4}-\d{2}-\d{2}/;function w(r){const e=x(r),o=r.filter(n=>n.path===d&&!m(n.path)),h=r.filter(n=>/^components\/[^/]+\.tsx$/.test(n.path));return[...e,...o,...h]}function f(r){const e=r.text,o=[],h=/noGlyph\(/g;let n;for(;n=h.exec(e);){const l=e.lastIndexOf(`
|
|
2
|
+
`,n.index)+1,s=e.slice(l,n.index);if(/^\s*(\/\/|\*|\/\*)/.test(s)||(s.match(/"/g)??[]).length%2===1||/\bfunction\s+$/.test(s))continue;let c=1,a=n.index+n[0].length;for(;a<e.length&&c>0;a++)e[a]==="("?c+=1:e[a]===")"&&(c-=1);const i=[...e.slice(n.index+n[0].length,a-1).matchAll(/"((?:[^"\\]|\\.)*)"/g)].map(g=>g[1]).join(""),p=e.slice(0,n.index).split(`
|
|
3
|
+
`).length;o.push({at:`${r.path}:${p}`,reason:i})}return o}function $(r,e){const{check:o,report:h}=y("no-glyph rows");{const t=f({path:"fixture.tsx",text:["/**"," * `noGlyph(reason)` \u2014 the docblock names it; that is not a use."," */","export function noGlyph(reason: string) {",' if (!reason) throw new Error("noGlyph() needs a reason");',"}",'const a = select("Process", noGlyph(',` "A facet's options grow out of the CATALOGUE \u2014 owner, " +`,' "2026-08-29.",',"));",'// noGlyph("in a comment") is not a use','const b = noGlyph("");'].join(`
|
|
4
|
+
`)});o("the reader finds the two calls, and neither the docblock, the declaration, the string nor the comment",t.length===2&&t[0].at==="fixture.tsx:7"&&t[1].at==="fixture.tsx:12",JSON.stringify(t)),o("\u2026reads a concatenated reason whole, so it can be checked for a source",t[0]?.reason==="A facet's options grow out of the CATALOGUE \u2014 owner, 2026-08-29."&&u.test(t[0].reason),JSON.stringify(t[0])),o("\u2026and reads a bare call as no reason",t[1]?.reason==="",JSON.stringify(t[1]))}const n=w(r),l=n.reduce((t,i)=>t+i.text.length,0);o(`the scan read the files it meant to (${n.length} files, ${l} characters, at least ${e.minChars})`,l>=e.minChars,"the registry, lib/puck/controls.tsx or components/ moved \u2014 a scan that reads nothing finds no exceptions");const s=n.flatMap(f),c=s.filter(t=>!t.reason.trim());o("every noGlyph() states a reason",c.length===0,c.map(t=>t.at).join(" \xB7 "));const a=s.filter(t=>t.reason.trim()&&!u.test(t.reason));if(o("\u2026and every reason names a source that can be checked",a.length===0,a.map(t=>`${t.at} \u2014 "${t.reason.slice(0,60)}"`).join(" \xB7 ")),o(`the no-glyph rows still number ${e.expected} (found ${s.length}${s.length?`: ${s.map(t=>t.at).join(", ")}`:""})`,s.length===e.expected,"a ruling was added or lost \u2014 move the number, with the ruling, in the guard that counts it"),e.controls){const t=r.find(p=>p.path===d)?.text??"";o(`read ${d}`,t.length>0,"the file noGlyph and iconOf are written in is not among the files handed in"),o(`noGlyph is still exported from ${d}`,/export function noGlyph\(/.test(t)),o("\u2026and a marker is unwrapped rather than drawn as an empty gutter",/export function iconOf\(/.test(t)&&/isNoGlyph\(icon\) \? undefined : icon/.test(t),"SettingsField draws its icon span only when given an icon");const i=(t.match(/icon=\{iconOf\(icon\)\}/g)??[]).length;o(`\u2026and the shared builders pass their icon through it (${i}, at least ${e.controls.buildersFloor})`,i>=e.controls.buildersFloor,`${i} builders`)}return h()}export{d as CONTROLS_FILE,$ as noGlyphRows,f as noGlyphRowsIn};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type RuleReport, type SourceFile } from "./rule.js";
|
|
2
|
+
export type OneColourControlOptions = {
|
|
3
|
+
readonly sharedControl?: string;
|
|
4
|
+
readonly minFiles: number;
|
|
5
|
+
};
|
|
6
|
+
export declare const stripComments: (src: string) => string;
|
|
7
|
+
export declare function oneColourControl(files: readonly SourceFile[], options: OneColourControlOptions): RuleReport;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{ruleChecks as $}from"./rule.js";const n=a=>a.replace(/\/\*[\s\S]*?\*\//g,"").replace(/(^|[^:])\/\/.*$/gm,"$1"),l=new RegExp('type=\\{?"color"'),d=new RegExp("<ColourPicker\\b"),c=new RegExp('className="[^"]*sf-(ink|colorinput)');function k(a,r){const{check:t,report:p}=$("one colour control");{const e='<input type="color" value={v} />',m="<ColourPicker value={v} onChange={f} />";t("the reader sees a native colour input",l.test(n(e))),t("\u2026and not one a comment talks about",!l.test(n(`/* ${e} */
|
|
2
|
+
// ${e}`))),t("the reader sees a ColourPicker",d.test(n(m))),t("\u2026and the retired classes in markup",c.test('<span className="sf-ink-row" />')&&c.test('<div className="x sf-colorinput" />'))}const s=a.filter(e=>/\.tsx?$/.test(e.path));t(`read the source (${s.length} TS/TSX files, at least ${r.minFiles})`,s.length>=r.minFiles,"fewer means the walk broke, and every check below is vacuous");const i=s.map(e=>[e.path,n(e.text)]),h=i.filter(([,e])=>l.test(e)).map(([e])=>e),o=i.filter(([,e])=>d.test(e)).map(([e])=>e);t("\xA71 nothing draws a native colour input \u2014 its window is the operating system's",h.length===0,h.join(", ")),r.sharedControl?(t(`read the shared control ${r.sharedControl}`,s.some(e=>e.path===r.sharedControl)),t("\xA71 exactly one file draws efficient-easel's ColourPicker",o.length===1,o.length===0?"NONE \u2014 the reader is broken, and every check below is vacuous":`${o.length}: ${o.join(", ")}`),t(`\xA71 \u2026and it is the shared control, ${r.sharedControl}`,o[0]===r.sharedControl,o.join(", "))):t("\xA71 no file here draws efficient-easel's ColourPicker \u2014 the builder's shared control is the one that does",o.length===0,`${o.length}: ${o.join(", ")}`);const u=s.filter(e=>c.test(e.text)).map(e=>e.path);return t("\xA79 nothing draws a `sf-ink-` or `sf-colorinput` class any more",u.length===0,u.join(", ")),p()}export{k as oneColourControl,n as stripComments};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type * as TS from "typescript";
|
|
2
|
+
import { type RuleReport, type SourceFile } from "./rule.js";
|
|
3
|
+
export type OneDropdownOptions = {
|
|
4
|
+
readonly notEditor?: Readonly<Record<string, readonly [number, string]>>;
|
|
5
|
+
readonly ownedNow?: Readonly<Record<string, readonly [number, string]>>;
|
|
6
|
+
readonly until?: Readonly<Record<string, readonly [number, string, () => boolean]>>;
|
|
7
|
+
readonly fieldSelectFloor: number;
|
|
8
|
+
readonly minFiles: number;
|
|
9
|
+
};
|
|
10
|
+
export declare function oneDropdown(ts: typeof TS, files: readonly SourceFile[], options: OneDropdownOptions): RuleReport;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import{ruleChecks as x}from"./rule.js";function S(c,d){const i=c.createSourceFile(d.path,d.text,c.ScriptTarget.Latest,!0,c.ScriptKind.TSX),n=[];let g=0;const h=s=>i.getLineAndCharacterOfPosition(s.getStart(i)).line+1,u=s=>{if(c.isJsxOpeningElement(s)||c.isJsxSelfClosingElement(s)){const a=s.tagName.getText(i);a==="select"&&n.push({file:d.path,line:h(s),what:"R1 raw <select> \u2014 use efficient-easel's FieldSelect"}),(a==="FieldSelect"||/^FieldSelect</.test(a))&&g++}if(c.isCallExpression(s)){const a=s.expression.getText(i),r=s.arguments[0];(a==="h"||/(^|\.)createElement$/.test(a))&&r&&c.isStringLiteralLike(r)&&r.text==="select"&&n.push({file:d.path,line:h(s),what:`R2 ${a}("select") \u2014 use efficient-easel's FieldSelect`})}c.forEachChild(s,u)};return u(i),{selects:n,fieldSelect:g}}function v(c,d,i){const{check:n,report:g}=x("one dropdown"),h=i.notEditor??{},u=i.ownedNow??{},s=i.until??{};{const e=["const a = <select value={v} onChange={f}><option>x</option></select>;",'const b = h("select", { value: v });','const c = React.createElement("select", null);',"// a comment about <select> is not a use","const d = <FieldSelect value={v} options={o} onChange={f} />;","const e = <FieldSelect<string> value={v} options={o} onChange={f} />;",'const s = "<select>"; const t = <Select />;'].join(`
|
|
2
|
+
`),{selects:t,fieldSelect:f}=S(c,{path:"fixture.tsx",text:e}),l=t.map(o=>o.line);n("R1 flags a JSX <select>",t.some(o=>o.line===1&&o.what.startsWith("R1"))),n('R2 flags h("select")',t.some(o=>o.line===2&&o.what.startsWith("R2"))),n('R2 flags React.createElement("select")',t.some(o=>o.line===3&&o.what.startsWith("R2"))),n("a comment, a string and a <Select> component are not uses",!l.includes(4)&&!l.includes(7)),n("FieldSelect passes and is counted, generic form too",!l.includes(5)&&!l.includes(6)&&f===2)}const a=d.filter(e=>/\.tsx?$/.test(e.path)&&!e.path.endsWith(".d.ts")),r=new Map;let w=0;for(const e of a){const t=S(c,e);t.selects.length&&r.set(e.path,t.selects),w+=t.fieldSelect}const p=[];for(const[e,t]of r)e in h||e in u||e in s||p.push(...t);n("no raw <select> in editor code",p.length===0,`${p.length} hit(s):
|
|
3
|
+
`+p.map(e=>`${e.file}:${e.line} ${e.what}`).join(`
|
|
4
|
+
`));for(const[e,[t,f]]of Object.entries(h)){const l=r.get(e)?.length??0;n(`shopper select still real and still ${t}: ${e} (${f})`,l===t,`found ${l} \u2014 fix or remove the entry`)}for(const[e,[t,f]]of Object.entries(u)){const l=r.get(e)?.length??0;n(`left for another card, exactly ${t}: ${e} (${f})`,l===t,l>t?`found ${l} \u2014 a NEW raw <select> in a file that is being replaced; use FieldSelect`:`found ${l} \u2014 that card has landed; remove this entry`)}for(const[e,[t,f,l]]of Object.entries(s)){const o=r.get(e)?.length??0;n(`waiting, exactly ${t}: ${e} (until ${f})`,o===t,`found ${o} \u2014 swapped? remove this entry`);let m=!1;try{m=l()}catch($){n(`could read whether ${e}'s wait is over`,!1,$.message);continue}n(`${e} is still waiting (installed efficient-easel lacks it)`,!m,`the installed efficient-easel now has ${f} \u2014 swap ${e} to FieldSelect and remove its UNTIL entry`)}return n(`walked the editor source (${a.length} TS/TSX files, at least ${i.minFiles})`,a.length>=i.minFiles),n(`found >= ${i.fieldSelectFloor} <FieldSelect> uses (found ${w})`,w>=i.fieldSelectFloor,"the builder + the swapped rows; fewer means a row went back to a raw <select> or the reader broke"),g()}export{v as oneDropdown};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type RuleReport, type SourceFile } from "./rule.js";
|
|
2
|
+
export type OneEditableListPresence = {
|
|
3
|
+
readonly controls?: string;
|
|
4
|
+
readonly locationsPanel?: string;
|
|
5
|
+
readonly tickerPanel?: string;
|
|
6
|
+
};
|
|
7
|
+
export type OneEditableListOptions = {
|
|
8
|
+
readonly minFiles: number;
|
|
9
|
+
readonly minSheets: number;
|
|
10
|
+
readonly presence?: OneEditableListPresence;
|
|
11
|
+
readonly listModules?: {
|
|
12
|
+
readonly locationsTree: object;
|
|
13
|
+
readonly controls: object;
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
export declare function oneEditableList(files: readonly SourceFile[], options: OneEditableListOptions): RuleReport;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import{ruleChecks as $}from"./rule.js";const y=s=>s.replace(/\/\*[\s\S]*?\*\//g,"").replace(/(^|[^:"'`])\/\/[^\n]*/g,"$1").replace(/\{\/\*[\s\S]*?\*\/\}/g,""),v=[["Move up / Move down buttons",/aria-label=["'{`]*Move (up|down)/],['"+ Add \u2026" buttons',/>\s*\+ Add [A-Za-z]|["'`]\+ Add [A-Za-z]/],["sf-textlist markup (the ticker's old list)",/["'` ]sf-textlist/],["TextListEditor",/\bTextListEditor\b/]];function M(s,h){const{check:U,report:w}=$("one editable list"),i=(t,d,o)=>{let p=!1,A=o;try{p=typeof d=="function"?d():d}catch(e){A=String(e.message??e)}return U(t,p,A)},x=`
|
|
2
|
+
<button type="button" style={iconBtn} aria-label="Move up" title="Move up" onClick={() => swap(1, 0)}>\u2191</button>
|
|
3
|
+
<button type="button" style={addBtn} onClick={addGroup}>+ Add group</button>
|
|
4
|
+
<div className="sf-textlist"><button className="sf-textlist-add">+ Add item</button></div>
|
|
5
|
+
export function TextListEditor() {}
|
|
6
|
+
`;for(const[t,d]of v)i(`control: the rule for ${t} catches it in old code`,d.test(y(x)));const a=s.filter(t=>t.path.endsWith(".tsx"));i(`read the editor's .tsx files (${a.length}, at least ${h.minFiles})`,a.length>=h.minFiles&&a.length>0,`only ${a.length}`);for(const[t,d]of v){const o=a.filter(p=>d.test(y(p.text))).map(p=>p.path);i(`no ${t} in the .tsx files`,o.length===0,o.join(", "))}const u=s.filter(t=>t.path.endsWith(".css"));i(`read the editor's stylesheets (${u.length}, at least ${h.minSheets})`,u.length>=h.minSheets);const r=u.filter(t=>/\.sf-textlist\b/.test(t.text.replace(/\/\*[\s\S]*?\*\//g,"")));i("no .sf-textlist rule left behind",r.length===0,r.map(t=>t.path).join(", "));const m=t=>{const d=s.find(o=>o.path===t);if(!d)throw new Error(`${t} was not among the files read`);return y(d.text)},c=h.presence??{};if(c.controls!==void 0){const t=c.controls;i(`${t} draws lines of copy with easel's ListField`,()=>/import \{[^}]*\bListField\b[^}]*\} from "efficient-easel\/fields"/.test(m(t)))}if(c.locationsPanel!==void 0){const t=c.locationsPanel;i(`the Locations panel (${t}) draws its groups and cities with ListField`,()=>(m(t).match(/<ListField\b/g)??[]).length===2)}if(c.tickerPanel!==void 0){const t=c.tickerPanel;i(`the ticker panel (${t}) draws Ticker items with the same TextListField the textList builder draws`,()=>/<TextListField\b/.test(m(t)))}return h.listModules&&E(i,h.listModules),w()}function E(s,h){const U=n=>()=>{throw new Error(`${n} does not exist`)},w=(n,l)=>n[l]??U(l),i=w(h.locationsTree,"writeGroupCities"),x=w(h.locationsTree,"writeGroupOrder"),a=w(h.controls,"aimAfterListChange"),u=(n,l)=>({name:n,group:l,groupName:""}),r=n=>n.map(l=>`${l.group}:${l.name}`).join(" "),m=(n,l,f)=>{const g=n.slice();return[g[l],g[f]]=[g[f],g[l]],g},c=(n,l,f,g)=>{const b=l.slice();return[b[f],b[f+g]]=[b[f+g],b[f]],b.flatMap(L=>n.filter(S=>(S.group??"")===L))},t=[u("Sydney","AU"),u("Austin","US"),u("Perth","AU"),u("Miami","US"),u("Hobart","AU")],d=[0,2,4],o=d.map(n=>t[n]);s("a city one step down saves what the old \u2193 saved",()=>r(i(t,"AU",[o[1],o[0],o[2]]))===r(m(t,0,2))),s("a city one step up saves what the old \u2191 saved",()=>r(i(t,"AU",[o[0],o[2],o[1]]))===r(m(t,4,2))),s("a city dragged from first to last leaves every other group's cards in their places",()=>{const n=i(t,"AU",[o[1],o[2],o[0]]);return n[1]===t[1]&&n[3]===t[3]&&n.length===t.length}),s("\u2026and puts the group's own cards in the new order",()=>{const n=i(t,"AU",[o[1],o[2],o[0]]);return r(d.map(l=>n[l]))==="AU:Perth AU:Hobart AU:Sydney"});const p={...u("","AU")};s('"+ Add city" at the end saves what the old button saved (the new card last)',()=>r(i(t,"AU",[...o,p]))===r([...t,p])),s("a group one step down saves what the old \u2193 saved",()=>r(x(t,["US","AU"],()=>[]))===r(c(t,["AU","US"],0,1)));const A=u("","Group 3");s('a new group gets its first city ("+ Add group" put it last)',()=>r(x(t,["AU","US","Group 3"],n=>n==="Group 3"?[A]:[]))===r([...c(t,["US","AU"],0,1),A]));const e=[{text:"a"},{text:"b"},{text:"c"}];s("typing in the aimed line keeps the aim",()=>a(e,[e[0],{text:"bb"},e[2]],1)===1),s("taking out a line BELOW the aimed one keeps the aim",()=>a(e,[e[0],e[1]],1)===1),s("taking out the aimed line lets go",()=>a(e,[e[0],e[2]],1)===null),s("taking out a line ABOVE the aimed one lets go (its box now holds other words)",()=>a(e,[e[1],e[2]],1)===null),s("a line added at the end keeps the aim",()=>a(e,[...e,{text:""}],1)===1),s("a line added above the aimed one lets go",()=>a(e,[e[0],{text:""},e[1],e[2]],1)===null),s("a move lets go (the caret going with the line aims again)",()=>a(e,[e[1],e[0],e[2]],1)===null),s("nothing aimed stays nothing aimed",()=>a(e,[e[1],e[0]],null)===null)}export{M as oneEditableList};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type RuleReport, type SourceFile } from "./rule.js";
|
|
2
|
+
export type OneEditorListOptions = {
|
|
3
|
+
readonly kept?: Readonly<Record<string, string>>;
|
|
4
|
+
readonly minFiles: number;
|
|
5
|
+
};
|
|
6
|
+
export declare function drawsList(text: string): boolean;
|
|
7
|
+
export declare function oneEditorList(files: readonly SourceFile[], options: OneEditorListOptions): RuleReport;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import{ruleChecks as d}from"./rule.js";function s(i){return i.includes('role="listbox"')||i.includes('type="checkbox"')&&/role="group"/.test(i)&&/set\w*Open\(/.test(i)}function u(i,o){const{check:t,report:c}=d("one editor list"),n=o.kept??{};t("a listbox is a list",s('<ul role="listbox">')),t("tick boxes in a group the file opens itself are a list",s(`const [o, setOpen] = useState(false);
|
|
2
|
+
<div role="group"><input type="checkbox" /></div>
|
|
3
|
+
setOpen(true);`)),t("a lone tick box is not a list",!s('<input type="checkbox" />')),t("FieldSelect is not a list of the file's own",!s("<FieldSelect options={o} multiple inline />"));const l=i.filter(e=>e.path.endsWith(".tsx"));t(`read the source (${l.length} .tsx files, at least ${o.minFiles})`,l.length>=o.minFiles,"fewer means the walk broke, and the census is vacuous");const r=l.filter(e=>s(e.text)).map(e=>e.path);for(const[e,p]of Object.entries(n))t(`the kept list is still real: ${e} (${p})`,r.includes(e),"it no longer draws a list \u2014 remove the stale entry");const a=r.filter(e=>!(e in n));return t("no second editor list: every file that draws a list of its own is a kept one",a.length===0,`a second editor list: ${a.join(", ")} \u2014 draw it with efficient-easel's FieldSelect`),c()}export{s as drawsList,u as oneEditorList};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type RuleReport, type SourceFile } from "./rule.js";
|
|
2
|
+
export type OneRightClickOptions = {
|
|
3
|
+
readonly editor?: {
|
|
4
|
+
readonly stylesheets: readonly string[];
|
|
5
|
+
readonly locationsRows: string;
|
|
6
|
+
};
|
|
7
|
+
readonly minPanelFiles: number;
|
|
8
|
+
readonly registryLabelFloor: number;
|
|
9
|
+
};
|
|
10
|
+
export declare function oneRightClick(files: readonly SourceFile[], options: OneRightClickOptions): RuleReport;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{ruleChecks as y}from"./rule.js";import{isPanelFile as b,readJsxLabels as m,readLabels as f,readPanelLabels as u,readRowLabels as w}from"./support/label-extraction.js";import{registryFiles as L,registryText as $}from"./support/registry-source.js";const F=/label:\s*"(?:[^"\\]|\\.)*"\s*,\s*onClick:/g;function p(e){const s=new Set;return[...f(e),...w(e),...m(e)].filter(t=>{const l=`${t.line}:${t.label}`;return s.has(l)?!1:(s.add(l),!0)})}function g(e){return{lost:p(e).length-u(e).length,actions:(e.match(F)??[]).length}}function k(e,s,t){const l=o=>s.find(a=>a.path===o)?.text,i=[...t.stylesheets,t.locationsRows],r=i.filter(o=>l(o)===void 0);e(`read the files drawn round the screen (${i.length-r.length} of ${i.length})`,r.length===0&&t.stylesheets.length>0,`not among the files handed in: ${r.join(", ")||"no stylesheet named"} \u2014 every clause below is vacuous without them`);const n=l(t.locationsRows)??"",c=t.stylesheets.filter(o=>(l(o)??"").includes("sf-paste-hint"));e("\xA71d no stylesheet of the editor's draws a second toast",c.length===0,`sf-paste-hint in ${c.join(", ")}`),e("\xA73 the Locations rows are where this reads them",/selectLocationsFocus\(si, \{ level: "group"/.test(n)&&/selectLocationsFocus\(si, \{ level: "city"/.test(n)),e("\xA73 a Locations group row is not addressed as a node",!/selectLocationsFocus\(si, \{ level: "group"[\s\S]{0,200}data-node-id/.test(n)&&!/data-node-id/.test(n)),e("\xA73 a Locations city row is not addressed as a node",!/selectLocationsFocus\(si, \{ level: "city"[\s\S]{0,200}data-node-id/.test(n))}function P(e,s){const{check:t,report:l}=y("one right click");s.editor&&k(t,e,s.editor);{const a=["const items = [",' { label: "Copy", onClick: () => copy() },',"];","const rows = [",' { key: "heading", label: "Heading", group: "text" },',"];"].join(`
|
|
2
|
+
`),d=u(a).map(h=>h.label);t("\xA74 the action rule drops an action's label and keeps a field's",d.length===1&&d[0]==="Heading"&&g(a).lost===1&&g(a).actions===1,JSON.stringify({kept:d,...g(a)}))}const i=e.filter(b);t(`\xA74 read the panel files (${i.length}, at least ${s.minPanelFiles})`,i.length>=s.minPanelFiles,"fewer means a panel stopped drawing a row or the predicate broke");const r=[];for(const a of i){const{lost:d,actions:h}=g(a.text);d>h&&r.push(`${a.path} (${d}, ${h} of them actions)`)}t("\xA74 no panel file loses a label to the action rule beyond its actions",r.length===0,r.join(", ")+" \u2014 a real panel dropping out of the vocabulary guard is the failure this rule must not cause");const n=L(e),c=$(e),o=f(c).length;return t(`\xA74 read the block registry (${n.length} files, ${o} labels)`,n.length>0,"no registry file among the files handed in"),t("\xA74 the inspector's own labels are read by a path the rule cannot reach",n.length>0&&(p(c).length===u(c).length||o>=s.registryLabelFloor),`the registry goes through readLabels, not readPanelLabels (${o} read, floor ${s.registryLabelFloor})`),l()}export{P as oneRightClick};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type * as TS from "typescript";
|
|
2
|
+
import { type RuleReport, type SourceFile } from "./rule.js";
|
|
3
|
+
export type OneSwitchOptions = {
|
|
4
|
+
readonly notEditor?: Readonly<Record<string, string>>;
|
|
5
|
+
readonly settingsSwitchFloor: number;
|
|
6
|
+
readonly minFiles: number;
|
|
7
|
+
readonly stylesheets?: readonly string[];
|
|
8
|
+
};
|
|
9
|
+
export declare function oneSwitch(ts: typeof TS, files: readonly SourceFile[], options: OneSwitchOptions): RuleReport;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import{ruleChecks as x}from"./rule.js";function S(i,o){const n=i.createSourceFile(o.path,o.text,i.ScriptTarget.Latest,!0,i.ScriptKind.TSX),s=[],f=[],a=t=>n.getLineAndCharacterOfPosition(t.getStart(n)).line+1,r=t=>{if(i.isJsxOpeningElement(t)||i.isJsxSelfClosingElement(t)){let h=!1,g="";for(const e of t.attributes.properties){if(!i.isJsxAttribute(e))continue;const c=e.name.getText(n),m=e.initializer,w=m?m.getText(n):"";c==="role"&&/["'`]switch["'`]/.test(w)&&(h=!0),c==="className"&&(g=w)}s.push({name:t.tagName.getText(n),line:a(t),roleSwitch:h,classText:g})}if(i.isPropertyAssignment(t)){const h=t.name.getText(n).replace(/["']/g,""),g=t.initializer.getText(n);h==="role"&&/^["'`]switch["'`]$/.test(g)&&s.push({name:"(createElement)",line:a(t),roleSwitch:!0,classText:""}),h==="className"&&f.push({line:a(t),text:g})}i.forEachChild(t,r)};return r(n),{tags:s,classStrings:f}}function p(i,o,n){const{tags:s,classStrings:f}=S(i,o),a=[];let r=0;for(const t of s)t.name==="SettingsSwitch"&&r++,t.name==="ToggleSwitch"&&a.push({file:o.path,line:t.line,what:"R1 <ToggleSwitch> \u2014 use easel's SettingsSwitch"}),t.roleSwitch&&!(o.path in n)&&a.push({file:o.path,line:t.line,what:`R2 hand-rolled role="switch" on <${t.name}> \u2014 use easel's SettingsSwitch`}),/\bsf-toggle\b/.test(t.classText)&&a.push({file:o.path,line:t.line,what:"R3 sf-toggle class in className"});for(const t of f)/\bsf-toggle\b/.test(t.text)&&a.push({file:o.path,line:t.line,what:"R3 sf-toggle class in className"});return{bad:a,settingsSwitch:r}}function d(i){const o=[];return i.text.replace(/\/\*[\s\S]*?\*\//g,s=>s.replace(/[^\n]/g," ")).split(`
|
|
2
|
+
`).forEach((s,f)=>{/\.sf-toggle\b/.test(s)&&o.push({file:i.path,line:f+1,what:"R3 .sf-toggle selector"})}),o}function b(i,o,n){const{check:s,report:f}=x("one switch"),a=n.notEditor??{};{const e=["const a = <ToggleSwitch value onChange={f} />;",'const b = <button role="switch" aria-checked={x} />;','const c = <span className={`sf-toggle ${on ? "is-on" : ""}`} />;','const d = h("button", { role: "switch", className: "sf-toggle" });',"// a comment about <ToggleSwitch> is not a use",'const ok = <SettingsSwitch checked onChange={f} ariaLabel="X" />;'].join(`
|
|
3
|
+
`),{bad:c,settingsSwitch:m}=p(i,{path:"fixture.tsx",text:e},{}),w=c.map(l=>l.line);s("R1 flags <ToggleSwitch>",c.some(l=>l.line===1&&l.what.startsWith("R1"))),s('R2 flags <button role="switch">',c.some(l=>l.line===2&&l.what.startsWith("R2"))),s("R3 flags an sf-toggle className",c.some(l=>l.line===3&&l.what.startsWith("R3"))),s("R2 + R3 flag the createElement form",w.filter(l=>l===4).length===2),s("a comment is not a use",!w.includes(5)),s("SettingsSwitch passes and is counted",!w.includes(6)&&m===1);const u=d({path:"fixture.css",text:`/* .sf-toggle in a comment */
|
|
4
|
+
.sf-toggle.is-on { }
|
|
5
|
+
.es-switch { }`});s("R3 flags a .sf-toggle selector, not a comment",u.length===1&&u[0].line===2)}const r=o.filter(e=>/\.tsx?$/.test(e.path)&&!e.path.endsWith(".d.ts")),t=o.filter(e=>e.path.endsWith(".css")),h=[];let g=0;for(const e of r){const c=p(i,e,a);h.push(...c.bad),g+=c.settingsSwitch}for(const e of t)h.push(...d(e));s('no local switch: no <ToggleSwitch>, no hand-rolled role="switch", no sf-toggle',h.length===0,`${h.length} hit(s):
|
|
6
|
+
`+h.map(e=>`${e.file}:${e.line} ${e.what}`).join(`
|
|
7
|
+
`)),s(`read the source (${r.length} TS/TSX files, at least ${n.minFiles})`,r.length>=n.minFiles);for(const e of n.stylesheets??[])s(`read the stylesheet ${e}`,t.some(c=>c.path===e));s(`found >= ${n.settingsSwitchFloor} <SettingsSwitch> uses (found ${g})`,g>=n.settingsSwitchFloor,"fewer means a row went back to a local switch or the reader broke");for(const[e,c]of Object.entries(a)){const m=o.find(u=>u.path===e),w=!!m&&S(i,m).tags.some(u=>u.roleSwitch);s(`the exception is still real: ${e} (${c})`,w,"remove the stale entry")}return f()}export{b as oneSwitch};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type RuleReport, type SourceFile } from "./rule.js";
|
|
2
|
+
export type OneUpLevelLinkOptions = {
|
|
3
|
+
readonly waiting?: Readonly<Record<string, {
|
|
4
|
+
readonly count: number;
|
|
5
|
+
readonly why: string;
|
|
6
|
+
}>>;
|
|
7
|
+
readonly upLevelUses?: readonly {
|
|
8
|
+
readonly file: string;
|
|
9
|
+
readonly words: readonly RegExp[];
|
|
10
|
+
readonly what: string;
|
|
11
|
+
}[];
|
|
12
|
+
readonly minEditorFiles: number;
|
|
13
|
+
};
|
|
14
|
+
export declare function backControls(source: string): number[];
|
|
15
|
+
export declare const isEditorCode: (source: string) => boolean;
|
|
16
|
+
export declare function oneUpLevelLink(files: readonly SourceFile[], options: OneUpLevelLinkOptions): RuleReport;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import{ruleChecks as w}from"./rule.js";const k=/className=["'][^"']*?(?<=["'\s-])back(?=["'\s-])/,v=/^\s*(?:<span[^>]*>\s*)?(?:\{\s*)?['"`]?\s*(?:[←‹↰⟵]|Back\b|All of\b)/,C=/<[A-Z]\w*(?:Back|Chevron|ArrowLeft)\w*\b/;function b(l){const a=l.replace(/=>/g,"=:"),e=[];for(const i of a.matchAll(/<button\b[^>]*(?<!\/)>([\s\S]*?)<\/button>/g)){const c=i[1],h=i[0].slice(0,i[0].length-c.length-9);(v.test(c)||k.test(h)||k.test(c)||C.test(c))&&e.push(a.slice(0,i.index).split(`
|
|
2
|
+
`).length)}return e}const y=l=>/from\s+["']efficient-easel\/(?!render["']|markup["']|data["'])[\w-]+["']/.test(l);function $(l,a){const{check:e,report:i}=w("one up-level link"),c=a.waiting??{},h=[["Locations link",`<button type="button" style={linkBtn} onClick={() => setLocationsFocus({ level: "groups" })}>
|
|
3
|
+
\u2190 Locations
|
|
4
|
+
</button>`],["Locations link, a name",'<button type="button" style={linkBtn} onClick={onBack}>\u2190 {String(card.name ?? "") || "City"}</button>'],["part panel back",`<button type="button" className="sf-part-back" onClick={onBack}>
|
|
5
|
+
<BackChevron />
|
|
6
|
+
<span>Back to the page</span>
|
|
7
|
+
</button>`],["easel's old list back",`<button type="button" className="es-list-back" onClick={() => onOpen(null)}>
|
|
8
|
+
<span className="es-list-back-chev" aria-hidden="true" />
|
|
9
|
+
{label}
|
|
10
|
+
</button>`],["a chevron as text",`<button type="button" onClick={() => setOpen(null)}>
|
|
11
|
+
<span aria-hidden>\u2039</span>
|
|
12
|
+
<span>All panels</span>
|
|
13
|
+
</button>`]];for(const[t,n]of h)e(`\xA71 the scanner sees a retired shape: ${t}`,b(n).length===1);const g=[["a select's chevron",`<button className="es-fin es-fsel-button" onClick={() => toggle()}>
|
|
14
|
+
<span className="es-fsel-chev" aria-hidden="true" />
|
|
15
|
+
</button>`],["a reorder arrow",'<button type="button" onClick={() => move(-1)}>\u2191</button>'],["a background class",'<button className="sf-background-chip">Fill</button>'],["a self-closing button before a real one",`<button className="sf-swatch" onClick={() => pick(t)} />
|
|
16
|
+
<span className="sf-go-back">x</span>
|
|
17
|
+
<button>Done</button>`]];for(const[t,n]of g)e(`\xA71 the scanner leaves alone: ${t}`,b(n).length===0);const p=l.filter(t=>/\.(tsx|jsx)$/.test(t.path)&&y(t.text));e(`\xA72 the scan reached the editor code (${p.length} files, at least ${a.minEditorFiles})`,p.length>=a.minEditorFiles,"fewer means the walk or the editor-code test broke, and the check below is vacuous");const u=[],f={};for(const t of p){const n=b(t.text);if(t.path in c)f[t.path]=n.length;else for(const r of n)u.push(`${t.path}:${r}`)}e("\xA72 no hand-built back control in editor code \u2014 use InspectorUpLevel from efficient-easel/chrome",u.length===0,u.join(`
|
|
18
|
+
`));for(const[t,{count:n,why:r}]of Object.entries(c)){const o=f[t];e(`\xA73 ${t} still has exactly ${n} waiting (${o??"file not scanned"})`,o===n,`${r}. If they moved, delete this waiting entry.`)}for(const t of a.upLevelUses??[]){const n=l.find(s=>s.path===t.file);if(!e(`\xA74 read ${t.file}`,!!n)||!n)continue;const r=n.text.replace(/=>/g,"=:"),o=[...r.matchAll(/<InspectorUpLevel\b([^>]*?)\/>/g)].map(s=>s[1]);e(`\xA74 ${t.file} draws InspectorUpLevel ${t.words.length} times (${o.length})`,o.length===t.words.length),e("\xA74 \u2026each inline: it sits in the panel body, under the inspector head",o.length>0&&o.every(s=>/\binline\b/.test(s)));const d=o.map(s=>s.match(/name=(\{.*?\}|"[^"]*")\s+onSelect=/)?.[1]??s);e(`\xA74 \u2026with the words it had: ${t.what}`,t.words.every((s,m)=>s.test(d[m]??"")),d.join(" | ")),e("\xA74 \u2026and no linkBtn back is left",!/style=\{linkBtn\}\s+onClick=\{(?:onBack|\(\) =: setLocationsFocus)/.test(r))}return i()}export{b as backControls,y as isEditorCode,$ as oneUpLevelLink};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type * as TS from "typescript";
|
|
2
|
+
import { type RuleReport, type SourceFile } from "./rule.js";
|
|
3
|
+
export type PanelRuling = {
|
|
4
|
+
readonly file: string;
|
|
5
|
+
readonly kind: "KEEP";
|
|
6
|
+
readonly count: number;
|
|
7
|
+
readonly why: string;
|
|
8
|
+
} | {
|
|
9
|
+
readonly file: string;
|
|
10
|
+
readonly kind: "UNTIL";
|
|
11
|
+
readonly count: number;
|
|
12
|
+
readonly until: string;
|
|
13
|
+
};
|
|
14
|
+
export type PanelColourTokensOptions = {
|
|
15
|
+
readonly editorRoot: (path: string) => boolean;
|
|
16
|
+
readonly publishedRoot: (path: string) => boolean;
|
|
17
|
+
readonly panelFile: (path: string) => boolean;
|
|
18
|
+
readonly allow: readonly PanelRuling[];
|
|
19
|
+
readonly anchors?: readonly string[];
|
|
20
|
+
readonly drawnByAField?: readonly string[];
|
|
21
|
+
readonly opacitySites?: readonly string[];
|
|
22
|
+
readonly shopperFacing?: readonly string[];
|
|
23
|
+
readonly floors: {
|
|
24
|
+
readonly editorRoots: number;
|
|
25
|
+
readonly publishedRoots: number;
|
|
26
|
+
readonly population: number;
|
|
27
|
+
readonly customFields: number;
|
|
28
|
+
readonly bytes: number;
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
export declare function blankVarFallbacks(input: string): string;
|
|
32
|
+
export type LiteralKind = "palette" | "bw" | "colour-value" | "size-value";
|
|
33
|
+
export declare function classifyClassToken(token: string): LiteralKind | null;
|
|
34
|
+
export type PanelLiteral = {
|
|
35
|
+
readonly file: string;
|
|
36
|
+
readonly line: number;
|
|
37
|
+
readonly kind: LiteralKind;
|
|
38
|
+
readonly text: string;
|
|
39
|
+
};
|
|
40
|
+
export declare function scanSource(ts: typeof TS, fileLabel: string, source: string): PanelLiteral[];
|
|
41
|
+
export declare function panelPopulation(ts: typeof TS, files: readonly SourceFile[], options: Pick<PanelColourTokensOptions, "editorRoot" | "publishedRoot" | "panelFile">): {
|
|
42
|
+
source: SourceFile[];
|
|
43
|
+
editorRoots: string[];
|
|
44
|
+
publishedRoots: string[];
|
|
45
|
+
customFields: string[];
|
|
46
|
+
population: string[];
|
|
47
|
+
};
|
|
48
|
+
export declare function panelColourTokens(ts: typeof TS, files: readonly SourceFile[], options: PanelColourTokensOptions): RuleReport;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import{ruleChecks as F}from"./rule.js";const I=new Set("slate gray zinc neutral stone red orange amber yellow lime green emerald teal cyan sky blue indigo violet purple fuchsia pink rose".split(" ")),S=new Set("text bg border ring fill stroke divide outline shadow from via to placeholder accent caret decoration".split(" ")),E=new Set("text w h p px py pt pb pl pr m mx my mt mb ml mr gap top bottom left right inset basis size leading tracking rounded border min-w max-w min-h max-h gap-x gap-y space-x space-y translate-x translate-y".split(" "));function R(t){let a=t;for(let s=0;s<20;s++){const n=a.replace(/var\(\s*--[A-Za-z0-9-]+\s*,((?:[^()]|\([^()]*\))*)\)/g,(d,u)=>`var(--x,${"\xB7".repeat(u.length)})`);if(n===a)break;a=n}return a}function N(t){const a=t.lastIndexOf("]"),s=t.indexOf("/",a+1);if(s===-1)return t;const n=t.slice(s+1);return/^(?:\d{1,3}|\[[^\]]*\])$/.test(n)?t.slice(0,s):t}function P(t){let a=t;for(let s=0;s<12;s++){const n=/^(?:[a-z0-9-]+|[a-z-]+-\[[^\]]*\]|\[[^\]]*\]):(.*)$/.exec(a);if(!n)break;a=n[1]}return N(a.replace(/^!/,"").replace(/^-/,""))}function O(t){const a=P(t),s=/^([a-z-]+)-\[([^\]]+)\]$/.exec(a);if(s){const[,u,o]=s;if(o.includes("\xB7")||/^var\(/.test(o)||/^url\(|^none$|^inherit$|^auto$/.test(o))return null;const p=/^#/.test(o)||/^(?:rgba?|hsla?|oklch|color-mix)\(/.test(o)||/^(?:white|black|transparent|currentColor)$/.test(o),f=/^-?[\d.]+(?:px|rem|em|%|vw|vh|ch|ex|pt|fr)?$|calc\(|^clamp\(/.test(o);return p&&(S.has(u)||E.has(u))?"colour-value":f&&E.has(u)?"size-value":S.has(u)&&!f?"colour-value":E.has(u)?"size-value":null}const n=/^([a-z-]+)-([a-z]+)-(\d{2,3})$/.exec(a);if(n&&S.has(n[1])&&I.has(n[2]))return"palette";const d=/^([a-z-]+)-(white|black)$/.exec(a);return d&&S.has(d[1])?"bw":null}const C=/#(?:[0-9a-fA-F]{8}|[0-9a-fA-F]{6}|[0-9a-fA-F]{4}|[0-9a-fA-F]{3})\b/g,B=/\b(?:rgba?|hsla?|oklch|color-mix)\(/g;function A(t,a,s){const n=t.createSourceFile(a,s,t.ScriptTarget.Latest,!0,t.ScriptKind.TSX),d=[],u=o=>{let p=null;if((t.isStringLiteral(o)||t.isNoSubstitutionTemplateLiteral(o)||t.isTemplateHead(o)||t.isTemplateMiddle(o)||t.isTemplateTail(o))&&(p=o.text),p&&p.length){const f=n.getLineAndCharacterOfPosition(o.getStart(n)).line+1;let r=R(p);for(const c of r.split(/[\s;{}]+/)){if(!c)continue;const w=O(c);w&&(d.push({file:a,line:f,kind:w,text:c}),c.includes("[")&&(r=r.split(c).join("\xB7".repeat(c.length))))}for(const c of[C,B]){c.lastIndex=0;let w;for(;w=c.exec(r);)d.push({file:a,line:f,kind:"colour-value",text:w[0]})}}t.forEachChild(o,u)};return t.forEachChild(n,u),d}function U(t,a,s){let n;if(a.startsWith("@/"))n=a.slice(2);else if(a.startsWith("./")||a.startsWith("../")){const d=s.split("/").slice(0,-1);for(const u of a.split("/"))u===".."?d.pop():u!=="."&&d.push(u);n=d.join("/")}else return null;for(const d of[`${n}.ts`,`${n}.tsx`,`${n}/index.ts`,`${n}/index.tsx`,n])if(t.has(d)&&/\.tsx?$/.test(d)&&!d.endsWith(".d.ts"))return d;return null}function j(t,a){const s=new Set(a.map(o=>o.path)),n=new Map,d=new Set;for(const o of a){const p=t.createSourceFile(o.path,o.text,t.ScriptTarget.Latest,!0,t.ScriptKind.TSX),f=new Map,r=[],c=(i,m)=>{const x=U(s,i,o.path);if(x&&(r.push(x),!!m&&(m.name&&f.set(m.name.text,x),m.namedBindings&&t.isNamedImports(m.namedBindings))))for(const g of m.namedBindings.elements)f.set(g.name.text,x)},w=i=>{if(t.isImportDeclaration(i)&&t.isStringLiteral(i.moduleSpecifier)&&c(i.moduleSpecifier.text,i.importClause),t.isExportDeclaration(i)&&i.moduleSpecifier&&t.isStringLiteral(i.moduleSpecifier)&&c(i.moduleSpecifier.text),t.isCallExpression(i)&&i.expression.kind===t.SyntaxKind.ImportKeyword){const m=i.arguments[0];m&&t.isStringLiteral(m)&&c(m.text)}if(t.isObjectLiteralExpression(i)){const m=i.properties.some(g=>t.isPropertyAssignment(g)&&t.isIdentifier(g.name)&&g.name.text==="type"&&t.isStringLiteral(g.initializer)&&g.initializer.text==="custom"),x=i.properties.find(g=>t.isPropertyAssignment(g)&&t.isIdentifier(g.name)&&g.name.text==="render");if(m&&x){const g=e=>{(t.isJsxOpeningElement(e)||t.isJsxSelfClosingElement(e))&&t.isIdentifier(e.tagName)&&f.has(e.tagName.text)&&d.add(f.get(e.tagName.text)),t.forEachChild(e,g)};g(x.initializer)}}t.forEachChild(i,w)};t.forEachChild(p,w),n.set(o.path,r)}return{customFieldTargets:d,reachableFrom:o=>{const p=new Set,f=[...o];for(;f.length;){const r=f.pop();if(!p.has(r)){p.add(r);for(const c of n.get(r)??[])f.push(c)}}return p}}}const L=["bg-[","url(a","/b.png)]"].join("");function K(t,a,s){const n=a.filter(i=>/\.tsx?$/.test(i.path)&&!i.path.endsWith(".d.ts")),d=j(t,n),u=n.filter(i=>s.editorRoot(i.path)).map(i=>i.path),o=n.filter(i=>s.publishedRoot(i.path)).map(i=>i.path),p=d.reachableFrom(u),f=d.reachableFrom(o),r=[...p].filter(i=>s.panelFile(i)&&!f.has(i)),c=[...d.customFieldTargets].filter(s.panelFile),w=[...new Set([...r,...c])].sort();return{source:n,editorRoots:u,publishedRoots:o,customFields:c,population:w}}function M(t,a,s){const{check:n,report:d}=F("panel colour tokens");{const e=["// a stale slot \u2014 #319 and 13.6:1","/** Theme 1 accent #2e2e2e + black ink */",'const a = "text-[13px] py-[7px]";','const b = "text-[var(--sf-warning,#b45309)]";','const c = "border-[var(--sf-line, rgba(128,128,128,0.3))]";','const d = "text-zinc-400 hover:bg-amber-100 md:text-white";','const e = "z-[200] grid-cols-[1fr_auto]";','const f = { color: "#d85a30", boxShadow: "0 1px 2px rgba(20,20,22,0.10)" };','const g = "text-[#eee] max-w-[170px]";','const h = "bg-black/30 text-zinc-400/50 border-white/10";','const j = "w-2 bg-white/45 hover:bg-white/70";',`const i = "${L} w-1/2";`].join(`
|
|
2
|
+
`),l=A(t,"sample.tsx",e).map(b=>`${b.kind}:${b.text}`).sort(),h=["bw:bg-black/30","bw:bg-white/45","bw:border-white/10","bw:hover:bg-white/70","bw:md:text-white","colour-value:#d85a30","colour-value:rgba(","colour-value:text-[#eee]","palette:hover:bg-amber-100","palette:text-zinc-400","palette:text-zinc-400/50","size-value:max-w-[170px]","size-value:py-[7px]","size-value:text-[13px]"];n("the scanner is CALIBRATED \u2014 it reads code, not comments, and not tokens",JSON.stringify(l)===JSON.stringify(h),`the scanner has drifted. It must (1) never read a comment \u2014 the card number #319 and the contrast table are not colours; (2) read var(--tok, #fallback) as the TOKEN it is, at any nesting; (3) decide colour-vs-size from the VALUE, so text-[13px] is a size and text-[#eee] is a colour; (4) ignore z-[\u2026] and grid-cols-[\u2026], which are neither; (5) see THROUGH an opacity modifier \u2014 bg-black/30 is still a hard-coded black \u2014 without mistaking the slash inside ${L} or the one in w-1/2 for one. Got: ${JSON.stringify(l)}`)}const{source:u,editorRoots:o,publishedRoots:p,customFields:f,population:r}=K(t,a,s),{floors:c}=s;n(`the editor entries were found (${o.length}, at least ${c.editorRoots})`,o.length>=c.editorRoots&&o.length>0,"the walk read no editor entry, so every rule below would be an assertion over an empty list and would pass for the wrong reason"),n(`the published entries were found (${p.length}, at least ${c.publishedRoots})`,p.length>=c.publishedRoots&&p.length>0,"without them every component would look editor-only and the population would balloon"),n(`the panel population is ${r.length} files (at least ${c.population})`,r.length>=c.population&&r.length>0,"a population that small is not a clean repository, it is a scan that read nowhere \u2014 something in module resolution broke"),n(`Puck custom fields draw ${f.length} panel files (at least ${c.customFields})`,f.length>=c.customFields,"rule B is what covers every settings field a registry reaches; if it stops matching, the field components leave the population in silence");for(const e of s.anchors??[])n(`${e} is panel chrome, and in the population`,r.includes(e),"it is missing \u2014 the walk has stopped reaching the editor");for(const e of s.drawnByAField??[])n(`${e} is drawn by a Puck custom field, and in the population`,r.includes(e),'it belongs to the panel, but its NAME does not say "panel" \u2014 rule B has stopped working');for(const e of s.opacitySites??[])n(`${e} carries a colour behind an opacity modifier, and stays in the population`,r.includes(e),"it is one of the sites this rule was once blind to; if it has dropped out, the rule is green while ignoring a defect it was written to find");for(const e of s.shopperFacing??[])n(`${e} paints a shopper's page, and is not in the population`,!r.includes(e),"it is not this rule's business, and taking it would make this a storefront gate wearing a panel gate's name");const w=new Map(u.map(e=>[e.path,e.text])),i=new Map;for(const e of r){const l=A(t,e,w.get(e)??"");l.length&&i.set(e,l)}const m=[...i.values()].reduce((e,l)=>e+l.length,0),x=new Map(s.allow.map(e=>[e.file,e])),g=r.reduce((e,l)=>e+(w.get(l)??"").length,0);n(`the scan read ${g} bytes of panel source (at least ${c.bytes})`,g>=c.bytes&&g>0,'that is not the editor. Every "no literals found" below would be meaningless.'),n("the scanner found literals while the allow list still lists files",m>0||s.allow.length===0,"the scanner found nothing anywhere while the allow list still lists files. A scan that reads nothing looks exactly like a clean codebase.");{const e=[];for(const[l,h]of[...i].sort()){if(x.has(l))continue;const b=h.slice(0,6).map($=>` ${l}:${$.line} ${$.text}`);e.push(` ${l} \u2014 ${h.length} literal${h.length===1?"":"s"}
|
|
3
|
+
`+b.join(`
|
|
4
|
+
`)+(h.length>b.length?`
|
|
5
|
+
\u2026and ${h.length-b.length} more`:""))}n("NO panel file outside the list carries a colour or size literal",e.length===0,`Hard-coded colour/size literals in editor PANEL components.
|
|
6
|
+
|
|
7
|
+
The panel's colours and sizes come from tokens \u2014 the --sf-* custom properties the editor's sheets define (efficient-easel/screen.css, and the builder's components/storefront-editor.css) and the .es-* classes efficient-easel draws. A literal here is a private copy of one step of that scale: it does not move when the scale moves, and nothing says it is wrong until somebody looks at the panel beside the campaign designer.
|
|
8
|
+
|
|
9
|
+
Spell it as a token. If it genuinely cannot be one, add a line to the allow list with KEEP (a design reason) or UNTIL (what has to land), and its exact count.
|
|
10
|
+
|
|
11
|
+
`+e.join(`
|
|
12
|
+
|
|
13
|
+
`))}{const e=[];for(const l of s.allow){const h=i.get(l.file);if(!r.includes(l.file)){e.push(` ${l.file} is on the list but is no longer a panel component (the editor does not reach it, and no Puck custom field draws it). Delete the line.`);continue}if(!h){e.push(` ${l.file} is CLEAN now \u2014 0 literals, the line still allows ${l.count}. Delete the line: that is what "done" looks like.`);continue}if(h.length>l.count){const b=h.slice(l.count).map($=>`${$.text} @${$.line}`);e.push(` ${l.file} has ${h.length} literals, the line allows ${l.count}. A NEW literal went into a file we already tolerate \u2014 this is exactly how the count creeps back. Spell it as a token; do not raise the number. (e.g. ${b.slice(0,3).join(", ")})`)}h.length<l.count&&e.push(` ${l.file} is down to ${h.length} literals from ${l.count}. Good \u2014 now finish it: either clear the rest and delete the line, or lower the count in this same PR. A line that allows more than the file spends goes on excusing a debt that has been paid.`)}n(`every allow line still describes its file \u2014 counts pinned BOTH ways (${s.allow.length} lines)`,e.length===0,`the allow list is out of date:
|
|
14
|
+
|
|
15
|
+
${e.join(`
|
|
16
|
+
|
|
17
|
+
`)}`)}{const e=[],l=new Set;for(const h of s.allow)l.has(h.file)&&e.push(` ${h.file} is listed twice`),l.add(h.file),h.count<1&&e.push(` ${h.file} pins count ${h.count} \u2014 a line allowing nothing is a deleted line`),h.kind==="KEEP"&&h.why.trim().length<20&&e.push(` ${h.file} is a KEEP with no design behind it. A KEEP says why the literal is RIGHT; if you cannot say that, it is an UNTIL.`),h.kind==="UNTIL"&&h.until.trim().length<20&&e.push(` ${h.file} is an UNTIL with no expiry. A reason explains why a line is here today; an expiry is what GETS IT OUT. Say what has to land.`);n("every allow line carries an EXPIRY, not just a reason",e.length===0,`allow lines are malformed:
|
|
18
|
+
|
|
19
|
+
${e.join(`
|
|
20
|
+
`)}`)}{const e=i.size,l=r.length-e,h=r.length?Math.round(l/r.length*100):0,b=s.allow.filter(y=>y.kind==="KEEP").length,$=s.allow.filter(y=>y.kind==="UNTIL").length,z=[...i.values()].flat().filter(y=>y.kind!=="size-value").length;n(`PROGRESS \u2014 panel token coverage: ${l}/${r.length} files clean (${h}%) \xB7 ${m} literals left in ${e} file${e===1?"":"s"} (${z} colour + ${m-z} size) \xB7 allow: ${b} KEEP + ${$} UNTIL`,r.length>0);for(const[y,T]of[...i].sort((k,v)=>v[1].length-k[1].length)){const k=T.filter(v=>v.kind!=="size-value").length;n(`PROGRESS ${String(k).padStart(3)} colour ${String(T.length-k).padStart(3)} size ${y}`,!0)}}return d()}export{R as blankVarFallbacks,O as classifyClassToken,M as panelColourTokens,K as panelPopulation,A as scanSource};
|