Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion components/FloatingNavbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ const DOCS_SECTIONS: Partial<Record<ProductId, DocsEntry[]>> = {
{
label: 'Ecosystem',
pages: [
{ label: 'mix_tailwinds', href: '/documentation/mix/ecosystem/mix-tailwinds' },
{ label: 'mix_winds', href: '/documentation/mix/ecosystem/mix-winds' },
{ label: 'mix_schema', href: '/documentation/mix/ecosystem/mix-schema' },
{ label: 'mix_lint', href: '/documentation/mix/ecosystem/mix-lint' },
{ label: 'mix_generator', href: '/documentation/mix/ecosystem/mix-generator' },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import type { CSSProperties } from "react";
import { NARROW_CAPTURE_QUERY, type Example } from "./content";

/* Both halves are real captures of the same class string: a browser rendering
Tailwind on the left, Flutter rendering mix_tailwinds on the right. Narrow
Tailwind on the left, Flutter rendering mix_winds on the right. Narrow
screens get the phone-width capture, because the desktop one shrinks past
legibility and the comparison stops meaning anything.

Expand All @@ -25,11 +25,11 @@ export function ComparisonSeam({ example }: { example: Example }) {
<picture>
<source
media={NARROW_CAPTURE_QUERY}
srcSet={`/mix-tailwinds/${example.slug}-tailwind-sm.png`}
srcSet={`/mix-winds/${example.slug}-tailwind-sm.png`}
/>
<img
className="mtw-seam-layer"
src={`/mix-tailwinds/${example.slug}-tailwind.png`}
src={`/mix-winds/${example.slug}-tailwind.png`}
alt={`${example.title} rendered in a browser with Tailwind CSS`}
draggable={false}
/>
Expand All @@ -38,12 +38,12 @@ export function ComparisonSeam({ example }: { example: Example }) {
<picture className="mtw-seam-clip" style={{ clipPath: `inset(0 0 0 ${position}%)` }}>
<source
media={NARROW_CAPTURE_QUERY}
srcSet={`/mix-tailwinds/${example.slug}-flutter-sm.png`}
srcSet={`/mix-winds/${example.slug}-flutter-sm.png`}
/>
<img
className="mtw-seam-layer"
src={`/mix-tailwinds/${example.slug}-flutter.png`}
alt={`${example.title} rendered by Flutter with mix_tailwinds`}
src={`/mix-winds/${example.slug}-flutter.png`}
alt={`${example.title} rendered by Flutter with mix_winds`}
draggable={false}
/>
</picture>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ import {
INSTALL_SNIPPET,
} from "./content";
import "../landing.css";
import "./mix-tailwinds.css";
import "./mix-winds.css";

const PUB_DEV_URL = "https://pub.dev/packages/mix_tailwinds";
const PUB_DEV_URL = "https://pub.dev/packages/mix_winds";
const GITHUB_URL =
"https://github.com/btwld/mix/tree/main/packages/mix_tailwinds";
"https://github.com/btwld/mix/tree/main/packages/mix_winds";

const exampleTabId = (slug: string) => `mtw-example-tab-${slug}`;
const examplePanelId = (slug: string) => `mtw-example-panel-${slug}`;
Expand All @@ -48,7 +48,7 @@ function CodePane({
);
}

export function MixTailwindsLanding() {
export function MixWindsLanding() {
const [activeSlug, setActiveSlug] = useState(EXAMPLES[0].slug);
const tabRefs = useRef<Array<HTMLButtonElement | null>>([]);
const active = EXAMPLES.find((e) => e.slug === activeSlug) ?? EXAMPLES[0];
Expand Down Expand Up @@ -95,7 +95,7 @@ export function MixTailwindsLanding() {
variants={{ visible: { transition: { staggerChildren: 0.08 } } }}
>
<motion.p className="mtw-eyebrow" variants={fadeUp} custom={0}>
mix_tailwinds
mix_winds
<span className="mtw-eyebrow-badge">Alpha</span>
</motion.p>

Expand Down Expand Up @@ -240,7 +240,7 @@ export function MixTailwindsLanding() {
<motion.div className="mtw-close-inner" {...reveal}>
<h2 className="mtw-close-title">Start with one class string.</h2>
<p className="mtw-close-lead">
mix_tailwinds is an open-source alpha built on Mix. Add it to a
mix_winds is an open-source alpha built on Mix. Add it to a
Flutter project and style your first widget the way you already
think about layout.
</p>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
/* Content for the mix_tailwinds landing page.
/* Content for the mix_winds landing page.

The captures under public/mix-tailwinds/ are produced by the package's own
The captures under public/mix-winds/ are produced by the package's own
comparison suite: each example is rendered once in a real browser on
Tailwind 4.3.1 and once in Flutter, from the same class string. Regenerate
them with `npm run compare:advanced` in packages/mix_tailwinds/tool/
them with `npm run compare:advanced` in packages/mix_winds/tool/
visual-comparison and copy the per-example captures across. The suite keeps
a 16px diagnostic margin around every capture; the landing crops that margin
at presentation time while preserving the source evidence. */
Expand All @@ -19,7 +19,7 @@ export type Example = {

/* Below this the desktop capture is too small to read, so the narrow capture —
the same component laid out for a phone — is served instead. Matches the CSS
breakpoint in mix-tailwinds.css. */
breakpoint in mix-winds.css. */
export const NARROW_CAPTURE_QUERY = "(max-width: 720px)";

export const EXAMPLES: Example[] = [
Expand Down Expand Up @@ -82,7 +82,7 @@ export const DART_SNIPPET = `div('flex flex-col gap-4 rounded-3xl bg-slate-950 p
),
])`;

export const INSTALL_SNIPPET = `flutter pub add mix_tailwinds`;
export const INSTALL_SNIPPET = `flutter pub add mix_winds`;

export const FEATURES = [
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* mix_tailwinds landing page.
/* mix_winds landing page.

Accent: iris, not another cyan. The sibling product pages already hold the
blue-to-cyan range, and this page is about translation between two systems,
Expand Down
4 changes: 4 additions & 0 deletions next.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ export default withNextra({
{ source: '/documentation/widgets/:path*', destination: '/documentation/mix/widgets/:path*', permanent: true },
{ source: '/documentation/tutorials/:path*', destination: '/documentation/mix/tutorials/:path*', permanent: true },
{ source: '/documentation/ecosystem/:path*', destination: '/documentation/mix/ecosystem/:path*', permanent: true },
// The package was renamed from mix_tailwinds to mix_winds; keep the
// published landing and ecosystem URLs reachable.
{ source: '/mix-tailwinds', destination: '/mix-winds', permanent: true },
{ source: '/documentation/mix/ecosystem/mix-tailwinds', destination: '/documentation/mix/ecosystem/mix-winds', permanent: true },
]
},
})
2 changes: 1 addition & 1 deletion packages/mix_docs_preview/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ The `lib/` layout mirrors the documentation site. When a doc section has multipl
- **`lib/guides/`** – Styling, directives, design tokens, dynamic styling (variants), animations, gradients. Multi-file sections use subfolders: `animations/`, `design_token/`, `directives/`, `dynamic_styling/`, `gradients/`.
- **`lib/widgets/`** – Box, text, icon, image, flexbox, stack, vbox, pressable, stylewidgets. Multi-file sections use subfolders: `box/`, `text/`, `icon/`, `image/`, `flexbox/`, `stack/`, `vbox/`.
- **`lib/tutorials/`** – Creating context variants, theming, creating a widget (e.g. `creating_a_widget/design_system_button.dart`), controlling widget state.
- **`lib/ecosystem/`** – Ecosystem demos (e.g. `mix_tailwinds.dart`).
- **`lib/ecosystem/`** – Ecosystem demos (e.g. `mix_winds.dart`).
- **`lib/components/`** – Shared UI (chip button, scaffold, tokens).
- **`lib/preview_registry.dart`** – Single source of truth for preview IDs and metadata.
- **`tool/generate_previews_manifest.dart`** – Generates `previews-manifest.json` from the registry for the website.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import 'package:flutter/material.dart';
import 'package:mix_tailwinds/mix_tailwinds.dart';
import 'package:mix_winds/mix_winds.dart';

// #docregion example
class Example extends StatelessWidget {
Expand Down
6 changes: 3 additions & 3 deletions packages/mix_docs_preview/lib/preview_registry.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import 'package:flutter/widgets.dart';

import 'ecosystem/mix_tailwinds.dart' as tw_card_alert;
import 'ecosystem/mix_winds.dart' as tw_card_alert;
import 'guides/animations/implicit_curved_scale.dart' as auto_scale;
import 'guides/animations/implicit_spring_translate.dart' as spring_anim;
import 'guides/animations/implicit_state_counter.dart'
Expand Down Expand Up @@ -544,8 +544,8 @@ class PreviewRegistry {
),
// ecosystem
PreviewEntry(
previewId: 'ecosystem/mix-tailwinds.0',
sourcePath: 'packages/mix_docs_preview/lib/ecosystem/mix_tailwinds.dart',
previewId: 'ecosystem/mix-winds.0',
sourcePath: 'packages/mix_docs_preview/lib/ecosystem/mix_winds.dart',
category: _ecosystem,
builder: (_) => const tw_card_alert.Example(),
snippetRegion: 'example',
Expand Down
24 changes: 13 additions & 11 deletions packages/mix_docs_preview/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -142,11 +142,12 @@ packages:
mix:
dependency: "direct main"
description:
name: mix
sha256: ed8382ac70d5d85c3d0f753c9f8f68f61d74958afbd05f3e3d7144a11ab8efad
url: "https://pub.dev"
source: hosted
version: "2.1.0"
path: "packages/mix"
ref: e3133c3565e0c788b3f05f889ed75cb83f8acecb
resolved-ref: e3133c3565e0c788b3f05f889ed75cb83f8acecb
url: "https://github.com/btwld/mix.git"
source: git
version: "2.2.0-beta.2"
mix_annotations:
dependency: transitive
description:
Expand All @@ -155,14 +156,15 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.2.0-beta.0"
mix_tailwinds:
mix_winds:
dependency: "direct main"
description:
name: mix_tailwinds
sha256: "362f00e3ebf9f960c84b790faabe83f9e9e2dafaa2c6140a24954b857f820309"
url: "https://pub.dev"
source: hosted
version: "0.0.1-alpha.1"
path: "packages/mix_winds"
ref: e3133c3565e0c788b3f05f889ed75cb83f8acecb
resolved-ref: e3133c3565e0c788b3f05f889ed75cb83f8acecb
url: "https://github.com/btwld/mix.git"
source: git
version: "0.1.0-alpha.0"
naked_ui:
dependency: transitive
description:
Expand Down
22 changes: 21 additions & 1 deletion packages/mix_docs_preview/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,15 @@ dependencies:
flutter:
sdk: flutter
mix: ^2.1.0
mix_tailwinds: ^0.0.1-alpha.1
# mix_winds was renamed from mix_tailwinds and is not on pub.dev under the new
# name yet, so it is pinned to the rename commit on btwld/mix main. Revert to
# a hosted `mix_winds: ^0.1.0-alpha.0` once it is published. This package is
# publish_to: none, so the git pin only affects the docs preview build.
mix_winds:
git:
url: https://github.com/btwld/mix.git
path: packages/mix_winds
ref: e3133c3565e0c788b3f05f889ed75cb83f8acecb
remix:
git:
url: https://github.com/btwld/remix.git
Expand All @@ -25,5 +33,17 @@ dev_dependencies:
dart_code_metrics_presets: ^2.24.0
flutter_lints: ^6.0.0

# mix_winds uses Mix APIs (onFocusVisible, Pressable.semanticsLabel) that exist
# in the monorepo but not in any published mix release, and remix pins mix from
# pub.dev, so the two sources cannot be reconciled by version solving alone.
# Overriding mix onto the same commit keeps the whole preview build on one Mix.
# Remove this once a mix prerelease ships those APIs.
dependency_overrides:
mix:
git:
url: https://github.com/btwld/mix.git
path: packages/mix
ref: e3133c3565e0c788b3f05f889ed75cb83f8acecb

flutter:
uses-material-design: true
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ function read(relativePath) {
return fs.readFileSync(path.join(root, relativePath), 'utf8')
}

test('wires the mix_tailwinds page into the landing shell', () => {
const route = read('src/app/mix-tailwinds/page.tsx')
const landing = read('components/landing/mix-tailwinds/MixTailwindsLanding.tsx')
const styles = read('components/landing/mix-tailwinds/mix-tailwinds.css')
test('wires the mix_winds page into the landing shell', () => {
const route = read('src/app/mix-winds/page.tsx')
const landing = read('components/landing/mix-winds/MixWindsLanding.tsx')
const styles = read('components/landing/mix-winds/mix-winds.css')

assert.match(route, /<MixTailwindsLanding\s*\/>/)
assert.match(route, /<MixWindsLanding\s*\/>/)
assert.match(route, /Tailwind classes\. Native Flutter\./)
assert.match(landing, /className="lp-root mtw-root"/)
assert.match(landing, /<Aurora \/>/)
Expand All @@ -23,19 +23,19 @@ test('wires the mix_tailwinds page into the landing shell', () => {
// inside the Mix site rather than a separate product in the navbar switcher.
assert.match(styles, /\.mtw-root \{[^}]*--lp-accent:/s)
const productStyles = read('components/landing/landing.css')
assert.doesNotMatch(productStyles, /data-product='mix-tailwinds'/)
assert.doesNotMatch(productStyles, /data-product='mix-winds'/)
const layout = read('src/app/layout.jsx')
assert.doesNotMatch(layout, /mix-tailwinds/)
assert.doesNotMatch(layout, /mix-winds/)
})

test('sells the package instead of reporting a pixel diff', () => {
const landing = read('components/landing/mix-tailwinds/MixTailwindsLanding.tsx')
const content = read('components/landing/mix-tailwinds/content.ts')
const seam = read('components/landing/mix-tailwinds/ComparisonSeam.tsx')
const landing = read('components/landing/mix-winds/MixWindsLanding.tsx')
const content = read('components/landing/mix-winds/content.ts')
const seam = read('components/landing/mix-winds/ComparisonSeam.tsx')

assert.match(landing, /Get started/)
assert.match(landing, /flutter pub add|INSTALL_SNIPPET/)
assert.match(content, /flutter pub add mix_tailwinds/)
assert.match(content, /flutter pub add mix_winds/)

// No parity percentages, budgets, or pass/fail language on the page.
const pageSource = [landing, content, seam].join('\n')
Expand All @@ -44,9 +44,9 @@ test('sells the package instead of reporting a pixel diff', () => {
})

test('makes every gallery example a clean browser-to-Flutter comparison', () => {
const landing = read('components/landing/mix-tailwinds/MixTailwindsLanding.tsx')
const content = read('components/landing/mix-tailwinds/content.ts')
const styles = read('components/landing/mix-tailwinds/mix-tailwinds.css')
const landing = read('components/landing/mix-winds/MixWindsLanding.tsx')
const content = read('components/landing/mix-winds/content.ts')
const styles = read('components/landing/mix-winds/mix-winds.css')

assert.match(
landing,
Expand All @@ -72,7 +72,7 @@ test('makes every gallery example a clean browser-to-Flutter comparison', () =>
})

test('connects the example tabs to one keyboard-operable comparison panel', () => {
const landing = read('components/landing/mix-tailwinds/MixTailwindsLanding.tsx')
const landing = read('components/landing/mix-winds/MixWindsLanding.tsx')

assert.match(landing, /aria-controls=\{examplePanelId\(example\.slug\)\}/)
assert.match(landing, /tabIndex=\{example\.slug === activeSlug \? 0 : -1\}/)
Expand All @@ -83,8 +83,8 @@ test('connects the example tabs to one keyboard-operable comparison panel', () =
})

test('shows the functional API with real HTML and Dart highlighting', () => {
const content = read('components/landing/mix-tailwinds/content.ts')
const landing = read('components/landing/mix-tailwinds/MixTailwindsLanding.tsx')
const content = read('components/landing/mix-winds/content.ts')
const landing = read('components/landing/mix-winds/MixWindsLanding.tsx')
const highlighter = read('components/landing/HighlightedCode.tsx')

// Functional helpers, not the class-based widget constructors.
Expand All @@ -102,9 +102,9 @@ test('shows the functional API with real HTML and Dart highlighting', () => {
})

test('serves a legible capture on narrow screens', () => {
const content = read('components/landing/mix-tailwinds/content.ts')
const seam = read('components/landing/mix-tailwinds/ComparisonSeam.tsx')
const styles = read('components/landing/mix-tailwinds/mix-tailwinds.css')
const content = read('components/landing/mix-winds/content.ts')
const seam = read('components/landing/mix-winds/ComparisonSeam.tsx')
const styles = read('components/landing/mix-winds/mix-winds.css')

assert.match(content, /NARROW_CAPTURE_QUERY = "\(max-width: 720px\)"/)
assert.match(seam, /<source\s+media=\{NARROW_CAPTURE_QUERY\}/s)
Expand All @@ -124,7 +124,7 @@ test('serves a legible capture on narrow screens', () => {
'flutter-sm.png',
]) {
assert.equal(
fs.existsSync(path.join(root, `public/mix-tailwinds/${slug}-${suffix}`)),
fs.existsSync(path.join(root, `public/mix-winds/${slug}-${suffix}`)),
true,
`missing capture: ${slug}-${suffix}`,
)
Expand All @@ -133,7 +133,7 @@ test('serves a legible capture on narrow screens', () => {
})

test('keeps the seam operable by keyboard and screen readers', () => {
const seam = read('components/landing/mix-tailwinds/ComparisonSeam.tsx')
const seam = read('components/landing/mix-winds/ComparisonSeam.tsx')

assert.match(seam, /type="range"/)
assert.match(seam, /aria-labelledby=/)
Expand Down
2 changes: 1 addition & 1 deletion src/app/examples/tailwind-plan-card/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export default function TailwindPlanCardPage() {
Tailwind reference output
</p>
<h1 className="text-3xl font-semibold text-slate-800">
Compare with the Flutter mix_tailwinds example
Compare with the Flutter mix_winds example
</h1>
</header>

Expand Down
12 changes: 6 additions & 6 deletions src/app/mix-tailwinds/page.tsx → src/app/mix-winds/page.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { MixTailwindsLanding } from "../../../components/landing/mix-tailwinds/MixTailwindsLanding";
import { MixWindsLanding } from "../../../components/landing/mix-winds/MixWindsLanding";

const description =
"Write Tailwind utility classes, render native Flutter widgets. Every example is measured against a real browser rendering the same class string, at three viewport widths.";
Expand All @@ -8,21 +8,21 @@ export const viewport = {
};

export const metadata = {
title: "mix_tailwinds — Tailwind classes. Native Flutter.",
title: "mix_winds — Tailwind classes. Native Flutter.",
description,
applicationName: "mix_tailwinds",
applicationName: "mix_winds",
openGraph: {
title: "mix_tailwinds — Tailwind classes, native Flutter widgets",
title: "mix_winds — Tailwind classes, native Flutter widgets",
description,
type: "website",
},
twitter: {
card: "summary_large_image",
title: "mix_tailwinds — Tailwind classes. Native Flutter.",
title: "mix_winds — Tailwind classes. Native Flutter.",
description,
},
};

export default function Page() {
return <MixTailwindsLanding />;
return <MixWindsLanding />;
}
Loading
Loading