Giter VIP home page Giter VIP logo

extended_sliver's Introduction

extended_sliver

pub package GitHub stars GitHub forks GitHub license GitHub issues flutter-candies

Language: English | 中文简体

Description

A powerful extension library of Sliver, which include SliverToNestedScrollBoxAdapter, SliverPinnedPersistentHeader, SliverPinnedToBoxAdapter and ExtendedSliverAppbar.

Usage

Add packages to dependencies

Add the package to pubspec.yaml under dependencies.

dependencies:
  extended_sliver: latest-version

Download with flutter packages get

SliverPinnedPersistentHeader

It's the same as SliverPersistentHeader(pinned: true), but you don't have to force values of minExtent and maxExtent.

It provides minExtentProtoType and maxExtentProtoType to calculate minExtent and maxExtent automatically.

It's useful that you don't know the final extent before the widgets are laid out.

    SliverPinnedPersistentHeader(
      delegate: MySliverPinnedPersistentHeaderDelegate(
        minExtentProtoType: Container(
          height: 120.0,
          color: Colors.red.withOpacity(0.5),
          child: FlatButton(
            child: const Text('minProtoType'),
            onPressed: () {
              print('minProtoType');
            },
          ),
          alignment: Alignment.topCenter,
        ),
        maxExtentProtoType: Container(
          height: 200.0,
          color: Colors.blue,
          child: FlatButton(
            child: const Text('maxProtoType'),
            onPressed: () {
              print('maxProtoType');
            },
          ),
          alignment: Alignment.bottomCenter,
        ),
      ),
    )

SliverPinnedToBoxAdapter

You can create a pinned Sliver easily with it.

It's useful that you don't know the final extent before the child are laid out.

    SliverPinnedToBoxAdapter(
      child: Container(
        padding: const EdgeInsets.all(20),
        color: Colors.blue.withOpacity(0.5),
        child: Column(
          children: <Widget>[
            const Text(
                '[love]Extended text help you to build rich text quickly. any special text you will have with extended text. '
                '\n\nIt\'s my pleasure to invite you to join \$FlutterCandies\$ if you want to improve flutter .[love]'
                '\n\nif you meet any problem, please let me konw @zmtzawqlp .[sun_glasses]'),
            FlatButton(
              child: const Text('I\'m button. click me!'),
              onPressed: () {
                debugPrint('click');
              },
            ),
          ],
        ),
      ),
    )

ExtendedSliverAppbar

You can create SliverAppbar with out force the expandedHeight.

return CustomScrollView(
  slivers: <Widget>[
    ExtendedSliverAppbar(
      title: const Text(
        'ExtendedSliverAppbar',
        style: TextStyle(color: Colors.white),
      ),
      leading: const BackButton(
        onPressed: null,
        color: Colors.white,
      ),
      background: Image.asset(
        'assets/cypridina.jpeg',
        fit: BoxFit.cover,
      ),
      actions: Padding(
        padding: const EdgeInsets.all(10.0),
        child: Icon(
          Icons.more_horiz,
          color: Colors.white,
        ),
      ),
    ),
  ],
);

SliverToNestedScrollBoxAdapter

You can create nested scrollable widget(like Webview) in CustomScrollView/NestedScrollView.

