Coder Social home page Coder Social logo

crispy-tailwind's Introduction

django-crispy-forms

http://codecov.io/github/django-crispy-forms/django-crispy-forms/coverage.svg?branch=main

The best way to have Django DRY forms. Build programmatic reusable layouts out of components, having full control of the rendered HTML without writing HTML in templates. All this without breaking the standard way of doing things in Django, so it plays nice with any other form application.

django-crispy-forms supports Django 4.2+ with Python 3.8+.

Looking for Bootstrap 5 support? See the crispy-bootstrap5 package.

The application mainly provides:

  • A filter named |crispy that will render elegant div based forms. Think of it as the built-in methods: as_table, as_ul and as_p. You cannot tune up the output, but it is easy to start using it.
  • A tag named {% crispy %} that will render a form based on your configuration and specific layout setup. This gives you amazing power without much hassle, helping you save tons of time.

Django-crispy-forms supports several frontend frameworks, such as Twitter Bootstrap (versions 2, 3, and 4), tailwind, Bulma and Foundation. You can also easily adapt your custom company's one, creating your own, see the docs for more information. You can easily switch among them using CRISPY_TEMPLATE_PACK setting variable.

Authors

django-crispy-forms is the new django-uni-form. django-uni-form was an application created by Daniel Greenfeld that I led since version 0.8.0. The name change tries to better explain the purpose of the application, which changed in a significant way since its birth.

If you are upgrading from django-uni-form, we have instructions for helping you.

Example

This is a teaser of what you can do with latest django-crispy-forms. Find here the gist for generating this form:

http://i.imgur.com/LSREg.png

Documentation

For extensive documentation see the docs folder or read it on readthedocs

Special thanks

  • To Daniel Feldroy (@pydanny) for his support, time and the opportunity given to me to do this.
  • The name of the project was suggested by the fantastic Audrey Feldroy (@audreyfeldroy)
  • To Kenneth Love (@kennethlove) for creating django-uni-form-contrib from which bootstrap template pack was started.

crispy-tailwind's People

Contributors

adamchainz avatar areski avatar bittermandel avatar blasferna avatar botpub avatar chriswedgwood avatar gigincg avatar gitron avatar grundleborg avatar io2 avatar justinmayer avatar shabinesh avatar smithdc1 avatar thutmose3 avatar yedpodtrzitko 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  avatar  avatar  avatar  avatar  avatar  avatar  avatar

crispy-tailwind's Issues

Run Linters in Pipeline / Actions

Hi @smithdc1 and @carltongibson

am I wrong or don't we validate the linting rules in our CI pipeline?

grafik

There is something in the per-pyhton-version setup but apparently, it's not being executed.

Futhermore, linting should / can be checked version-independly, right?

What's your take on this?

Best
Ronny

Not working for latest release django-crispy-form

crispy_forms.compatibility.py has been removed in versions of django-crispy-forms >1.11.1, thus giving the following error:

ImportError raised when trying to load 'crispy_tailwind.templatetags.tailwind_filters': No module named 'crispy_forms.compatibility'

Incorrect rendering of optgroups

Hi There,

I'm having an issue where select dropdowns with optgroups are not rendering out correctly at all and can't seem to find a way for it to render out correctly either

An example can be found here in the Django docs for what I mean by optgroups

I've also attached two images below of what is looks like with {% crispy form %} and without
with crispy
without crispy

If you need any more information please reach out to me at anytime

CSS classes not found by tailwind watcher

Hi there!

I'm a huge fan of crispy-forms since about 2012. I'm trying out Tailwind right now and was super delighted to find this template pack.

What I don't get: Tailwind automatically searches for class usages. If a class is not used, it's not being delivered. Since all the tailwind classes are hidden away in this package, how can I make tailwind understand that I need them? ๐Ÿ˜…

