WIP rust-only css stack

This commit is contained in:
Tristan D. 2025-03-24 16:20:56 +01:00
parent c0b893f3e0
commit 9452bbccff
Signed by: tristan
SSH key fingerprint: SHA256:9oFM1J63hYWJjCnLG6C0fxBS15rwNcWwdQNMOHYKJ/4
5 changed files with 537 additions and 6 deletions

View file

@ -10,9 +10,17 @@
*** [X] "embd tmpl": Maud *** [X] "embd tmpl": Maud
*** [X] "html tmpl": minijinja *** [X] "html tmpl": minijinja
- only index yaml for now, test in app wether inline or external templates feel better - only index yaml for now, test in app wether inline or external templates feel better
*** [ ] CSS Basic *** [-] CSS Basic
- [X] UnoCSS - [X] UnoCSS
- bulma ?
- daisyUI? - daisyUI?
- pure rust ?
- encre-css
- grimoire_css
*** [-] Pure rust css stack
- rsass (sass in rust)
- encro-css (encor)
- lightning css (minify/bundle)
*** [ ] UI framework *** [ ] UI framework
- data* js basic - data* js basic
- data* axum sdk - data* axum sdk

View file

@ -0,0 +1,79 @@
#!/usr/bin/env rust-script
//! This is a regular crate doc comment, but it also contains a partial
//! Cargo manifest. Note the use of a *fenced* code block, and the
//! `cargo` "language".
//!
//! ```cargo
//! [dependencies]
//! encre-css = "0.14"
//! walkdir = "2"
//! ```
use std::{
collections::BTreeSet,
fs::{self, File},
io::{self, Write},
path::Path,
};
use encre_css::{utils::split_ignore_arbitrary, Config, Scanner};
use walkdir::WalkDir;
fn main() -> io::Result<()> {
// Define the source directory to scan
let source_dir = "./"; // Change this to your source directory
eprintln!("Scanning directory: {}", source_dir);
// Walk through the directory structure
let contents = WalkDir::new(source_dir)
.into_iter()
.filter_map(|e| e.ok())
.filter(|e| {
e.file_type().is_file()
&& e.path()
.extension()
.map_or(false, |ext| ext == "rs" || ext == "scss")
})
.map(|entry| {
let path = entry.path();
eprintln!("Processing file: {}", path.display());
let content = fs::read_to_string(path).expect("Failed to read");
let bx = Box::new(content);
let static_ref: &'static str = Box::leak(bx);
static_ref
});
let mut config = Config::default();
config.scanner = Scanner::from_fn(|val| {
let mut is_arbitrary = false;
val.split(|ch| {
// Escape all characters in arbitrary values prefixed by a dash (used to avoid
// ignoring values in, for example, JS arrays, given that they are defined
// using square brackets)
match ch {
'[' => {
is_arbitrary = true;
false
}
']' => {
is_arbitrary = false;
false
}
_ => {
ch == ' '
|| (!is_arbitrary
&& (ch == '.' || ch == '\'' || ch == '"' || ch == '`' || ch == '\n'))
}
}
})
.collect::<BTreeSet<&str>>()
});
let generated = encre_css::generate(contents, &config);
println!("{generated}");
Ok(())
}

View file

