All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 3m26s
Loading: lazy loading, infinite scroll, progress bar Forms: active search, inline validation, value select, reset on submit Records: edit row, bulk update Swap/DOM: swap positions, select filter, tabs Display: animations, dialogs, keyboard shortcuts HTTP: PUT/PATCH, JSON encoding, vals & headers Resilience: loading states, request abort (sync replace), retry Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
239 lines
11 KiB
Python
239 lines
11 KiB
Python
"""Documentation content for the sx docs site.
|
|
|
|
All page content as Python data structures, consumed by sx_components.py
|
|
to build s-expression page trees.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Navigation
|
|
# ---------------------------------------------------------------------------
|
|
|
|
DOCS_NAV = [
|
|
("Introduction", "/docs/introduction"),
|
|
("Getting Started", "/docs/getting-started"),
|
|
("Components", "/docs/components"),
|
|
("Evaluator", "/docs/evaluator"),
|
|
("Primitives", "/docs/primitives"),
|
|
("CSS", "/docs/css"),
|
|
("Server Rendering", "/docs/server-rendering"),
|
|
]
|
|
|
|
REFERENCE_NAV = [
|
|
("Attributes", "/reference/"),
|
|
("Headers", "/reference/headers"),
|
|
("Events", "/reference/events"),
|
|
("JS API", "/reference/js-api"),
|
|
]
|
|
|
|
PROTOCOLS_NAV = [
|
|
("Wire Format", "/protocols/wire-format"),
|
|
("Fragments", "/protocols/fragments"),
|
|
("Resolver I/O", "/protocols/resolver-io"),
|
|
("Internal Services", "/protocols/internal-services"),
|
|
("ActivityPub", "/protocols/activitypub"),
|
|
("Future", "/protocols/future"),
|
|
]
|
|
|
|
EXAMPLES_NAV = [
|
|
("Click to Load", "/examples/click-to-load"),
|
|
("Form Submission", "/examples/form-submission"),
|
|
("Polling", "/examples/polling"),
|
|
("Delete Row", "/examples/delete-row"),
|
|
("Inline Edit", "/examples/inline-edit"),
|
|
("OOB Swaps", "/examples/oob-swaps"),
|
|
("Lazy Loading", "/examples/lazy-loading"),
|
|
("Infinite Scroll", "/examples/infinite-scroll"),
|
|
("Progress Bar", "/examples/progress-bar"),
|
|
("Active Search", "/examples/active-search"),
|
|
("Inline Validation", "/examples/inline-validation"),
|
|
("Value Select", "/examples/value-select"),
|
|
("Reset on Submit", "/examples/reset-on-submit"),
|
|
("Edit Row", "/examples/edit-row"),
|
|
("Bulk Update", "/examples/bulk-update"),
|
|
("Swap Positions", "/examples/swap-positions"),
|
|
("Select Filter", "/examples/select-filter"),
|
|
("Tabs", "/examples/tabs"),
|
|
("Animations", "/examples/animations"),
|
|
("Dialogs", "/examples/dialogs"),
|
|
("Keyboard Shortcuts", "/examples/keyboard-shortcuts"),
|
|
("PUT / PATCH", "/examples/put-patch"),
|
|
("JSON Encoding", "/examples/json-encoding"),
|
|
("Vals & Headers", "/examples/vals-and-headers"),
|
|
("Loading States", "/examples/loading-states"),
|
|
("Request Abort", "/examples/sync-replace"),
|
|
("Retry", "/examples/retry"),
|
|
]
|
|
|
|
ESSAYS_NAV = [
|
|
("sx sucks", "/essays/sx-sucks"),
|
|
("Why S-Expressions", "/essays/why-sexps"),
|
|
("The htmx/React Hybrid", "/essays/htmx-react-hybrid"),
|
|
("On-Demand CSS", "/essays/on-demand-css"),
|
|
]
|
|
|
|
MAIN_NAV = [
|
|
("Docs", "/docs/introduction"),
|
|
("Reference", "/reference/"),
|
|
("Protocols", "/protocols/wire-format"),
|
|
("Examples", "/examples/click-to-load"),
|
|
("Essays", "/essays/sx-sucks"),
|
|
]
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Reference: Attributes
|
|
# ---------------------------------------------------------------------------
|
|
|
|
REQUEST_ATTRS = [
|
|
("sx-get", "Issue a GET request to the given URL", True),
|
|
("sx-post", "Issue a POST request to the given URL", True),
|
|
("sx-put", "Issue a PUT request to the given URL", True),
|
|
("sx-delete", "Issue a DELETE request to the given URL", True),
|
|
("sx-patch", "Issue a PATCH request to the given URL", True),
|
|
]
|
|
|
|
BEHAVIOR_ATTRS = [
|
|
("sx-trigger", "Specifies the event that triggers the request. Modifiers: once, changed, delay:<time>, from:<selector>, intersect, revealed, load, every:<time>", True),
|
|
("sx-target", "CSS selector for the target element to update", True),
|
|
("sx-swap", "How to swap the response: outerHTML, innerHTML, afterend, beforeend, afterbegin, beforebegin, delete, none", True),
|
|
("sx-swap-oob", "Out-of-band swap — update elements elsewhere in the DOM by ID", True),
|
|
("sx-select", "CSS selector to pick a fragment from the response", True),
|
|
("sx-confirm", "Shows a confirmation dialog before issuing the request", True),
|
|
("sx-push-url", "Push the request URL into the browser location bar", True),
|
|
("sx-sync", "Synchronization strategy for requests from this element", True),
|
|
("sx-encoding", "Set the encoding for the request (e.g. multipart/form-data)", True),
|
|
("sx-headers", "Add headers to the request as a JSON string", True),
|
|
("sx-include", "Include additional element values in the request", True),
|
|
("sx-vals", "Add values to the request as a JSON string", True),
|
|
("sx-media", "Only enable this element when the media query matches", True),
|
|
("sx-disable", "Disable sx processing on this element and its children", True),
|
|
]
|
|
|
|
SX_UNIQUE_ATTRS = [
|
|
("sx-retry", "Exponential backoff retry on request failure", True),
|
|
("data-sx", "Client-side rendering — evaluate the sx source in this attribute and render into the element", True),
|
|
("data-sx-env", "Provide environment variables as JSON for data-sx rendering", True),
|
|
]
|
|
|
|
HTMX_MISSING_ATTRS = [
|
|
("hx-boost", "Progressively enhance links and forms (not yet implemented)", False),
|
|
("hx-preload", "Preload content on hover/focus (not yet implemented)", False),
|
|
("hx-preserve", "Preserve element across swaps (not yet implemented)", False),
|
|
("hx-optimistic", "Optimistic UI updates (not yet implemented)", False),
|
|
("hx-indicator", "sx uses .sx-request CSS class instead — no dedicated attribute (not yet implemented)", False),
|
|
("hx-validate", "Custom validation (not yet implemented — sx has sx-disable)", False),
|
|
("hx-ignore", "Ignore element (not yet implemented — sx has sx-disable)", False),
|
|
]
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Reference: Headers
|
|
# ---------------------------------------------------------------------------
|
|
|
|
REQUEST_HEADERS = [
|
|
("SX-Request", "true", "Set on every sx-initiated request"),
|
|
("SX-Current-URL", "URL", "The current URL of the browser"),
|
|
("SX-Target", "CSS selector", "The target element for the response"),
|
|
("SX-Components", "~comp1,~comp2,...", "Component names the client already has cached"),
|
|
("SX-Css", "hash or class list", "CSS classes/hash the client already has"),
|
|
("SX-History-Restore", "true", "Set when restoring from browser history"),
|
|
("SX-Css-Hash", "8-char hash", "Hash of the client's known CSS class set"),
|
|
]
|
|
|
|
RESPONSE_HEADERS = [
|
|
("SX-Css-Hash", "8-char hash", "Hash of the cumulative CSS class set after this response"),
|
|
("SX-Css-Add", "class1,class2,...", "New CSS classes added by this response"),
|
|
]
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Reference: Events
|
|
# ---------------------------------------------------------------------------
|
|
|
|
EVENTS = [
|
|
("sx:beforeRequest", "Fired before an sx request is issued. Call preventDefault() to cancel."),
|
|
("sx:afterRequest", "Fired after a successful sx response is received."),
|
|
("sx:afterSwap", "Fired after the response has been swapped into the DOM."),
|
|
("sx:afterSettle", "Fired after the DOM has settled (scripts executed, etc)."),
|
|
("sx:responseError", "Fired on HTTP error responses (4xx, 5xx)."),
|
|
("sx:sendError", "Fired when the request fails to send (network error)."),
|
|
]
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Reference: JS API
|
|
# ---------------------------------------------------------------------------
|
|
|
|
JS_API = [
|
|
("Sx.parse(text)", "Parse a single s-expression from text"),
|
|
("Sx.parseAll(text)", "Parse multiple s-expressions from text"),
|
|
("Sx.eval(expr, env)", "Evaluate an expression in the given environment"),
|
|
("Sx.render(expr, env)", "Render an expression to DOM nodes"),
|
|
("Sx.renderToString(expr, env)", "Render an expression to an HTML string"),
|
|
("Sx.renderComponent(name, kwargs, env)", "Render a named component with keyword arguments"),
|
|
("Sx.loadComponents(text)", "Parse and register component definitions"),
|
|
("Sx.getEnv()", "Get the current component environment"),
|
|
("Sx.mount(target, expr, env)", "Mount an expression into a DOM element"),
|
|
("Sx.update(target, newEnv)", "Re-render an element with new environment data"),
|
|
("Sx.hydrate(root)", "Find and render all [data-sx] elements within root"),
|
|
("SxEngine.process(root)", "Process all sx attributes in the DOM subtree"),
|
|
("SxEngine.executeRequest(elt, verb, url)", "Programmatically trigger an sx request"),
|
|
]
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Primitives
|
|
# ---------------------------------------------------------------------------
|
|
|
|
PRIMITIVES = {
|
|
"Arithmetic": ["+", "-", "*", "/", "mod", "sqrt", "pow", "abs", "floor", "ceil", "round", "min", "max"],
|
|
"Comparison": ["=", "!=", "<", ">", "<=", ">="],
|
|
"Logic": ["not", "and", "or"],
|
|
"String": ["str", "upper", "lower", "trim", "split", "join", "starts-with?", "ends-with?", "replace", "substring"],
|
|
"Collections": ["list", "dict", "len", "first", "last", "rest", "nth", "cons", "append", "keys", "vals", "merge", "assoc", "range", "concat", "reverse", "sort", "flatten", "zip"],
|
|
"Higher-Order": ["map", "map-indexed", "filter", "reduce", "some", "every?", "for-each"],
|
|
"Predicates": ["nil?", "number?", "string?", "list?", "dict?", "empty?", "contains?", "odd?", "even?", "zero?"],
|
|
"Type Conversion": ["int", "float", "number"],
|
|
}
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Example items for delete demo
|
|
# ---------------------------------------------------------------------------
|
|
|
|
DELETE_DEMO_ITEMS = [
|
|
("1", "Implement dark mode"),
|
|
("2", "Fix login bug"),
|
|
("3", "Write documentation"),
|
|
("4", "Deploy to production"),
|
|
("5", "Add unit tests"),
|
|
]
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Static data for new examples
|
|
# ---------------------------------------------------------------------------
|
|
|
|
SEARCH_LANGUAGES = [
|
|
"Python", "JavaScript", "TypeScript", "Rust", "Go", "Java", "C", "C++",
|
|
"Ruby", "Elixir", "Haskell", "Clojure", "Scala", "Kotlin", "Swift",
|
|
"Zig", "OCaml", "Lua", "Perl", "PHP",
|
|
]
|
|
|
|
PROFILE_DEFAULT = {"name": "Ada Lovelace", "email": "ada@example.com", "role": "Engineer"}
|
|
|
|
BULK_USERS = [
|
|
{"id": "1", "name": "Alice Chen", "email": "alice@example.com", "status": "active"},
|
|
{"id": "2", "name": "Bob Rivera", "email": "bob@example.com", "status": "inactive"},
|
|
{"id": "3", "name": "Carol Zhang", "email": "carol@example.com", "status": "active"},
|
|
{"id": "4", "name": "Dan Okafor", "email": "dan@example.com", "status": "inactive"},
|
|
{"id": "5", "name": "Eve Larsson", "email": "eve@example.com", "status": "active"},
|
|
]
|
|
|
|
VALUE_SELECT_DATA = {
|
|
"Languages": ["Python", "JavaScript", "Rust", "Go"],
|
|
"Frameworks": ["Quart", "FastAPI", "React", "Svelte"],
|
|
"Databases": ["PostgreSQL", "Redis", "SQLite", "MongoDB"],
|
|
}
|
|
|
|
EDIT_ROW_DATA = [
|
|
{"id": "1", "name": "Widget A", "price": "19.99", "stock": "142"},
|
|
{"id": "2", "name": "Widget B", "price": "24.50", "stock": "89"},
|
|
{"id": "3", "name": "Widget C", "price": "12.00", "stock": "305"},
|
|
{"id": "4", "name": "Widget D", "price": "45.00", "stock": "67"},
|
|
]
|