Init
This commit is contained in:
68
dev/hiccup/src/dev/hiccup.clj
Normal file
68
dev/hiccup/src/dev/hiccup.clj
Normal file
@@ -0,0 +1,68 @@
|
||||
(ns dev.hiccup
|
||||
(:require [org.httpkit.server :as http]
|
||||
[hiccup2.core :as h]
|
||||
[ui.button :as button]))
|
||||
|
||||
(def variants [:primary :secondary :ghost :danger])
|
||||
(def sizes [:sm :md :lg])
|
||||
|
||||
(defn button-grid []
|
||||
[:div {:style "display: grid; grid-template-columns: repeat(4, auto); gap: 1rem; align-items: center;"}
|
||||
;; Header row
|
||||
[:div]
|
||||
(for [size sizes]
|
||||
[:div {:style "font-weight: 600; text-align: center; color: var(--fg-1); font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.05em;"}
|
||||
(name size)])
|
||||
|
||||
;; Variant rows
|
||||
(for [variant variants]
|
||||
(list
|
||||
[:div {:style "font-weight: 600; color: var(--fg-1); font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.05em;"}
|
||||
(name variant)]
|
||||
(for [size sizes]
|
||||
[:div {:style "text-align: center;"}
|
||||
(button/button {:variant variant :size size}
|
||||
(str (name variant) " " (name size)))])))])
|
||||
|
||||
(defn disabled-row []
|
||||
[:div {:style "display: flex; gap: 0.75rem; flex-wrap: wrap;"}
|
||||
(for [variant variants]
|
||||
(button/button {:variant variant :disabled true}
|
||||
(str (name variant) " disabled")))])
|
||||
|
||||
(defn page []
|
||||
(str
|
||||
(h/html
|
||||
[:html
|
||||
[:head
|
||||
[:meta {:charset "utf-8"}]
|
||||
[:meta {:name "viewport" :content "width=device-width, initial-scale=1"}]
|
||||
[:link {:rel "stylesheet" :href "/theme.css"}]
|
||||
[:style "body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; padding: 2rem; background: var(--bg-0); color: var(--fg-0); margin: 0; transition: background-color 0.2s, color 0.2s; }"]]
|
||||
[:body
|
||||
[:div {:style "max-width: 800px; margin: 0 auto;"}
|
||||
[:div {:style "display: flex; justify-content: space-between; align-items: center; margin-bottom: 2rem;"}
|
||||
[:h2 {:style "margin: 0; color: var(--fg-0);"} "Hiccup (Backend)"]
|
||||
[:button {:onclick "document.documentElement.dataset.theme = document.documentElement.dataset.theme === 'dark' ? 'light' : 'dark'"
|
||||
:style "padding: 0.5rem 1rem; cursor: pointer; border-radius: var(--radius-md); border: var(--border-0); background: var(--bg-1); color: var(--fg-0);"}
|
||||
"Toggle Dark Mode"]]
|
||||
[:h3 {:style "color: var(--fg-1); margin-bottom: 1rem;"} "Button Grid"]
|
||||
(button-grid)
|
||||
[:h3 {:style "color: var(--fg-1); margin: 2rem 0 1rem;"} "Disabled States"]
|
||||
(disabled-row)]]])))
|
||||
|
||||
(defn handler [{:keys [uri]}]
|
||||
(case uri
|
||||
"/" {:status 200
|
||||
:headers {"Content-Type" "text/html; charset=utf-8"}
|
||||
:body (page)}
|
||||
"/theme.css" {:status 200
|
||||
:headers {"Content-Type" "text/css"}
|
||||
:body (slurp "dist/theme.css")}
|
||||
{:status 404
|
||||
:headers {"Content-Type" "text/plain"}
|
||||
:body "Not found"}))
|
||||
|
||||
(defn start! [{:keys [port] :or {port 3003}}]
|
||||
(println (str "Hiccup server running at http://localhost:" port))
|
||||
(http/run-server handler {:port port}))
|
||||
84
dev/index.html
Normal file
84
dev/index.html
Normal file
@@ -0,0 +1,84 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>UI Framework — Test Page</title>
|
||||
<style>
|
||||
* { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
||||
background: #f0f0f0;
|
||||
color: #1a1a1a;
|
||||
}
|
||||
.tabs {
|
||||
display: flex;
|
||||
gap: 0;
|
||||
background: #fff;
|
||||
border-bottom: 2px solid #e0e0e0;
|
||||
padding: 0 1rem;
|
||||
}
|
||||
.tab {
|
||||
padding: 0.75rem 1.5rem;
|
||||
cursor: pointer;
|
||||
border: none;
|
||||
background: none;
|
||||
font-size: 0.875rem;
|
||||
font-weight: 500;
|
||||
color: #666;
|
||||
border-bottom: 2px solid transparent;
|
||||
margin-bottom: -2px;
|
||||
transition: color 0.15s, border-color 0.15s;
|
||||
}
|
||||
.tab:hover { color: #1a1a1a; }
|
||||
.tab.active {
|
||||
color: #2563eb;
|
||||
border-bottom-color: #2563eb;
|
||||
}
|
||||
.tab.disabled {
|
||||
color: #ccc;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
.frame-container {
|
||||
height: calc(100vh - 45px);
|
||||
}
|
||||
iframe {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border: none;
|
||||
}
|
||||
.placeholder {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
color: #999;
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="tabs">
|
||||
<button class="tab active" data-target="hiccup" data-url="http://localhost:3003">Hiccup</button>
|
||||
<button class="tab" data-target="replicant" data-url="http://localhost:3001">Replicant</button>
|
||||
<button class="tab" data-target="squint" data-url="http://localhost:3002">Squint</button>
|
||||
</div>
|
||||
<div class="frame-container" id="frame-container">
|
||||
<iframe id="target-frame" src="http://localhost:3003"></iframe>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const tabs = document.querySelectorAll('.tab');
|
||||
const frame = document.getElementById('target-frame');
|
||||
|
||||
tabs.forEach(tab => {
|
||||
tab.addEventListener('click', () => {
|
||||
if (tab.classList.contains('disabled')) return;
|
||||
tabs.forEach(t => t.classList.remove('active'));
|
||||
tab.classList.add('active');
|
||||
frame.src = tab.dataset.url;
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
3
dev/replicant/deps.edn
Normal file
3
dev/replicant/deps.edn
Normal file
@@ -0,0 +1,3 @@
|
||||
{:paths ["src" "../../src"]
|
||||
:deps {no.cjohansen/replicant {:mvn/version "2025.12.1"}
|
||||
thheller/shadow-cljs {:mvn/version "2.28.23"}}}
|
||||
1565
dev/replicant/package-lock.json
generated
Normal file
1565
dev/replicant/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
7
dev/replicant/package.json
Normal file
7
dev/replicant/package.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"name": "ui-framework-dev-replicant",
|
||||
"private": true,
|
||||
"devDependencies": {
|
||||
"shadow-cljs": "^2.28.0"
|
||||
}
|
||||
}
|
||||
22
dev/replicant/public/index.html
Normal file
22
dev/replicant/public/index.html
Normal file
@@ -0,0 +1,22 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<link rel="stylesheet" href="/theme.css" />
|
||||
<style>
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
||||
padding: 2rem;
|
||||
background: var(--bg-0);
|
||||
color: var(--fg-0);
|
||||
margin: 0;
|
||||
transition: background-color 0.2s, color 0.2s;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script src="/js/main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
9
dev/replicant/shadow-cljs.edn
Normal file
9
dev/replicant/shadow-cljs.edn
Normal file
@@ -0,0 +1,9 @@
|
||||
{:deps true
|
||||
:dev-http {3001 "public"}
|
||||
:builds
|
||||
{:app
|
||||
{:target :browser
|
||||
:output-dir "public/js"
|
||||
:asset-path "/js"
|
||||
:modules {:main {:init-fn dev.replicant/init!}}
|
||||
:devtools {:after-load dev.replicant/reload!}}}}
|
||||
59
dev/replicant/src/dev/replicant.cljs
Normal file
59
dev/replicant/src/dev/replicant.cljs
Normal file
@@ -0,0 +1,59 @@
|
||||
(ns dev.replicant
|
||||
(:require [replicant.dom :as d]
|
||||
[ui.button :as button]))
|
||||
|
||||
(def variants [:primary :secondary :ghost :danger])
|
||||
(def sizes [:sm :md :lg])
|
||||
|
||||
(defn button-grid []
|
||||
[:div {:style {:display "grid"
|
||||
:grid-template-columns "repeat(4, auto)"
|
||||
:gap "1rem"
|
||||
:align-items "center"}}
|
||||
[:div]
|
||||
(for [size sizes]
|
||||
[:div {:style {:font-weight "600" :text-align "center" :color "var(--fg-1)"
|
||||
:font-size "0.75rem" :text-transform "uppercase" :letter-spacing "0.05em"}}
|
||||
(name size)])
|
||||
(for [variant variants]
|
||||
(list
|
||||
[:div {:style {:font-weight "600" :color "var(--fg-1)"
|
||||
:font-size "0.75rem" :text-transform "uppercase" :letter-spacing "0.05em"}}
|
||||
(name variant)]
|
||||
(for [size sizes]
|
||||
[:div {:style {:text-align "center"}}
|
||||
(button/button {:variant variant :size size
|
||||
:on-click (fn [_] (js/console.log (str "Clicked: " (name variant) " " (name size))))}
|
||||
(str (name variant) " " (name size)))])))])
|
||||
|
||||
(defn disabled-row []
|
||||
[:div {:style {:display "flex" :gap "0.75rem" :flex-wrap "wrap"}}
|
||||
(for [variant variants]
|
||||
(button/button {:variant variant :disabled true}
|
||||
(str (name variant) " disabled")))])
|
||||
|
||||
(defn toggle-theme! [_e]
|
||||
(let [el (.-documentElement js/document)
|
||||
current (.. el -dataset -theme)]
|
||||
(set! (.. el -dataset -theme)
|
||||
(if (= current "dark") "light" "dark"))))
|
||||
|
||||
(defn app []
|
||||
[:div {:style {:max-width "800px" :margin "0 auto"}}
|
||||
[:div {:style {:display "flex" :justify-content "space-between" :align-items "center" :margin-bottom "2rem"}}
|
||||
[:h2 {:style {:margin "0" :color "var(--fg-0)"}} "Replicant (CLJS)"]
|
||||
[:button {:on {:click toggle-theme!}
|
||||
:style {:padding "0.5rem 1rem" :cursor "pointer" :border-radius "var(--radius-md)"
|
||||
:border "var(--border-0)" :background "var(--bg-1)" :color "var(--fg-0)"}}
|
||||
"Toggle Dark Mode"]]
|
||||
[:h3 {:style {:color "var(--fg-1)" :margin-bottom "1rem"}} "Button Grid"]
|
||||
(button-grid)
|
||||
[:h3 {:style {:color "var(--fg-1)" :margin "2rem 0 1rem"}} "Disabled States"]
|
||||
(disabled-row)])
|
||||
|
||||
(defn ^:export init! []
|
||||
(d/set-dispatch! (fn [_ _]))
|
||||
(d/render (.getElementById js/document "app") (app)))
|
||||
|
||||
(defn ^:export reload! []
|
||||
(d/render (.getElementById js/document "app") (app)))
|
||||
22
dev/squint/index.html
Normal file
22
dev/squint/index.html
Normal file
@@ -0,0 +1,22 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<link rel="stylesheet" href="/theme.css" />
|
||||
<style>
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
||||
padding: 2rem;
|
||||
background: var(--bg-0);
|
||||
color: var(--fg-0);
|
||||
margin: 0;
|
||||
transition: background-color 0.2s, color 0.2s;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script type="module" src=".compiled/dev/squint.mjs"></script>
|
||||
</body>
|
||||
</html>
|
||||
1160
dev/squint/package-lock.json
generated
Normal file
1160
dev/squint/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
16
dev/squint/package.json
Normal file
16
dev/squint/package.json
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"name": "ui-framework-dev-squint",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "npx squint watch & npx vite --port 3002",
|
||||
"build": "npx squint compile && npx vite build"
|
||||
},
|
||||
"devDependencies": {
|
||||
"squint-cljs": "latest",
|
||||
"vite": "^6.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"eucalypt": "latest"
|
||||
}
|
||||
}
|
||||
2
dev/squint/squint.edn
Normal file
2
dev/squint/squint.edn
Normal file
@@ -0,0 +1,2 @@
|
||||
{:paths ["src" "../../src"]
|
||||
:output-dir ".compiled"}
|
||||
73
dev/squint/src/dev/squint.cljs
Normal file
73
dev/squint/src/dev/squint.cljs
Normal file
@@ -0,0 +1,73 @@
|
||||
(ns dev.squint
|
||||
(:require ["eucalypt" :as eu]
|
||||
[ui.button :as button]))
|
||||
|
||||
(def variants ["primary" "secondary" "ghost" "danger"])
|
||||
(def sizes ["sm" "md" "lg"])
|
||||
|
||||
(defn toggle-theme! [_e]
|
||||
(let [el (.-documentElement js/document)
|
||||
current (.. el -dataset -theme)]
|
||||
(set! (.. el -dataset -theme)
|
||||
(if (= current "dark") "light" "dark"))))
|
||||
|
||||
(def label-style {"font-weight" "600"
|
||||
"color" "var(--fg-1)"
|
||||
"font-size" "0.75rem"
|
||||
"text-transform" "uppercase"
|
||||
"letter-spacing" "0.05em"})
|
||||
|
||||
(defn button-grid []
|
||||
(into
|
||||
[:div {:style {"display" "grid"
|
||||
"grid-template-columns" "repeat(4, auto)"
|
||||
"gap" "1rem"
|
||||
"align-items" "center"}}
|
||||
[:div]
|
||||
[:div {:style (merge label-style {"text-align" "center"})} "sm"]
|
||||
[:div {:style (merge label-style {"text-align" "center"})} "md"]
|
||||
[:div {:style (merge label-style {"text-align" "center"})} "lg"]]
|
||||
(mapcat (fn [variant]
|
||||
[[:div {:style label-style} variant]
|
||||
[:div {:style {"text-align" "center"}}
|
||||
(button/button {:variant variant :size "sm"
|
||||
:on-click (fn [_] (js/console.log (str "Clicked: " variant " sm")))}
|
||||
(str variant " sm"))]
|
||||
[:div {:style {"text-align" "center"}}
|
||||
(button/button {:variant variant :size "md"
|
||||
:on-click (fn [_] (js/console.log (str "Clicked: " variant " md")))}
|
||||
(str variant " md"))]
|
||||
[:div {:style {"text-align" "center"}}
|
||||
(button/button {:variant variant :size "lg"
|
||||
:on-click (fn [_] (js/console.log (str "Clicked: " variant " lg")))}
|
||||
(str variant " lg"))]])
|
||||
variants)))
|
||||
|
||||
(defn disabled-row []
|
||||
(into
|
||||
[:div {:style {"display" "flex" "gap" "0.75rem" "flex-wrap" "wrap"}}]
|
||||
(map (fn [variant]
|
||||
(button/button {:variant variant :disabled true}
|
||||
(str variant " disabled")))
|
||||
variants)))
|
||||
|
||||
(defn app []
|
||||
[:div {:style {"max-width" "800px" "margin" "0 auto"}}
|
||||
[:div {:style {"display" "flex" "justify-content" "space-between" "align-items" "center" "margin-bottom" "2rem"}}
|
||||
[:h2 {:style {"margin" "0" "color" "var(--fg-0)"}} "Squint (Eucalypt)"]
|
||||
[:button {:on-click toggle-theme!
|
||||
:style {"padding" "0.5rem 1rem" "cursor" "pointer" "border-radius" "var(--radius-md)"
|
||||
"border" "var(--border-0)" "background" "var(--bg-1)" "color" "var(--fg-0)"}}
|
||||
"Toggle Dark Mode"]]
|
||||
[:h3 {:style {"color" "var(--fg-1)" "margin-bottom" "1rem"}} "Button Grid"]
|
||||
(button-grid)
|
||||
[:h3 {:style {"color" "var(--fg-1)" "margin" "2rem 0 1rem"}} "Disabled States"]
|
||||
(disabled-row)])
|
||||
|
||||
(defn init! []
|
||||
(eu/render (app) (js/document.getElementById "app")))
|
||||
|
||||
(defn reload! []
|
||||
(eu/render (app) (js/document.getElementById "app")))
|
||||
|
||||
(init!)
|
||||
9
dev/squint/vite.config.js
Normal file
9
dev/squint/vite.config.js
Normal file
@@ -0,0 +1,9 @@
|
||||
import { defineConfig } from "vite";
|
||||
|
||||
export default defineConfig({
|
||||
root: ".",
|
||||
publicDir: "public",
|
||||
server: {
|
||||
port: 3002,
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user