Currently, the results are as expected: The form gets rendered correctly HTML-wise but has no CSS. When I manually copy all templates to my source code, the classes are being found and the CSS is there. But that's obviously not a neat solution.

I found this post but first I don't want to disable JIT and secondly, I can't since tailwind v3.

I went throught the docs and issues but couldn't find a single reference to this major problem (that everybody has to have? ๐Ÿค”).

What am I missing?

Thx a lot!
Ronny

Problems with django-smart-select

Additional class=chained-fk and data-* attributes from the widget ChainedSelect (https://github.com/jazzband/django-smart-selects/blob/master/smart_selects/widgets.py#L54) does not render. They're needed attributes so bindfields.js would work properly.

Tried @Thutmose3's branch (#163) as well, with no luck.


Here's what I understand so far:

  1. ChainedSelect widget generates attributes (class=chained-fk, and some data-attributes) that's later picked-up by the jQuery functions of django-smart-select.
  2. Widget attributes for some reason does not render in the template when using django-crispy-forms + tailwind.
  3. Found out that attributes are generated differently on <select>: field|build_attrs vs {% include "tailwind/layout/attrs.html" ... %}.
  4. Replaced tailwind/layout/select.html so that it uses Django's original template (plus some modifications so that variables match), and additional attributes are still not rendering.

Where could the attributes from ChainedSelect have gone?

cc: @RJAA-25

css_container is missing from context in widgets with custom templates e.g. CheckboxMultipleSelect

I'm not sure if there's a bug here, or if I just don't fully understand what CSSContainer is / how it is supposed to work. When rendering a widget such as CheckboxMultipleSelect which has it's own custom template which does not use the tailwind_field template tag to render the field, the CSS classes are taken from the css_container object. However, this does not appear to be present in the context, so setting the default classes in CrispyTailwindFieldNode.default_styles of tailwind_field.py has no effect. I'm not sure whether I'm expecting the wrong thing to happen here, or whether these widgets with custom templates are not even expected to work yet. Any pointers would be most welcome, as I am trying to get this and a few other widgets working properly for a project, as well as sending PRs to this repo with any fixes and/or missing functionality to arise from this.

Invite Ronny Vedrilla to team.

I'd like to propose adding Ronny @GitRon to the team for crispy-tailwind.

I can vouch for Ronny personally. He's a lovely person. And crispy-tailwind could do with more bandwidth.

@smithdc1 I don't believe you're actively using tailwind right? Whilst I am, I'm not currently using crispy for that (as part of my experiment into What Now? given the Django 4.x+ forms changes). Ronny is going both, and is well placed to take the lead here.

Whilst we're here, I'd state my thoughts on the scope/goals:

  • Keep it small โ€” it's a demonstration of what you can do, and a starting point, not an always solution.
  • Link to and document other things in How-Tos
  • Encourage folks to override what they want to in their own projects.

Less opiniated defaults

Hello,
I played a little bit with your app today and I think the default classes added to elements are a little too opiniated. For example the select field add a SVG handle and multiple classes for the colors of the border or the text.
I usually style my inputs starting from this @tailwindcss/forms as recommended by the authors of TailwindCSS. It doesn't play well with your templates. The select element get multiple handles for example.
One solution would be to override the templates for these elements, but it is a lot of work. Would it be possible to add these default styles through the CSSContainer for example? Or provide another way to start from less opiniated templates?
Thanks for your work!
Cedric

How do I implement the dark theme for Tailwind styling?

I am struggling to figure out how to implement specific styles for a crispy form. I'm new to crispy forms and my site is essentially dark theme only. Everything I render with crispy tailwind is light mode. How do I default to dark mode?

select_option.html inherits parent attributes

There is an option to enable and disable parent attributes for options at ChoiceWidget:

image

https://github.com/django/django/blob/5b3d3e400ab9334ba429ca360c9818c6dfc3a51b/django/forms/widgets.py#L585

So select_option.html doesn't take this into account.

One of the solutions is to use field.field.widget.option_inherits_attrs:

<option value="{{ value|stringformat:'s' }}" {% if field.field.widget.option_inherits_attrs %} {{ field.field.widget.attrs|flatatt }}{% endif %}{% if field.value|stringformat:'s' == value|stringformat:'s' %} selected{% endif %}>{{ label }}</option>

Workflow/Configuration for purge

Hi thanks for the project

I have an issue where I am using the purge option for my templates

module.exports = {
  purge: {

   content: ['./**/templates/**/*.html'],
   safelist: ['underline','cursor-pointer','grid-cols-3','gap-1','grid-cols-2'],

},

The css for the templates is not being applied when I deploy to prod
If I am using the crispy template pack fields do I just need to add a path to my content that will be for the path to the templates in site packages?

PyPI release

Heya there

I know this project is pretty young, but is there a chance of a pypi release, in line with the readme?

$ pip3 install crispy_tailwind

ERROR: Could not find a version that satisfies the requirement crispy_tailwind (from versions: none)
ERROR: No matching distribution found for crispy_tailwind

I know it's possible to -e the git URL in requirements.txt, but in a Docker build that results in the dependency being installed at the user, not system level, making it effectively invisible to the app.

Cheers!

checkbox before label

Hello, How can I implement a checkbox for a BooleanField before its label.
For example :

  • Remember me

For now, I have the label and then the checkbox input on a new line.
I have got :
Remember me

  • .

Thank you

To Do

Hi @carltongibson @bittermandel

I've pushed an initial commit based upon the pull request to django-crispy-forms master from last week. It's not much more than a POC at the moment, with the current tests passing.

Much work to be done; here are my current thoughts. This won't be a complete list but is enough to be getting on with for now - and probably we can get an inital release out before completing all of them.

EDIT: I've updated the below to split into sections to give some sort of percieved importance. I'll keep this list live for now.

Completed

  • Template imports - needs to be {% load tailwind_field %}
  • Setup GitHub actions for testing, isort, black, flake8
  • Include a default rendering option (something like {{ form|crispy }})
  • Setup development environment with crispy-test-project
  • Add oppinionated rendering to |crispy
  • Add an example image to README
  • code coverage + template coverage? (seems to be a bug with codecov, see PR)
  • GH Action - let's try and cache the dependencies to stop pulling all the dependencies every time. e.g. Django get's downloaded 14 times for every pull request that is merged = circa.105mb. Note: cache is 41mb per run (500mb for a merged PR?)
  • Docs why are images not showing (do we 'just' need to use RTD?). Note: Img files need to be lower case.
  • Should we publish something to PyPI now to get the name?
  • Custom objects - e.g. prepend/postpend
  • Find out why codecov went missing again. (It's reporting https://codecov.io/gh/django-crispy-forms/crispy-tailwind, but it's not commenting on PRs any more)
  • Non form errors (e.g. passwords do not match?)

Sooner โ„ข๏ธ

  • Review project strucutre - can someone review how I've setup the licence, setup.py etc?
  • Add more tests for layout
  • Add test for Field layout object
  • Docs
  • Fix flake8 - we're running well over on line length. Also why isn't it failing!?

Later

  • What to do about radio / checkbox
  • Put tests into more logical structure.
  • Put note on django-crispy-forms that this template pack exists
  • Review to do list items I've left in the code
  • Tidy up code base
  • Review GH Actions - are they running as expected?
  • Refactor field / label class when using crispy filter. (don't need to add classes to tailwind_filters - can we remove this file?!)

Is this project dead?

There are so many PR that fixes some of the bugs in this package, but it is not merged

Improve readme

Improve readme. We can do much more than only |crispy

Override Default Input Styles

For stacked forms the inputs in the Field attribute need to take in custom css styles. I noticed that the base_inputs are not overridden for this instance. It would also be nice to get rid of the default mb-3 when custom styles are needed.

Screen Shot 2020-10-11 at 11 16 39 AM

Screen Shot 2020-10-11 at 11 17 03 AM

Dropdown Empty

Hello,

I'am using this form class to populate an dropdown list. My problem the dropdown is empty

class LeadModelForm(forms.ModelForm):
class Meta:
model = InstaProfile
fields = fields = 'all'
choices = Category.objects.all().values_list('name','name')
choice_list = []

    for item in choices:
        choice_list.append(item)

        

    widgets ={

        'category': forms.Select(choices=choice_list,attrs={'class': 'form-select'}),

    }

If a i remove the crispy filter on my html template file is working

Any idea ?

Thank you

Greg

#Enhancements# Support for Dark mode + Capitalize field label

Hello,
Since I've just heard about this repository and i'm super enthusiastic about it I thought of two enhancements to it if they're not already planned :

  • Support for dark mode with reverses values (ex text-gray-700 dark:text-white / text-red-700 dark text-red-400.
  • The second is to capitalise fields' labels i don't know why but they seem weird to me in lowercase.

I could work on these if someone would navigate me on how to edit the templates because i read the django-crispy-forms documentation about it and i didn't understand a single word.

Set label_class or field_class on as_crispy_field

Hi,

I'm trying to figure out if it's possible to set the field_class when using as_crispy_field, for instance when calling the following:
{{ form.field|as_crispy_field:"tailwind" }}

Reference to as_crispy_field in the code:

def as_crispy_field(field, template_pack=TEMPLATE_PACK, label_class="", field_class=""):

as_crispy_field is a django filter, so according to django documentation it should not be possible to pass multi arguments, which only work with template tag.

As the method as_crispy_field has those 2 arguments in the function definition, maybe I'm missing something.
Any pointer would be appreciated.

form select fields lose their values if form is returned with an error.

When using any of the formset_factorys to generate multiple forms, the select fields lose their values if the form is returned with an error.

This happens because the template renders field.name instead of field.html_name.

field.name is the same for all forms, field.html_name is unique for each form instance

"selected"-Option is missing @SelectMultiple

My Model:

class Service(models.Model):
    staff = models.ManyToManyField(
            User,
            blank=True,
    )

My Form:

class ServiceUpdateForm(forms.ModelForm):
    class Meta:
        model=Service
        exclude = []
        widgets = { 
                'staff': forms.SelectMultiple(
                    attrs={'multiple': 'multiple'}
                ),  
        }

In my template {{form}} generate this:

<select name="staff" multiple="" id="id_staff">
  <option value="1" selected="">name1</option>
  <option value="2" selected="">name2</option>
  <option value="3">name3</option>
</select>

With {{form|crispy}} django generate this:

<select class="bg-white focus:outline-none border border-gray-300 rounded-lg py-2 px-4 block w-full appearance-none leading-normal text-gray-700" name="staff" multiple="multiple"> 
  <option value="1" multiple="multiple">name1</option> 
  <option value="2" multiple="multiple">name2</option> 
  <option value="3" multiple="multiple">name3</option> 
</select>

|crispy not compatible with Django's custom form.Select create_option()

The functionality

Django forms give the ability to override the create_option() function for custom Select fields.

You can use this to set custom attributes for each select option.

The function is triggered when the form is called in the template. So if we have {{ form.custom_select_field }} in the html file, create_option is called when the file is rendered. This works fine with the above syntax, but when using {{ form.field|as_crispy_field }} the create_option no longer executes. (Note: though I verified that the CustomSelect's __init__ method was still being called.

Source code

requirements.txt

python = "^3.9"
django = "^4.2.1"
django-widget-tweaks = "^1.4.12"
django-crispy-forms = "^2.0"

forms.py

class RegionSelect(forms.Select):
    _region_map = None

    @property
    def region_map(self):
        if self._region_map is None:
            self._region_map = {r.id: r for r in Region.objects.all()}
        return self._region_map

    def create_option(
        self, name, value, label, selected, index, subindex=None, attrs=None
    ):
        option = super().create_option(
            name, value, label, selected, index, subindex, attrs
        )
        region = self.region_map.get(value)
        if region:
            option["attrs"]["label"] = region.name
            option["attrs"]["data-country-id"] = region.country_id
        return option


class AddressForm(forms.ModelForm):
    street = forms.CharField(
        max_length=255,
        required=False
    )
    city = forms.CharField(max_length=100, required=False)
    state = forms.ModelChoiceField(
        queryset=Region.objects.all(),
        required=False,
        widget=RegionSelect()
    )
    country = forms.ModelChoiceField(
        queryset=Country.objects.all(),
        required=False
    )
    postal_code = forms.CharField(max_length=20, required=False)

    class Meta:
        model = Address
        fields = "__all__"

form.html

{% extends 'main/base.html' %}
{% load static %}
{% load widget_tweaks %}
{% load tailwind_filters %}
{% load crispy_forms_tags %}

{% block content %}

<form class="rounded-xl bg-white p-5 shadow-lg shadow-gray-500/40 sm:p-10 sm:px-20"
      method="POST">
    {% csrf_token %}
    {{ form.street|as_crispy_field }}
    <div id="hidden_address_fields" class="hidden">
        <div class="grid grid-cols-1 sm:grid-cols-2 sm:gap-4">
            <div>{{ form.country|as_crispy_field }}</div>
            <div>{{ form.state }}</div>
        </div>
        {{ form.city|as_crispy_field }}
        {{ form.postal_code|as_crispy_field }}
    </div>
    <button type="submit" class="btn btn-primary">Submit</button>
</form>

{% endblock content %}

Notes

All the form fields render fine with the styling, but the custom select widget only works for {{ form.state }} without the as_crispy_field.

I put a print statement in RegionSelect.create_option() and confirmed that it never even executes when we use crispy.

This behavior is also true with {{ form }} working as expected, but {{ form|crispy }} causing RegionSelect.create_option() to not execute.

Error when following the contributing process

Looking to add a documentation PR I did the following:

forked and cloned
python -m venv venv
source ./venv/bin/activate
(venv) pip install -r requirements.txt

image

Looking at the requirements file there isn't any pinning.

Will get a working version and then pin?

Many to many field rendering

Hello,
I'm working on a project using many to many fields in model, and I would like to render it in the same way that the admin panel (filter_horizontaly) offer, but with a tailwind style, does someone already worked on such thing ?

Thank you guys !
Henri

crispy-tailwind CSS is not load to main CSS

I use Django-tailwind with crispy-tailwind but after rendering the form, input CSS is not extract to main.css. That's why input field don't apply CSS properly. How to extract crispy input CSS to main CSS when Django-tailwind compiling CSS.

[bug] checkboxmultipleselect is a radio

as per https://github.com/django/django/blob/main/django/forms/widgets.py#L839

unfortunately the widget inherits from radioselect which means that isinstance will return true an show a radio select due to the order in https://github.com/django-crispy-forms/crispy-tailwind/blob/main/crispy_tailwind/templates/tailwind/field.html#L20

as is demonstrated here

(Pdb) isinstance(form.fields.get('infrastructure').widget, forms.CheckboxSelectMultiple)
True
(Pdb) isinstance(form.fields.get('infrastructure').widget, forms.RadioSelect)
True

a working fix would be to test for the class name rather?

 form.fields.get('infrastructure').widget.__class__.__name__
'CheckboxSelectMultiple'

Form alerts look odd

Hello ,
Thank's for this repo i'm actually using it in a django app with tailwindcss v2 as my front end framework but i noticed that forms look kind of odd with alerts :
image
i also wanted to ask if the project is still maintained and if it's upgraded to tailwindcss v2.
Thank's in advance

DIV for select box not terminated

In templates/tailwind/field.html none of the divs are terminated (for release 1.0.1),

I think there's some mismatch between how you are doing it in the layout folder and in this template - I suspect it makes more sense to move all the closing DIVs back up to this file. In the select.html there is no </div> whereas I think in the radio and checkboxes there are.

crispy_field load tag

I'm seeing this error when using it:

_Compressing... Invalid template /usr/local/lib/python3.9/site-packages/crispy_tailwind/templates/tailwind/layout/inline_field.html: Invalid block tag on line 9: 'crispy_field', expected 'elif', 'else' or 'endif'. Did you forget to register or load this tag?

Invalid template /usr/local/lib/python3.9/site-packages/crispy_tailwind/templates/tailwind/layout/field_with_buttons.html: Invalid block tag on line 12: 'crispy_field'. Did you forget to register or load this tag?`_

Any pointers on how to fix this?

Release for django 4.0

Hi!

I see that there were some bug fixes for django 4.0 on the main branch. Is there a plan to create a release for this? Thanks!

Tailwind forms styling not applied correctly

Hi

I've installed tailwind, crispy_forms & crispy_tailwind but the form styling doesn't seem to be working and I get huge SVG arrow appearing underneath.

crispytailwind

settings.py

    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'tailwind',
        'theme',
        'crispy_forms',
        'crispy_tailwind',
        'accs',
        'user',
    ]
...
CRISPY_ALLOWED_TEMPLATE_PACKS = "tailwind"
CRISPY_TEMPLATE_PACK = "tailwind"
...

my_form_template.html

{% extends 'core/base.html' %}
{% load tailwind_filters %}

{% block content %}

   <div class="container mx-auto">
    <h2 class="text-lg text-gray-900 font-bold text-xl pt-4">Edit Payee</h2>
   <hr class="pt-4 border-gray-900">
   </div>
    <form action="" method="post">{% csrf_token %}
      {{ form|crispy }}
      <input class="text-base bg-transparent hover:bg-blue-400 text-blue-400 font-semibold hover:text-white py-2 px-4 border border-blue-400 hover:border-transparent rounded" type="submit" value="Update">
    </form>

{% endblock content %}

I've tried with/without the form tags and with/without {% load crispy_forms_tags %} - neither have any effect.
Any ideas what I'm missing?

Thanks

In ModelChoiceField 'selected'-Tag is missing, when ModelForm is invalid

Hello,

I have a model with at least two ForeignKey-ModelFields. Both fields are blank = False. I Use a Modelform and Crispy-Tailwind. If the Foreign-Fields in an object are assigned except one and you commit the form, the form will be invalid. The problem is, that in the next rendering of all ForeignFields the "selected"-HTML-tag are missing and so all Foreign-Fields are unselected. The problem does not occur without Crispy-Tailwind.

You can see the problem in my repository: https://github.com/datenrebell/bug_in_crispy_tailwind

I hope you can help me with this Issue.
Thanks.

Preappend / postappend etc

https://codepen.io/david_smith/pen/qBbdvRm

Here is my current workings on what this could look like. My aim is to make it fit with the default style of the other boxes. Seems ok. Will leave for a while and come back to it in a day or so with a fresh pair of eyes.

image

Edit: now it's blown the image up that big I'm slightly concerned about contrast.... ๐Ÿค”

Automate releases

Hi @carltongibson question on releases.

I used Simon W's cookie cutter for this template and he uses a GitHub action to publish releases to PyPI (you add a release on GH, and this triggers the workflow).

Part of me likes this as I'd rather have a system do it via a script than me manually doing it. To do this, I'd create a key for just this project and add it to the secrets. The only concern (and I dont think it is much) is it means anyone with commit access can add a release and push it to PyPI -- but only via the workflow.

I'm probably being a bit more agressive pushing new boundaries which may be too much...

If your happy I'll try it for this project.

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.