From 0f8c3865da96b84abe12a77a8ab39eb75bebe6bd Mon Sep 17 00:00:00 2001 From: Parker Lougheed Date: Wed, 29 Jan 2025 19:31:40 -0600 Subject: [PATCH 01/12] Removal and replacement of bootstrap --- package.json | 3 - pnpm-lock.yaml | 9 - src/_includes/cookie-notice.html | 2 +- src/_includes/docs/catalog-page-material.md | 26 +-- src/_includes/docs/catalog-page.md | 64 +++--- src/_includes/header.html | 90 ++------- src/_layouts/base.html | 6 +- src/_layouts/default.html | 2 +- src/_sass/base/_base.scss | 207 +++++--------------- src/_sass/base/_material-colors.scss | 154 --------------- src/_sass/base/_mixins.scss | 3 + src/_sass/base/_reset.scss | 28 +++ src/_sass/base/_utils.scss | 21 +- src/_sass/base/_variables.scss | 2 +- src/_sass/components/_alert.scss | 6 +- src/_sass/components/_banner.scss | 51 ----- src/_sass/components/_button.scss | 73 +++++++ src/_sass/components/_card.scss | 170 ++++++++++++++++ src/_sass/components/_code.scss | 39 +++- src/_sass/components/_content.scss | 57 ++++-- src/_sass/components/_cookie-notice.scss | 30 +-- src/_sass/components/_d2h.scss | 7 - src/_sass/components/_footer.scss | 4 +- src/_sass/components/_header.scss | 81 +++----- src/_sass/components/_juicy-button.scss | 41 ---- src/_sass/components/_misc.scss | 81 ++++++++ src/_sass/components/_sidebar.scss | 19 +- src/_sass/components/_toc.scss | 3 +- src/_sass/site.scss | 26 ++- src/_sass/vendor/_bootstrap.scss | 151 -------------- src/content/add-to-app/index.md | 50 ++--- src/content/assets/js/main.js | 18 +- src/content/get-started/codelab.md | 2 +- src/content/index.md | 50 ++--- src/content/reference/widgets.md | 32 +-- src/content/ui/navigation/deep-linking.md | 16 +- src/content/ui/widgets/index.md | 86 ++++---- 37 files changed, 745 insertions(+), 965 deletions(-) delete mode 100644 src/_sass/base/_material-colors.scss create mode 100644 src/_sass/base/_mixins.scss create mode 100644 src/_sass/base/_reset.scss delete mode 100644 src/_sass/components/_banner.scss create mode 100644 src/_sass/components/_button.scss create mode 100644 src/_sass/components/_card.scss delete mode 100644 src/_sass/components/_d2h.scss delete mode 100644 src/_sass/components/_juicy-button.scss create mode 100644 src/_sass/components/_misc.scss delete mode 100644 src/_sass/vendor/_bootstrap.scss diff --git a/package.json b/package.json index d9264d53ba..8f28564b19 100644 --- a/package.json +++ b/package.json @@ -18,9 +18,6 @@ "build-site-for-staging": "PRODUCTION=false OPTIMIZE=true tsx node_modules/@11ty/eleventy/cmd.cjs --config=eleventy.config.ts", "build-site-for-production": "PRODUCTION=true OPTIMIZE=true tsx node_modules/@11ty/eleventy/cmd.cjs --config=eleventy.config.ts" }, - "dependencies": { - "bootstrap-scss": "^4.6.2" - }, "devDependencies": { "@11ty/eleventy": "^3.0.0", "@types/hast": "^3.0.4", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 28f0bb20ca..ec371e1cf7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -7,10 +7,6 @@ settings: importers: .: - dependencies: - bootstrap-scss: - specifier: ^4.6.2 - version: 4.6.2 devDependencies: '@11ty/eleventy': specifier: ^3.0.0 @@ -763,9 +759,6 @@ packages: boolbase@1.0.0: resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} - bootstrap-scss@4.6.2: - resolution: {integrity: sha512-emVpCI/S9aeFV1/qqKrztPZLiyow4XfRWLxOAu2SR/67Vau0y6IHNRukQrTx8+OUQ+aVPDhql40eDHSxGoAceA==} - boxen@5.1.2: resolution: {integrity: sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==} engines: {node: '>=10'} @@ -3967,8 +3960,6 @@ snapshots: boolbase@1.0.0: {} - bootstrap-scss@4.6.2: {} - boxen@5.1.2: dependencies: ansi-align: 3.0.1 diff --git a/src/_includes/cookie-notice.html b/src/_includes/cookie-notice.html index 27275c27c6..df3b02805d 100644 --- a/src/_includes/cookie-notice.html +++ b/src/_includes/cookie-notice.html @@ -4,6 +4,6 @@ enhance the quality of its services and to analyze traffic. Learn more.

- + diff --git a/src/_includes/docs/catalog-page-material.md b/src/_includes/docs/catalog-page-material.md index 8df5a208b3..65f9e52176 100644 --- a/src/_includes/docs/catalog-page-material.md +++ b/src/_includes/docs/catalog-page-material.md @@ -7,22 +7,22 @@ ## {{sub.name}} -
+
{% for comp in components -%} -
- -
- Rendered example of the {{comp.name}} Material widget. -
- -
+
+
+ Rendered example of the {{comp.name}} Material widget. +
+
-
-
-
{{comp.name}}
-

{{ comp.description | truncatewords: 25 }}

-
+
+
{{comp.name}}
+
+
+

{{ comp.description | truncatewords: 25 }}

+
+ {% endfor -%}
diff --git a/src/_includes/docs/catalog-page.md b/src/_includes/docs/catalog-page.md index 6aff325523..f10b6beeee 100644 --- a/src/_includes/docs/catalog-page.md +++ b/src/_includes/docs/catalog-page.md @@ -6,23 +6,23 @@ {% if components.size != 0 -%}
{% for comp in components -%} - {% endif -%} @@ -36,23 +36,23 @@
{% for comp in components -%} - {% endif -%} diff --git a/src/_includes/header.html b/src/_includes/header.html index cc06737fbd..0667517ba9 100644 --- a/src/_includes/header.html +++ b/src/_includes/header.html @@ -1,9 +1,13 @@ {% assign route = page.url|regex_replace:'/index$|/index\.html$|\.html$|/$' %} diff --git a/src/_layouts/base.html b/src/_layouts/base.html index 3a75999755..fc6e1e4c61 100644 --- a/src/_layouts/base.html +++ b/src/_layouts/base.html @@ -1,4 +1,4 @@ -{% assign cache_bust = '?v=2' %} +{% assign cache_bust = '?v=3' %} {% assign page_url = page.url | regex_replace: '/index$|/index.html$|\.html$|/$' -%} @@ -72,9 +72,6 @@ {% endif -%} - - Skip to main content - {% render cookie-notice.html %} @@ -98,7 +95,6 @@
- diff --git a/src/_layouts/default.html b/src/_layouts/default.html index 12de112e10..2aaad7df98 100644 --- a/src/_layouts/default.html +++ b/src/_layouts/default.html @@ -19,7 +19,7 @@ {% include side-toc.html tocContents=tocContents %} {% endif -%}
-
+

{{ title }}