return CustomScrollView(
  slivers: <Widget>[
      SliverToBoxAdapter(
        child: Container(
          height: 100,
          color: Colors.red,
          child: const Center(
            child: Text(
              'Header',
              style: TextStyle(color: Colors.white),
            ),
          ),
        ),
      ),
    ValueListenableBuilder<double>(
      valueListenable: nestedWebviewController.scrollHeightNotifier,
      builder: (
        BuildContext context,
        double scrollHeight,
        Widget? child,
      ) {
        return SliverToNestedScrollBoxAdapter(
          childExtent: scrollHeight,
          onScrollOffsetChanged: (double scrollOffset) {
            double y = scrollOffset;
            if (Platform.isAndroid) {
              // https://github.com/flutter/flutter/issues/75841
              y *= window.devicePixelRatio;
      
            nestedWebviewController.webviewController
                ?.scrollTo(0, y.ceil());
          },
          child: child,
        );
      },
      child: WebView(
        initialUrl: nestedWebviewController.initialUrl,
        onPageStarted: nestedWebviewController.onPageStarted,
        onPageFinished: nestedWebviewController.onPageFinished,
        onWebResourceError:
            nestedWebviewController.onWebResourceError,
        onWebViewCreated: nestedWebviewController.onWebViewCreated,
        onProgress: nestedWebviewController.onProgress,
        javascriptChannels: <JavascriptChannel>{
          nestedWebviewController
              .scrollHeightNotifierJavascriptChannel
        },
        javascriptMode: JavascriptMode.unrestricted,
      ),
    ),
    SliverToBoxAdapter(
        child: Container(
          height: 300,
          color: Colors.green,
          child: const Center(
            child: Text(
              'Footer',
              style: TextStyle(color: Colors.white),
            ),
          ),
        ),
    ),
  ],
);

Complex Demo

Complex Demo

image

extended_sliver's People

Contributors

alexv525 avatar zmtzawqlp avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

extended_sliver's Issues

【bug!!】ExtendSliverAppBar嵌套PageView时,会重建

Content

ExtendedSliverAppbar(
leading: Row(children: [
Visibility(
child: InkWell(
child: Container(
child: Image(
image: AssetImage(
'res/images/idee536ecd91c3436f94a19bbb2fb5f133.png'),
width: 30.0,
height: 30.0,
fit: BoxFit.fill,
),
margin: EdgeInsets.only(left: 16.0),
),
onTap: () {
ActionAssetImage_984c8ff982174315a305c926987f5335()
.onTap(
context,
);
},
),
visible: true,
),
SizedBox(width: 45.0),
]),
title: Obx(() {
return Text(
vm.headerTitle.value,
overflow: TextOverflow.ellipsis,
style: TextStyle(
fontSize: 18.0,
fontWeight: FontWeight.w700,
color: Color(0xff1f1f1f),
),
);
}),
background: AspectRatio(
aspectRatio: 375 / 281,
child: EasyRefresh(
controller: vm.refreshController,
child: Stack(
alignment: AlignmentDirectional.bottomEnd,
children: [
Obx(() {
return PageView(
children:
_build1d6dc7c0c2764a5090ebe6702a68d105PageViewChildren(
context,
),
controller: vm.bannerController,
onPageChanged: (pageIndex) {
ActionPageView_1d6dc7c0c2764a5090ebe6702a68d105()
.onPageChanged(context, pageIndex);
},
);
}),
Obx(() {
return Visibility(
child: Container(
child: Obx(() {
return ToggleSwitch(
initialLabelIndex: vm.pageViewPosition.value,
minWidth: 50.0,
minHeight: 18.0,
cornerRadius: 14.0,
radiusStyle: true,
inactiveBgColor: Color(0x80e0e0e0),
inactiveFgColor: Color(0xff1f1f1f),
activeFgColor: Color(0xffffffff),
fontSize: 12.0,
activeBgColor: [Color(0xffff6644)],
labels: [
'直播',
'图片',
],
onToggle: (toggleIndex) {
ActionToggleSwitch_9ea5049cd0d74da0b1046ee3e6fce0a0()
.onToggle(context, toggleIndex);
},
);
}),
margin: EdgeInsets.only(
right: 20.0,
bottom: 15.0,
),
),
visible: vm.showToggleSwitch.value,
);
}),
],
),
onLoad: () {
ActionRefresh_97927526f84646b1a8958b759320409a().onLoad(
context,
);
},
),
),
actions: Row(children: [
Container(
child: Image(
image: AssetImage(
'res/images/idb69528cd0292479ea5088ac9d3d77f60.png'),
width: 30.0,
height: 30.0,
fit: BoxFit.fill,
),
margin: EdgeInsets.only(right: 15.0),
),
Container(
child: Image(
image: AssetImage(
'res/images/id43e8a5b5ca234d6a8f4aeadbe026b301.png'),
width: 30.0,
height: 30.0,
fit: BoxFit.fill,
),
margin: EdgeInsets.only(right: 12.0),
),
]),
toolBarColor: Color(0xffffffff),
),

调用PageView的controller去改变页面时,会报异常:一个controller绑定到了多个PageView上,经检查是PageView重建了,用系统的SliverAppBar无此问题

title overflow when long string

Hi, thanks for package.
Could you please help me to fix my issue?
So when I set very long title text inside title widget, I'm getting overflow exception.

ExtendedSliverAppbar(
      mainAxisAlignment: MainAxisAlignment.start,
      title: Text(
              "Very long long long long long long title",
              overflow: TextOverflow.ellipsis,
              maxLines: 1,
              softWrap: false,
              textAlign: TextAlign.start,
            ),
...)

I also tried to use Row with flexible, but didn't help:

ExtendedSliverAppbar(
      mainAxisAlignment: MainAxisAlignment.start,
      title: Row(
        mainAxisSize: MainAxisSize.min,
        children: [
          Flexible(
            child: Text(
              "Very long long long long long long title",
              overflow: TextOverflow.ellipsis,
              maxLines: 1,
              softWrap: false,
            ),
          ),
        ],
      ),

What should I do, to give ellipsis behavior in Title?

[InAppWebViewExample] updateAcquireFence: Did not find frame.

Getting updateAcquireFence: Did not find frame in debugging log

E/FrameEvents(31705): updateAcquireFence: Did not find frame.
E/FrameEvents(31705): updateAcquireFence: Did not find frame.
E/FrameEvents(31705): updateAcquireFence: Did not find frame.

[✓] Flutter (Channel stable, 3.0.5, on macOS 12.5 21G72 darwin-arm, locale en-CN)
• Flutter version 3.0.5 at /Users/devorz/fvm/versions/3.0.5
• Upstream repository https://github.com/flutter/flutter.git
• Framework revision f1875d570e (5 weeks ago), 2022-07-13 11:24:16 -0700
• Engine revision e85ea0e79c
• Dart version 2.17.6
• DevTools version 2.12.2

centerTitle

  Row (
    mainAxisAlignment: mainAxisAlignment,
    crossAxisAlignment: crossAxisAlignment,
    children: <Widget>[
      leading ??
          const BackButton(
            onPressed: null,
          ),
      titleWidget,
      actions ?? Container(),
    ],
  );

改成

  Stack(
    alignment: Alignment.center,
    children: [
      Row (
        mainAxisAlignment: mainAxisAlignment,
        crossAxisAlignment: crossAxisAlignment,
        children: <Widget>[
          leading ??
              const BackButton(
                onPressed: null,
              ),
          const Spacer(),
          actions ?? Container(),
        ],
      ),
      titleWidget,
    ],
  );

才能让title居中,不然 两边不一样(指有leading没actions)就不是居中的了

ExtendedSliverAppbar centerTitle

Seem like the title always center, is that so?
Could yo please provide an option to align the title, and hide the back button in the next release? Thanks

[Bug] The phenomenon of sliding and shaking occurs in the "CustomiScrollView+WebView".

Version

extended_sliver 2.1.3

Platforms

Android

Device Model

huawei nova 6 android10

flutter info

[√] Flutter (Channel stable, 3.13.5, on Microsoft Windows [版本 10.0.19042.630], locale zh-CN)
    • Flutter version 3.13.5 on channel stable at D:\flutter\flutter                          
    • Upstream repository https://github.com/flutter/flutter/                                 
    • FLUTTER_GIT_URL = https://github.com/flutter/flutter/                                   
    • Framework revision 12fccda598 (30 hours ago), 2023-09-19 13:56:11 -0700                 
    • Engine revision bd986c5ed2                                                              
    • Dart version 3.1.2                                                                      
    • DevTools version 2.25.0                                                                 
    • Pub download mirror https://pub.flutter-io.cn
    • Flutter download mirror https://storage.flutter-io.cn

[√] Windows Version (Installed version of Windows is version 10 or higher)

[√] Android toolchain - develop for Android devices (Android SDK version 33.0.2)
    • Android SDK at D:\Android\sdk
    • Platform android-33, build-tools 33.0.2
    • ANDROID_HOME = D:\Android\sdk
    • ANDROID_SDK_ROOT = D:\Android\sdk
    • Java binary at: D:\Program Files\Android\android-studio2  2023  3.1\jbr\bin\java
    • Java version OpenJDK Runtime Environment (build 17.0.7+0-b2043.56-10353782)
    • All Android licenses accepted.

How to reproduce?

使用https://github.com/fluttercandies/extended_sliver/blob/master/example/lib/pages/nested/webview.dart进行测试,滑动列表到底部显示绿色的位置。滑动列表一定位置后,手指保持不动,此时列表出现抖动。

Usinghttps://github.com/fluttercandies/extended_sliver/blob/master/example/lib/pages/nested/webview.dartPerform the test by sliding the list to the bottom where it appears in green. After sliding the list to a certain position, keep your fingers still, and the list will shake.

60ff7a37b1e70a7d83d83c936a857a7f.mp4

Logs

No response

Example code (optional)

https://github.com/fluttercandies/extended_sliver/blob/master/example/lib/pages/nested/webview.dart

Contact

No response

SliverToNestedScrollBoxAdapter, webview disappear on keyboard input open

I'm using part of the code from the example
https://github.com/fluttercandies/extended_sliver/blob/master/example/lib/pages/nested/webview.dart

When I click on an editable field of the Webview, the complet view disappear, do you know why ?

import 'dart:io';
import 'dart:ui';

import 'package:extended_sliver/extended_sliver.dart';
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';

class NestedWebview extends StatelessWidget {
  NestedWebview({
    required this.url,
    Key? key,
  })  : nestedWebviewController = NestedWebviewController(url),
        super(key: key);

  final String url;
  final NestedWebviewController nestedWebviewController;

  final ScrollController scrollController = ScrollController();

  @override
  Widget build(BuildContext context) {
    return CustomScrollView(
      primary: false,
      shrinkWrap: true,
      controller: scrollController,
      slivers: <Widget>[
        ValueListenableBuilder<double>(
          valueListenable: nestedWebviewController.scrollHeightNotifier,
          builder: (
            BuildContext context,
            double scrollHeight,
            Widget? child,
          ) {
            return SliverToNestedScrollBoxAdapter(
              childExtent: scrollHeight,
              onScrollOffsetChanged: (double scrollOffset) {
                double y = scrollOffset;
                if (Platform.isAndroid) {
                  // https://github.com/flutter/flutter/issues/75841
                  y *= window.devicePixelRatio;
                }
                nestedWebviewController.webviewController
                    ?.scrollTo(0, y.ceil());
              },
              child: child,
            );
          },
          child: WebView(
            initialUrl: nestedWebviewController.initialUrl,
            onPageStarted: nestedWebviewController.onPageStarted,
            onPageFinished: nestedWebviewController.onPageFinished,
            onWebResourceError: nestedWebviewController.onWebResourceError,
            onWebViewCreated: nestedWebviewController.onWebViewCreated,
            javascriptChannels: <JavascriptChannel>{
              nestedWebviewController.scrollHeightNotifierJavascriptChannel
            },
            javascriptMode: JavascriptMode.unrestricted,
          ),
        ),
      ],
    );
  }
}

class NestedWebviewController {
  NestedWebviewController(this.initialUrl);

  final String initialUrl;

  WebViewController? _webviewController;

  WebViewController? get webviewController => _webviewController;

  ValueNotifier<double> scrollHeightNotifier = ValueNotifier<double>(1);
  ValueNotifier<WebViewStatus> webViewStatusNotifier =
      ValueNotifier<WebViewStatus>(WebViewStatus.loading);

  void onWebViewCreated(WebViewController controller) {
    _webviewController = controller;
  }

  void onPageStarted(String url) {
    if (url == initialUrl ||
        webViewStatusNotifier.value == WebViewStatus.failed) {
      webViewStatusNotifier.value = WebViewStatus.loading;
    }
  }

  void onPageFinished(String url) {
    if (webViewStatusNotifier.value != WebViewStatus.failed) {
      _webviewController?.runJavascript(scrollHeightJs);
    }
  }

  void onWebResourceError(WebResourceError error) {
    webViewStatusNotifier.value = WebViewStatus.failed;
  }

  JavascriptChannel get scrollHeightNotifierJavascriptChannel =>
      JavascriptChannel(
        name: 'ScrollHeightNotifier',
        onMessageReceived: (JavascriptMessage message) {
          final String msg = message.message;
          final double? height = double.tryParse(msg);
          if (height != null) {
            scrollHeightNotifier.value = height;
            webViewStatusNotifier.value = WebViewStatus.completed;
          }
        },
      );
}

enum WebViewStatus {
  loading,
  failed,
  completed,
}

const String scrollHeightJs = '''(function() {
  var height = 0;
  var notifier = window.ScrollHeightNotifier || window.webkit.messageHandlers.ScrollHeightNotifier;
  if (!notifier) return;

  function checkAndNotify() {
    var curr = document.body.scrollHeight;
    if (curr !== height) {
      height = curr;
      notifier.postMessage(height.toString());
    }
  }

  var timer;
  var ob;
  if (window.ResizeObserver) {
    ob = new ResizeObserver(checkAndNotify);
    ob.observe(document.body);
  } else {
    timer = setTimeout(checkAndNotify, 200);
  }
  window.onbeforeunload = function() {
    ob && ob.disconnect();
    timer && clearTimeout(timer);
  };
})();''';

Simple demos -> SliverAppbar throw a exception

I got this exception as running the example.

Exception has occurred.
FlutterError (The maxExtent for this RenderSliverPinnedPersistentHeader is less than its minExtent.
The specified maxExtent was: 0.0
The specified minExtent was: 80.0)

Run the example, and click "1. Simple", then click "3. SliverAppbar"

Env:

  • Flutter 2.8.1
  • macOS 12.2, Apple M1 Max
  • Android Emulator, API 32

SliverGeometry is not valid: The "layoutExtent" exceeds the "paintExtent"

When I scroll up/down couple of times that happens,
Seems to be a rounding error.

If I comment layoutExtent in line 74 lib/src/rendering.dart so that it uses paintExtent instead the issue seems solved. No more errors and everything seems to work fine for me.

geometry = SliverGeometry(
      scrollExtent: maxExtent,
      paintOrigin: constraints.overlap,
      paintExtent: math.min(childExtent, effectiveRemainingPaintExtent),
      //layoutExtent: layoutExtent,
      maxPaintExtent: maxExtent,
      maxScrollObstructionExtent: minExtent,
      cacheExtent: layoutExtent > 0.0
          ? -constraints.cacheOrigin + layoutExtent
          : layoutExtent,
      hasVisualOverflow:
          true, // Conservatively say we do have overflow to avoid complexity.
    );

Here is couple examples:
The paintExtent is 74.6651785714286, but the layoutExtent is 74.66517857142861
The paintExtent is 148.74255952380966, but the layoutExtent is 148.7425595238097

The following assertion was thrown during performLayout():
SliverGeometry is not valid: The "layoutExtent" exceeds the "paintExtent".

The paintExtent is 74.6651785714286, but the layoutExtent is 74.66517857142861.

Maybe you have fallen prey to floating point rounding errors, and should explicitly apply the min() or max() functions, or the clamp() method, to the layoutExtent?

The RenderSliver that returned the offending geometry was: RenderSliverPinnedPersistentHeader#942fa relayoutBoundary=up1 NEEDS-LAYOUT NEEDS-PAINT
...  needs compositing
...  parentData: paintOffset=Offset(0.0, 0.0) (can use size)
...  constraints: SliverConstraints(AxisDirection.down, GrowthDirection.forward, ScrollDirection.reverse, scrollOffset: 85.3, remainingPaintExtent: 547.4, crossAxisExtent: 411.4, crossAxisDirection: AxisDirection.right, viewportMainAxisExtent: 547.4, remainingCacheExtent: 882.8, cacheOrigin: -85.3)
...  geometry: SliverGeometry(scrollExtent: 160.0, paintExtent: 74.7, layoutExtent: 74.7, maxPaintExtent: 160.0, hasVisualOverflow: true, cacheExtent: 160.0)
...    scrollExtent: 160.0
...    paintExtent: 74.7
...    layoutExtent: 74.7
...    maxPaintExtent: 160.0
...    hasVisualOverflow: true
...    cacheExtent: 160.0
...  child position: 0.0
The relevant error-causing widget was: 
  SliverPinnedPersistentHeader SliverPinnedPersistentHeader```



```PS C:\Projekt\app> flutter doctor -v
[√] Flutter (Channel stable, 3.0.0, on Microsoft Windows [Version 10.0.19043.1706], locale sv-SE)
    • Flutter version 3.0.0 at C:\Projekt\flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision ee4e09cce0 (4 days ago), 2022-05-09 16:45:18 -0700
    • Engine revision d1b9a6938a
    • Dart version 2.17.0
    • DevTools version 2.12.2

[√] Android toolchain - develop for Android devices (Android SDK version 33.0.0-rc2)
    • Android SDK at C:\Users\blah\AppData\Local\Android\sdk
    • Platform android-31, build-tools 33.0.0-rc2
    • Java binary at: C:\Program Files\Android\Android Studio\jre\bin\java
    • Java version openjdk version "11.0.12" 2021-07-20
    • All Android licenses accepted.

[√] Chrome - develop for the web
    • Chrome at C:\Program Files\Google\Chrome\Application\chrome.exe

[X] Visual Studio - develop for Windows
    X Visual Studio not installed; this is necessary for Windows development.
      Download at https://visualstudio.microsoft.com/downloads/.
      Please install the "Desktop development with C++" workload, including all of its default components

[√] Android Studio (version 2021.2)
    • Android Studio at C:\Program Files\Android\Android Studio
    • Flutter plugin can be installed from:
       https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
       https://plugins.jetbrains.com/plugin/6351-dart
    • Java version openjdk version "11.0.12" 2021-07-20

[√] IntelliJ IDEA Community Edition (version 2021.3)
    • IntelliJ at C:\Program Files\JetBrains\IntelliJ IDEA Community Edition
    • Flutter plugin can be installed from:
       https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
       https://plugins.jetbrains.com/plugin/6351-dart

[√] Connected device (4 available)
    • sdk gphone64 x86 64 (mobile) • emulator-5554 • android-x64    • Android 12 (API 31) (emulator)
    • Windows (desktop)            • windows       • windows-x64    • Microsoft Windows [Version 10.0.19043.1706]
    • Chrome (web)                 • chrome        • web-javascript • Google Chrome 101.0.4951.54
    • Edge (web)                   • edge          • web-javascript • Microsoft Edge 101.0.1210.32

[√] HTTP Host Availability
    • All required HTTP hosts are available

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.