@ -104,16 +104,16 @@ async fn main() {
.merge(AssetsController::into_router(app_state.clone())) .merge(AssetsController::into_router(app_state.clone()))
.fallback_service(get(handle_404)) .fallback_service(get(handle_404))
.method_not_allowed_fallback(handle_405) .method_not_allowed_fallback(handle_405)
// High level logging of requests and responses
.layer(TraceLayer::new_for_http())
// Mark the `Authorization` request header as sensitive so it doesn't show in logs
.layer(SetSensitiveRequestHeadersLayer::new(once(http::header::AUTHORIZATION)))
// Compress responses // Compress responses
.layer(CompressionLayer::new()) .layer(CompressionLayer::new())
// Propagate `X-Request-Id`s from requests to responses // Propagate `X-Request-Id`s from requests to responses
.layer(PropagateHeaderLayer::new(http::HeaderName::from_static("x-request-id"))) .layer(PropagateHeaderLayer::new(http::HeaderName::from_static("x-request-id")))
// If the response has a known size set the `Content-Length` header // If the response has a known size set the `Content-Length` header
.layer(SetResponseHeaderLayer::overriding(http::header::CONTENT_TYPE, content_length_from_response)) .layer(SetResponseHeaderLayer::overriding(http::header::CONTENT_TYPE, content_length_from_response))
// High level logging of requests and responses
.layer(TraceLayer::new_for_http())
// Mark the `Authorization` request header as sensitive so it doesn't show in logs
.layer(SetSensitiveRequestHeadersLayer::new(once(http::header::AUTHORIZATION)))
.with_state(app_state); .with_state(app_state);
let _ = axum::serve(listener, router.into_make_service()).await; let _ = axum::serve(listener, router.into_make_service()).await;

443
darm_test/style/encr.css Normal file
View file

@ -0,0 +1,443 @@
*, ::before, ::after {
box-sizing: border-box;
border-width: 0;
border-style: solid;
border-color: currentColor;
}
::before, ::after {
--en-content: '';
}
html {
line-height: 1.5;
-webkit-text-size-adjust: 100%;
-moz-tab-size: 4;
tab-size: 4;
font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
}
body {
margin: 0;
line-height: inherit;
}
hr {
height: 0;
color: inherit;
border-top-width: 1px;
}
abbr:where([title]) {
text-decoration: underline dotted;
}
h1, h2, h3, h4, h5, h6 {
font-size: inherit;
font-weight: inherit;
}
a {
color: inherit;
text-decoration: inherit;
}
b, strong {
font-weight: bolder;
}
code, kbd, samp, pre {
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
font-size: 1em;
}
small {
font-size: 80%;
}
sub, sup {
font-size: 75%;
line-height: 0;
position: relative;
vertical-align: baseline;
}
sub {
bottom: -0.25em;
}
sup {
top: -0.5em;
}
table {
text-indent: 0;
border-color: inherit;
border-collapse: collapse;
}
button, input, optgroup, select, textarea {
font-family: inherit;
font-size: 100%;
font-weight: inherit;
line-height: inherit;
color: inherit;
margin: 0;
padding: 0;
}
button, select {
text-transform: none;
}
button, [type='button'], [type='reset'], [type='submit'] {
-webkit-appearance: button;
background-color: transparent;
background-image: none;
}
:-moz-focusring {
outline: auto;
}
:-moz-ui-invalid {
box-shadow: none;
}
progress {
vertical-align: baseline;
}
::-webkit-inner-spin-button, ::-webkit-outer-spin-button {
height: auto;
}
[type='search'] {
-webkit-appearance: textfield;
outline-offset: -2px;
}
::-webkit-search-decoration {
-webkit-appearance: none;
}
::-webkit-file-upload-button {
-webkit-appearance: button;
font: inherit;
}
summary {
display: list-item;
}
blockquote, dl, dd, h1, h2, h3, h4, h5, h6, hr, figure, p, pre {
margin: 0;
}
fieldset {
margin: 0;
padding: 0;
}
legend {
padding: 0;
}
ol, ul, menu {
list-style: none;
margin: 0;
padding: 0;
}
textarea {
resize: vertical;
}
input::placeholder, textarea::placeholder {
opacity: 1;
color: #9ca3af;
}
button, [role="button"] {
cursor: pointer;
}
:disabled {
cursor: default;
}
img, svg, video, canvas, audio, iframe, embed, object {
display: block;
vertical-align: middle;
}
img, video {
max-width: 100%;
height: auto;
}
*, ::before, ::after {
--en-border-spacing-x: 0;
--en-border-spacing-y: 0;
--en-translate-x: 0;
--en-translate-y: 0;
--en-rotate: 0;
--en-skew-x: 0;
--en-skew-y: 0;
--en-scale-x: 1;
--en-scale-y: 1;
--en-pan-x: ;
--en-pan-y: ;
--en-pinch-zoom: ;
--en-scroll-snap-strictness: proximity;
--en-ordinal: ;
--en-slashed-zero: ;
--en-numeric-figure: ;
--en-numeric-spacing: ;
--en-numeric-fraction: ;
--en-ring-inset: ;
--en-ring-offset-width: 0px;
--en-ring-offset-color: #fff;
--en-ring-color: rgb(59 130 246 / 0.5);
--en-ring-offset-shadow: 0 0 #0000;
--en-ring-shadow: 0 0 #0000;
--en-shadow: 0 0 #0000;
--en-shadow-colored: 0 0 #0000;
--en-blur: ;
--en-brightness: ;
--en-contrast: ;
--en-grayscale: ;
--en-hue-rotate: ;
--en-invert: ;
--en-saturate: ;
--en-sepia: ;
--en-drop-shadow: ;
--en-backdrop-blur: ;
--en-backdrop-brightness: ;
--en-backdrop-contrast: ;
--en-backdrop-grayscale: ;
--en-backdrop-hue-rotate: ;
--en-backdrop-invert: ;
--en-backdrop-opacity: ;
--en-backdrop-saturate: ;
--en-backdrop-sepia: ;
}
::-webkit-backdrop {
--en-border-spacing-x: 0;
--en-border-spacing-y: 0;
--en-translate-x: 0;
--en-translate-y: 0;
--en-rotate: 0;
--en-skew-x: 0;
--en-skew-y: 0;
--en-scale-x: 1;
--en-scale-y: 1;
--en-pan-x: ;
--en-pan-y: ;
--en-pinch-zoom: ;
--en-scroll-snap-strictness: proximity;
--en-ordinal: ;
--en-slashed-zero: ;
--en-numeric-figure: ;
--en-numeric-spacing: ;
--en-numeric-fraction: ;
--en-ring-inset: ;
--en-ring-offset-width: 0px;
--en-ring-offset-color: #fff;
--en-ring-color: rgb(59 130 246 / 0.5);
--en-ring-offset-shadow: 0 0 #0000;
--en-ring-shadow: 0 0 #0000;
--en-shadow: 0 0 #0000;
--en-shadow-colored: 0 0 #0000;
--en-blur: ;
--en-brightness: ;
--en-contrast: ;
--en-grayscale: ;
--en-hue-rotate: ;
--en-invert: ;
--en-saturate: ;
--en-sepia: ;
--en-drop-shadow: ;
--en-backdrop-blur: ;
--en-backdrop-brightness: ;
--en-backdrop-contrast: ;
--en-backdrop-grayscale: ;
--en-backdrop-hue-rotate: ;
--en-backdrop-invert: ;
--en-backdrop-opacity: ;
--en-backdrop-saturate: ;
--en-backdrop-sepia: ;
}
::backdrop {
--en-border-spacing-x: 0;
--en-border-spacing-y: 0;
--en-translate-x: 0;
--en-translate-y: 0;
--en-rotate: 0;
--en-skew-x: 0;
--en-skew-y: 0;
--en-scale-x: 1;
--en-scale-y: 1;
--en-pan-x: ;
--en-pan-y: ;
--en-pinch-zoom: ;
--en-scroll-snap-strictness: proximity;
--en-ordinal: ;
--en-slashed-zero: ;
--en-numeric-figure: ;
--en-numeric-spacing: ;
--en-numeric-fraction: ;
--en-ring-inset: ;
--en-ring-offset-width: 0px;
--en-ring-offset-color: #fff;
--en-ring-color: rgb(59 130 246 / 0.5);
--en-ring-offset-shadow: 0 0 #0000;
--en-ring-shadow: 0 0 #0000;
--en-shadow: 0 0 #0000;
--en-shadow-colored: 0 0 #0000;
--en-blur: ;
--en-brightness: ;
--en-contrast: ;
--en-grayscale: ;
--en-hue-rotate: ;
--en-invert: ;
--en-saturate: ;
--en-sepia: ;
--en-drop-shadow: ;
--en-backdrop-blur: ;
--en-backdrop-brightness: ;
--en-backdrop-contrast: ;
--en-backdrop-grayscale: ;
--en-backdrop-hue-rotate: ;
--en-backdrop-invert: ;
--en-backdrop-opacity: ;
--en-backdrop-saturate: ;
--en-backdrop-sepia: ;
}
.container {
width: 100%;
}
@media (min-width: 640px) {
.container {
max-width: 640px;
}
}
@media (min-width: 768px) {
.container {
max-width: 768px;
}
}
@media (min-width: 1024px) {
.container {
max-width: 1024px;
}
}
@media (min-width: 1280px) {
.container {
max-width: 1280px;
}
}
@media (min-width: 1536px) {
.container {
max-width: 1536px;
}
}
.static {
position: static;
}
.m-2 {
margin: 0.5rem;
}
.m-4 {
margin: 1rem;
}
.mx-auto {
margin-left: auto;
margin-right: auto;
}
.mb-2 {
margin-bottom: 0.5rem;
}
.contents {
display: contents;
}
.h1 {
height: 0.25rem;
}
.w-full {
width: 100%;
}
.rounded-lg {
border-radius: 0.5rem;
}
.border {
border-width: 1px;
}
.bg-blue-500 {
--en-bg-opacity: 1;
background-color: rgb(59 130 246 / var(--en-bg-opacity));
}
.bg-gray-100 {
--en-bg-opacity: 1;
background-color: rgb(243 244 246 / var(--en-bg-opacity));
}
.bg-white {
--en-bg-opacity: 1;
background-color: rgb(255 255 255 / var(--en-bg-opacity));
}
.p-2 {
padding: 0.5rem;
}
.p-4 {
padding: 1rem;
}
.p-6 {
padding: 1.5rem;
}
.text-2xl {
font-size: 1.5rem;
line-height: 2rem;
}
.font-bold {
font-weight: 700;
}
.text-white {
--en-text-opacity: 1;
color: rgb(255 255 255 / var(--en-text-opacity));
}
.shadow-md {
--en-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
--en-shadow-colored: 0 4px 6px -1px var(--en-shadow-color), 0 2px 4px -2px var(--en-shadow-color);
box-shadow: var(--en-ring-offset-shadow, 0 0 #0000), var(--en-ring-shadow, 0 0 #0000), var(--en-shadow);
}
.\[dependencies\] {
}

View file

@ -1,7 +1,8 @@
// @use '../../node_modules/@unocss/reset/normalize.css'; // @use '../../node_modules/@unocss/reset/normalize.css';
@use '../../node_modules/@unocss/reset/tailwind-compat.css'; @use '../../node_modules/@unocss/reset/tailwind-compat.css';
// @use '../../node_modules/animate.css/animate.min.css'; // @use '../../node_modules/animate.css/animate.min.css';
@use 'uno'; // @use 'uno';
@use 'encr';
.btn { .btn {
// p-2 text-white bg-blue-500 rounded-lg // p-2 text-white bg-blue-500 rounded-lg