{% if show_breadcrumbs != false -%} {% include breadcrumbs.html %} diff --git a/src/_sass/base/_base.scss b/src/_sass/base/_base.scss index 6392fea9a2..3572d1850f 100644 --- a/src/_sass/base/_base.scss +++ b/src/_sass/base/_base.scss @@ -8,7 +8,10 @@ body { -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; + font-family: $site-font-family-base; overflow-x: hidden; + line-height: 1.5; + color: $site-color-body; } .container main { @@ -28,10 +31,6 @@ body { justify-content: space-between; } -h1 { - margin-bottom: 2.5rem; -} - h2 { clear: both; } @@ -54,106 +53,10 @@ picture { max-height: 100%; } -.card-grid { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr)); - grid-auto-rows: 1fr; - gap: 1rem; - margin-bottom: 1rem; - - .card { - overflow: hidden; - max-width: 50vw; - } - - .card-body img { - width: 72px; - height: 72px; - } - - .card-image-holder { - display: flex; - justify-content: center; - align-items: center; - height: 12rem; - - img { - max-width: 100%; - max-height: 100%; - width: auto; - z-index: 1; - } - - svg { - height: 100%; - width: 100%; - } - } - - &.wide { - grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr)); - } - - &.narrow { - grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr)); - } -} - -.card-footer.card-footer--transparent { - border: none; - background-color: transparent; -} - -.card-footer.card-footer--links { - > *:not(:last-child) { - margin-right: 1rem; - } -} - -.card-title-material-3 { - color: $site-color-body; -} - .d-block.h1 > .material-symbols { font-size: 3rem; } -.card-image-holder-material-3 { - align-items: center; - z-index: -1; - background-size: 0; - opacity: .999; - background-color: var(--bg-color, white); - - img { - max-width: 100%; - max-height: 100%; - width: auto; - z-index: 1; - } -} - -.card-image-material-3-hover { - position: absolute; - top: 0; - bottom: 0; - left: 0; - right: 0; - opacity: 0; - transition: .25s ease; - z-index: -1; - - img { - width: 100%; - max-height: 100%; - z-index: -1; - } -} - -.card-image-holder-material-3:hover .card-image-material-3-hover { - opacity: 1; -} - .card-app-type { border-color: $site-color-nav-links; } @@ -177,8 +80,13 @@ picture { white-space: nowrap; word-wrap: normal; direction: ltr; + font-feature-settings: 'liga'; -webkit-font-feature-settings: 'liga'; -webkit-font-smoothing: antialiased; + + &.ms-filled { + font-variation-settings: 'FILL' 1; + } } .site-mobile-screenshot { @@ -229,11 +137,6 @@ main figure { } } -.list-image { - width: 48px; - margin: 0.25rem; -} - .text-icon { margin: 0 0.125rem; width: 1.5rem; @@ -247,48 +150,53 @@ main figure { max-height: 60vh; } -.table-wrapper, .scrollable-table { - overflow-x: auto; -} +.table { + width: 100%; + border-spacing: 0; -.scrollable-table { - overflow-y: scroll; - max-height: 20rem; + thead { + vertical-align: bottom; - table { - width: 100%; + th { + border-bottom: 1px solid $site-color-light-grey; + text-align: start; + } + } + + tbody { + tr { + vertical-align: top; + + &:nth-of-type(odd) { + background-color: rgba(0, 0, 0, 0.05); + } + } + } + + td, th { + border-top: 1px solid $site-color-light-grey; + padding: .75rem; } } // If table head has empty children, just hide it -// since markdown-it-table doesn't support headless tables. +// since markdown-it's tables don't support headless tables. thead:has(th:empty) { display: none; } -.searchbar { - > * { - max-width: 640px; - width:100% - } +.table-wrapper, .scrollable-table { + overflow-x: auto; + margin-block-start: 1rem; + margin-block-end: 1rem; } -.install-help { - text-align: right; - margin-top: -2.5rem; - - a { - display: inline-flex; - align-items: center; - - &:hover { - text-decoration: none; - } - } +.scrollable-table { + overflow-y: scroll; + max-height: 20rem; - .material-symbols { - font-size: 20px; - margin-right: 0.125rem; + table { + width: 100%; } } @@ -345,8 +253,8 @@ td ol, td ul, td dl, td p { } p + ul, p + ol, p + dl { - margin-top: .5rem; - margin-bottom: .5rem; + margin-block-start: 0.75rem; + margin-block-end: 0.75rem; } td ol, td ul, td dl, td p { @@ -364,9 +272,9 @@ td ol, td ul, td dl, td p { ::before { content: ""; position: absolute; - top: 0.5rem; - left: 0.5rem; - width: 24px; + top: 0.5rem; + left: 0.5rem; + width: 24px; height: 24px; background-position: center center; background-size: contain; @@ -404,27 +312,6 @@ td ol, td ul, td dl, td p { } } -#skip-to-main { - top: 10px; - left: 10px; - position: absolute; - z-index: 2000; - padding: 1rem; - background-color: $site-color-primary; - color: $site-color-white; - border-radius: 0.5rem; - transform: translateY(-5rem); - - &:focus { - opacity: 1; - transform: translateY(0); - } -} - -#site-content-title { - scroll-margin-top: 5rem; -} - .video-wrapper { display: flex; flex-direction: column; diff --git a/src/_sass/base/_material-colors.scss b/src/_sass/base/_material-colors.scss deleted file mode 100644 index 9b896706d4..0000000000 --- a/src/_sass/base/_material-colors.scss +++ /dev/null @@ -1,154 +0,0 @@ -// Material Design Colors -// -// Colors based off the material design palette -// https://material.google.com/style/color.html#color-color-palette - -$amber-50: #FFF8E1; -$amber-100: #FFECB3; -$amber-200: #FFE082; -$amber-300: #FFD54F; -$amber-400: #FFCA28; -$amber-500: #FFC107; -$amber-600: #FFB300; -$amber-700: #FFA000; -$amber-800: #FF8F00; -$amber-900: #FF6F00; -$amber-A100: #FFE57F; -$amber-A200: #FFD740; -$amber-A400: #FFC400; -$amber-A700: #FFAB00; - -$blue-50: #E3F2FD; -$blue-100: #BBDEFB; -$blue-200: #90CAF9; -$blue-300: #64B5F6; -$blue-400: #42A5F5; -$blue-500: #2196F3; -$blue-600: #1E88E5; -$blue-700: #1976D2; -$blue-800: #1565C0; -$blue-900: #0D47A1; -$blue-A100: #82B1FF; -$blue-A200: #448AFF; -$blue-A400: #2979FF; -$blue-A700: #2962FF; - -$blue-grey-50: #ECEFF1; -$blue-grey-100: #CFD8DC; -$blue-grey-200: #B0BEC5; -$blue-grey-300: #90A4AE; -$blue-grey-400: #78909C; -$blue-grey-500: #607D8B; -$blue-grey-600: #546E7A; -$blue-grey-700: #455A64; -$blue-grey-800: #37474F; -$blue-grey-900: #263238; - -$cyan-50: #E0F7FA; -$cyan-100: #B2EBF2; -$cyan-200: #80DEEA; -$cyan-300: #4DD0E1; -$cyan-400: #26C6DA; -$cyan-500: #00BCD4; -$cyan-600: #00ACC1; -$cyan-700: #0097A7; -$cyan-800: #00838F; -$cyan-900: #006064; -$cyan-A100: #84FFFF; -$cyan-A200: #18FFFF; -$cyan-A400: #00E5FF; -$cyan-A700: #00B8D4; - -$grey-400: #BDBDBD; -$grey-500: #9E9E9E; -$grey-900: #212121; - -$green-50: #E8F5E9; -$green-100: #C8E6C9; -$green-200: #A5D6A7; -$green-300: #81C784; -$green-400: #66BB6A; -$green-500: #4CAF50; -$green-600: #43A047; -$green-700: #388E3C; -$green-800: #2E7D32; -$green-900: #1B5E20; -$green-A100: #B9F6CA; -$green-A200: #69F0AE; -$green-A400: #00E676; -$green-A700: #00C853; - -$light-green-50: #F1F8E9; -$light-green-100: #DCEDC8; -$light-green-200: #C5E1A5; -$light-green-300: #AED581; -$light-green-400: #9CCC65; -$light-green-500: #8BC34A; -$light-green-600: #7CB342; -$light-green-700: #689F38; -$light-green-800: #558B2F; -$light-green-900: #33691E; -$light-green-A100: #CCFF90; -$light-green-A200: #B2FF59; -$light-green-A400: #76FF03; -$light-green-A700: #64DD17; - -$pink-50: #FCE4EC; -$pink-100: #F8BBD0; -$pink-200: #F48FB1; -$pink-300: #F06292; -$pink-400: #EC407A; -$pink-500: #E91E63; -$pink-600: #D81B60; -$pink-700: #C2185B; -$pink-800: #AD1457; -$pink-900: #880E4F; -$pink-A100: #FF80AB; -$pink-A200: #FF4081; -$pink-A400: #F50057; -$pink-A700: #C51162; - -$purple-50: #F3E5F5; -$purple-100: #E1BEE7; -$purple-200: #CE93D8; -$purple-300: #BA68C8; -$purple-400: #AB47BC; -$purple-500: #9C27B0; -$purple-600: #8E24AA; -$purple-700: #7B1FA2; -$purple-800: #6A1B9A; -$purple-900: #4A148C; -$purple-A100: #EA80FC; -$purple-A200: #E040FB; -$purple-A400: #D500F9; -$purple-A700: #AA00FF; - -$red-50: #FFEBEE; -$red-100: #FFCDD2; -$red-200: #EF9A9A; -$red-300: #E57373; -$red-400: #EF5350; -$red-500: #F44336; -$red-600: #E53935; -$red-700: #D32F2F; -$red-800: #C62828; -$red-900: #B71C1C; -$red-A100: #FF8A80; -$red-A200: #FF5252; -$red-A400: #FF1744; -$red-A700: #D50000; - -$teal-50: #E0F2F1; -$teal-100: #B2DFDB; -$teal-200: #80CBC4; -$teal-300: #4DB6AC; -$teal-400: #26A69A; -$teal-500: #009688; -$teal-600: #00897B; -$teal-700: #00796B; -$teal-800: #00695C; -$teal-900: #004D40; -$teal-A100: #A7FFEB; -$teal-A200: #64FFDA; -$teal-A400: #1DE9B6; -$teal-A700: #00BFA5; diff --git a/src/_sass/base/_mixins.scss b/src/_sass/base/_mixins.scss new file mode 100644 index 0000000000..fd324a18b9 --- /dev/null +++ b/src/_sass/base/_mixins.scss @@ -0,0 +1,3 @@ +@mixin interaction-style($percentage: 4%) { + background-image: linear-gradient(rgb(var(--site-interaction-base-values) / $percentage) 0 0); +} diff --git a/src/_sass/base/_reset.scss b/src/_sass/base/_reset.scss new file mode 100644 index 0000000000..686713cefb --- /dev/null +++ b/src/_sass/base/_reset.scss @@ -0,0 +1,28 @@ +@use 'variables' as *; + +*, ::before, ::after { + box-sizing: border-box; + border-width: 0; +} + +html, body { + padding: 0; + margin: 0; +} + +button, input, select, textarea { + font-family: inherit; + font-feature-settings: inherit; + font-variation-settings: inherit; + font-size: 100%; + font-weight: inherit; + line-height: inherit; + letter-spacing: inherit; + color: inherit; + margin: 0; + padding: 0; +} + +*:focus-visible { + outline: 2px solid $site-color-primary; +} diff --git a/src/_sass/base/_utils.scss b/src/_sass/base/_utils.scss index fd324a18b9..a684c0902a 100644 --- a/src/_sass/base/_utils.scss +++ b/src/_sass/base/_utils.scss @@ -1,3 +1,20 @@ -@mixin interaction-style($percentage: 4%) { - background-image: linear-gradient(rgb(var(--site-interaction-base-values) / $percentage) 0 0); +.side-by-side { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(min(100%, 24rem), 1fr)); + column-gap: 2rem; + row-gap: 0; + justify-content: center; +} + +.centered-rows { + display: flex; + flex-direction: column; + align-items: center; + margin-left: 1rem; + margin-right: 1rem; + justify-content: center; +} + +.text-center { + text-align: center; } diff --git a/src/_sass/base/_variables.scss b/src/_sass/base/_variables.scss index 222125c2ea..9bb834e47e 100644 --- a/src/_sass/base/_variables.scss +++ b/src/_sass/base/_variables.scss @@ -30,7 +30,7 @@ $site-color-panel-background: color.scale($site-color-primary, $lightness: 95%); // Fonts $font-size-base-weight: 400; $site-font-family-base: 'Google Sans Text', 'Roboto', sans-serif; -$site-font-family-alt: 'Google Sans', 'Google Sans Text', 'Roboto', sans-serif; +$site-font-family-ui: 'Google Sans', 'Google Sans Text', 'Roboto', sans-serif; $site-font-family-icon: 'Material Symbols Outlined'; $site-font-family-monospace: 'Google Sans Mono', 'Roboto Mono', monospace; $site-font-icon: 24px/1 $site-font-family-icon; diff --git a/src/_sass/components/_alert.scss b/src/_sass/components/_alert.scss index 3666afa501..6b169e3bfe 100644 --- a/src/_sass/components/_alert.scss +++ b/src/_sass/components/_alert.scss @@ -13,10 +13,6 @@ aside.alert { // --alert-warning-color: #cea11f; // --alert-error-color: #ff4141; - // TODO(parlough): Remove these resets once bootstrap is removed. - margin: 0; - border: none; - padding: 0.75rem; margin-block-start: 1rem; margin-block-end: 1rem; @@ -29,7 +25,7 @@ aside.alert { align-items: center; gap: 0.5rem; margin-block-end: 0.5rem; - font-family: $site-font-family-alt; + font-family: $site-font-family-ui; font-size: 1.125rem; font-weight: 500; -webkit-font-smoothing: antialiased; diff --git a/src/_sass/components/_banner.scss b/src/_sass/components/_banner.scss deleted file mode 100644 index 2bdd3d841a..0000000000 --- a/src/_sass/components/_banner.scss +++ /dev/null @@ -1,51 +0,0 @@ -@use '../base/variables' as *; - -.site-banner { - background-color: $flutter-color-blue; - color: $site-color-white; - font-family: $site-font-family-alt; - font-size: 1.25rem; - padding: 1.25rem; - position: relative; - text-align: center; - z-index: 1020; - - p { - margin-bottom: 0.75rem; - - &:last-of-type { - margin-bottom: 0; - } - } - - a { - color: $flutter-color-blue-on-dark; - - &:hover { - color: $flutter-color-blue-on-dark; - } - } - - // customizations per banner - - &.site-banner--default { - &:before, - &:after { - background-image: url('/assets/images/flutter-chevron-bg.svg'); - background-position: right center; - background-repeat: no-repeat; - background-size: auto 100%; - content: ''; - height: 100%; - left: 0; - pointer-events: none; - position: absolute; - top: 0; - width: 100%; - } - - &:before { - transform: scaleX(-1); - } - } -} diff --git a/src/_sass/components/_button.scss b/src/_sass/components/_button.scss new file mode 100644 index 0000000000..81dd231239 --- /dev/null +++ b/src/_sass/components/_button.scss @@ -0,0 +1,73 @@ +@use '../base/mixins'; +@use '../base/variables' as *; + +a { + color: $site-color-primary; + border-radius: 0.25rem; + + &:hover { + color: $site-color-primary; + text-decoration: underline; + } + + &:active { + color: $flutter-color-blue-600; + } + + &:visited { + color: $site-color-primary; + } +} + +a, button { + text-decoration: none; + background: none; + cursor: pointer; + + &.filled-button { + display: flex; + align-items: center; + width: fit-content; + white-space: nowrap; + outline-offset: 2px; + + font-weight: 500; + padding: 0.5rem 1rem; + background-color: $site-color-primary; + color: $site-color-white; + text-decoration: none; + border-radius: 0; + cursor: pointer; + user-select: none; + + &:hover { + @include mixins.interaction-style(8%); + } + + &:active { + @include mixins.interaction-style(16%); + } + } + + &.icon-button { + border-radius: 0.25rem; + padding: 0.25rem; + color: $site-color-nav-links; + text-decoration: none; + + display: flex; + align-items: center; + cursor: pointer; + user-select: none; + -webkit-user-select: none; + background: none; + + > span { + font-size: 1.75rem; + } + + &:hover { + color: $site-color-body; + } + } +} diff --git a/src/_sass/components/_card.scss b/src/_sass/components/_card.scss new file mode 100644 index 0000000000..06138bf8b2 --- /dev/null +++ b/src/_sass/components/_card.scss @@ -0,0 +1,170 @@ +@use '../base/mixins'; +@use '../base/variables' as *; + +.card-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(min(100%, var(--card-min-width, 15rem)), 1fr)); + gap: var(--card-grid-gap, 1rem); + margin-block-end: 1rem; + justify-content: center; + + &.wide { + --card-min-width: 19rem; + } + + &.narrow { + --card-min-width: 10rem; + } + + .card { + display: flex; + flex-direction: column; + + border-radius: 0.25rem; + padding: 1rem; + gap: 0.5rem; + height: auto; + overflow: hidden; + + scroll-margin: 5rem; + + &.hidden { + display: none; + } + + &.filled-card { + background-color: var(--card-container-color, rgb(242, 245, 255)); + } + + &.outlined-card { + border: 1px solid var(--card-border-color, rgba(0, 0, 0, .125)); + } + + &.wrapped-card { + padding: 0; + } + + .card-header { + display: flex; + flex-direction: row; + justify-content: space-between; + align-items: center; + color: $site-color-body; + + .card-title { + font-size: 1.25rem; + font-weight: 500; + margin: 0; + overflow: hidden; + font-family: $site-font-family-ui; + } + + &.text-center { + justify-content: center; + } + } + + .card-content { + display: flex; + align-items: center; + gap: 0.75rem; + color: var(--card-text-color, $site-color-body); + + p { + margin: 0; + margin-block-end: 0.75rem; + + code { + font-size: 0.95em; + background-color: rgba(0, 0, 0, .05); + color: var(--card-text-color, $site-color-body); + border-radius: .25rem; + padding: .1rem .25rem; + text-wrap: nowrap; + } + } + } + + .material-symbols { + user-select: none; + } + } + + a.card { + text-decoration: none; + + .card-title { + color: $site-color-primary; + } + + &:hover { + @include mixins.interaction-style(3%); + } + + &:active { + @include mixins.interaction-style(5%); + } + } + + .card-image-holder { + position: relative; + display: flex; + justify-content: center; + align-items: center; + height: 11rem; + margin: -1rem -1rem 0; + + img { + max-width: 100%; + max-height: 100%; + width: auto; + z-index: 1; + -webkit-user-drag: none; + } + + svg { + height: 100%; + width: 100%; + } + } +} + + +.card-image-holder-material-3 { + position: relative; + align-items: center; + z-index: -1; + background-size: 0; + opacity: .999; + background-color: var(--bg-color, white); + margin: -1rem -1rem 0; + + img { + max-width: 100%; + max-height: 100%; + width: auto; + display: block; + } +} + +.card:hover { + .card-image-material-3-hover { + opacity: 1; + } +} + +.card-image-material-3-hover { + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + opacity: 0; + transition: .25s ease; + z-index: -1; + + img { + width: 100%; + max-height: 100%; + } +} diff --git a/src/_sass/components/_code.scss b/src/_sass/components/_code.scss index 01d040feeb..c858245a05 100644 --- a/src/_sass/components/_code.scss +++ b/src/_sass/components/_code.scss @@ -2,11 +2,40 @@ @use '../base/variables' as *; +pre, code, kbd, samp { + font-family: $site-font-family-monospace; +} + +// Inline code spans found within the primary contents of the page. +// Targets all elements, but
 shouldn't have many of these.
+main code {
+  font-size: 0.9em;
+  line-height: 1.25em;
+  padding: 0.1rem 0.25rem;
+  background-color: $site-color-light-grey;
+  background-color: color-mix(in srgb, $site-color-light-grey 35%, transparent);
+  border: 1px solid rgb(195, 201, 214);
+  border-radius: 0.25rem;
+  word-wrap: break-word;
+  white-space: nowrap;
+}
+
 pre {
   margin-bottom: 1rem;
-  font-size: 0.9375rem;
-  font-weight: 400;
   padding: 1.25rem;
+  overflow: auto;
+
+  > code {
+    // Undo the core `code` styles.
+    font-size: 0.9125rem;
+    line-height: 1.75em;
+    padding: 0;
+    background: none;
+    border: none;
+    border-radius: unset;
+    word-break: normal;
+    white-space: pre;
+  }
 
   a {
     font-family: inherit;
@@ -219,7 +248,7 @@ pre {
   }
 
   pre {
-    margin-bottom: 0;
+    margin: 0;
     padding-right: 0;
     padding-left: 0;
 
@@ -228,10 +257,6 @@ pre {
       min-width: fit-content;
       width: 100%;
     }
-
-    &:not([lang="console"]) {
-      line-height: 1.8;
-    }
   }
 }
 
diff --git a/src/_sass/components/_content.scss b/src/_sass/components/_content.scss
index 43bebe071c..0449bf6560 100644
--- a/src/_sass/components/_content.scss
+++ b/src/_sass/components/_content.scss
@@ -24,22 +24,60 @@
   }
 
   &__title {
-    margin-bottom: 2rem;
+    margin-block-end: 1.5rem;
 
     h1 {
       margin-bottom: 0;
     }
   }
 
+  p {
+    margin-block-start: 0;
+  }
+
+  b, strong {
+    font-weight: bolder;
+  }
+
   h1, h2, h3, h4, h5, h6 {
     text-wrap: balance;
     scroll-margin-top: 5rem;
+    line-height: 1.2;
+    font-family: $site-font-family-ui;
+    font-weight: 500;
+  }
+
+  h1 {
+    font-size: 3rem;
+    margin-top: 0;
+    margin-bottom: 0;
+    scroll-margin-top: 6rem;
+  }
+
+  h2 {
+    font-size: 1.875rem;
+  }
+
+  h3 {
+    font-size: 1.5rem;
+  }
+
+  h4 {
+    font-size: 1.3125rem;
+  }
+
+  h5 {
+    font-size: 1.125rem;
+  }
+
+  h6 {
+    font-size: 0.9375rem;
   }
 
   .header-wrapper {
     display: flex;
-    margin-top: 1.5rem;
-    margin-bottom: 0.75rem;
+    margin-block-start: 1.5rem;
+    margin-block-end: 0.75rem;
     align-items: center;
 
     h1, h2, h3, h4, h5, h6 {
@@ -86,16 +124,17 @@
 
 nav.breadcrumbs {
   align-items: center;
-  margin-bottom: 1rem;
+  margin-block-end: 1rem;
 
   > ol {
     border-radius: 0.375rem;
+    margin-block-start: 0;
     padding: 0.375rem 0;
 
     align-items: center;
     list-style: none;
 
-    font-family: $site-font-family-alt;
+    font-family: $site-font-family-ui;
 
     display: flex;
     flex-wrap: wrap;
@@ -129,14 +168,6 @@ nav.breadcrumbs {
   }
 }
 
-#page-github-links {
-  font-style: italic;
-  font-size: 0.75rem;
-  padding-top: 0.25rem;
-
-  border-top: 0.05rem solid $site-color-light-grey;
-}
-
 .video-card {
   flex: 0 0 calc((100% / 2) - 1rem);
   position: relative;
diff --git a/src/_sass/components/_cookie-notice.scss b/src/_sass/components/_cookie-notice.scss
index 7669bd04b5..ccc8aebf05 100644
--- a/src/_sass/components/_cookie-notice.scss
+++ b/src/_sass/components/_cookie-notice.scss
@@ -1,9 +1,10 @@
+@use '../base/variables' as *;
+
 #cookie-notice {
-  background-color: white;
-  padding: 2.5rem 0;
+  background-color: $site-color-white;
+  padding: 2rem;
   position: fixed;
   bottom: 0;
-  left: 0;
   width: 100%;
   box-shadow: -1px 1px 4px rgba(0, 0, 0, 0.3);
   opacity: 0;
@@ -11,17 +12,16 @@
   z-index: 1060;
 
   @keyframes fadein {
-      0% { opacity: 0; }
-    100% { opacity: 1; }
-  }
-
-  a.btn {
-    padding-left: 1.5rem;
-    padding-right: 1.5rem;
+    0% {
+      opacity: 0;
+    }
+    100% {
+      opacity: 1;
+    }
   }
 
-  button {
-    text-wrap: nowrap;
+  button.filled-button {
+    font-size: 1rem;
   }
 
   &.show {
@@ -39,12 +39,14 @@
     justify-content: space-between;
     align-items: center;
     max-width: 1080px;
+    min-width: 0;
+    width: auto;
+    gap: 1.5rem;
 
     p {
       font-size: 1rem;
       line-height: 1.6;
-      margin-right: 1.5rem;
-      margin-bottom: 0;
+      margin: 0;
     }
   }
 }
diff --git a/src/_sass/components/_d2h.scss b/src/_sass/components/_d2h.scss
deleted file mode 100644
index e309d4cec4..0000000000
--- a/src/_sass/components/_d2h.scss
+++ /dev/null
@@ -1,7 +0,0 @@
-.d2h-wrapper {
-    margin: 1.5rem 0;
-}
-
-.d2h-file-header {
-    display: none;
-}
diff --git a/src/_sass/components/_footer.scss b/src/_sass/components/_footer.scss
index 06e95c83a0..76acf1a678 100644
--- a/src/_sass/components/_footer.scss
+++ b/src/_sass/components/_footer.scss
@@ -8,7 +8,7 @@
 
   color: $site-color-light-grey;
   font-weight: 400;
-  font-family: $site-font-family-alt;
+  font-family: $site-font-family-ui;
   font-size: 14px;
 
   .brand {
@@ -97,7 +97,7 @@
 
   a {
     color: $site-color-light-grey;
-    font-family: $site-font-family-alt;
+    font-family: $site-font-family-ui;
 
     &:hover, &:focus, &:active {
       color: $site-color-white;
diff --git a/src/_sass/components/_header.scss b/src/_sass/components/_header.scss
index 77b43576c0..3595ca3890 100644
--- a/src/_sass/components/_header.scss
+++ b/src/_sass/components/_header.scss
@@ -3,30 +3,23 @@
 .site-header {
   background-color: $site-color-white;
   box-shadow: 0 2px 4px rgba(0, 0, 0, .1);
-  font-family: $site-font-family-alt;
+  font-family: $site-font-family-ui;
   position: sticky;
   top: 0;
   z-index: $site-z-header;
 
   .navbar {
-    font-size: 1rem;
+    position: relative;
+    display: flex;
+    flex-wrap: wrap;
+    align-items: center;
+    justify-content: space-between;
+    padding: .5rem 1rem;
+
     min-height: $site-header-height;
 
     #menu-toggle {
-      appearance: none;
-      border: none;
-      background: none;
-      color: $site-color-nav-links;
-      margin-right: 1rem;
-      padding: 0;
-
-      .material-symbols {
-        font-size: 28px;
-      }
-
-      &:hover {
-        color: $site-color-body;
-      }
+      margin-right: 0.75rem;
 
       @media (min-width: 1024px) {
         display: none;
@@ -39,6 +32,7 @@
       img {
         width: 129px;
         height: 37px;
+        vertical-align: middle;
       }
     }
 
@@ -49,6 +43,9 @@
     }
 
     .navbar-nav {
+      list-style: none;
+      padding: 0;
+      margin: 0;
       flex-direction: row;
       gap: 0.5rem;
       display: none;
@@ -70,7 +67,7 @@
     }
   }
 
-  &__cta {
+  #call-to-action {
     margin-left: 0.5rem;
     padding: 0.5rem 1rem !important;
     display: none;
@@ -81,10 +78,15 @@
   }
 
   &__search {
-    display: flex;
+    display: none;
     position: relative;
     align-items: center;
     vertical-align: middle;
+    margin-left: 1rem;
+
+    @media (min-width: 576px) {
+      display: flex;
+    }
 
     &::before {
       content: 'search';
@@ -98,17 +100,12 @@
     &:hover::before {
       color: $site-color-body;
     }
-
-    @media (min-width: 768px) {
-      margin-left: 1rem;
-    }
   }
 
   &__searchfield {
     border: 0;
-    padding-left: 2rem;
+    padding: 0.5rem 0.5rem 0.5rem 2rem;
     font-size: 1rem;
-    height: unset;
     transition: width .35s ease-in-out;
     width: 24px;
     cursor: pointer;
@@ -118,40 +115,10 @@
       cursor: auto;
     }
   }
-}
-
-
-header.site-header {
-  .dropdown-menu {
-    position: absolute;
-    float: none;
-    top: 32px;
-    box-shadow: 0 2px 4px rgba(0, 0, 0, .1);
-    border-radius: 4px;
-    padding: 0.75rem;
-    border: 1px solid #eee;
-  }
-
-  .dropdown-item {
-    padding: 0.55rem 1.2rem;
-    font-size: 14px;
-    color: #444;
-    border-radius: 4px;
-
-    &:hover,
-    &.active {
-      color: #000;
-      background-color: #f6f6f6;
-      transition: background-color 300ms ease;
-    }
 
-    &.active {
-      font-weight: 500;
+  #fallback-search-button {
+    @media (min-width: 576px) {
+      display: none;
     }
   }
-
-  .dropdown-toggle::after {
-    position: relative;
-    top: 1px;
-  }
 }
diff --git a/src/_sass/components/_juicy-button.scss b/src/_sass/components/_juicy-button.scss
deleted file mode 100644
index eecdf18ed4..0000000000
--- a/src/_sass/components/_juicy-button.scss
+++ /dev/null
@@ -1,41 +0,0 @@
-// A big button centered on top of an image.
-//
-// The container is typically a 
element. The div has only 2 children: -// an element (the background) and a button. -// -// The image should be very bright and slightly blurred so that the button -// stands out. -.juicy-button-container { - position: relative; - width: 100%; - padding: 2em 0; - - img { - // Take available space in the container. - width: 100%; - height: auto; - } - - .btn { - // Center the button in the container. - position: absolute; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); - -ms-transform: translate(-50%, -50%); - - // Add a white "glow" that separates the button from the background. - box-shadow: 0 0 10px 10px white ; - - // Make the button extra large. - @media (min-width: 600px) { - font-size: 150%; - padding: 0.7rem; - } - - @media (min-width: 900px) { - font-size: 200%; - padding: 1.0rem; - } - } -} diff --git a/src/_sass/components/_misc.scss b/src/_sass/components/_misc.scss new file mode 100644 index 0000000000..90a47902ae --- /dev/null +++ b/src/_sass/components/_misc.scss @@ -0,0 +1,81 @@ +@use '../base/variables' as *; + +.install-help { + text-align: right; + margin-top: -2.5rem; + + a { + display: inline-flex; + align-items: center; + + &:hover { + text-decoration: none; + } + } + + .material-symbols { + font-size: 20px; + margin-right: 0.125rem; + } +} + +#skip-to-main { + position: absolute; + top: 0.75rem; + left: -24rem; + z-index: 1080; + transform: translateX(0); + + &:focus { + transform: translateX(25rem); + } +} + +#page-github-links { + font-style: italic; + font-size: 0.75rem; + padding-top: 0.5rem; + margin-bottom: 0; + + border-top: 0.05rem solid $site-color-light-grey; +} + +// A big button centered on top of an image. +// +// The container is typically a
element. The div has only 2 children: +// an element (the background) and a button. +// +// The image should be very bright and slightly blurred so that the button +// stands out. +.juicy-button-container { + position: relative; + padding: 2em 0; + + img { + width: 100%; + height: auto; + margin-bottom: 0; + } + + .filled-button { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + white-space: nowrap; + + // Add a white "glow" that separates the button from the background. + box-shadow: 0 0 10px 10px white; + + // Make the button extra large. + @media (min-width: 576px) { + font-size: 150%; + padding: 0.7rem; + } + + @media (min-width: 900px) { + font-size: 200%; + padding: 1rem; + } + } +} diff --git a/src/_sass/components/_sidebar.scss b/src/_sass/components/_sidebar.scss index b35aff60c9..12209adb82 100644 --- a/src/_sass/components/_sidebar.scss +++ b/src/_sass/components/_sidebar.scss @@ -1,5 +1,5 @@ @use '../base/variables' as *; -@use '../base/utils'; +@use '../base/mixins'; $sidenav-divider-color: #e7e8ed; @@ -89,7 +89,7 @@ $sidenav-divider-color: #e7e8ed; cursor: pointer; color: $site-color-body; - font-family: $site-font-family-alt, sans-serif; + font-family: $site-font-family-ui; text-decoration: none; &:focus-visible { @@ -120,11 +120,11 @@ $sidenav-divider-color: #e7e8ed; } &:hover { - @include utils.interaction-style(3%); + @include mixins.interaction-style(3%); } &:active { - @include utils.interaction-style(5%); + @include mixins.interaction-style(5%); } &:not(.collapsed) { @@ -157,15 +157,4 @@ $sidenav-divider-color: #e7e8ed; margin-left: 0.675rem; } } - - .navbar-nav { - display: none; - - a.nav-link { - font-size: 1.125rem; - margin-top: 0.5rem; - margin-bottom: 0.5rem; - padding: 0.375rem 0.6rem; - } - } } diff --git a/src/_sass/components/_toc.scss b/src/_sass/components/_toc.scss index 5cd893a634..cc733006e0 100644 --- a/src/_sass/components/_toc.scss +++ b/src/_sass/components/_toc.scss @@ -1,6 +1,8 @@ @use '../base/variables' as *; .site-toc { + font-family: $site-font-family-ui; + ul { padding-left: 0; margin-left: 0; @@ -9,7 +11,6 @@ } &__title { - font-family: $site-font-family-alt; font-size: 18px; margin-bottom: 0.5rem; } diff --git a/src/_sass/site.scss b/src/_sass/site.scss index 134c12a796..658d9343a9 100644 --- a/src/_sass/site.scss +++ b/src/_sass/site.scss @@ -1,34 +1,32 @@ -// -- Vars/config -@use 'base/variables'; -@use 'base/material-colors'; +// Must be imported first to ensure that +// the reset is applied before any other styles are applied. +@use 'base/reset'; -// -- Vendor -@use 'vendor/bootstrap'; - -// -- Base +// Base site styles. @use 'base/base'; +@use 'base/utils'; -// -- Components -// (alpha ordered) +// Styles for individual components or content types, alphabetically ordered. @use 'components/alert'; -@use 'components/banner'; @use 'components/books'; +@use 'components/button'; +@use 'components/card'; @use 'components/code'; @use 'components/content'; @use 'components/cookie-notice'; -@use 'components/d2h'; @use 'components/expansion-list'; @use 'components/footer'; @use 'components/header'; -@use 'components/juicy-button'; +@use 'components/misc'; @use 'components/next-prev-nav'; @use 'components/pill'; @use 'components/sidebar'; @use 'components/toc'; -// -- Pages (alpha ordered) +// Styles for specific pages, alphabetically ordered. @use 'pages/not-found'; @use 'pages/search'; -// -- Overrides +// Must be imported last to ensure that +// the print overrides take priority over earlier defined styles. @use 'base/print-overrides'; diff --git a/src/_sass/vendor/_bootstrap.scss b/src/_sass/vendor/_bootstrap.scss deleted file mode 100644 index b7fd93e146..0000000000 --- a/src/_sass/vendor/_bootstrap.scss +++ /dev/null @@ -1,151 +0,0 @@ -@use 'sass:color'; - -@use '../base/variables' as *; - -// Import from NPM library directly -@forward '../../../node_modules/bootstrap-scss/bootstrap' with ( - $primary: $site-color-primary, - $body-color: $site-color-body, - - // Font config - $font-family-sans-serif: $site-font-family-base, - $font-family-monospace: $site-font-family-monospace, - $font-weight-base: $font-size-base-weight, - $font-weight-bold: 500, - $headings-font-family: $site-font-family-alt, - $headings-font-weight: $font-size-base-weight, - $dt-font-weight: $font-size-base-weight, - - // Code config - $code-color: color.scale($flutter-color-teal, $lightness: -10%, $saturation: 10%), - $kbd-font-size: 0.75rem, - - // Layout config - $container-max-widths: ( - sm: 540px, - md: 720px, - lg: 960px, - xl: 1140px, - xxl: 1330px - ), - $grid-breakpoints: ( - 0: 0, - xxs: 320px, - xs: 480px, - sm: 576px, - md: 768px, - lg: 992px, - xl: 1200px, - xxl: 1440px - ), - $spacers: ( - 1: ($site-spacer * 0.25), - 2: ($site-spacer * 0.5), - 3: ($site-spacer * 0.75), - 4: $site-spacer, - 5: ($site-spacer * 1.25), - 6: ($site-spacer * 1.5), - 7: ($site-spacer * 1.75), - 8: ($site-spacer * 2), - 9: ($site-spacer * 2.25), - 10: ($site-spacer * 2.5), - 11: ($site-spacer * 2.75), - 12: ($site-spacer * 3), - ), - - // Component config - - $border-radius: 0, - $border-radius-lg: 0, - $border-radius-sm: 0, - - $breadcrumb-divider: 'chevron_right', - $breadcrumb-bg: none, - $breadcrumb-padding-x: 0, - - $card-border-radius: 4px, - $card-group-margin: $site-spacer * 0.5, - - $grid-gutter-width: 50px, - - $nav-tabs-link-active-color: $site-color-body, - $nav-tabs-link-active-border-color: transparent transparent $site-color-primary, - - $tooltip-bg: #343a40, -); - -@use '../../../node_modules/bootstrap-scss/bootstrap'; - -// Bootstrap adjustments - -a.card { - color: inherit; - - .card-title { color: $site-color-primary; } - - .card-subtitle { - font-size: 0.875rem; - } - - &.card-highlight { - border: 1px solid rgba(0, 0, 0, 0.5); - } - - &:hover { - $border-height: 0.25rem; - - border-bottom: $border-height solid $site-color-primary; - text-decoration: none; - - .card-body { - padding-bottom: bootstrap.$card-spacer-x - $border-height; - } - } -} - -.card-title { - font-family: $site-font-family-alt; - font-size: 1.25rem; - margin-bottom: 0.5rem; -} - -.btn { - font-family: $site-font-family-alt; - font-weight: 500; - padding: 0.5rem; - white-space: normal; -} - -.btn-link { - &:hover, &:focus { - text-decoration: none; - } -} - -.nav-tabs { - font-family: $site-font-family-alt; - margin-bottom: 0.75rem; - - .nav-item { - &:not(:last-child) { - margin-right: 2rem; - } - - a { - color: $site-color-nav-links; - padding: 1rem 0; - } - } - - .nav-link { - &, &:hover { - border: none; - border-bottom: 2px solid transparent; - } - - &.active, &:active { - border-color: $site-color-primary; - background-color: unset; - } - } -} diff --git a/src/content/add-to-app/index.md b/src/content/add-to-app/index.md index 486df38e85..3015048684 100644 --- a/src/content/add-to-app/index.md +++ b/src/content/add-to-app/index.md @@ -15,7 +15,7 @@ piecemeal, as a module. This feature is known as "add-to-app". The module can be imported into your existing app to render part of your app using Flutter, while the rest can be rendered using existing technology. This method can also be used to run shared non-UI logic by taking advantage of Dart's portability and -interopability with other languages. +interoperability with other languages. Add-to-app is currently supported on Android, iOS, and web. @@ -122,25 +122,19 @@ To get started, see our project integration guide for Android and iOS:
- -
-
- Android -
+
+
+
Android
- -
-
- iOS -
+
+
+
iOS
- - @@ -151,25 +145,19 @@ After Flutter is integrated into your project, see our API usage guides at the following links:
- -
-
- Android -
+
+
+
Android
- -
-
- iOS -
+
+
+
iOS
- - diff --git a/src/content/assets/js/main.js b/src/content/assets/js/main.js index 7c9ffc4d22..dcd7267872 100644 --- a/src/content/assets/js/main.js +++ b/src/content/assets/js/main.js @@ -4,14 +4,14 @@ document.addEventListener("DOMContentLoaded", function(_) { scrollSidenavIntoView(); initCookieNotice(); - setupMenuToggle(); + setupSidenavInteractivity(); setUpCodeBlockButtons(); setupSearch(); setupTabs(); }); -function setupMenuToggle() { +function setupSidenavInteractivity() { document.getElementById('menu-toggle')?.addEventListener('click', function (e) { e.stopPropagation(); document.body.classList.toggle('open_menu'); @@ -25,6 +25,15 @@ function setupMenuToggle() { } } }); + + // Set up collapse and expand for sidenav buttons. + const toggles = document.querySelectorAll('.nav-link.collapsible'); + toggles.forEach(function (toggle) { + toggle.addEventListener('click', (e) => { + toggle.classList.toggle('collapsed'); + e.preventDefault(); + }); + }); } /** @@ -96,11 +105,6 @@ function adjustToc() { }); } - // This will not be migrated for now until we migrate - // the entire site to Bootstrap 5. - // see https://github.com/flutter/website/pull/9167#discussion_r1286457246 - $('body').scrollspy({ offset: 100, target: tocId }); - function _scrollToTop() { const distanceBetweenTop = document.documentElement.scrollTop || document.body.scrollTop; if (distanceBetweenTop > 0) { diff --git a/src/content/get-started/codelab.md b/src/content/get-started/codelab.md index 36f80ff5dd..8294590d58 100644 --- a/src/content/get-started/codelab.md +++ b/src/content/get-started/codelab.md @@ -25,7 +25,7 @@ that works on mobile, desktop, and web. Unicode character. The non-breaking space after it makes the button look nicer. {% endcomment -%} - ▶  Start codelab diff --git a/src/content/index.md b/src/content/index.md index cbf4ab0f34..6f05d21cbc 100644 --- a/src/content/index.md +++ b/src/content/index.md @@ -6,13 +6,15 @@ description: Get started with Flutter. Widgets, examples, updates, and API docs **To see changes to the site since our last release, @@ -76,16 +78,16 @@ Learn more about `Stateless` and `Stateful` widgets in [What is State?][]
-
-
- {% ytEmbed 'xWV71C2kp38', 'Create your first Flutter app', true, true %} -
+
+
+ {% ytEmbed 'xWV71C2kp38', 'Create your first Flutter app', true, true %}
-
-
- {% ytEmbed 'QlwiL_yLh6E', 'What is state?', true, true %} -
+
+
+
+ {% ytEmbed 'QlwiL_yLh6E', 'What is state?', true, true %}
+
[first-app]: {{site.yt.watch}}?v=xWV71C2kp38 @@ -103,16 +105,16 @@ using helper methods][standalone-widgets] or [what is "BuildContext" and how is it used][buildcontext]?
-
-
- {% ytEmbed 'IOyq-eTRhvo', 'Widgets vs helper methods | Decoding Flutter', true, true %} -
+
+
+ {% ytEmbed 'IOyq-eTRhvo', 'Widgets vs helper methods | Decoding Flutter', true, true %}
-
-
- {% ytEmbed 'rIaaH87z1-g', 'BuildContext?! | Decoding Flutter', true, true %} -
+
+
+
+ {% ytEmbed 'rIaaH87z1-g', 'BuildContext?! | Decoding Flutter', true, true %}
+
[standalone-widgets]: {{site.yt.watch}}?v=IOyq-eTRhvo @@ -123,6 +125,6 @@ see our [videos][] page. We release new videos almost every week on the Flutter YouTube channel: -Explore more Flutter videos +Explore more Flutter videos [videos]: /resources/videos diff --git a/src/content/reference/widgets.md b/src/content/reference/widgets.md index edba90f1d2..33f3e7f7da 100644 --- a/src/content/reference/widgets.md +++ b/src/content/reference/widgets.md @@ -22,23 +22,23 @@ our [videos](/resources/videos) page.
{% for comp in sorted -%} - diff --git a/src/content/ui/navigation/deep-linking.md b/src/content/ui/navigation/deep-linking.md index 7116d138e2..637e10f9e3 100644 --- a/src/content/ui/navigation/deep-linking.md +++ b/src/content/ui/navigation/deep-linking.md @@ -39,18 +39,14 @@ If you are a visual learner, check out the following video: To get started, see our cookbooks for Android and iOS:
- -
-
- Android -
+
+
+
Android
- - diff --git a/src/content/ui/widgets/index.md b/src/content/ui/widgets/index.md index e6dd214ff5..c0677ffc51 100644 --- a/src/content/ui/widgets/index.md +++ b/src/content/ui/widgets/index.md @@ -16,14 +16,16 @@ Flutter ships with two design systems as part of the SDK.
{% assign categories = catalog.index | sort: 'name' -%} {% for section in categories %} - {%- if section.name == "Cupertino" or section.name == "Material components" -%} -
-
-
{{section.name}}
-

{{section.description}}

-
-
- {% endif -%} + {%- if section.name == "Cupertino" or section.name == "Material components" -%} + +
+
{{section.name}}
+
+
+

{{section.description}}

+
+
+ {% endif -%} {% endfor %}
@@ -41,14 +43,16 @@ like input, layout, and text.
{% assign categories = catalog.index | sort: 'name' -%} {% for section in categories %} - {%- if section.name != "Cupertino" and section.name != "Material components" and section.name != "Material 2 components" -%} -
-
-
{{section.name}}
-

{{section.description}}

-
-
- {% endif -%} + {%- if section.name != "Cupertino" and section.name != "Material components" and section.name != "Material 2 components" -%} + +
+
{{section.name}}
+
+
+

{{section.description}}

+
+
+ {% endif -%} {% endfor %}
@@ -58,38 +62,38 @@ like input, layout, and text. help you quickly get started with Flutter widgets.
-
-
- {% ytEmbed '1z6YP7YmvwA', 'TextStyle - Flutter widget of the week', true, true %} -
+
+
+ {% ytEmbed '1z6YP7YmvwA', 'TextStyle - Flutter widget of the week', true, true %}
-
-
- {% ytEmbed 'VdkRy3yZiPo', 'flutter_rating_bar - Flutter package of the week', true, true %} -
+
+
+
+ {% ytEmbed 'VdkRy3yZiPo', 'flutter_rating_bar - Flutter package of the week', true, true %}
-
-
- {% ytEmbed 'gYNTcgZVcWw', 'LinearGradient - Flutter widget of the week', true, true %} -
+
+
+
+ {% ytEmbed 'gYNTcgZVcWw', 'LinearGradient - Flutter widget of the week', true, true %}
-
-
- {% ytEmbed '-Nny8kzW380', 'AutoComplete - Flutter widget of the week', true, true %} -
+
+
+
+ {% ytEmbed '-Nny8kzW380', 'AutoComplete - Flutter widget of the week', true, true %}
-
-
- {% ytEmbed 'y9xchtVTtqQ', 'NavigationRail - Flutter widget of the week', true, true %} -
+
+
+
+ {% ytEmbed 'y9xchtVTtqQ', 'NavigationRail - Flutter widget of the week', true, true %}
-
-
- {% ytEmbed 'qjA0JFiPMnQ', 'mason - Flutter package of the week', true, true %} -
+
+
+
+ {% ytEmbed 'qjA0JFiPMnQ', 'mason - Flutter package of the week', true, true %}
+
-Watch more widget of the week videos +Watch more widget of the week videos [widget index]: /reference/widgets From edf4d1c3a0068b948820f11a6913e77e91a2dc72 Mon Sep 17 00:00:00 2001 From: Parker Lougheed Date: Wed, 29 Jan 2025 20:56:38 -0600 Subject: [PATCH 02/12] Migrate getting started cards --- src/_sass/base/_base.scss | 18 ++------ src/_sass/components/_card.scss | 46 +++++++++++++++++-- src/_sass/components/_content.scss | 4 +- src/content/assets/js/page/install-current.js | 4 +- .../get-started/install/chromeos/index.md | 30 ++++++------ src/content/get-started/install/index.md | 15 +++--- .../get-started/install/linux/index.md | 34 +++++++------- .../get-started/install/macos/index.md | 40 ++++++++-------- .../get-started/install/windows/index.md | 36 +++++++-------- .../android/install-android/index.md | 38 ++++++++------- .../ios/install-ios/index.md | 36 +++++++-------- .../linux/install-linux/index.md | 28 +++++------ .../macos/install-macos/index.md | 36 +++++++-------- .../windows/install-windows/index.md | 32 ++++++------- src/content/ui/animations/tutorial.md | 3 +- 15 files changed, 200 insertions(+), 200 deletions(-) diff --git a/src/_sass/base/_base.scss b/src/_sass/base/_base.scss index 3572d1850f..1377d59b01 100644 --- a/src/_sass/base/_base.scss +++ b/src/_sass/base/_base.scss @@ -53,14 +53,6 @@ picture { max-height: 100%; } -.d-block.h1 > .material-symbols { - font-size: 3rem; -} - -.card-app-type { - border-color: $site-color-nav-links; -} - .material-symbols { font-family: $site-font-family-icon; font-variation-settings: @@ -269,7 +261,7 @@ td ol, td ul, td dl, td p { .card-os-bug { position: relative; - ::before { + &::before { content: ""; position: absolute; top: 0.5rem; @@ -286,28 +278,28 @@ td ol, td ul, td dl, td p { .card-macos { @extend .card-os-bug; - ::before { + &::before { background-image: url("/assets/images/docs/brand-svg/macos-bug.svg"); } } .card-windows { @extend .card-os-bug; - ::before { + &::before { background-image: url("/assets/images/docs/brand-svg/windows-bug.svg"); } } .card-linux { @extend .card-os-bug; - ::before { + &::before { background-image: url("/assets/images/docs/brand-svg/linux.svg"); } } .card-chromeos { @extend .card-os-bug; - ::before { + &::before { background-image: url("/assets/images/docs/brand-svg/chromeos.svg"); } } diff --git a/src/_sass/components/_card.scss b/src/_sass/components/_card.scss index 06138bf8b2..e592a78992 100644 --- a/src/_sass/components/_card.scss +++ b/src/_sass/components/_card.scss @@ -14,6 +14,7 @@ &.narrow { --card-min-width: 10rem; + grid-auto-rows: 1fr; } .card { @@ -40,15 +41,23 @@ border: 1px solid var(--card-border-color, rgba(0, 0, 0, .125)); } + &.card-highlight { + border-color: rgba(0, 0, 0, .375); + } + &.wrapped-card { padding: 0; } - .card-header { + .card-leading { display: flex; - flex-direction: row; - justify-content: space-between; align-items: center; + justify-content: center; + } + + .card-header { + display: flex; + flex-direction: column; color: $site-color-body; .card-title { @@ -59,8 +68,16 @@ font-family: $site-font-family-ui; } + .card-subtitle { + font-size: 0.875rem; + font-weight: 400; + margin-top: -0.25rem; + color: $site-color-primary; + } + &.text-center { justify-content: center; + text-wrap: pretty; } } @@ -88,6 +105,27 @@ .material-symbols { user-select: none; } + + &.install-card { + padding: 1.25rem; + + .card-leading { + margin: 0.4rem 0; + + img { + max-height: 72px; + } + + span.material-symbols { + font-size: 3.5rem; + } + } + + .card-title { + color: $site-color-body-light; + font-weight: 400; + } + } } a.card { @@ -136,7 +174,7 @@ z-index: -1; background-size: 0; opacity: .999; - background-color: var(--bg-color, white); + background-color: $site-color-white; margin: -1rem -1rem 0; img { diff --git a/src/_sass/components/_content.scss b/src/_sass/components/_content.scss index 0449bf6560..e155f48127 100644 --- a/src/_sass/components/_content.scss +++ b/src/_sass/components/_content.scss @@ -44,11 +44,11 @@ scroll-margin-top: 5rem; line-height: 1.2; font-family: $site-font-family-ui; - font-weight: 500; + font-weight: 400; } h1 { - font-size: 3rem; + font-size: 2.75rem; margin-top: 0; margin-bottom: 0; scroll-margin-top: 6rem; diff --git a/src/content/assets/js/page/install-current.js b/src/content/assets/js/page/install-current.js index 0e45fee876..fa5d853ad8 100644 --- a/src/content/assets/js/page/install-current.js +++ b/src/content/assets/js/page/install-current.js @@ -11,9 +11,9 @@ document.addEventListener("DOMContentLoaded", function(_) { osButton.classList.add('card-highlight'); - const header = osButton.querySelector('.card-title'); + const header = osButton.querySelector('.card-header'); if (!header) return; - const currentSubtitle = document.createElement('div'); + const currentSubtitle = document.createElement('span'); currentSubtitle.textContent = 'Current device'; currentSubtitle.classList.add('card-subtitle'); header.appendChild(currentSubtitle); diff --git a/src/content/get-started/install/chromeos/index.md b/src/content/get-started/install/chromeos/index.md index ebe677ad03..345e434bbe 100644 --- a/src/content/get-started/install/chromeos/index.md +++ b/src/content/get-started/install/chromeos/index.md @@ -14,22 +14,20 @@ js: [{url: '/assets/js/temp/chromeos-install-redirector.js'}]
{% for target in target-list %} - -
-
- - {% assign icon = target | downcase -%} - {% if icon == 'android' -%} - phone_android - {% else -%} - web - {% endif -%} - - {{target}} - {% if icon == 'android' -%} -
Recommended
- {% endif -%} -
+
+ {% assign icon = target | downcase -%} +
+ {% if icon == 'android' -%} + + {% else -%} + + {% endif -%} +
+
+
{{target}}
+ {% if icon == 'android' -%} + Recommended + {% endif -%}
{% endfor %} diff --git a/src/content/get-started/install/index.md b/src/content/get-started/install/index.md index c2e896f97d..4b32f5efea 100644 --- a/src/content/get-started/install/index.md +++ b/src/content/get-started/install/index.md @@ -8,15 +8,12 @@ js: [{url: '/assets/js/page/install-current.js'}]
{% for os in os-list %} - -
-
- - {% assign icon = os | downcase -%} - - - {{os}} -
+
+
+ +
+
+
{{os}}
{% endfor %} diff --git a/src/content/get-started/install/linux/index.md b/src/content/get-started/install/linux/index.md index 04e7a1e7dd..23124afd59 100644 --- a/src/content/get-started/install/linux/index.md +++ b/src/content/get-started/install/linux/index.md @@ -14,24 +14,22 @@ js: [{url: '/assets/js/temp/linux-install-redirector.js'}]
{% for target in target-list %} - -
-
- - {% assign icon = target | downcase -%} - {% if icon == 'desktop' -%} - desktop_windows - {% elsif icon == 'android' -%} - phone_android - {% else -%} - web - {% endif -%} - - {{target}} - {% if icon == 'android' -%} -
Recommended
- {% endif -%} -
+
+ {% assign icon = target | downcase -%} +
+ {% if icon == 'desktop' -%} + + {% elsif icon == 'android' -%} + + {% else -%} + + {% endif -%} +
+
+
{{target}}
+ {% if icon == 'android' -%} + Recommended + {% endif -%}
{% endfor %} diff --git a/src/content/get-started/install/macos/index.md b/src/content/get-started/install/macos/index.md index b081d9db09..853540fcea 100644 --- a/src/content/get-started/install/macos/index.md +++ b/src/content/get-started/install/macos/index.md @@ -21,27 +21,25 @@ js: [{url: '/assets/js/temp/macos-install-redirector.js'}] {% assign targetlink = target | downcase %} {% endcase %} - -
-
- - {% assign icon = target | downcase -%} - {% case icon %} - {% when 'desktop' -%} - laptop_mac - {% when 'ios' -%} - phone_iphone - {% when 'android' -%} - phone_android - {% when 'web' -%} - web - {% endcase -%} - - {{ target }} - {% if icon == 'ios' -%} -
Recommended
- {% endif -%} -
+
+ {% assign icon = target | downcase -%} +
+ {% case icon %} + {% when 'desktop' -%} + + {% when 'ios' -%} + + {% when 'android' -%} + + {% when 'web' -%} + + {% endcase -%} +
+
+
{{target}}
+ {% if icon == 'ios' -%} + Recommended + {% endif -%}
diff --git a/src/content/get-started/install/windows/index.md b/src/content/get-started/install/windows/index.md index 208074a833..ac9d3bf788 100644 --- a/src/content/get-started/install/windows/index.md +++ b/src/content/get-started/install/windows/index.md @@ -20,25 +20,23 @@ js: [{url: '/assets/js/temp/windows-install-redirector.js'}] {% else %} {% assign targetlink = target | downcase %} {% endcase %} - -
-
- - {% assign icon = target | downcase -%} - {% case icon %} - {% when 'desktop' -%} - desktop_windows - {% when 'android' -%} - phone_android - {% when 'web' -%} - web - {% endcase -%} - - {{target}} - {% if icon == 'android' -%} -
Recommended
- {% endif -%} -
+
+ {% assign icon = target | downcase -%} +
+ {% case icon %} + {% when 'desktop' -%} + + {% when 'android' -%} + + {% when 'web' -%} + + {% endcase -%} +
+
+
{{target}}
+ {% if icon == 'android' -%} + Recommended + {% endif -%}
{% endfor %} diff --git a/src/content/platform-integration/android/install-android/index.md b/src/content/platform-integration/android/install-android/index.md index f221fabad7..d1b3fc57bd 100644 --- a/src/content/platform-integration/android/install-android/index.md +++ b/src/content/platform-integration/android/install-android/index.md @@ -23,25 +23,24 @@ or the platform you already have set up. {% assign bug = 'card-chromeos' %} {% endif %} - -
-
- - {% assign icon = target | downcase | replace: " ", "-" -%} - {% case icon %} - {% when 'macos' -%} - laptop_mac - {% when 'windows','linux' -%} - desktop_windows - {% when 'ios' -%} - phone_iphone - {% else -%} - web - {% endcase -%} - add - phone_android - - + + {% assign icon = target | downcase | replace: " ", "-" -%} +
+ {% case icon %} + {% when 'macos' -%} + + {% when 'windows','linux' -%} + + {% when 'ios' -%} + + {% else -%} + + {% endcase -%} + + +
+
+
Make Android and {% if target contains "iOS" -%} {{target}} apps on macOS @@ -50,7 +49,6 @@ or the platform you already have set up. {%- else -%} {{target}} desktop apps {%- endif -%} -
diff --git a/src/content/platform-integration/ios/install-ios/index.md b/src/content/platform-integration/ios/install-ios/index.md index 996f2d2bff..b836bbaf5d 100644 --- a/src/content/platform-integration/ios/install-ios/index.md +++ b/src/content/platform-integration/ios/install-ios/index.md @@ -12,26 +12,22 @@ or the platform you already have set up.
{% for target in target-list %} {% assign targetLink = '/platform-integration/ios/install-ios/install-ios-from-' | append: target | downcase %} - -
-
- - {% assign icon = target | downcase -%} - {% case icon %} - {% when 'macos' -%} - laptop_mac - {% when 'android' -%} - phone_android - {% when 'web' -%} - web - {% endcase -%} - add - phone_iphone - - - Make iOS and {{ target }}{% if target == 'macOS' %} desktop{% endif %} apps - -
+
+ {% assign icon = target | downcase -%} +
+ {% case icon %} + {% when 'macos' -%} + + {% when 'android' -%} + + {% when 'web' -%} + + {% endcase -%} + + +
+
+
Make iOS and {{ target }}{% if target == 'macOS' %} desktop{% endif %} apps
{% endfor %} diff --git a/src/content/platform-integration/linux/install-linux/index.md b/src/content/platform-integration/linux/install-linux/index.md index a63e865349..69225b33e2 100644 --- a/src/content/platform-integration/linux/install-linux/index.md +++ b/src/content/platform-integration/linux/install-linux/index.md @@ -12,22 +12,18 @@ or the platform you already have set up.
{% for target in target-list %} {% assign targetLink = '/platform-integration/linux/install-linux/install-linux-from-' | append: target | downcase %} - -
-
- - {% assign icon = target | downcase -%} - {% case icon %} - {% when 'android' -%} - phone_android - {% when 'web' -%} - web - {% endcase -%} - - - Make {{ target }} and Linux desktop apps - -
+
+ {% assign icon = target | downcase -%} +
+ {% case icon %} + {% when 'android' -%} + + {% when 'web' -%} + + {% endcase -%} +
+
+
Make {{ target }} and Linux desktop apps
{% endfor %} diff --git a/src/content/platform-integration/macos/install-macos/index.md b/src/content/platform-integration/macos/install-macos/index.md index b31611fbe7..198e78b639 100644 --- a/src/content/platform-integration/macos/install-macos/index.md +++ b/src/content/platform-integration/macos/install-macos/index.md @@ -12,26 +12,22 @@ or the platform you already have set up.
{% for target in target-list %} {% assign targetLink = '/platform-integration/macos/install-macos/install-macos-from-' | append: target | downcase %} - -
-
- - {% assign icon = target | downcase -%} - {% case icon %} - {% when 'ios' -%} - phone_iphone - {% when 'android' -%} - phone_android - {% when 'web' -%} - web - {% endcase -%} - add - laptop_mac - - - Make {{ target }} and macOS desktop apps - -
+
+ {% assign icon = target | downcase -%} +
+ {% case icon %} + {% when 'ios' -%} + + {% when 'android' -%} + + {% when 'web' -%} + + {% endcase -%} + + +
+
+
Make {{ target }} and macOS desktop apps
{% endfor %} diff --git a/src/content/platform-integration/windows/install-windows/index.md b/src/content/platform-integration/windows/install-windows/index.md index 0e4c2c9e64..60f04da410 100644 --- a/src/content/platform-integration/windows/install-windows/index.md +++ b/src/content/platform-integration/windows/install-windows/index.md @@ -12,24 +12,20 @@ or the platform you already have set up.
{% for target in target-list %} {% assign targetLink = '/platform-integration/windows/install-windows/install-windows-from-' | append: target | downcase %} - -
-
- - {% assign icon = target | downcase -%} - {% case icon %} - {% when 'android' -%} - phone_android - {% when 'web' -%} - web - {% endcase -%} - add - desktop_windows - - - Make Windows desktop and {{ target }} apps - -
+
+ {% assign icon = target | downcase -%} +
+ {% case icon %} + {% when 'android' -%} + + {% when 'web' -%} + + {% endcase -%} + + +
+
+
Make Windows desktop and {{ target }} apps
{% endfor %} diff --git a/src/content/ui/animations/tutorial.md b/src/content/ui/animations/tutorial.md index 2e212deb08..3518a8dae3 100644 --- a/src/content/ui/animations/tutorial.md +++ b/src/content/ui/animations/tutorial.md @@ -391,8 +391,7 @@ dirty as necessary, so you don't need to call `addListener()`. The widget tree for the [animate4][] example looks like this: -AnimatedBuilder widget tree +{% render docs/app-figure.md, image:"ui/AnimatedBuilder-WidgetTree.png", alt:"AnimatedBuilder widget tree" %} Starting from the bottom of the widget tree, the code for rendering the logo is straightforward: From d22a5aab6010471769d36fb40395c70bbcce0ad0 Mon Sep 17 00:00:00 2001 From: Parker Lougheed Date: Wed, 29 Jan 2025 21:22:23 -0600 Subject: [PATCH 03/12] Fix download buttons and kbd elements --- .../docs/install/deprecated/get-sdk-linux.md | 2 +- src/_includes/docs/install/deprecated/get-sdk-mac.md | 2 +- src/_includes/docs/install/deprecated/get-sdk-win.md | 2 +- src/_includes/docs/install/flutter/download.md | 10 +++++----- src/_sass/base/_base.scss | 12 ++++++++---- src/_sass/components/_code.scss | 10 ++++++++-- src/_sass/components/_misc.scss | 3 ++- 7 files changed, 26 insertions(+), 15 deletions(-) diff --git a/src/_includes/docs/install/deprecated/get-sdk-linux.md b/src/_includes/docs/install/deprecated/get-sdk-linux.md index f4961371d5..9d1babc72d 100644 --- a/src/_includes/docs/install/deprecated/get-sdk-linux.md +++ b/src/_includes/docs/install/deprecated/get-sdk-linux.md @@ -35,7 +35,7 @@ If you aren't using `snapd`, follow these steps to install Flutter. 1. Download the installation bundle for the latest {{site.sdk.channel}} release of the Flutter SDK: - [(loading...)](#){:.download-latest-link-{{os}} .btn .btn-primary} + [(loading...)](#){:.download-latest-link-{{os}} .filled-button} You can find older builds and other release channels in the [SDK archive][]. diff --git a/src/_includes/docs/install/deprecated/get-sdk-mac.md b/src/_includes/docs/install/deprecated/get-sdk-mac.md index c0b4c2f2b1..c6488c017b 100644 --- a/src/_includes/docs/install/deprecated/get-sdk-mac.md +++ b/src/_includes/docs/install/deprecated/get-sdk-mac.md @@ -7,7 +7,7 @@ |Intel | | Apple Silicon | |------| | ---------------| - |[(loading...)](#){:.download-latest-link-{{os}} .btn .btn-primary} | | [(loading...)](#){:.download-latest-link-{{os}}-arm64 .apple-silicon .btn .btn-primary} | + |[(loading...)](#){:.download-latest-link-{{os}} .filled-button} | | [(loading...)](#){:.download-latest-link-{{os}}-arm64 .apple-silicon .filled-button} |
For other release channels, and older builds, diff --git a/src/_includes/docs/install/deprecated/get-sdk-win.md b/src/_includes/docs/install/deprecated/get-sdk-win.md index 1aa91d5f1d..caba1678f7 100644 --- a/src/_includes/docs/install/deprecated/get-sdk-win.md +++ b/src/_includes/docs/install/deprecated/get-sdk-win.md @@ -7,7 +7,7 @@ 1. Download the following installation bundle to get the latest {{site.sdk.channel}} release of the Flutter SDK: - [(loading...)](#){:.download-latest-link-{{os}} .btn .btn-primary} + [(loading...)](#){:.download-latest-link-{{os}} .filled-button} For other release channels, and older builds, check out the [SDK archive][]. diff --git a/src/_includes/docs/install/flutter/download.md b/src/_includes/docs/install/flutter/download.md index ec1dc36787..d1cb126817 100644 --- a/src/_includes/docs/install/flutter/download.md +++ b/src/_includes/docs/install/flutter/download.md @@ -15,7 +15,7 @@ {% assign dirdl='%USERPROFILE%\\Downloads' %} {% assign ps-dir-dl='$env:USERPROFILE\\Downloads\\' %} {% assign ps-dir-target='$env:USERPROFILE\\dev\\' %} - {% capture uz %} + {% capture uz -%} {{prompt}} Expand-Archive ` –Path {{ps-dir-dl}}flutter_sdk_v1.0.0.zip ` -Destination {{ps-dir-target}} @@ -57,13 +57,13 @@ then extract the SDK. {% if include.os=='macOS' %} - | Intel Processor | Apple Silicon | - |---------------------------------------------------------------------|-------------------------------------------------------------------------------------------| - | [(loading...)](#){:.download-latest-link-{{osl}} .btn .btn-primary} | [(loading...)](#){:.download-latest-link-{{osl}}-arm64 .apple-silicon .btn .btn-primary} | + | Intel Processor | Apple Silicon | + |------------------------------------------------------------------|---------------------------------------------------------------------------------------| + | [(loading...)](#){:.download-latest-link-{{osl}} .filled-button} | [(loading...)](#){:.download-latest-link-{{osl}}-arm64 .apple-silicon .filled-button} | {% else %} - [(loading...)](#){:.download-latest-link-{{osl}} .btn .btn-primary} + [(loading...)](#){:.download-latest-link-{{osl}} .filled-button} {% endif -%} diff --git a/src/_sass/base/_base.scss b/src/_sass/base/_base.scss index 1377d59b01..c9c3b652ff 100644 --- a/src/_sass/base/_base.scss +++ b/src/_sass/base/_base.scss @@ -142,6 +142,12 @@ main figure { max-height: 60vh; } +table { + td, th { + padding: .25rem; + } +} + .table { width: 100%; border-spacing: 0; @@ -209,9 +215,11 @@ details { > summary { font-weight: 500; user-select: none; + border-radius: 0.125rem; &:hover { color: $site-color-primary; + cursor: pointer; } } @@ -229,10 +237,6 @@ details { } } -summary { - margin-bottom: 1rem; -} - main { ol + img, ul + img, ol + p, ul + p, p + p + img, li:not(.toc-entry, .breadcrumb-item, .nav-item):last-child, ul + p:last-child { diff --git a/src/_sass/components/_code.scss b/src/_sass/components/_code.scss index c858245a05..a6fe55986e 100644 --- a/src/_sass/components/_code.scss +++ b/src/_sass/components/_code.scss @@ -8,18 +8,24 @@ pre, code, kbd, samp { // Inline code spans found within the primary contents of the page. // Targets all elements, but
 shouldn't have many of these.
-main code {
+main code, main kbd {
   font-size: 0.9em;
   line-height: 1.25em;
   padding: 0.1rem 0.25rem;
   background-color: $site-color-light-grey;
   background-color: color-mix(in srgb, $site-color-light-grey 35%, transparent);
   border: 1px solid rgb(195, 201, 214);
-  border-radius: 0.25rem;
+  border-radius: 0.2rem;
   word-wrap: break-word;
   white-space: nowrap;
 }
 
+main kbd {
+  background-color: $site-color-body;
+  border: none;
+  color: $site-color-light-grey;
+}
+
 pre {
   margin-bottom: 1rem;
   padding: 1.25rem;
diff --git a/src/_sass/components/_misc.scss b/src/_sass/components/_misc.scss
index 90a47902ae..cb60e2dff2 100644
--- a/src/_sass/components/_misc.scss
+++ b/src/_sass/components/_misc.scss
@@ -2,7 +2,7 @@
 
 .install-help {
   text-align: right;
-  margin-top: -2.5rem;
+  margin-block-start: -2.5rem;
 
   a {
     display: inline-flex;
@@ -16,6 +16,7 @@
   .material-symbols {
     font-size: 20px;
     margin-right: 0.125rem;
+    user-select: none;
   }
 }
 

From 6c1f650f0fc8aa0d254fcbb94f85decb90c6ae9c Mon Sep 17 00:00:00 2001
From: Parker Lougheed 
Date: Wed, 29 Jan 2025 21:43:13 -0600
Subject: [PATCH 04/12] Remove more bootstrap util class usages

---
 src/_includes/docs/app-figure.md             |  4 ++--
 src/_sass/base/_base.scss                    |  5 ++++-
 src/_sass/base/_utils.scss                   |  8 ++++++++
 src/_sass/components/_code.scss              |  2 +-
 src/_sass/components/_content.scss           | 17 +----------------
 src/content/ui/animations/hero-animations.md | 12 ++----------
 src/content/ui/interactivity/index.md        | 12 ++++++------
 7 files changed, 24 insertions(+), 36 deletions(-)

diff --git a/src/_includes/docs/app-figure.md b/src/_includes/docs/app-figure.md
index f774ec9019..1e3b3ed0ee 100644
--- a/src/_includes/docs/app-figure.md
+++ b/src/_includes/docs/app-figure.md
@@ -13,8 +13,8 @@
 
 
- {{alt}} - {% if caption -%} + {{alt | escape}} + {% if caption and caption != '' -%}
{{caption}}
{% endif -%}
diff --git a/src/_sass/base/_base.scss b/src/_sass/base/_base.scss index c9c3b652ff..a4951d39f3 100644 --- a/src/_sass/base/_base.scss +++ b/src/_sass/base/_base.scss @@ -120,7 +120,10 @@ main figure { flex: 0 1 auto; max-width: 100%; - img { width: 100%; } + img { + display: block; + width: 100%; + } figcaption { margin-top: 1rem; diff --git a/src/_sass/base/_utils.scss b/src/_sass/base/_utils.scss index a684c0902a..e121eb1c20 100644 --- a/src/_sass/base/_utils.scss +++ b/src/_sass/base/_utils.scss @@ -1,9 +1,13 @@ +@use 'variables' as *; + .side-by-side { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 24rem), 1fr)); column-gap: 2rem; row-gap: 0; justify-content: center; + margin-block-start: 0.75rem; + margin-block-end: 0.75rem; } .centered-rows { @@ -18,3 +22,7 @@ .text-center { text-align: center; } + +.simple-border { + border: 1px solid $site-color-light-grey; +} diff --git a/src/_sass/components/_code.scss b/src/_sass/components/_code.scss index a6fe55986e..4ccbc0be45 100644 --- a/src/_sass/components/_code.scss +++ b/src/_sass/components/_code.scss @@ -11,7 +11,7 @@ pre, code, kbd, samp { main code, main kbd { font-size: 0.9em; line-height: 1.25em; - padding: 0.1rem 0.25rem; + padding: 0.05rem 0.2rem; background-color: $site-color-light-grey; background-color: color-mix(in srgb, $site-color-light-grey 35%, transparent); border: 1px solid rgb(195, 201, 214); diff --git a/src/_sass/components/_content.scss b/src/_sass/components/_content.scss index e155f48127..769b80b7e0 100644 --- a/src/_sass/components/_content.scss +++ b/src/_sass/components/_content.scss @@ -164,26 +164,11 @@ nav.breadcrumbs { .child-icon { user-select: none; + color: $site-color-body-light; } } } -.video-card { - flex: 0 0 calc((100% / 2) - 1rem); - position: relative; - display: flex; - flex-direction: column; - min-width: 0; - word-wrap: break-word; - background-color: #fff; - background-clip: border-box; - border: 1px solid rgba(0, 0, 0, 0.125); - border-radius: 4px; - margin-bottom: 1rem; - margin-left: 0.5rem; - margin-right: 0.5rem; -} - .full-width { width: 100%; } diff --git a/src/content/ui/animations/hero-animations.md b/src/content/ui/animations/hero-animations.md index 3b146b5d7f..d181ad8a5c 100644 --- a/src/content/ui/animations/hero-animations.md +++ b/src/content/ui/animations/hero-animations.md @@ -286,11 +286,7 @@ The custom PhotoHero class maintains the hero, and its size, image, and behavior when tapped. The PhotoHero builds the following widget tree: -
- - ![PhotoHero class widget tree](/assets/images/docs/ui/animations/photohero-class.png) - -
+{% render docs/app-figure.md, image:"ui/animations/photohero-class.png", alt:"PhotoHero class widget tree %} Here's the code: @@ -552,11 +548,7 @@ with a rectangular clip (that remains a constant size throughout). To do this, it builds the following widget tree: -
- - ![RadialExpansion widget tree](/assets/images/docs/ui/animations/radial-expansion-class.png) - -
+{% render docs/app-figure.md, image:"ui/animations/radial-expansion-class.png", alt:"RadialExpansion widget tree" %} Here's the code: diff --git a/src/content/ui/interactivity/index.md b/src/content/ui/interactivity/index.md index f02aec2191..f7ccb0d72e 100644 --- a/src/content/ui/interactivity/index.md +++ b/src/content/ui/interactivity/index.md @@ -33,7 +33,7 @@ replacing the solid star with an outline and decreasing the count. Tapping again favorites the lake, drawing a solid star and increasing the count. -The custom widget you'll create +{% render docs/app-figure.md, image:"ui/favorited-not-favorited.png", alt:"The custom widget you'll create" %} To accomplish this, you'll create a single custom widget that includes both the star and the count, @@ -349,17 +349,17 @@ creates a container that, when tapped, toggles between a green or grey box. The `_active` boolean determines the color: green for active or grey for inactive. -
-
- Active state - Inactive state +
+
+ Active state + Inactive state
These examples use [`GestureDetector`][] to capture activity on the `Container`. - + ### The widget manages its own state From 8cef852babc520079e11ba5e76da70e50fa3ee50 Mon Sep 17 00:00:00 2001 From: Parker Lougheed Date: Wed, 29 Jan 2025 21:48:34 -0600 Subject: [PATCH 05/12] Remove unnecessary usages of mw-100 utility class --- .../docs/install/deprecated/ios-setup.md | 6 +- .../docs/install/devices/ios-physical.md | 6 +- .../docs/install/test-drive/androidstudio.md | 2 +- .../android/add-flutter-fragment.md | 9 +-- .../add-to-app/android/add-flutter-screen.md | 6 +- .../add-to-app/android/add-flutter-view.md | 3 +- .../data-and-backend/serialization/json.md | 3 +- .../android/splash-screen.md | 3 +- .../flutter-driver-migration.md | 2 +- .../testing/integration-tests/index.md | 8 +-- src/content/tools/vs-code.md | 6 +- src/content/ui/animations/index.md | 3 +- src/content/ui/design/text/typography.md | 6 +- src/content/ui/layout/constraints.md | 65 +++++++++---------- src/content/ui/layout/index.md | 65 ++++++++----------- 15 files changed, 85 insertions(+), 108 deletions(-) diff --git a/src/_includes/docs/install/deprecated/ios-setup.md b/src/_includes/docs/install/deprecated/ios-setup.md index 5d6577d145..23d9bddb52 100644 --- a/src/_includes/docs/install/deprecated/ios-setup.md +++ b/src/_includes/docs/install/deprecated/ios-setup.md @@ -137,7 +137,7 @@ Configure your physical iOS device to connect to Xcode. 1. Click **Trust**. - ![Trust Mac][]{:.mw-100} + ![Trust Mac][] 1. When prompted, unlock your iOS device. @@ -218,7 +218,7 @@ Follow the Xcode signing flow to provision your project. The **Team** dropdown displays that option as **Your Name (Personal Team)**. - ![Xcode account add][]{:.mw-100} + ![Xcode account add][] After you select a team, Xcode performs the following tasks: @@ -232,7 +232,7 @@ If automatic signing fails in Xcode, verify that the project's **Identity** > **Bundle Identifier** value is unique. -![Check the app's Bundle ID][]{:.mw-100} +![Check the app's Bundle ID][] #### Enable trust of your Mac and iOS device {:#trust} diff --git a/src/_includes/docs/install/devices/ios-physical.md b/src/_includes/docs/install/devices/ios-physical.md index c06b7ea1b7..8ab9bdb519 100644 --- a/src/_includes/docs/install/devices/ios-physical.md +++ b/src/_includes/docs/install/devices/ios-physical.md @@ -38,7 +38,7 @@ Configure your physical iOS device to connect to Xcode. 1. Click **Trust**. - ![Trust Mac][]{:.mw-100} + ![Trust Mac][] 1. When prompted, unlock your iOS device. @@ -119,7 +119,7 @@ To provision your project, follow the Xcode signing flow. The **Team** dropdown displays that option as **Your Name (Personal Team)**. - ![Xcode account add][]{:.mw-100} + ![Xcode account add][] After you select a team, Xcode performs the following tasks: @@ -132,7 +132,7 @@ If automatic signing fails in Xcode, verify that the project's **Identity** > **Bundle Identifier** value is unique. -![Check the app's Bundle ID][]{:.mw-100} +![Check the app's Bundle ID][] ##### Enable trust of your Mac and iOS device {:#trust} diff --git a/src/_includes/docs/install/test-drive/androidstudio.md b/src/_includes/docs/install/test-drive/androidstudio.md index 3f5931e5e3..26cd921ef3 100644 --- a/src/_includes/docs/install/test-drive/androidstudio.md +++ b/src/_includes/docs/install/test-drive/androidstudio.md @@ -49,7 +49,7 @@ uses [Material Components][]. 1. Locate the main Android Studio toolbar at the top of the Android Studio edit window. - ![Main IntelliJ toolbar][]{:.mw-100} + ![Main IntelliJ toolbar][] 1. In the **target selector**, select an Android device for running the app. You created your Android target device in the **Install** section. diff --git a/src/content/add-to-app/android/add-flutter-fragment.md b/src/content/add-to-app/android/add-flutter-fragment.md index 021bd4912e..e9e292c4d0 100644 --- a/src/content/add-to-app/android/add-flutter-fragment.md +++ b/src/content/add-to-app/android/add-flutter-fragment.md @@ -4,8 +4,7 @@ short-title: Add a Flutter Fragment description: Learn how to add a Flutter Fragment to your existing Android app. --- -Add Flutter Fragment Header +Add Flutter Fragment Header This guide describes how to add a Flutter `Fragment` to an existing Android app. In Android, a [`Fragment`][] represents a modular @@ -577,8 +576,7 @@ In these apps, it would be reasonable for a `Fragment` to control system chrome like Android's status bar, navigation bar, and orientation. -Fullscreen Flutter +Fullscreen Flutter In other apps, `Fragment`s are used to represent only a portion of a UI. A `FlutterFragment` might be used to @@ -588,8 +586,7 @@ inappropriate for the `FlutterFragment` to affect Android's system chrome because there are other UI pieces within the same `Window`. -Flutter as Partial UI +Flutter as Partial UI `FlutterFragment` comes with a concept that helps differentiate between the case when a `FlutterFragment` diff --git a/src/content/add-to-app/android/add-flutter-screen.md b/src/content/add-to-app/android/add-flutter-screen.md index 90fd957267..0c93f85263 100644 --- a/src/content/add-to-app/android/add-flutter-screen.md +++ b/src/content/add-to-app/android/add-flutter-screen.md @@ -12,8 +12,7 @@ Both options are described in this guide. ## Add a normal Flutter screen -Add Flutter Screen Header +Add Flutter Screen Header ### Step 1: Add FlutterActivity to AndroidManifest.xml @@ -346,8 +345,7 @@ of Flutter, use a release build. ## Add a translucent Flutter screen -Add Flutter Screen With Translucency Header +Add Flutter Screen With Translucency Header Most full-screen Flutter experiences are opaque. However, some apps would like to deploy a Flutter diff --git a/src/content/add-to-app/android/add-flutter-view.md b/src/content/add-to-app/android/add-flutter-view.md index 0750b69c62..1278992436 100644 --- a/src/content/add-to-app/android/add-flutter-view.md +++ b/src/content/add-to-app/android/add-flutter-view.md @@ -26,8 +26,7 @@ will be specific to your application. ## A sample -Add Flutter View sample video +Add Flutter View sample video Unlike the guides for FlutterActivity and FlutterFragment, the FlutterView integration could be better demonstrated with a sample project. diff --git a/src/content/data-and-backend/serialization/json.md b/src/content/data-and-backend/serialization/json.md index c10f15b5bc..5b0afca77c 100644 --- a/src/content/data-and-backend/serialization/json.md +++ b/src/content/data-and-backend/serialization/json.md @@ -354,8 +354,7 @@ final String verificationCode; When creating `json_serializable` classes the first time, you'll get errors similar to what is shown in the image below. -![IDE warning when the generated code for a model class does not exist -yet.](/assets/images/docs/json/ide_warning.png){:.mw-100} +![IDE warning when the generated code for a model class does not exist yet.](/assets/images/docs/json/ide_warning.png) These errors are entirely normal and are simply because the generated code for the model class does not exist yet. To resolve this, run the code diff --git a/src/content/platform-integration/android/splash-screen.md b/src/content/platform-integration/android/splash-screen.md index fddcf70ad5..b482df900d 100644 --- a/src/content/platform-integration/android/splash-screen.md +++ b/src/content/platform-integration/android/splash-screen.md @@ -4,8 +4,7 @@ short-title: Splash screen description: Learn how to add a splash screen to your Android app. --- -A graphic outlining the launch flow of an app including a splash screen +A graphic outlining the launch flow of an app including a splash screen Splash screens (also known as launch screens) provide a simple initial experience while your Android app loads. diff --git a/src/content/release/breaking-changes/flutter-driver-migration.md b/src/content/release/breaking-changes/flutter-driver-migration.md index de37e6720f..ff35595422 100644 --- a/src/content/release/breaking-changes/flutter-driver-migration.md +++ b/src/content/release/breaking-changes/flutter-driver-migration.md @@ -30,7 +30,7 @@ functionality: * The list of plants is loaded from a local JSON file located in the `/assets` folder. -Starter project screenshot +Starter project screenshot You can find the full code example in the [Example Project][] folder. diff --git a/src/content/testing/integration-tests/index.md b/src/content/testing/integration-tests/index.md index 4e9f4ed230..7dd2600abc 100644 --- a/src/content/testing/integration-tests/index.md +++ b/src/content/testing/integration-tests/index.md @@ -502,7 +502,7 @@ section of the README. 1. Navigate to **Quality > Test Lab**. - Firebase Test Lab Console + Firebase Test Lab Console #### Upload an Android APK @@ -536,7 +536,7 @@ To start a Robo test and run other tests, drag the "debug" APK from `/build/app/outputs/apk/debug` into the **Android Robo Test** target on the web page. -Firebase Test Lab upload +Firebase Test Lab upload 1. Click **Run a test**. @@ -550,11 +550,11 @@ into the **Android Robo Test** target on the web page. `/build/app/outputs/apk/androidTest/debug/.apk` -Firebase Test Lab upload two APKs +Firebase Test Lab upload two APKs If a failure occurs, click the red icon to view the output: -Firebase Test Lab test results +Firebase Test Lab test results #### Upload an Android APK from the command line diff --git a/src/content/tools/vs-code.md b/src/content/tools/vs-code.md index a45519c37c..03e2d11f4a 100644 --- a/src/content/tools/vs-code.md +++ b/src/content/tools/vs-code.md @@ -89,7 +89,7 @@ The code analysis can: - You can also press Ctrl / Cmd + Shift + M. - The Problems pane displays any analysis issues:
- ![Problems pane](/assets/images/docs/tools/vs-code/problems.png){:.mw-100 .pt-1} + ![Problems pane](/assets/images/docs/tools/vs-code/problems.png) ## Running and debugging @@ -115,7 +115,7 @@ When a Flutter project is open in VS Code, you should see a set of Flutter specific entries in the status bar, including a Flutter SDK version and a device name (or the message **No Devices**):
-![VS Code status bar][]{:.mw-100 .pt-1} +![VS Code status bar][] :::note - If you do not see a Flutter version number or device info, @@ -155,7 +155,7 @@ You can also press Ctrl + F5. 1. Click **Run** > **Start Debugging**. You can also press F5. The status bar turns orange to show you are in a debug session.
- ![Debug console](/assets/images/docs/tools/vs-code/debug_console.png){:.mw-100 .pt-1} + ![Debug console](/assets/images/docs/tools/vs-code/debug_console.png) - The left **Debug Sidebar** shows stack frames and variables. - The bottom **Debug Console** pane shows detailed logging output. diff --git a/src/content/ui/animations/index.md b/src/content/ui/animations/index.md index 36708c14ac..4cbe1f0ab9 100644 --- a/src/content/ui/animations/index.md +++ b/src/content/ui/animations/index.md @@ -32,8 +32,7 @@ As shown in the video, the following decision tree helps you decide what approach to use when implementing a Flutter animation: -The animation decision tree +The animation decision tree ## Animation deep dive diff --git a/src/content/ui/design/text/typography.md b/src/content/ui/design/text/typography.md index 272ab06c76..a0c11079b2 100644 --- a/src/content/ui/design/text/typography.md +++ b/src/content/ui/design/text/typography.md @@ -45,8 +45,7 @@ There are also three size variations for each: Each of these fifteen combinations of a category and text size are represented by a single [`TextStyle`][]. -Listing of typographical scale for Material TextTheme +Listing of typographical scale for Material TextTheme All the platform specific typographical scales that Flutter exposes are contained in the [`Typography`][] class. Usually, you will not need to @@ -73,8 +72,7 @@ A growing number of fonts on Google Fonts offer some variable font capabilities. You can see the range of options by using the Type Tester and see how you might vary a single font. -Demonstration of varying aspects for Noto Sans with Lorem ipsum text +Demonstration of varying aspects for Noto Sans with Lorem ipsum text In real time, move the slider on any of the axes to see how it affects the font. When programming a variable font, diff --git a/src/content/ui/layout/constraints.md b/src/content/ui/layout/constraints.md index c8c00fc51d..c92b7ab0f9 100644 --- a/src/content/ui/layout/constraints.md +++ b/src/content/ui/layout/constraints.md @@ -9,8 +9,7 @@ js: -Hero image from the article +Hero image from the article :::note If you are experiencing specific layout errors, @@ -61,7 +60,7 @@ For example, if a composed widget contains a column with some padding, and wants to lay out its two children as follows: -Visual layout +Visual layout The negotiation goes something like this: @@ -1300,7 +1299,7 @@ The examples are explained in the following sections. ### Example 1 -Example 1 layout +Example 1 layout ```dart @@ -1314,7 +1313,7 @@ So the `Container` fills the screen and paints it red. ### Example 2 -Example 2 layout +Example 2 layout ```dart @@ -1329,7 +1328,7 @@ So the `Container` fills the screen. ### Example 3 -Example 3 layout +Example 3 layout ```dart @@ -1347,7 +1346,7 @@ can indeed be 100 × 100. ### Example 4 -Example 4 layout +Example 4 layout ```dart @@ -1367,7 +1366,7 @@ available space. ### Example 5 -Example 5 layout +Example 5 layout ```dart @@ -1387,7 +1386,7 @@ it just fills the screen. ### Example 6 -Example 6 layout +Example 6 layout ```dart @@ -1414,7 +1413,7 @@ how it behaves, depending on the circumstances. ### Example 7 -Example 7 layout +Example 7 layout ```dart @@ -1445,7 +1444,7 @@ entirely covers the red `Container`. ### Example 8 -Example 8 layout +Example 8 layout ```dart @@ -1467,7 +1466,7 @@ in the previous example. ### Example 9 -Example 9 layout +Example 9 layout ```dart @@ -1494,7 +1493,7 @@ to also assume the size of the screen, thus ignoring its ### Example 10 -Example 10 layout +Example 10 layout ```dart @@ -1521,7 +1520,7 @@ so it ends up having 70 (the minimum). ### Example 11 -Example 11 layout +Example 11 layout ```dart @@ -1548,7 +1547,7 @@ so it ends up having 150 (the maximum). ### Example 12 -Example 12 layout +Example 12 layout ```dart @@ -1575,7 +1574,7 @@ since that's between 70 and 150. ### Example 13 -Example 13 layout +Example 13 layout ```dart @@ -1590,7 +1589,7 @@ lets its child `Container` be any size it wants. ### Example 14 -Example 14 layout +Example 14 layout ```dart @@ -1610,7 +1609,7 @@ the much dreaded "overflow warning". ### Example 15 -Example 15 layout +Example 15 layout ```dart @@ -1638,7 +1637,7 @@ with no warnings given. ### Example 16 -Example 16 layout +Example 16 layout ```dart @@ -1657,7 +1656,7 @@ the following message: `BoxConstraints forces an infinite width.` ### Example 17 -Example 17 layout +Example 17 layout ```dart @@ -1689,7 +1688,7 @@ and a `ConstrainedBox`. ### Example 18 -Example 18 layout +Example 18 layout ```dart @@ -1710,7 +1709,7 @@ the available width. ### Example 19 -Example 19 layout +Example 19 layout ```dart @@ -1732,7 +1731,7 @@ no scaling happens. ### Example 20 -Example 20 layout +Example 20 layout ```dart @@ -1754,7 +1753,7 @@ and resizes `Text` so that it fits the screen, too. ### Example 21 -Example 21 layout +Example 21 layout ```dart @@ -1770,7 +1769,7 @@ and breaks the line so that it fits the screen. ### Example 22 -Example 22 layout +Example 22 layout ```dart @@ -1790,7 +1789,7 @@ and you'll see an error in the console. ### Example 23 -Example 23 layout +Example 23 layout ```dart @@ -1813,7 +1812,7 @@ and any extra space remains empty. ### Example 24 -Example 24 layout +Example 24 layout ```dart @@ -1839,7 +1838,7 @@ the available width of the `Row`. In this case, just like an ### Example 25 -Example 25 layout +Example 25 layout ```dart @@ -1873,7 +1872,7 @@ the original child's width becomes irrelevant, and is ignored. ### Example 26 -Example 26 layout +Example 26 layout ```dart @@ -1911,7 +1910,7 @@ its children. ### Example 27 -Example 27 layout +Example 27 layout ```dart @@ -1955,7 +1954,7 @@ when you use `Expanded` or `Flexible`. ### Example 28 -Example 28 layout +Example 28 layout ```dart @@ -1985,7 +1984,7 @@ to its child. More on that later. ### Example 29 -Example 29 layout +Example 29 layout ```dart @@ -2177,7 +2176,7 @@ Here's an example: `performLayout()`. This is the method that does the layout for the `Column`. -A goodbye layout +A goodbye layout --- diff --git a/src/content/ui/layout/index.md b/src/content/ui/layout/index.md index aac8d72af6..5f6b247f88 100644 --- a/src/content/ui/layout/index.md +++ b/src/content/ui/layout/index.md @@ -31,8 +31,8 @@ under each one:
- Sample layout - Sample layout with visual debugging + Sample layout + Sample layout with visual debugging
@@ -49,7 +49,7 @@ For more information, see Here's a diagram of the widget tree for this UI: -Node tree +Node tree Most of this should look as you might expect, but you might be wondering about the containers (shown in pink). [`Container`][] is a widget class @@ -333,13 +333,11 @@ columns inside of rows or columns. This layout is organized as a `Row`. The row contains two children: a column on the left, and an image on the right: -Screenshot with callouts showing the row containing two children +Screenshot with callouts showing the row containing two children The left column's widget tree nests rows and columns. -Diagram showing a left column broken down to its sub-rows and sub-columns +Diagram showing a left column broken down to its sub-rows and sub-columns You'll implement some of Pavlova's layout code in [Nesting rows and columns](#nesting-rows-and-columns). @@ -366,9 +364,9 @@ vertically. For a column, the main axis runs vertically and the cross axis runs horizontally.
- Diagram showing the main axis and cross axis for a row - Diagram showing the main axis and cross axis for a column
@@ -408,7 +406,7 @@ space evenly between, before, and after each image.
- Row with 3 evenly spaced images + Row with 3 evenly spaced images **App source:** [row_column]({{examples}}/layout/row_column)
@@ -450,7 +448,7 @@ When a layout is too large to fit a device, a yellow and black striped pattern appears along the affected edge. Here is an [example][sizing] of a row that is too wide: -Overly-wide row +Overly-wide row Widgets can be sized to fit within a row or column by using the [`Expanded`][] widget. To fix the previous example where the @@ -480,8 +478,7 @@ wrap each image with an `Expanded` widget.
- Row of 3 images that are too wide, but each is constrained to take only 1/3 of the space + Row of 3 images that are too wide, but each is constrained to take only 1/3 of the space **App source:** [sizing]({{examples}}/layout/sizing)
@@ -517,8 +514,7 @@ the flex factor of the middle image to 2:
- Row of 3 images with the middle image twice as wide as the others + Row of 3 images with the middle image twice as wide as the others **App source:** [sizing]({{examples}}/layout/sizing)
@@ -552,8 +548,7 @@ uses this property to pack the star icons together.
- Row of 5 stars, packed together in the middle of the row + Row of 5 stars, packed together in the middle of the row **App source:** [pavlova]({{examples}}/layout/pavlova)
@@ -566,8 +561,7 @@ inside of rows and columns as deeply as you need. Let's look at the code for the outlined section of the following layout: -Screenshot of the pavlova app, with the ratings and icon rows outlined in red +Screenshot of the pavlova app, with the ratings and icon rows outlined in red The outlined section is implemented as two rows. The ratings row contains five stars and the number of reviews. The icons row contains three @@ -575,7 +569,7 @@ columns of icons and text. The widget tree for the ratings row: -Ratings row widget tree +Ratings row widget tree The `ratings` variable creates a row containing a smaller row of 5-star icons, and text: @@ -624,7 +618,7 @@ The icons row, below the ratings row, contains 3 columns; each column contains an icon and two lines of text, as you can see in its widget tree: -Icon widget tree +Icon widget tree The `iconList` variable defines the icons row: @@ -794,9 +788,7 @@ color or image.
- Diagram showing: margin, border, padding, and content + Diagram showing: margin, border, padding, and content
@@ -828,8 +820,7 @@ of the column to a lighter grey.
- Screenshot showing 2 rows, each containing 2 images + Screenshot showing 2 rows, each containing 2 images
@@ -897,7 +888,7 @@ it's the entry in the "calorie" column for the "avocado" row), use
- A 3-column grid of photos + A 3-column grid of photos Uses `GridView.extent` to create a grid with tiles a maximum 150 pixels wide. @@ -905,8 +896,7 @@ it's the entry in the "calorie" column for the "avocado" row), use **App source:** [grid_and_list]({{examples}}/layout/grid_and_list)
- A 2 column grid with footers + A 2 column grid with footers Uses `GridView.count` to create a grid that's 2 tiles wide in portrait mode, and 3 tiles wide in landscape mode. @@ -954,7 +944,7 @@ its render box.
- ListView containing movie theaters and restaurants Uses `ListView` to display a list of businesses using @@ -964,7 +954,7 @@ its render box. **App source:** [grid_and_list]({{examples}}/layout/grid_and_list)
- ListView containing shades of blue Uses `ListView` to display the [`Colors`][] from @@ -1033,7 +1023,7 @@ or partially overlap the base widget.
- Circular avatar image with a label + Circular avatar image with a label Uses `Stack` to overlay a `Container` (that displays its `Text` on a translucent @@ -1044,7 +1034,7 @@ or partially overlap the base widget. **App source:** [card_and_stack]({{examples}}/layout/card_and_stack)
- An image with a icon overlaid on top + An image with a icon overlaid on top Uses `Stack` to overlay an icon on top of an image. @@ -1118,7 +1108,7 @@ Specifying an unsupported value disables the drop shadow entirely.
- Card containing 3 ListTiles + Card containing 3 ListTiles A `Card` containing 3 ListTiles and sized by wrapping it with a `SizedBox`. A `Divider` separates the first @@ -1127,8 +1117,7 @@ Specifying an unsupported value disables the drop shadow entirely. **App source:** [card_and_stack]({{examples}}/layout/card_and_stack)
- Tappable card containing an image and multiple forms of text + Tappable card containing an image and multiple forms of text A `Card` containing an image and text. @@ -1202,14 +1191,14 @@ and trailing icons. `ListTile` is most commonly used in
- Card containing 3 ListTiles + Card containing 3 ListTiles A `Card` containing 3 `ListTile`s. **App source:** [card_and_stack]({{examples}}/layout/card_and_stack)
- 4 ListTiles, each containing a leading avatar Uses `ListTile` with leading widgets. From 02afd3b54685093430dc1d862069f958a95794b0 Mon Sep 17 00:00:00 2001 From: Parker Lougheed Date: Thu, 30 Jan 2025 16:48:04 -0600 Subject: [PATCH 06/12] Add tabs styling --- src/_sass/components/_tabs.scss | 61 +++++++++++++++++++++++++++++++++ src/_sass/site.scss | 1 + 2 files changed, 62 insertions(+) create mode 100644 src/_sass/components/_tabs.scss diff --git a/src/_sass/components/_tabs.scss b/src/_sass/components/_tabs.scss new file mode 100644 index 0000000000..8959863cd0 --- /dev/null +++ b/src/_sass/components/_tabs.scss @@ -0,0 +1,61 @@ +@use '../base/mixins'; +@use '../base/variables' as *; + +.tab-pane { + display: none; + + &.active { + display: block; + } +} + +ul.nav-tabs { + list-style: none; + + display: flex; + flex-direction: row; + align-items: center; + + padding: 0.375rem; + border-radius: 0.125rem; + background-color: $site-color-codeblock-bg; + gap: 0.5rem; + overflow-x: scroll; + scrollbar-width: thin; + + li { + margin: 0; + } + + a { + font-family: $site-font-family-ui; + text-decoration: none; + color: inherit; + display: block; + padding: 0.375rem 0.75rem; + border-radius: 0.125rem; + white-space: nowrap; + user-select: none; + + &:hover { + @include mixins.interaction-style(4%); + } + + &.active { + background-color: $site-color-primary; + color: $site-color-white; + } + + &:active { + @include mixins.interaction-style(8%); + } + + &:focus-visible { + outline: 2px solid var(--focus-outline-color); + + a { + outline: none; + } + } + } +} diff --git a/src/_sass/site.scss b/src/_sass/site.scss index 658d9343a9..cbd34cb5a5 100644 --- a/src/_sass/site.scss +++ b/src/_sass/site.scss @@ -21,6 +21,7 @@ @use 'components/next-prev-nav'; @use 'components/pill'; @use 'components/sidebar'; +@use 'components/tabs'; @use 'components/toc'; // Styles for specific pages, alphabetically ordered. From dc7d9db48d223d77a8f759640ec63cc104748ba9 Mon Sep 17 00:00:00 2001 From: Parker Lougheed Date: Thu, 30 Jan 2025 17:32:44 -0600 Subject: [PATCH 07/12] Improve formatting of fwe content --- src/_includes/docs/code-and-image.md | 25 ++++----- src/_sass/base/_base.scss | 53 ++++++++++++++++++- src/_sass/base/_utils.scss | 2 +- src/content/get-started/fundamentals/index.md | 8 +-- .../get-started/fundamentals/layout.md | 4 +- src/content/ui/layout/index.md | 22 ++++---- 6 files changed, 82 insertions(+), 32 deletions(-) diff --git a/src/_includes/docs/code-and-image.md b/src/_includes/docs/code-and-image.md index 014661a8ef..ec6cbf4501 100644 --- a/src/_includes/docs/code-and-image.md +++ b/src/_includes/docs/code-and-image.md @@ -12,20 +12,17 @@ {% endif -%} -
-
-
- {{code}} -
-
- {{alt}} - {% if caption -%} -
- {{caption}} -
- {% endif -%} -
+
+
+ {{code}} +
+
+ {{alt | escape}} + {% if caption -%} +
+ {{caption}} +
+ {% endif -%}
- diff --git a/src/_sass/base/_base.scss b/src/_sass/base/_base.scss index a4951d39f3..5fe64ab37e 100644 --- a/src/_sass/base/_base.scss +++ b/src/_sass/base/_base.scss @@ -117,17 +117,65 @@ main figure { } .site-figure-container { + display: flex; + justify-content: center; flex: 0 1 auto; max-width: 100%; + text-align: center; img { display: block; width: 100%; } + // TODO(parlough): Is this necessary? figcaption { margin-top: 1rem; - text-align: center; + } + } + + figcaption { + font-size: 0.875em; + font-style: italic; + text-align: center; + } + + &.code-and-image { + margin: 0; + margin-block-end: 1rem; + gap: 0.25rem; + justify-content: space-between; + flex-direction: row; + flex-wrap: wrap; + + > div { + width: 100%; + + &:last-child { + text-align: center; + } + } + + @media(min-width: 769px) { + > div { + &:first-child { + flex: 0 0 49%; + max-width: 49%; + } + + &:last-child { + flex: 0 0 48%; + max-width: 48%; + } + } + + figcaption { + text-align: left; + } + + img { + max-width: 100%; + } } } } @@ -205,7 +253,8 @@ blockquote { background-color: $site-color-codeblock-bg; padding: 0.75rem 1rem; border-left: solid 5px $site-color-light-grey; - margin-bottom: 1rem; + margin: 0; + margin-block-end: 1rem; p { margin-bottom: 0; diff --git a/src/_sass/base/_utils.scss b/src/_sass/base/_utils.scss index e121eb1c20..82d119bc5a 100644 --- a/src/_sass/base/_utils.scss +++ b/src/_sass/base/_utils.scss @@ -4,7 +4,7 @@ display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 24rem), 1fr)); column-gap: 2rem; - row-gap: 0; + row-gap: 1rem; justify-content: center; margin-block-start: 0.75rem; margin-block-end: 0.75rem; diff --git a/src/content/get-started/fundamentals/index.md b/src/content/get-started/fundamentals/index.md index 0cc0621465..280b2bd336 100644 --- a/src/content/get-started/fundamentals/index.md +++ b/src/content/get-started/fundamentals/index.md @@ -9,8 +9,8 @@ toc: false -
-
+
+
## Find your way with Flutter! @@ -25,8 +25,8 @@ how Flutter works.
-
- {% render docs/app-figure.md, img-class:"w-75", image:"fwe/dash-search.png", alt:"Dash with magnifying glass" %} +
+ {% render docs/app-figure.md, image:"fwe/dash-search.png", alt:"Dash with magnifying glass", width: "75%"%}
diff --git a/src/content/get-started/fundamentals/layout.md b/src/content/get-started/fundamentals/layout.md index d7db3a4f47..f2087281be 100644 --- a/src/content/get-started/fundamentals/layout.md +++ b/src/content/get-started/fundamentals/layout.md @@ -202,8 +202,8 @@ The first figure on this page used both. This is the most basic example of using a `Row` widget. -{% render docs/code-and-image.md, -image:"fwe/layout/row.png", +{% render docs/code-and-image.md, +image:"fwe/layout/row.png", caption: "This figure shows a row widget with three children." alt: "A screenshot of a row widget with three children" code:" diff --git a/src/content/ui/layout/index.md b/src/content/ui/layout/index.md index 5f6b247f88..5ea32ee744 100644 --- a/src/content/ui/layout/index.md +++ b/src/content/ui/layout/index.md @@ -29,10 +29,12 @@ You create a layout by composing widgets to build more complex widgets. For example, the first screenshot below shows 3 icons with a label under each one: -
-
- Sample layout - Sample layout with visual debugging +
+
+ Sample layout +
+
+ Sample layout with visual debugging
@@ -363,11 +365,13 @@ For a row, the main axis runs horizontally and the cross axis runs vertically. For a column, the main axis runs vertically and the cross axis runs horizontally. -
- Diagram showing the main axis and cross axis for a row - Diagram showing the main axis and cross axis for a column +
+
+ Diagram showing the main axis and cross axis for a row +
+
+ Diagram showing the main axis and cross axis for a column +
The [`MainAxisAlignment`][] and [`CrossAxisAlignment`][] From b3d7f4df980f6e63336bc9993b54ed67aa3e07b4 Mon Sep 17 00:00:00 2001 From: Parker Lougheed Date: Thu, 30 Jan 2025 19:49:07 -0600 Subject: [PATCH 08/12] Update and simplify platform adaptation page implementation --- src/_includes/docs/app-figure.md | 2 +- src/_sass/base/_base.scss | 8 +- src/_sass/base/_utils.scss | 16 + .../breaking-changes/androidx-migration.md | 16 +- .../platform-adaptations.md | 428 +++--------------- 5 files changed, 91 insertions(+), 379 deletions(-) diff --git a/src/_includes/docs/app-figure.md b/src/_includes/docs/app-figure.md index 1e3b3ed0ee..ffe426a74e 100644 --- a/src/_includes/docs/app-figure.md +++ b/src/_includes/docs/app-figure.md @@ -13,7 +13,7 @@
- {{alt | escape}} + {{alt | escape}} {% if caption and caption != '' -%}
{{caption}}
{% endif -%} diff --git a/src/_sass/base/_base.scss b/src/_sass/base/_base.scss index 5fe64ab37e..089b6d5828 100644 --- a/src/_sass/base/_base.scss +++ b/src/_sass/base/_base.scss @@ -111,6 +111,8 @@ picture { main figure { display: flex; justify-content: center; + margin: 0; + margin-block-end: 1rem; &.site-image-right { max-height: none; @@ -118,6 +120,7 @@ main figure { .site-figure-container { display: flex; + flex-direction: column; justify-content: center; flex: 0 1 auto; max-width: 100%; @@ -128,9 +131,8 @@ main figure { width: 100%; } - // TODO(parlough): Is this necessary? figcaption { - margin-top: 1rem; + margin-top: 0.5rem; } } @@ -141,8 +143,6 @@ main figure { } &.code-and-image { - margin: 0; - margin-block-end: 1rem; gap: 0.25rem; justify-content: space-between; flex-direction: row; diff --git a/src/_sass/base/_utils.scss b/src/_sass/base/_utils.scss index 82d119bc5a..9baf027714 100644 --- a/src/_sass/base/_utils.scss +++ b/src/_sass/base/_utils.scss @@ -8,6 +8,22 @@ justify-content: center; margin-block-start: 0.75rem; margin-block-end: 0.75rem; + + figure { + margin: 0; + } +} + +.wrapping-row { + display: flex; + flex-wrap: wrap; + gap: 1.5rem; + justify-content: space-around; + margin: 1rem; + + > figure { + margin-block-end: 0; + } } .centered-rows { diff --git a/src/content/release/breaking-changes/androidx-migration.md b/src/content/release/breaking-changes/androidx-migration.md index f56ad084c5..b81e57147f 100644 --- a/src/content/release/breaking-changes/androidx-migration.md +++ b/src/content/release/breaking-changes/androidx-migration.md @@ -35,23 +35,13 @@ you can download the latest version from the but if it doesn't, select **Sync Project with Gradle Files** from the **File** menu). 5. Select **Migrate to AndroidX** from the Refactor menu. -6. If you are asked to backup the project before proceeding, +6. If you're asked to back up the project before proceeding, check **Backup project as Zip file**, then click **Migrate**. Lastly, save the zip file in your location of preference. - Select backup project as zip file + Select backup project as zip file 7. The refactoring preview shows the list of changes. Finally, click **Do Refactor**: - An animation of the bottom-up page transition on Android + An animation of the bottom-up page transition on Android 8. That is it! You successfully migrated your project to AndroidX. Finally, if you migrated a plugin, diff --git a/src/content/ui/adaptive-responsive/platform-adaptations.md b/src/content/ui/adaptive-responsive/platform-adaptations.md index 4c9485321b..be9c9b6579 100644 --- a/src/content/ui/adaptive-responsive/platform-adaptations.md +++ b/src/content/ui/adaptive-responsive/platform-adaptations.md @@ -62,33 +62,10 @@ On **iOS**: is true. This represents iOS's Present/Modal style transition and is typically used on fullscreen modal pages. -
-
-
-
- An animation of the bottom-up page transition on Android -
- Android page transition -
-
-
-
-
- An animation of the end-start style push page transition on iOS -
- iOS push transition -
-
-
-
-
- An animation of the bottom-up style present page transition on iOS -
- iOS present transition -
-
-
-
+
+ {% render docs/app-figure.md, image:"platform-adaptations/navigation-android.gif", img-style:"border-radius: 12px;", caption:"Android page transition", alt:"An animation of the bottom-up page transition on Android" %} + {% render docs/app-figure.md, image:"platform-adaptations/navigation-ios.gif", img-style:"border-radius: 22px;", caption:"iOS push transition", alt:"An animation of the end-start style push page transition on iOS" %} + {% render docs/app-figure.md, image:"platform-adaptations/navigation-ios-modal.gif", img-style:"border-radius: 22px;", caption:"iOS present transition", alt:"An animation of the bottom-up style present page transition on iOS" %}
[`Navigator.push()`]: {{site.api}}/flutter/widgets/Navigator/push.html @@ -108,25 +85,9 @@ automatically animate each subcomponent to its corresponding subcomponent on the next or previous page's `CupertinoNavigationBar` or `CupertinoSliverNavigationBar`. -
-
-
-
- An animation of the page transition on Android -
- Android -
-
-
-
-
- An animation of the nav bar transitions during a page transition on iOS -
- iOS Nav Bar -
-
-
-
+
+ {% render docs/app-figure.md, image:"platform-adaptations/android-zoom-animation.png", img-style:"border-radius: 12px;", caption:"Android", alt:"An animation of the page transition on Android" %} + {% render docs/app-figure.md, image:"platform-adaptations/navigation-ios-nav-bar.gif", img-style:"border-radius: 22px;", caption:"iOS Nav Bar", alt:"An animation of the nav bar transitions during a page transition on iOS" %}
[`ZoomPageTransitionsBuilder`]: {{site.api}}/flutter/material/ZoomPageTransitionsBuilder-class.html @@ -142,25 +103,9 @@ and pops the top route of the [`WidgetsApp`][]'s Navigator. On **iOS**, an edge swipe gesture can be used to pop the top route. -
-
-
-
- A page transition triggered by the Android back button -
- Android back button -
-
-
-
-
- A page transition triggered by an iOS back swipe gesture -
- iOS back swipe gesture -
-
-
-
+
+ {% render docs/app-figure.md, image:"platform-adaptations/navigation-android-back.gif", img-style:"border-radius: 12px;", caption:"Android back button", alt:"A page transition triggered by the Android back button" %} + {% render docs/app-figure.md, image:"platform-adaptations/navigation-ios-back.gif", img-style:"border-radius: 22px;", caption:"iOS back swipe gesture", alt:"A page transition triggered by an iOS back swipe gesture" %}
[`WidgetsApp`]: {{site.api}}/flutter/widgets/WidgetsApp-class.html @@ -180,33 +125,10 @@ dynamic friction but Android has more static friction. Therefore iOS gains high speed more gradually but stops less abruptly and is more slippery at slow speeds. -
-
-
-
- A soft fling where the iOS scrollable slid longer at lower speed than Android -
- Soft fling comparison -
-
-
-
-
- A medium force fling where the Android scrollable reached speed faster and stopped more abruptly after reaching a longer distance -
- Medium fling comparison -
-
-
-
-
- A strong fling where the Android scrollable reach speed faster and reached significantly more distance -
- Strong fling comparison -
-
-
-
+
+ {% render docs/app-figure.md, image:"platform-adaptations/scroll-soft.gif", caption:"Soft fling comparison", alt:"A soft fling where the iOS scrollable slid longer at lower speed than Android" %} + {% render docs/app-figure.md, image:"platform-adaptations/scroll-medium.gif", caption:"Medium fling comparison", alt:"A medium force fling where the Android scrollable reaches speed faster and stopped more abruptly after reaching a longer distance" %} + {% render docs/app-figure.md, image:"platform-adaptations/scroll-strong.gif", caption:"Strong fling comparison", alt:"A strong fling where the Android scrollable reaches speed faster and covered significantly more distance" %}
### Overscroll behavior @@ -219,25 +141,9 @@ of the current Material theme). On **iOS**, scrolling past the edge of a scrollable [overscrolls][] with increasing resistance and snaps back. -
-
-
-
- Android and iOS scrollables being flung past their edge and exhibiting platform specific overscroll behavior -
- Dynamic overscroll comparison -
-
-
-
-
- Android and iOS scrollables being overscrolled from a resting position and exhibiting platform specific overscroll behavior -
- Static overscroll comparison -
-
-
-
+
+ {% render docs/app-figure.md, image:"platform-adaptations/scroll-overscroll.gif", caption:"Dynamic overscroll comparison", alt:"Android and iOS scrollables being flung past their edge and exhibiting platform specific overscroll behavior" %} + {% render docs/app-figure.md, image:"platform-adaptations/scroll-static-overscroll.gif", caption:"Static overscroll comparison", alt:"Android and iOS scrollables being overscrolled from a resting position and exhibiting platform specific overscroll behavior" %}
[overscroll glow indicator]: {{site.api}}/flutter/widgets/GlowingOverscrollIndicator-class.html @@ -250,17 +156,8 @@ repeated flings in the same direction stacks momentum and builds more speed with each successive fling. There is no equivalent behavior on Android. -
-
-
-
- Repeated scroll flings building momentum on iOS -
- iOS scroll momentum -
-
-
-
+
+ {% render docs/app-figure.md, image:"platform-adaptations/scroll-momentum-ios.gif", caption:"iOS scroll momentum", alt:"Repeated scroll flings building momentum on iOS" %}
### Return to top @@ -270,17 +167,8 @@ tapping the OS status bar scrolls the primary scroll controller to the top position. There is no equivalent behavior on Android. -
-
-
-
- Tapping the status bar scrolls the primary scrollable back to the top -
- iOS status bar tap to top -
-
-
-
+
+ {% render docs/app-figure.md, image:"platform-adaptations/scroll-tap-to-top-ios.gif", img-style:"border-radius: 22px;", caption:"iOS status bar tap to top", alt:"Tapping the status bar scrolls the primary scrollable back to the top" %}
## Typography @@ -305,25 +193,9 @@ widgets to match the default text styling on iOS. You can see widget-specific examples in the [UI Component section](#ui-components). -
-
-
-
- Roboto font on Android -
- Roboto on Android -
-
-
-
-
- San Francisco font on iOS -
- San Francisco on iOS -
-
-
-
+
+ {% render docs/app-figure.md, image:"platform-adaptations/typography-android.png", img-style:"border-radius: 12px;", caption:"Roboto on Android", alt:"Roboto font typography scale on Android" %} + {% render docs/app-figure.md, image:"platform-adaptations/typography-ios.png", img-style:"border-radius: 22px;", caption:"San Francisco on iOS", alt:"San Francisco typography scale on iOS" %}
[default theme]: {{site.repo.flutter}}/blob/main/packages/flutter/lib/src/cupertino/text_theme.dart @@ -338,25 +210,9 @@ are horizontal on iOS and vertical on Android. The back button is a simple chevron on iOS and has a stem/shaft on Android. -
-
-
-
- Android appropriate icons -
- Icons on Android -
-
-
-
-
- iOS appropriate icons -
- Icons on iOS -
-
-
-
+
+ {% render docs/app-figure.md, image:"platform-adaptations/iconography-android.png", caption:"Icons on Android", alt:"Android appropriate icons" %} + {% render docs/app-figure.md, image:"platform-adaptations/iconography-ios.png", caption:"Icons on iOS", alt:"iOS appropriate icons" %}
The material library also provides a set of @@ -398,25 +254,9 @@ a force-press-drag gesture could be made on the soft keyboard to move the cursor in 2D via a floating cursor. This works on both Material and Cupertino text fields. -
-
-
-
- Moving the cursor via the space key on Android -
- Android space key cursor move -
-
-
-
-
- Moving the cursor via 3D Touch drag on the keyboard on iOS -
- iOS 3D Touch drag cursor move -
-
-
-
+
+ {% render docs/app-figure.md, image:"platform-adaptations/text-keyboard-move-android.gif", caption:"Android space key cursor move", alt:"Moving the cursor via the space key on Android" %} + {% render docs/app-figure.md, image:"platform-adaptations/text-keyboard-move-ios.gif", caption:"iOS 3D Touch drag cursor move", alt:"Moving the cursor via 3D Touch drag on the keyboard on iOS" %}
### Text selection toolbar @@ -429,25 +269,9 @@ With **Material on iOS** or when using **Cupertino**, the iOS style selection toolbar is shown when a text selection is made in a text field. -
-
-
-
- Android appropriate text toolbar -
- Android text selection toolbar -
-
-
-
-
- iOS appropriate text toolbar -
- iOS text selection toolbar -
-
-
-
+
+ {% render docs/app-figure.md, image:"platform-adaptations/text-toolbar-android.png", caption:"Android text selection toolbar", alt:"Android appropriate text toolbar" %} + {% render docs/app-figure.md, image:"platform-adaptations/text-toolbar-ios.png", caption:"iOS text selection toolbar", alt:"iOS appropriate text toolbar" %}
### Single tap gesture @@ -465,25 +289,9 @@ nearest edge of the word tapped. Collapsed text selections don't have draggable handles on iOS. -
-
-
-
- Moving the cursor to the tapped position on Android -
- Android tap -
-
-
-
-
- Moving the cursor to the nearest edge of the tapped word on iOS -
- iOS tap -
-
-
-
+
+ {% render docs/app-figure.md, image:"platform-adaptations/text-single-tap-android.gif", caption:"Android tap", alt:"Moving the cursor to the tapped position on Android" %} + {% render docs/app-figure.md, image:"platform-adaptations/text-single-tap-ios.gif", caption:"iOS tap", alt:"Moving the cursor to the nearest edge of the tapped word on iOS" %}
### Long-press gesture @@ -496,25 +304,9 @@ With **Material on iOS** or when using **Cupertino**, a long press places the cursor at the location of the long press. The selection toolbar is shown upon release. -
-
-
-
- Selecting a word via long press on Android -
- Android long press -
-
-
-
-
- Selecting a position via long press on iOS -
- iOS long press -
-
-
-
+
+ {% render docs/app-figure.md, image:"platform-adaptations/text-long-press-android.gif", caption:"Android long press", alt:"Selecting a word with long press on Android" %} + {% render docs/app-figure.md, image:"platform-adaptations/text-long-press-ios.gif", caption:"iOS long press", alt:"Selecting a position with long press on iOS" %}
### Long-press drag gesture @@ -525,25 +317,9 @@ dragging while holding the long press expands the words selected. With **Material on iOS** or when using **Cupertino**, dragging while holding the long press moves the cursor. -
-
-
-
- Expanding word selection via long press drag on Android -
- Android long press drag -
-
-
-
-
- Moving the cursor via long press drag on iOS -
- iOS long press drag -
-
-
-
+
+ {% render docs/app-figure.md, image:"platform-adaptations/text-long-press-drag-android.gif", caption:"Android long-press drag", alt:"Expanding word selection with a long-press drag on Android" %} + {% render docs/app-figure.md, image:"platform-adaptations/text-long-press-drag-ios.gif", caption:"iOS long-press drag", alt:"Moving the cursor with a long-press drag on iOS" %}
### Double tap gesture @@ -552,25 +328,9 @@ On both Android and iOS, a double tap selects the word receiving the double tap and shows the selection toolbar. -
-
-
-
- Selecting a word via double tap on Android -
- Android double tap -
-
-
-
-
- Selecting a word via double tap on iOS -
- iOS double tap -
-
-
-
+
+ {% render docs/app-figure.md, image:"platform-adaptations/text-double-tap-android.gif", caption:"Android double tap", alt:"Selecting a word via double tap on Android" %} + {% render docs/app-figure.md, image:"platform-adaptations/text-double-tap-ios.gif", caption:"iOS double tap", alt:"Selecting a word via double tap on iOS" %}
## UI components @@ -597,13 +357,13 @@ Therefore, we recommend that you follow platform conventions. | Material widget | Cupertino widget | Adaptive constructor | |---|---|---| -|Switch in Material 3
`Switch`|Switch in HIG
`CupertinoSwitch`|[`Switch.adaptive()`][]| -|Slider in Material 3
`Slider`|Slider in HIG
`CupertinoSlider`|[`Slider.adaptive()`][]| -|Circular progress indicator in Material 3
`CircularProgressIndicator`|Activity indicator in HIG
`CupertinoActivityIndicator`|[`CircularProgressIndicator.adaptive()`][]| -|Refresh indicator in Material 3
`RefreshProgressIndicator`|Refresh indicator in HIG
`CupertinoActivityIndicator`|[`RefreshIndicator.adaptive()`][]| -|  Checkbox in Material 3
`Checkbox`| Checkbox in HIG
`CupertinoCheckbox`|[`Checkbox.adaptive()`][]| -|Radio in Material 3
`Radio`|Radio in HIG
`CupertinoRadio`|[`Radio.adaptive()`][]| -|AlertDialog in Material 3
`AlertDialog`|AlertDialog in HIG
`CupertinoAlertDialog`|[`AlertDialog.adaptive()`][]| +|Switch in Material 3
`Switch`|Switch in HIG
`CupertinoSwitch`|[`Switch.adaptive()`][]| +|Slider in Material 3
`Slider`|Slider in HIG
`CupertinoSlider`|[`Slider.adaptive()`][]| +|Circular progress indicator in Material 3
`CircularProgressIndicator`|Activity indicator in HIG
`CupertinoActivityIndicator`|[`CircularProgressIndicator.adaptive()`][]| +|Refresh indicator in Material 3
`RefreshProgressIndicator`|Refresh indicator in HIG
`CupertinoActivityIndicator`|[`RefreshIndicator.adaptive()`][]| +| Checkbox in Material 3
`Checkbox`| Checkbox in HIG
`CupertinoCheckbox`|[`Checkbox.adaptive()`][]| +|Radio in Material 3
`Radio`|Radio in HIG
`CupertinoRadio`|[`Radio.adaptive()`][]| +|AlertDialog in Material 3
`AlertDialog`|AlertDialog in HIG
`CupertinoAlertDialog`|[`AlertDialog.adaptive()`][]| [`AlertDialog.adaptive()`]: {{site.api}}/flutter/material/AlertDialog/AlertDialog.adaptive.html [`Checkbox.adaptive()`]: {{site.api}}/flutter/material/Checkbox/Checkbox.adaptive.html @@ -618,29 +378,11 @@ Therefore, we recommend that you follow platform conventions. Since Android 12, the default UI for top app bars follows the design guidelines defined in [Material 3][mat-appbar]. On iOS, an equivalent component called "Navigation Bars" -is defined in [Apple's Human Interface Guidelines][hig-appbar] (HIG). - -
-
-
-
-  Top App Bar in Material 3 -
- Top App Bar in Material 3 -
-
-
-
-
- Navigation Bar in Human Interface Guidelines -
- Navigation Bar in Human Interface Guidelines -
-
-
-
+is defined in [Apple's Human Interface Guidelines][hig-appbar] (HIG). + +
+ {% render docs/app-figure.md, image:"platform-adaptations/mat-appbar.png", caption:"Top App Bar in Material 3", alt:"Top App Bar in Material 3", height: "240px" %} + {% render docs/app-figure.md, image:"platform-adaptations/hig-appbar.png", caption:"Navigation Bar in Human Interface Guidelines", alt:"Navigation Bar in Human Interface Guidelines", height: "240px" %}
Certain properties of app bars in Flutter apps should be adapted, @@ -693,29 +435,11 @@ additional code samples and a further explanation in Since Android 12, the default UI for bottom navigation bars follow the design guidelines defined in [Material 3][mat-navbar]. On iOS, an equivalent component called "Tab Bars" -is defined in [Apple's Human Interface Guidelines][hig-tabbar] (HIG). - -
-
-
-
- Bottom Navigation Bar in Material 3 -
- Bottom Navigation Bar in Material 3 -
-
-
-
-
- Tab Bar in Human Interface Guidelines -
- Tab Bar in Human Interface Guidelines -
-
-
-
+is defined in [Apple's Human Interface Guidelines][hig-tabbar] (HIG). + +
+ {% render docs/app-figure.md, image:"platform-adaptations/mat-navbar.png", caption:"Bottom Navigation Bar in Material 3", alt:"Bottom Navigation Bar in Material 3", height: "160px" %} + {% render docs/app-figure.md, image:"platform-adaptations/hig-tabbar.png", caption:"Tab Bar in Human Interface Guidelines", alt:"Tab Bar in Human Interface Guidelines", height: "160px" %}
Since tab bars are persistent across your app, they should match your @@ -777,29 +501,11 @@ Scaffold( Since Android 12, text fields follow the [Material 3][m3-text-field] (M3) design guidelines. On iOS, Apple's [Human Interface Guidelines][hig-text-field] (HIG) define -an equivalent component. - -
-
-
-
- Text Field in Material 3 -
- Text Field in Material 3 -
-
-
-
-
- Text Field in Human Interface Guidelines -
- Text Field in HIG -
-
-
-
+an equivalent component. + +
+ {% render docs/app-figure.md, image:"platform-adaptations/m3-text-field.png", caption:"Text Field in Material 3", alt:"Text Field in Material 3", width:"320px", height:"100px" %} + {% render docs/app-figure.md, image:"platform-adaptations/hig-text-field.png", caption:"Text Field in HIG", alt:"Text Field in Human Interface Guidelines", width:"320px", height:"100px" %}
Since text fields require user input, From 2382a9eed9f5fd27924ee45eb8c535a393452576 Mon Sep 17 00:00:00 2001 From: Parker Lougheed Date: Thu, 30 Jan 2025 20:22:20 -0600 Subject: [PATCH 09/12] Fix last remaining usages besides layout index --- src/_includes/docs/code-and-image.md | 4 ++-- src/_sass/base/_base.scss | 10 ++++---- src/_sass/components/_content.scss | 2 +- .../app-architecture/case-study/index.md | 23 ++++--------------- .../app-architecture/case-study/ui-layer.md | 18 ++++++--------- src/content/app-architecture/index.md | 12 ++++------ src/content/get-started/fundamentals/index.md | 2 +- .../accessibility.md | 10 +++----- 8 files changed, 28 insertions(+), 53 deletions(-) diff --git a/src/_includes/docs/code-and-image.md b/src/_includes/docs/code-and-image.md index ec6cbf4501..9f5df9ab3d 100644 --- a/src/_includes/docs/code-and-image.md +++ b/src/_includes/docs/code-and-image.md @@ -17,8 +17,8 @@ {{code}}
- {{alt | escape}} - {% if caption -%} + {{alt | escape}} + {% if caption and caption != '' -%}
{{caption}}
diff --git a/src/_sass/base/_base.scss b/src/_sass/base/_base.scss index 089b6d5828..70a97db037 100644 --- a/src/_sass/base/_base.scss +++ b/src/_sass/base/_base.scss @@ -149,7 +149,7 @@ main figure { flex-wrap: wrap; > div { - width: 100%; + width: 100%; &:last-child { text-align: center; @@ -159,13 +159,13 @@ main figure { @media(min-width: 769px) { > div { &:first-child { - flex: 0 0 49%; - max-width: 49%; + flex: 0 0 58%; + max-width: 58%; } &:last-child { - flex: 0 0 48%; - max-width: 48%; + flex: 0 0 40%; + max-width: 40%; } } diff --git a/src/_sass/components/_content.scss b/src/_sass/components/_content.scss index 769b80b7e0..9f5cb2994a 100644 --- a/src/_sass/components/_content.scss +++ b/src/_sass/components/_content.scss @@ -18,7 +18,7 @@ object-fit: contain; } - > img, > p > img:not(.text-icon) { + > img { margin-bottom: 1rem; } } diff --git a/src/content/app-architecture/case-study/index.md b/src/content/app-architecture/case-study/index.md index 4b27f04b57..20b8e47ba9 100644 --- a/src/content/app-architecture/case-study/index.md +++ b/src/content/app-architecture/case-study/index.md @@ -20,24 +20,11 @@ includes brand-specific styling, and contains high test coverage. In these ways and more, it simulates a real-world, feature-rich Flutter application. -
- -
- -![A screenshot of the splash screen of the compass app.](/assets/images/docs/app-architecture/case-study/splash_screen.png) -
-
- -![A screenshot of the home screen of the compass app.](/assets/images/docs/app-architecture/case-study/home_screen.png) -
-
- -![A screenshot of the search form screen of the compass app.](/assets/images/docs/app-architecture/case-study/search_form_screen.png) -
-
- -![A screenshot of the booking screen of the compass app.](/assets/images/docs/app-architecture/case-study/booking_screen.png) -
+
+ {% render docs/app-figure.md, image:"app-architecture/case-study/splash_screen.png", alt:"A screenshot of the splash screen of the compass app.", img-style:"max-height: 400px;" %} + {% render docs/app-figure.md, image:"app-architecture/case-study/home_screen.png", alt:"A screenshot of the home screen of the compass app.", img-style:"max-height: 400px;" %} + {% render docs/app-figure.md, image:"app-architecture/case-study/search_form_screen.png", alt:"A screenshot of the search form screen of the compass app.", img-style:"max-height: 400px;" %} + {% render docs/app-figure.md, image:"app-architecture/case-study/booking_screen.png", alt:"A screenshot of the booking screen of the compass app.", img-style:"max-height: 400px;" %}
The Compass app's architecture most resembles the [MVVM design pattern][] diff --git a/src/content/app-architecture/case-study/ui-layer.md b/src/content/app-architecture/case-study/ui-layer.md index 900fb97663..ffc1712ea8 100644 --- a/src/content/app-architecture/case-study/ui-layer.md +++ b/src/content/app-architecture/case-study/ui-layer.md @@ -180,7 +180,7 @@ new state needs to be emitted, [`notifyListeners`][] is called. ![A screenshot of the booking screen of the compass app.](/assets/images/docs/app-architecture/case-study/mvvm-case-study-update-ui-steps.png) -
+
This figure shows from a high-level how new data in the repository propagates up to the UI layer and triggers a re-build of your Flutter widgets.
@@ -404,9 +404,11 @@ a [`Dismissible`][] widget. Recall this code from the previous snippet: -
-
- +{% render docs/code-and-image.md, +image:"app-architecture/case-study/dismissible.gif", +img-style:"max-height: 480px; border-radius: 12px; border: black 2px solid;", +alt: "A clip that demonstrates the 'dismissible' functionality of the Compass app." +code:" ```dart title=home_screen.dart highlightLines=9-10 SliverList.builder( itemCount: widget.viewModel.bookings.length, @@ -421,13 +423,7 @@ SliverList.builder( ), ), ``` - -
-
-A clip that demonstrates the 'dismissible' functionality of the Compass app. - -
-
+" %} On the `HomeScreen`, a user's saved trip is represented by the `_Booking` widget. When a `_Booking` is dismissed, diff --git a/src/content/app-architecture/index.md b/src/content/app-architecture/index.md index 8fe5f58371..8c1df30728 100644 --- a/src/content/app-architecture/index.md +++ b/src/content/app-architecture/index.md @@ -7,17 +7,15 @@ toc: false next: title: Architecture concepts path: /app-architecture/concepts - --- -
-
+
+
Architecture is an important part of building a maintainable, resilient, and scalable Flutter app. In this guide, you'll learn app architecture principles and best practices for building Flutter apps. -
'Architecture' is a word that's hard to define. It's a broad term and can refer to any number @@ -26,10 +24,8 @@ of topics depending on the context. In this guide, your Flutter app in order to scale as your project requirements and team grow.
-
- -Hero image - +
+Hero image
diff --git a/src/content/get-started/fundamentals/index.md b/src/content/get-started/fundamentals/index.md index 280b2bd336..ec3c68dd7e 100644 --- a/src/content/get-started/fundamentals/index.md +++ b/src/content/get-started/fundamentals/index.md @@ -26,7 +26,7 @@ how Flutter works.
- {% render docs/app-figure.md, image:"fwe/dash-search.png", alt:"Dash with magnifying glass", width: "75%"%} + {% render docs/app-figure.md, image:"fwe/dash-search.png", alt:"Dash with magnifying glass", img-style: "max-height: 320px;"%}
diff --git a/src/content/ui/accessibility-and-internationalization/accessibility.md b/src/content/ui/accessibility-and-internationalization/accessibility.md index 39e1b9eb66..38d842936f 100644 --- a/src/content/ui/accessibility-and-internationalization/accessibility.md +++ b/src/content/ui/accessibility-and-internationalization/accessibility.md @@ -78,13 +78,9 @@ The following two screenshots show the standard Flutter app template rendered with the default iOS font setting, and with the largest font setting selected in iOS accessibility settings. -
-
- {% render docs/app-figure.md, image:"a18n/app-regular-fonts.png", caption:"Default font setting", img-class:"border" %} -
-
- {% render docs/app-figure.md, image:"a18n/app-large-fonts.png", caption:"Largest accessibility font setting", img-class:"border" %} -
+
+ {% render docs/app-figure.md, image:"a18n/app-regular-fonts.png", caption:"Default font setting", img-class:"simple-border", img-style:"max-height: 480px;" %} + {% render docs/app-figure.md, image:"a18n/app-large-fonts.png", caption:"Largest accessibility font setting", img-class:"simple-border", img-style:"max-height: 480px;" %}
## Screen readers From a912ce0c67159314b6fa548c5b9ad92ae93332f8 Mon Sep 17 00:00:00 2001 From: Parker Lougheed Date: Thu, 30 Jan 2025 21:52:24 -0600 Subject: [PATCH 10/12] Migrate layout index --- src/_sass/base/_utils.scss | 80 ++++++++++++-------- src/content/ui/layout/index.md | 134 ++++++++++++++++----------------- 2 files changed, 111 insertions(+), 103 deletions(-) diff --git a/src/_sass/base/_utils.scss b/src/_sass/base/_utils.scss index 9baf027714..e3cbe6bac4 100644 --- a/src/_sass/base/_utils.scss +++ b/src/_sass/base/_utils.scss @@ -1,44 +1,60 @@ @use 'variables' as *; -.side-by-side { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(min(100%, 24rem), 1fr)); - column-gap: 2rem; - row-gap: 1rem; - justify-content: center; - margin-block-start: 0.75rem; - margin-block-end: 0.75rem; - - figure { - margin: 0; +main { + .side-by-side { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(min(100%, 24rem), 1fr)); + column-gap: 1.5rem; + row-gap: 1rem; + justify-content: center; + margin-block-start: 0.75rem; + margin-block-end: 0.75rem; + + figure { + margin: 0; + } + + .header-wrapper { + margin-block-start: 0.5rem; + } } -} -.wrapping-row { - display: flex; - flex-wrap: wrap; - gap: 1.5rem; - justify-content: space-around; - margin: 1rem; + .code-and-content { + display: grid; + grid-template-columns: 1fr; + column-gap: 1.5rem; - > figure { - margin-block-end: 0; + @media (min-width: 768px) { + grid-template-columns: minmax(60%, 1fr) auto; + } + } + + .wrapping-row { + display: flex; + flex-wrap: wrap; + gap: 1.5rem; + justify-content: space-around; + margin: 1rem; + + > figure { + margin-block-end: 0; + } + } + + .centered-rows { + display: flex; + flex-direction: column; + align-items: center; + margin-left: 1rem; + margin-right: 1rem; + justify-content: center; } -} -.centered-rows { - display: flex; - flex-direction: column; - align-items: center; - margin-left: 1rem; - margin-right: 1rem; - justify-content: center; + .simple-border { + border: 1px solid $site-color-light-grey; + } } .text-center { text-align: center; } - -.simple-border { - border: 1px solid $site-color-light-grey; -} diff --git a/src/content/ui/layout/index.md b/src/content/ui/layout/index.md index 5ea32ee744..a083dcb650 100644 --- a/src/content/ui/layout/index.md +++ b/src/content/ui/layout/index.md @@ -9,8 +9,6 @@ description: Learn how Flutter's layout mechanism works and how to build a layou - - :::secondary What's the point? * Widgets are classes used to build UIs. * Widgets are used for both layout and UI elements. @@ -287,22 +285,19 @@ or background color. If you want these features in a non-Material app, you have to build them yourself. This app changes the background color to white and the text to dark grey to mimic a Material app. -
-
+
+
- That's it! When you run the app, you should see _Hello World_. +That's it! When you run the app, you should see _Hello World_. - App source code: +App source code: - * [Material app]({{examples}}/layout/base) - * [Non-Material app]({{examples}}/layout/non_material) +* [Material app]({{examples}}/layout/base) +* [Non-Material app]({{examples}}/layout/non_material)
-
- {% render docs/app-figure.md, img-class:"site-mobile-screenshot border w-75", image:"ui/layout/hello-world.png", alt:"Hello World" %} -
+{% render docs/app-figure.md, image:"ui/layout/hello-world.png", alt:"Screenshot of app displaying Hello World", img-class:"simple-border", img-style:"max-height: 400px;" %}
-
## Lay out multiple widgets vertically and horizontally @@ -393,10 +388,10 @@ is more than 300 pixels wide, so setting the main axis alignment to `spaceEvenly` divides the free horizontal space evenly between, before, and after each image. -
-
+
+
- + ```dart [!Row!]( mainAxisAlignment: MainAxisAlignment.spaceEvenly, @@ -409,7 +404,7 @@ space evenly between, before, and after each image. ```
-
+
Row with 3 evenly spaced images **App source:** [row_column]({{examples}}/layout/row_column) @@ -422,8 +417,8 @@ of 3 images, each is 100 pixels high. The height of the render box setting the main axis alignment to `spaceEvenly` divides the free vertical space evenly between, above, and below each image. -
-
+
+
```dart @@ -437,12 +432,11 @@ space evenly between, above, and below each image. ); ``` - **App source:** [row_column]({{examples}}/layout/row_column) -
-
- Column showing 3 images spaced evenly +
+ Column showing 3 images spaced evenly + + **App source:** [row_column]({{examples}}/layout/row_column)
@@ -459,8 +453,8 @@ Widgets can be sized to fit within a row or column by using the row of images is too wide for its render box, wrap each image with an `Expanded` widget. -
-
+
+
```dart @@ -481,7 +475,7 @@ wrap each image with an `Expanded` widget. ```
-
+
Row of 3 images that are too wide, but each is constrained to take only 1/3 of the space **App source:** [sizing]({{examples}}/layout/sizing) @@ -494,8 +488,8 @@ an integer that determines the flex factor for a widget. The default flex factor is 1. The following code sets the flex factor of the middle image to 2: -
-
+
+
```dart @@ -517,7 +511,7 @@ the flex factor of the middle image to 2: ```
-
+
Row of 3 images with the middle image twice as wide as the others **App source:** [sizing]({{examples}}/layout/sizing) @@ -533,8 +527,8 @@ as possible, but if you want to pack the children closely together, set its `mainAxisSize` to `MainAxisSize.min`. The following example uses this property to pack the star icons together. -
-
+
+
```dart @@ -551,8 +545,8 @@ uses this property to pack the star icons together. ```
-
- Row of 5 stars, packed together in the middle of the row +
+ Row of 5 stars, packed together in the middle of the row **App source:** [pavlova]({{examples}}/layout/pavlova)
@@ -781,18 +775,19 @@ You can change the device's background by placing the entire layout into a `Container` and changing its background color or image. -
-
-

Summary (Container)

+
+
+ +#### Summary (Container) * Add padding, margins, borders * Change background color or image -* Contains a single child widget, but that child can be a Row, - Column, or even the root of a widget tree +* Contains a single child widget, but that child can be a `Row`, + `Column`, or even the root of a widget tree
-
- Diagram showing: margin, border, padding, and content +
+ Diagram showing: margin, border, padding, and content
@@ -802,8 +797,8 @@ This layout consists of a column with two rows, each containing 2 images. A [`Container`][] is used to change the background color of the column to a lighter grey. -
-
+
+
```dart @@ -823,7 +818,7 @@ of the column to a lighter grey. ```
-
+
Screenshot showing 2 rows, each containing 2 images
@@ -890,24 +885,24 @@ it's the entry in the "calorie" column for the "avocado" row), use #### Examples (GridView) -
-
- A 3-column grid of photos +
+
+ A 3-column grid of photos Uses `GridView.extent` to create a grid with tiles a maximum 150 pixels wide. **App source:** [grid_and_list]({{examples}}/layout/grid_and_list)
-
- A 2 column grid with footers +
+ A 2 column grid with footers Uses `GridView.count` to create a grid that's 2 tiles wide in portrait mode, and 3 tiles wide in landscape mode. The titles are created by setting the `footer` property for each [`GridTile`][]. - **Dart code:** + **Dart code:** [`grid_list_demo.dart`]({{examples}}/layout/gallery/lib/grid_list_demo.dart)
@@ -946,10 +941,9 @@ its render box. #### Examples (ListView) -
-
- ListView containing movie theaters and restaurants +
+
+ ListView containing movie theaters and restaurants Uses `ListView` to display a list of businesses using `ListTile`s. A `Divider` separates the theaters from @@ -957,9 +951,8 @@ its render box. **App source:** [grid_and_list]({{examples}}/layout/grid_and_list)
-
- ListView containing shades of blue +
+ ListView containing shades of blue Uses `ListView` to display the [`Colors`][] from the [Material 2 Design palette][] @@ -1025,9 +1018,9 @@ or partially overlap the base widget. #### Examples (Stack) -
-
- Circular avatar image with a label +
+
+ Circular avatar image with a label Uses `Stack` to overlay a `Container` (that displays its `Text` on a translucent @@ -1037,8 +1030,8 @@ or partially overlap the base widget. **App source:** [card_and_stack]({{examples}}/layout/card_and_stack)
-
- An image with a icon overlaid on top +
+ An image with a icon overlaid on top Uses `Stack` to overlay an icon on top of an image. @@ -1110,9 +1103,9 @@ Specifying an unsupported value disables the drop shadow entirely. #### Examples (Card) -
-
- Card containing 3 ListTiles +
+
+ Card containing 3 ListTiles A `Card` containing 3 ListTiles and sized by wrapping it with a `SizedBox`. A `Divider` separates the first @@ -1120,8 +1113,8 @@ Specifying an unsupported value disables the drop shadow entirely. **App source:** [card_and_stack]({{examples}}/layout/card_and_stack)
-
- Tappable card containing an image and multiple forms of text +
+ Tappable card containing an image and multiple forms of text A `Card` containing an image and text. @@ -1193,17 +1186,16 @@ and trailing icons. `ListTile` is most commonly used in #### Examples (ListTile) -
-
+
+
Card containing 3 ListTiles A `Card` containing 3 `ListTile`s. **App source:** [card_and_stack]({{examples}}/layout/card_and_stack)
-
- 4 ListTiles, each containing a leading avatar +
+ 4 ListTiles, each containing a leading avatar Uses `ListTile` with leading widgets. From 96fb9bbdc67afcf492891e3bb45d12fe2606f4ab Mon Sep 17 00:00:00 2001 From: Parker Lougheed Date: Thu, 30 Jan 2025 21:55:59 -0600 Subject: [PATCH 11/12] Update code excerpt from accidental indentation --- src/content/ui/layout/index.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/content/ui/layout/index.md b/src/content/ui/layout/index.md index a083dcb650..8a23a0ec2e 100644 --- a/src/content/ui/layout/index.md +++ b/src/content/ui/layout/index.md @@ -392,16 +392,16 @@ space evenly between, before, and after each image.
- ```dart - [!Row!]( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - Image.asset('images/pic1.jpg'), - Image.asset('images/pic2.jpg'), - Image.asset('images/pic3.jpg'), - ], - ); - ``` +```dart +[!Row!]( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Image.asset('images/pic1.jpg'), + Image.asset('images/pic2.jpg'), + Image.asset('images/pic3.jpg'), + ], +); +```
From 58e02e14d966e554280c072fd28d81e01a046450 Mon Sep 17 00:00:00 2001 From: Parker Lougheed Date: Thu, 30 Jan 2025 22:43:52 -0600 Subject: [PATCH 12/12] Add community cross link to header --- src/_includes/header.html | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/_includes/header.html b/src/_includes/header.html index 0667517ba9..776d91ef9e 100644 --- a/src/_includes/header.html +++ b/src/_includes/header.html @@ -28,6 +28,9 @@ +