milestone 23 s3: move srOnly into the shared style vocabulary
This commit is contained in:
@@ -1,9 +1,19 @@
|
||||
# nxdns
|
||||
|
||||
A self-hosted DNS sinkhole for a household LAN, written in Zig 0.16. One
|
||||
static musl binary, SQLite for state, a Raspberry Pi 5 as the reference
|
||||
target. It answers your network's DNS, blocks what you tell it to, and shows
|
||||
you what asked for what.
|
||||
nxdns is a DNS sinkhole for your LAN. It blocks the names you do not want, and
|
||||
forwards the rest over an encrypted connection.
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
devices["Your devices"] -- "DNS query" --> nxdns["nxdns"]
|
||||
nxdns -- "answer" --> devices
|
||||
nxdns -- "allowed" --> upstream["Upstream resolvers<br/>DoH / DoT"]
|
||||
upstream -- "answer" --> nxdns
|
||||
nxdns -- "blocked" --> sink["0.0.0.0 / NXDOMAIN"]
|
||||
```
|
||||
|
||||
One static Zig binary. SQLite holds the state and the query log, which the web
|
||||
UI, the REST API and `/metrics` read.
|
||||
|
||||
## Features
|
||||
|
||||
|
||||
@@ -79,17 +79,6 @@ const styles = stylex.create({
|
||||
dimWhenDisabled: {
|
||||
opacity: { default: 1, ":disabled": 0.5 },
|
||||
},
|
||||
srOnly: {
|
||||
position: "absolute",
|
||||
width: 1,
|
||||
height: 1,
|
||||
padding: 0,
|
||||
margin: -1,
|
||||
overflow: "hidden",
|
||||
clipPath: "inset(50%)",
|
||||
whiteSpace: "nowrap",
|
||||
borderWidth: 0,
|
||||
},
|
||||
});
|
||||
|
||||
export default function BlocklistsPage() {
|
||||
@@ -170,7 +159,7 @@ export default function BlocklistsPage() {
|
||||
<th {...stylex.props(shared.th)}>Skipped regex</th>
|
||||
<th {...stylex.props(shared.th)}>Last updated</th>
|
||||
<th {...stylex.props(shared.th)}>
|
||||
<span {...stylex.props(styles.srOnly)}>Actions</span>
|
||||
<span {...stylex.props(shared.srOnly)}>Actions</span>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
@@ -96,17 +96,6 @@ const styles = stylex.create({
|
||||
* The accessible name of the actions column, kept out of the visual table
|
||||
* without leaving the accessibility tree.
|
||||
*/
|
||||
srOnly: {
|
||||
position: "absolute",
|
||||
width: 1,
|
||||
height: 1,
|
||||
padding: 0,
|
||||
margin: -1,
|
||||
overflow: "hidden",
|
||||
clipPath: "inset(50%)",
|
||||
whiteSpace: "nowrap",
|
||||
borderWidth: 0,
|
||||
},
|
||||
});
|
||||
|
||||
export default function ClientsPage() {
|
||||
@@ -138,7 +127,7 @@ export default function ClientsPage() {
|
||||
<th {...stylex.props(styles.cell)}>First seen</th>
|
||||
<th {...stylex.props(styles.cell)}>Last seen</th>
|
||||
<th {...stylex.props(styles.cell)}>
|
||||
<span {...stylex.props(styles.srOnly)}>Actions</span>
|
||||
<span {...stylex.props(shared.srOnly)}>Actions</span>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
@@ -91,17 +91,6 @@ const styles = stylex.create({
|
||||
dimWhenDisabled: {
|
||||
opacity: { default: 1, ":disabled": 0.5 },
|
||||
},
|
||||
srOnly: {
|
||||
position: "absolute",
|
||||
width: 1,
|
||||
height: 1,
|
||||
padding: 0,
|
||||
margin: -1,
|
||||
overflow: "hidden",
|
||||
clipPath: "inset(50%)",
|
||||
whiteSpace: "nowrap",
|
||||
borderWidth: 0,
|
||||
},
|
||||
});
|
||||
|
||||
function RecordForm({
|
||||
@@ -268,7 +257,7 @@ export default function RecordsTab() {
|
||||
TTL
|
||||
</th>
|
||||
<th scope="col" {...stylex.props(styles.headCellLast)}>
|
||||
<span {...stylex.props(styles.srOnly)}>Actions</span>
|
||||
<span {...stylex.props(shared.srOnly)}>Actions</span>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
@@ -87,17 +87,6 @@ const styles = stylex.create({
|
||||
dimWhenDisabled: {
|
||||
opacity: { default: 1, ":disabled": 0.5 },
|
||||
},
|
||||
srOnly: {
|
||||
position: "absolute",
|
||||
width: 1,
|
||||
height: 1,
|
||||
padding: 0,
|
||||
margin: -1,
|
||||
overflow: "hidden",
|
||||
clipPath: "inset(50%)",
|
||||
whiteSpace: "nowrap",
|
||||
borderWidth: 0,
|
||||
},
|
||||
});
|
||||
|
||||
function ZoneForm({
|
||||
@@ -232,7 +221,7 @@ export default function ZonesTab() {
|
||||
Resolver
|
||||
</th>
|
||||
<th scope="col" {...stylex.props(styles.headCellLast)}>
|
||||
<span {...stylex.props(styles.srOnly)}>Actions</span>
|
||||
<span {...stylex.props(shared.srOnly)}>Actions</span>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
@@ -78,17 +78,6 @@ const styles = stylex.create({
|
||||
submitRow: {
|
||||
display: "flex",
|
||||
},
|
||||
srOnly: {
|
||||
position: "absolute",
|
||||
width: 1,
|
||||
height: 1,
|
||||
padding: 0,
|
||||
margin: -1,
|
||||
overflow: "hidden",
|
||||
clipPath: "inset(50%)",
|
||||
whiteSpace: "nowrap",
|
||||
borderWidth: 0,
|
||||
},
|
||||
});
|
||||
|
||||
export default function RulesPage() {
|
||||
@@ -137,7 +126,7 @@ export default function RulesPage() {
|
||||
<th {...stylex.props(shared.th)}>Group</th>
|
||||
<th {...stylex.props(shared.th)}>Created</th>
|
||||
<th {...stylex.props(shared.th)}>
|
||||
<span {...stylex.props(styles.srOnly)}>Actions</span>
|
||||
<span {...stylex.props(shared.srOnly)}>Actions</span>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
@@ -53,17 +53,6 @@ const styles = stylex.create({
|
||||
dimWhenDisabled: {
|
||||
opacity: { default: 1, ":disabled": 0.5 },
|
||||
},
|
||||
srOnly: {
|
||||
position: "absolute",
|
||||
width: 1,
|
||||
height: 1,
|
||||
padding: 0,
|
||||
margin: -1,
|
||||
overflow: "hidden",
|
||||
clipPath: "inset(50%)",
|
||||
whiteSpace: "nowrap",
|
||||
borderWidth: 0,
|
||||
},
|
||||
});
|
||||
|
||||
export default function UpstreamsPage() {
|
||||
@@ -127,7 +116,7 @@ export default function UpstreamsPage() {
|
||||
<th {...stylex.props(shared.th)}>Enabled</th>
|
||||
<th {...stylex.props(shared.th)}>TLS name</th>
|
||||
<th {...stylex.props(shared.th)}>
|
||||
<span {...stylex.props(styles.srOnly)}>Actions</span>
|
||||
<span {...stylex.props(shared.srOnly)}>Actions</span>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
@@ -151,6 +151,19 @@ export const styles = stylex.create({
|
||||
color: colors.dangerText,
|
||||
},
|
||||
|
||||
/** Visible to a screen reader only; the element keeps its place in the a11y tree. */
|
||||
srOnly: {
|
||||
position: "absolute",
|
||||
width: 1,
|
||||
height: 1,
|
||||
padding: 0,
|
||||
margin: -1,
|
||||
overflow: "hidden",
|
||||
clipPath: "inset(50%)",
|
||||
whiteSpace: "nowrap",
|
||||
borderWidth: 0,
|
||||
},
|
||||
|
||||
th: {
|
||||
borderBottomWidth: 1,
|
||||
borderBottomStyle: "solid",
|
||||
|
||||
Reference in New Issue
Block a user