Implemented responsive tables, removed bootstrap

No need for all of bootstrap since we only need to style a few elements.

Implemented responsive table pattern from here:
https://css-tricks.com/responsive-data-tables/

Refs #16
pull/81/head
Simon Willison 2017-11-10 21:55:50 -08:00
rodzic 21c9c04310
commit 7d81083d40
8 zmienionych plików z 112 dodań i 57 usunięć

Wyświetl plik

@ -16,6 +16,7 @@ import time
from .utils import (
build_where_clauses,
CustomJSONEncoder,
escape_css_string,
InvalidSql,
path_from_row_pks,
path_with_added_args,
@ -443,6 +444,7 @@ class Datasette:
str(app_root / 'datasette' / 'templates')
])
)
self.jinja.add_env('escape_css_string', escape_css_string, 'filters')
app.add_route(IndexView.as_view(self), '/')
# TODO: /favicon.ico and /-/static/ deserve far-future cache expires
app.add_route(favicon, '/favicon.ico')

Wyświetl plik

@ -0,0 +1,54 @@
body {
margin: 0 1em;
font-family: "Helvetica Neue", sans-serif;
font-size: 1rem;
font-weight: 400;
line-height: 1.5;
color: #212529;
text-align: left;
background-color: #fff;
}
table {
border-collapse: collapse;
}
td {
border-top: 1px solid #ccc;
padding: 4px;
vertical-align: top;
}
th {
padding-right: 1em;
}
@media only screen and (max-width: 576px) {
/* Force table to not be like tables anymore */
table, thead, tbody, th, td, tr {
display: block;
}
/* Hide table headers (but not display: none;, for accessibility) */
thead tr {
position: absolute;
top: -9999px;
left: -9999px;
}
tr {
border: 1px solid #ccc;
margin-bottom: 1em;
}
td {
/* Behave like a "row" */
border: none;
border-bottom: 1px solid #eee;
padding: 0;
padding-left: 10%;
}
td:before {
display: block;
margin-left: -10%;
font-size: 0.8em;
}
}

File diff suppressed because one or more lines are too long

Wyświetl plik

@ -2,21 +2,17 @@
<html>
<head>
<title>{% block title %}{% endblock %}</title>
<link rel="stylesheet" href="/-/static/bootstrap-4.0.0-beta.2.min.css">
<style>
th {
text-align: left;
}
</style>
<link rel="stylesheet" href="/-/static/app.css">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
{% block extra_head %}{% endblock %}
</head>
<body>
<div class="container">
{% if error %}
<div style="padding: 1em; margin: 1em; border: 3px solid red;">{{ error }}</div>
{% endif %}
{% block content %}
{% endblock %}
</div>
</body>
</html>

Wyświetl plik

@ -7,17 +7,13 @@
<p><a href="/{{ database }}-{{ database_hash }}.db">download {{ database }}.db</a></p>
<style>
td {
vertical-align: top;
border-top: 1px solid #666;
padding: 2px 4px;
}
</style>
<table>
<tr>
{% for column in columns %}<th scope="col">{{ column }}</th>{% endfor %}
</tr>
<thead>
<tr>
{% for column in columns %}<th scope="col">{{ column }}</th>{% endfor %}
</tr>
</thead>
<tbody>
{% for row in rows %}
<tr>
{% for td in row %}
@ -31,5 +27,6 @@ td {
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}

Wyświetl plik

@ -2,34 +2,36 @@
{% block title %}{{ database }}: {{ table }}{% endblock %}
{% block extra_head %}
<style>
@media only screen and (max-width: 576px) {
{% for column in columns %}
td:nth-of-type({{ loop.index }}):before { content: "{{ column|escape_css_string }}"; }
{% endfor %}
}
</style>
{% endblock %}
{% block content %}
<h1 style="padding-left: 10px; border-left: 10px solid #{{ database_hash[:6] }}"><a href="/{{ database }}-{{ database_hash }}">{{ database }}</a></h1>
<h2><a href="/{{ database }}-{{ database_hash }}/{{ table }}">{{ table }}</a></h2>
<style>
td {
white-space: pre;
vertical-align: top;
border-top: 1px solid #666;
padding: 2px 4px;
}
</style>
<table>
<tr>
{% if primary_keys and row_link %}<th scope="col">Link</th>{% endif %}
{% for column in columns %}<th scope="col">{{ column }}</th>{% endfor %}
</tr>
<thead>
<tr>
{% for column in columns %}<th scope="col">{{ column }}</th>{% endfor %}
</tr>
</thead>
<tbody>
{% for row in rows %}
<tr>
{% if primary_keys and row_link %}
<td><a href="/{{ database }}-{{ database_hash }}/{{ table }}/{{ row_link(row) }}">{{ row_link(row) }}</a></td>
{% endif %}
{% for td in row %}
<td>{{ td }}</td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
{% if took_ms %}<small>Took {{ took_ms }}</small>{% endif %}
{% endblock %}

Wyświetl plik

@ -2,37 +2,41 @@
{% block title %}{{ database }}: {{ table }}{% endblock %}
{% block extra_head %}
<style>
@media only screen and (max-width: 576px) {
td:nth-of-type(1):before { content: "{% if use_rowid %}rowid{% else %}Link{% endif %}"; }
{% for column in display_columns %}
td:nth-of-type({{ loop.index + 1 }}):before { content: "{{ column|escape_css_string }}"; }
{% endfor %}
}
</style>
{% endblock %}
{% block content %}
<h1 style="padding-left: 10px; border-left: 10px solid #{{ database_hash[:6] }}"><a href="/{{ database }}-{{ database_hash }}">{{ database }}</a></h1>
<h2>{{ table }}{% if total_rows != None %} ({{ "{:,}".format(total_rows) }} total row{% if total_rows == 1 %}{% else %}s{% endif %} in this table){% endif %}</h2>
<style>
th {
padding-right: 1em;
}
td {
white-space: pre;
vertical-align: top;
border-top: 1px solid #666;
padding: 2px 4px;
}
</style>
<table>
<tr>
<th scope="col">{% if use_rowid %}rowid{% else %}Link{% endif %}</th>
{% for column in display_columns %}<th scope="col">{{ column }}</th>{% endfor %}
</tr>
<thead>
<tr>
<th scope="col">{% if use_rowid %}rowid{% else %}Link{% endif %}</th>
{% for column in display_columns %}<th scope="col">{{ column }}</th>{% endfor %}
</tr>
</thead>
<tbody>
{% for row in rows %}
<tr>
<td><a href="/{{ database }}-{{ database_hash }}/{{ table }}/{{ row_link(row) }}">{{ row_link(row) }}</a></td>
{% for td in row %}
{% if not use_rowid or (use_rowid and not loop.first) %}
<td>{{ td }}</td>
<td>{{ td or "&nbsp;" }}</td>
{% endif %}
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
{% if after_link %}
<p><a href="{{ after_link }}">Next page</a></p>

Wyświetl plik

@ -1,6 +1,7 @@
from contextlib import contextmanager
import base64
import json
import re
import sqlite3
import time
import urllib
@ -107,3 +108,10 @@ def path_with_added_args(request, args):
current = request.raw_args.copy()
current.update(args)
return request.path + '?' + urllib.parse.urlencode(current)
_css_re = re.compile(r'''['"\n\\]''')
def escape_css_string(s):
return _css_re.sub(lambda m: '\\{:X}'.format(ord(m.group())), s)