├── .gitignore
├── CODE_OF_CONDUCT.md
├── LICENSE.md
├── README.md
├── package.json
├── packages
├── api
│ ├── README.md
│ └── package.json
├── db
│ ├── README.md
│ └── package.json
├── ui.deprecated
│ ├── .gitignore
│ ├── .npmrc
│ ├── DISTRIBUTION.md
│ ├── README.md
│ ├── bin
│ │ └── org-setup.sh
│ ├── bunfig.toml
│ ├── examples
│ │ ├── backend
│ │ │ ├── README.md
│ │ │ ├── index.js
│ │ │ ├── package.json
│ │ │ └── sample.env
│ │ ├── button
│ │ │ ├── Button.svelte
│ │ │ └── button.html
│ │ ├── camera-subscribe-example
│ │ │ ├── README.md
│ │ │ ├── css
│ │ │ │ └── styles.css
│ │ │ ├── index.html
│ │ │ └── js
│ │ │ │ ├── app.js
│ │ │ │ ├── camera.js
│ │ │ │ ├── subscribe.js
│ │ │ │ └── sync-service.js
│ │ ├── div
│ │ │ ├── Div.svelte
│ │ │ └── div.html
│ │ ├── form-example
│ │ │ ├── README.md
│ │ │ ├── abstraction-example.html
│ │ │ └── index.html
│ │ ├── kde-example
│ │ │ └── index.html
│ │ ├── section
│ │ │ ├── Section.svelte
│ │ │ └── section.html
│ │ └── ui-elements
│ │ │ ├── README.md
│ │ │ └── index.html
│ ├── favicon.ico
│ ├── favicon.png
│ ├── index.html
│ ├── ios
│ │ ├── README.md
│ │ ├── WKWebViewHandler.swift
│ │ └── WebViewViewController.swift
│ ├── logo.png
│ ├── logo.svg
│ ├── native
│ │ ├── kde
│ │ │ ├── README.md
│ │ │ ├── main.cpp
│ │ │ ├── mainwindow.cpp
│ │ │ ├── mainwindow.h
│ │ │ ├── resources.qrc
│ │ │ ├── sans-ui-kde.pro
│ │ │ ├── webbridge.cpp
│ │ │ └── webbridge.h
│ │ └── qt
│ │ │ ├── main.cpp
│ │ │ ├── mainwindow.cpp
│ │ │ ├── mainwindow.h
│ │ │ ├── resources.qrc
│ │ │ ├── sans-ui-qt.pro
│ │ │ ├── webbridge.cpp
│ │ │ └── webbridge.h
│ ├── package.json
│ ├── pnpm-lock.yaml
│ ├── releaase-package.yml
│ ├── scripts
│ │ ├── build-components.js
│ │ └── build-deno.js
│ ├── src
│ │ ├── app.svelte
│ │ ├── components
│ │ │ ├── WebViewComponent.svelte
│ │ │ └── html5
│ │ │ │ ├── A.svelte
│ │ │ │ ├── AComponent.js
│ │ │ │ ├── Article.svelte
│ │ │ │ ├── ArticleComponent.js
│ │ │ │ ├── Aside.svelte
│ │ │ │ ├── AsideComponent.js
│ │ │ │ ├── Button.svelte
│ │ │ │ ├── ButtonComponent.js
│ │ │ │ ├── Div.svelte
│ │ │ │ ├── DivComponent.js
│ │ │ │ ├── Footer.svelte
│ │ │ │ ├── FooterComponent.js
│ │ │ │ ├── FormComponent.js
│ │ │ │ ├── H1.svelte
│ │ │ │ ├── H1Component.js
│ │ │ │ ├── Header.svelte
│ │ │ │ ├── HeaderComponent.js
│ │ │ │ ├── Img.svelte
│ │ │ │ ├── ImgComponent.js
│ │ │ │ ├── InputComponent.js
│ │ │ │ ├── LabelComponent.js
│ │ │ │ ├── Main.svelte
│ │ │ │ ├── MainComponent.js
│ │ │ │ ├── Nav.svelte
│ │ │ │ ├── NavComponent.js
│ │ │ │ ├── OptionComponent.js
│ │ │ │ ├── P.svelte
│ │ │ │ ├── PComponent.js
│ │ │ │ ├── Section.svelte
│ │ │ │ ├── SectionComponent.js
│ │ │ │ ├── SelectComponent.js
│ │ │ │ ├── TextareaComponent.js
│ │ │ │ ├── a.html
│ │ │ │ ├── article.html
│ │ │ │ ├── aside.html
│ │ │ │ ├── button.html
│ │ │ │ ├── div.html
│ │ │ │ ├── footer.html
│ │ │ │ ├── h1.html
│ │ │ │ ├── header.html
│ │ │ │ ├── index.js
│ │ │ │ ├── main.html
│ │ │ │ ├── nav.html
│ │ │ │ ├── p.html
│ │ │ │ └── section.html
│ │ ├── index.js
│ │ └── lib
│ │ │ ├── components
│ │ │ ├── ComponentAdapter.js
│ │ │ ├── ComponentFactory.js
│ │ │ ├── README.md
│ │ │ └── index.js
│ │ │ └── webview
│ │ │ ├── QtWebEngineBridge.js
│ │ │ ├── WKWebViewBridge.js
│ │ │ ├── WebViewAdapter.js
│ │ │ └── types.d.ts
│ ├── static
│ │ └── logos
│ │ │ ├── api
│ │ │ ├── favicon.sans-api.svg
│ │ │ ├── favicon.sans-api.white.svg
│ │ │ ├── logo.sans-api.svg
│ │ │ └── logo.sans-api.white.svg
│ │ │ ├── db
│ │ │ ├── favicon.db.svg
│ │ │ ├── favicon.db.white.svg
│ │ │ ├── logo.sans-db.svg
│ │ │ └── logo.sans-db.white.svg
│ │ │ └── ui
│ │ │ ├── favicon.sans-ui.svg
│ │ │ ├── favicon.sans-ui.white.svg
│ │ │ ├── logo.sans-ui.svg
│ │ │ └── logo.sans-ui.white.svg
│ ├── tsconfig.json
│ └── vite.config.js
└── ui
│ ├── .gitignore
│ ├── DISTRIBUTION.md
│ ├── README.md
│ ├── bin
│ └── org-setup.sh
│ ├── bunfig.toml
│ ├── examples
│ ├── backend
│ │ ├── README.md
│ │ ├── index.js
│ │ ├── package.json
│ │ └── sample.env
│ ├── button
│ │ ├── Button.svelte
│ │ └── button.html
│ ├── camera-subscribe-example
│ │ ├── README.md
│ │ ├── css
│ │ │ └── styles.css
│ │ ├── index.html
│ │ └── js
│ │ │ ├── app.js
│ │ │ ├── camera.js
│ │ │ ├── subscribe.js
│ │ │ └── sync-service.js
│ ├── common
│ │ ├── common.js
│ │ ├── navbar.html
│ │ └── styles.css
│ ├── desktop-example
│ │ ├── index.html
│ │ └── index.js
│ ├── div
│ │ ├── Div.svelte
│ │ └── div.html
│ ├── form-example
│ │ ├── README.md
│ │ ├── abstraction-example.html
│ │ └── index.html
│ ├── index.html
│ ├── kde-example
│ │ └── index.html
│ ├── mobile-example
│ │ ├── app.js
│ │ └── index.html
│ ├── native-ui-example
│ │ └── index.html
│ ├── section
│ │ ├── Section.svelte
│ │ └── section.html
│ └── ui-elements
│ │ ├── README.md
│ │ └── index.html
│ ├── favicon.ico
│ ├── favicon.png
│ ├── index.html
│ ├── ios
│ ├── README.md
│ ├── WKWebViewHandler.swift
│ └── WebViewViewController.swift
│ ├── logo.png
│ ├── logo.svg
│ ├── native
│ ├── kde
│ │ ├── README.md
│ │ ├── main.cpp
│ │ ├── mainwindow.cpp
│ │ ├── mainwindow.h
│ │ ├── resources.qrc
│ │ ├── sans-ui-kde.pro
│ │ ├── webbridge.cpp
│ │ └── webbridge.h
│ └── qt
│ │ ├── main.cpp
│ │ ├── mainwindow.cpp
│ │ ├── mainwindow.h
│ │ ├── resources.qrc
│ │ ├── sans-ui-qt.pro
│ │ ├── webbridge.cpp
│ │ └── webbridge.h
│ ├── package.json
│ ├── pnpm-lock.yaml
│ ├── releaase-package.yml
│ ├── scripts
│ ├── build-components.js
│ └── build-deno.js
│ ├── src
│ ├── app.svelte
│ ├── components
│ │ ├── WebViewComponent.svelte
│ │ └── html5
│ │ │ ├── A.svelte
│ │ │ ├── AComponent.js
│ │ │ ├── Article.svelte
│ │ │ ├── ArticleComponent.js
│ │ │ ├── Aside.svelte
│ │ │ ├── AsideComponent.js
│ │ │ ├── Button.svelte
│ │ │ ├── ButtonComponent.js
│ │ │ ├── Div.svelte
│ │ │ ├── DivComponent.js
│ │ │ ├── Footer.svelte
│ │ │ ├── FooterComponent.js
│ │ │ ├── FormComponent.js
│ │ │ ├── H1.svelte
│ │ │ ├── H1Component.js
│ │ │ ├── Header.svelte
│ │ │ ├── HeaderComponent.js
│ │ │ ├── Img.svelte
│ │ │ ├── ImgComponent.js
│ │ │ ├── InputComponent.js
│ │ │ ├── LabelComponent.js
│ │ │ ├── Main.svelte
│ │ │ ├── MainComponent.js
│ │ │ ├── Nav.svelte
│ │ │ ├── NavComponent.js
│ │ │ ├── OptionComponent.js
│ │ │ ├── P.svelte
│ │ │ ├── PComponent.js
│ │ │ ├── Section.svelte
│ │ │ ├── SectionComponent.js
│ │ │ ├── SelectComponent.js
│ │ │ ├── TextareaComponent.js
│ │ │ ├── a.html
│ │ │ ├── article.html
│ │ │ ├── aside.html
│ │ │ ├── button.html
│ │ │ ├── div.html
│ │ │ ├── footer.html
│ │ │ ├── h1.html
│ │ │ ├── header.html
│ │ │ ├── index.js
│ │ │ ├── main.html
│ │ │ ├── nav.html
│ │ │ ├── p.html
│ │ │ └── section.html
│ ├── index.js
│ └── lib
│ │ ├── components
│ │ ├── ComponentAdapter.js
│ │ ├── ComponentFactory.js
│ │ ├── README.md
│ │ └── index.js
│ │ ├── native
│ │ ├── NativeUIAdapter.js
│ │ ├── desktop
│ │ │ └── DesktopAdapter.js
│ │ ├── mobile
│ │ │ └── MobileAdapter.js
│ │ └── web
│ │ │ └── WebAdapter.js
│ │ ├── platform
│ │ └── PlatformDetector.js
│ │ └── webview
│ │ ├── QtWebEngineBridge.js
│ │ ├── WKWebViewBridge.js
│ │ ├── WebViewAdapter.js
│ │ └── types.d.ts
│ ├── static
│ └── logos
│ │ ├── api
│ │ ├── favicon.sans-api.svg
│ │ ├── favicon.sans-api.white.svg
│ │ ├── logo.sans-api.svg
│ │ └── logo.sans-api.white.svg
│ │ ├── db
│ │ ├── favicon.db.svg
│ │ ├── favicon.db.white.svg
│ │ ├── logo.sans-db.svg
│ │ └── logo.sans-db.white.svg
│ │ └── ui
│ │ ├── favicon.sans-ui.svg
│ │ ├── favicon.sans-ui.white.svg
│ │ ├── logo.sans-ui.svg
│ │ └── logo.sans-ui.white.svg
│ ├── tsconfig.json
│ ├── vite.config.js
│ └── vite.docs.js
└── publish-packages.sh
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | pnpm-debug.log*
8 | lerna-debug.log*
9 |
10 | # Dependency directories
11 | node_modules
12 | .npm
13 |
14 | # Build outputs
15 | dist
16 | dist-ssr
17 | *.local
18 |
19 | # Editor directories and files
20 | .vscode/*
21 | !.vscode/extensions.json
22 | .idea
23 | .DS_Store
24 | *.suo
25 | *.ntvs*
26 | *.njsproj
27 | *.sln
28 | *.sw?
29 |
30 | # Vite specific
31 | .vite/
32 |
33 | # Environment variables
34 | .env
35 | .env.*
36 | !.env.example
37 |
38 | # Coverage directory used by tools like istanbul
39 | coverage
40 |
41 | # Optional npm cache directory
42 | .npm
43 |
44 | # Optional eslint cache
45 | .eslintcache
46 |
47 | # Optional stylelint cache
48 | .stylelintcache
49 |
50 | # Yarn Integrity file
51 | .yarn-integrity
52 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Code of Conduct
2 |
3 | This project adheres to No Code of Conduct. We are all adults. We accept anyone's contributions. Nothing else matters.
4 |
5 | For more information please visit the [No Code of Conduct](https://nocodeofconduct.com) homepage.
6 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | # ISC License
2 |
3 | Copyright (c) 2025, Profullstack, Inc.
4 |
5 | Permission to use, copy, modify, and/or distribute this software for any
6 | purpose with or without fee is hereby granted, provided that the above
7 | copyright notice and this permission notice appear in all copies.
8 |
9 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@profullstack/sans",
3 | "version": "1.0.0",
4 | "description": "Sans framework with UI, API, and DB components",
5 | "type": "module",
6 | "private": true,
7 | "workspaces": [
8 | "ui",
9 | "api",
10 | "db"
11 | ],
12 | "scripts": {
13 | "build": "pnpm --filter ./ui build",
14 | "test": "pnpm --filter ./ui test",
15 | "lint": "pnpm --filter ./ui lint",
16 | "format": "pnpm --filter ./ui format"
17 | },
18 | "keywords": [
19 | "sans",
20 | "framework",
21 | "ui",
22 | "api",
23 | "db"
24 | ],
25 | "author": "Profullstack",
26 | "license": "ISC",
27 | "repository": {
28 | "type": "git",
29 | "url": "https://github.com/profullstack/sans.git"
30 | },
31 | "bugs": {
32 | "url": "https://github.com/profullstack/sans/issues"
33 | },
34 | "homepage": "https://github.com/profullstack/sans"
35 | }
36 |
--------------------------------------------------------------------------------
/packages/api/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | # Sans API
8 |
9 | A lightweight API framework for building backend services.
10 |
11 | ## Coming Soon
12 |
13 | The Sans API framework is currently under development. Stay tuned for updates!
14 |
15 | ## Features (Planned)
16 |
17 | - RESTful API support
18 | - GraphQL integration
19 | - Authentication and authorization
20 | - Rate limiting and caching
21 | - Middleware support
22 | - Documentation generation
23 | - Integration with Sans UI and Sans DB
24 |
25 | ## Integration with Sans Component Abstraction Layer
26 |
27 | Sans API will integrate seamlessly with the Sans UI component abstraction layer, allowing for easy communication between frontend and backend components.
28 |
29 | ---
30 |
31 | ## Connect With Us
32 |
33 | [](https://www.reddit.com/r/sans_ui/)
34 | [](https://x.com/profullstackinc)
35 | [](https://www.linkedin.com/company/profullstackinc)
36 | [](https://t.me/+VGCI_sR-guhmNTNh)
37 | [](https://join.slack.com/t/profullstackinc/shared_invite/zt-2d9c842fk-jo848We~tDajW9nn6DEggw)
38 | [](https://discord.gg/XXvzu4G4)
39 | [](https://github.com/profullstack)
40 |
41 | *Built happily using "Windsurf on Linux"*
42 | *Sponsored by [Profullstack, Inc.](https://profullstack.com)*
43 |
--------------------------------------------------------------------------------
/packages/api/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@profullstack/sans-api",
3 | "version": "1.0.3",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "keywords": [],
10 | "author": "",
11 | "license": "ISC",
12 | "publishConfig": {
13 | "access": "public"
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/packages/db/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@profullstack/sans-db",
3 | "version": "1.0.3",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "keywords": [],
10 | "author": "",
11 | "license": "ISC",
12 | "publishConfig": {
13 | "access": "public"
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/packages/ui.deprecated/.gitignore:
--------------------------------------------------------------------------------
1 | # Dependencies
2 | node_modules/
3 |
4 | # Environment variables
5 | .env*
6 |
7 | # Build artifacts
8 | /dist/
9 | /.svelte-kit/
10 | /build/
11 |
12 | # IDE and editor files
13 | .idea/
14 | .vscode/
15 | *.sublime-project
16 | *.sublime-workspace
17 |
18 | # OS files
19 | .DS_Store
20 | Thumbs.db
21 |
22 | # Logs
23 | npm-debug.log*
24 | yarn-debug.log*
25 | yarn-error.log*
26 | pnpm-debug.log*
27 |
28 | # Cache
29 | .cache/
30 | .pnpm-store/
31 |
--------------------------------------------------------------------------------
/packages/ui.deprecated/.npmrc:
--------------------------------------------------------------------------------
1 | @profullstack:registry=https://npm.pkg.github.com
--------------------------------------------------------------------------------
/packages/ui.deprecated/bunfig.toml:
--------------------------------------------------------------------------------
1 | # Sans UI Bun Configuration
2 |
3 | [install]
4 | dry-run = false
5 | frozen-lockfile = false
6 |
7 | [install.cache]
8 | dir = ".bun/install/cache"
9 | enabled = true
10 |
11 | [test]
12 | coverage = false
13 |
14 | [build]
15 | entrypoints = ["src/index.js"]
16 | outdir = "dist"
17 | splitting = true
18 | minify = true
19 | modules = true
20 |
21 | [publish]
22 | access = "public"
23 | scope = "profullstack"
24 | registry = "https://registry.npmjs.org/"
25 |
--------------------------------------------------------------------------------
/packages/ui.deprecated/examples/backend/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "sans-ui-backend-example",
3 | "version": "1.0.0",
4 | "description": "Backend API example for Sans UI using Elysia and Mailgun",
5 | "main": "index.js",
6 | "type": "module",
7 | "scripts": {
8 | "start": "node index.js",
9 | "dev": "node --watch index.js"
10 | },
11 | "keywords": [
12 | "sans-ui",
13 | "elysia",
14 | "mailgun",
15 | "api"
16 | ],
17 | "author": "",
18 | "license": "ISC",
19 | "dependencies": {
20 | "@elysiajs/cors": "^0.8.0",
21 | "@supabase/supabase-js": "^2.39.0",
22 | "dotenv": "^16.3.1",
23 | "elysia": "^0.8.9",
24 | "form-data": "^4.0.0",
25 | "mailgun.js": "^9.3.0"
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/packages/ui.deprecated/examples/backend/sample.env:
--------------------------------------------------------------------------------
1 | # API Configuration
2 | PORT=3001
3 | API_KEY=your_api_key_here
4 |
5 | # Mailgun Configuration
6 | MAILGUN_API_KEY=your_mailgun_api_key_here
7 | MAILGUN_DOMAIN=your_mailgun_domain.com
8 | EMAIL_FROM=Sans UI
9 |
10 | # Supabase Configuration
11 | SUPABASE_URL=https://your-project-id.supabase.co
12 | SUPABASE_KEY=your_supabase_anon_key_here
13 | SUPABASE_TABLE=subscribers
14 |
15 | # CORS Configuration
16 | ALLOW_ORIGINS=http://localhost:3000,http://localhost:8000
17 |
--------------------------------------------------------------------------------
/packages/ui.deprecated/examples/ui-elements/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | # Sans UI Elements Showcase
8 |
9 | This example showcases all the available UI elements and components in the Sans UI library. It serves as a visual reference and documentation for developers using the Sans UI framework.
10 |
11 | ## Components Demonstrated
12 |
13 | ### Basic HTML Components
14 | - `sans-div`: Basic container component
15 | - `sans-p`: Paragraph component
16 | - `sans-h1`: Heading component
17 | - `sans-a`: Anchor/link component
18 | - `sans-img`: Image component
19 | - `sans-button`: Button component
20 |
21 | ### Form Components
22 | - `sans-form`: Form container component
23 | - `sans-input`: Input field component (text, number, checkbox, etc.)
24 | - `sans-select`: Dropdown select component
25 | - `sans-option`: Option component for select dropdowns
26 | - `sans-textarea`: Multi-line text input component
27 | - `sans-label`: Label component for form fields
28 |
29 | ### Layout Components
30 | - `sans-section`: Section container component
31 | - `sans-article`: Article container component
32 | - `sans-header`: Header component
33 | - `sans-footer`: Footer component
34 |
35 | ## Color Palette
36 | The example also demonstrates the standard color palette used in Sans UI:
37 | - Primary: #6200ee
38 | - Secondary: #03dac6
39 | - Error: #b00020
40 | - Warning: #ffab00
41 | - Info: #2196f3
42 | - Success: #4caf50
43 |
44 | ## Component Abstraction Layer
45 | The example includes a demonstration of the Component Abstraction Layer, showing how to create and manipulate components programmatically using the `ComponentFactory` class.
46 |
47 | ## Usage
48 | To view this example, run the development server using:
49 |
50 | ```bash
51 | pnpm dev
52 | ```
53 |
54 | Then navigate to the UI Elements example from the home page or go directly to `/examples/ui-elements/`.
55 |
56 | ## Integration
57 | All components shown in this example can be used in your own applications by importing and registering them from the Sans UI library:
58 |
59 | ```javascript
60 | import { registerAllComponents } from 'sans-ui/components/html5/index.js';
61 |
62 | // Register all components
63 | registerAllComponents();
64 | ```
65 |
66 | For programmatic component creation, use the Component Factory:
67 |
68 | ```javascript
69 | import ComponentFactory from 'sans-ui/lib/components/ComponentFactory.js';
70 |
71 | const button = ComponentFactory.createButton({
72 | textContent: 'Click Me',
73 | id: 'myButton'
74 | });
75 |
76 | document.body.appendChild(button.getElement());
77 | ```
78 |
--------------------------------------------------------------------------------
/packages/ui.deprecated/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/profullstack/sans/2f6b03811f6ee84704ecad6d7b72317c55c90709/packages/ui.deprecated/favicon.ico
--------------------------------------------------------------------------------
/packages/ui.deprecated/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/profullstack/sans/2f6b03811f6ee84704ecad6d7b72317c55c90709/packages/ui.deprecated/favicon.png
--------------------------------------------------------------------------------
/packages/ui.deprecated/ios/WebViewViewController.swift:
--------------------------------------------------------------------------------
1 | import UIKit
2 | import WebKit
3 |
4 | /**
5 | * WebViewViewController
6 | * A sample iOS view controller that implements the WKWebView integration
7 | */
8 | class WebViewViewController: UIViewController {
9 |
10 | private var webView: WKWebView!
11 | private var webViewHandler: WKWebViewHandler!
12 |
13 | var initialUrl: URL = URL(string: "https://example.com")!
14 |
15 | override func viewDidLoad() {
16 | super.viewDidLoad()
17 |
18 | setupWebView()
19 | loadInitialUrl()
20 | }
21 |
22 | private func setupWebView() {
23 | // Create WKWebView configuration
24 | let configuration = WKWebViewConfiguration()
25 | configuration.allowsInlineMediaPlayback = true
26 | configuration.mediaTypesRequiringUserActionForPlayback = []
27 |
28 | // Create WKWebView
29 | webView = WKWebView(frame: view.bounds, configuration: configuration)
30 | webView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
31 | view.addSubview(webView)
32 |
33 | // Create and setup the WKWebView handler
34 | webViewHandler = WKWebViewHandler(webView: webView)
35 | }
36 |
37 | private func loadInitialUrl() {
38 | let request = URLRequest(url: initialUrl)
39 | webView.load(request)
40 | }
41 |
42 | // Example of how to expose native functionality to JavaScript
43 | func exposeNativeFunctions() {
44 | // This could include additional native functionality like camera access, location, etc.
45 | // For example, to add a function that shows a native alert:
46 | let script = """
47 | window.nativeApp = window.nativeApp || {};
48 | window.nativeApp.showAlert = function(title, message) {
49 | window.webkit.messageHandlers.webViewBridge.postMessage({
50 | id: 'alert_' + Date.now(),
51 | action: 'showAlert',
52 | data: { title: title, message: message }
53 | });
54 | };
55 | """
56 |
57 | let userScript = WKUserScript(source: script, injectionTime: .atDocumentEnd, forMainFrameOnly: false)
58 | webView.configuration.userContentController.addUserScript(userScript)
59 | }
60 |
61 | // MARK: - Additional Native Functionality
62 |
63 | func showNativeAlert(title: String, message: String) {
64 | let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
65 | alertController.addAction(UIAlertAction(title: "OK", style: .default))
66 | present(alertController, animated: true)
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/packages/ui.deprecated/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/profullstack/sans/2f6b03811f6ee84704ecad6d7b72317c55c90709/packages/ui.deprecated/logo.png
--------------------------------------------------------------------------------
/packages/ui.deprecated/logo.svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/packages/ui.deprecated/native/kde/main.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include "mainwindow.h"
5 |
6 | int main(int argc, char *argv[])
7 | {
8 | QApplication app(argc, argv);
9 | app.setApplicationName("Sans UI KDE WebEngine");
10 | app.setApplicationVersion("1.0.0");
11 |
12 | QCommandLineParser parser;
13 | parser.setApplicationDescription("Sans UI KDE WebEngine Bridge");
14 | parser.addHelpOption();
15 | parser.addVersionOption();
16 |
17 | // Add URL option
18 | QCommandLineOption urlOption(QStringList() << "u" << "url", "URL to load", "url", "http://localhost:3000");
19 | parser.addOption(urlOption);
20 |
21 | // Add title option
22 | QCommandLineOption titleOption(QStringList() << "t" << "title", "Window title", "title", "Sans UI Application");
23 | parser.addOption(titleOption);
24 |
25 | // Add window size options
26 | QCommandLineOption widthOption(QStringList() << "w" << "width", "Window width", "width", "800");
27 | QCommandLineOption heightOption(QStringList() << "h" << "height", "Window height", "height", "600");
28 | parser.addOption(widthOption);
29 | parser.addOption(heightOption);
30 |
31 | // Process the command line arguments
32 | parser.process(app);
33 |
34 | // Get values from command line
35 | QString url = parser.value(urlOption);
36 | QString title = parser.value(titleOption);
37 | int width = parser.value(widthOption).toInt();
38 | int height = parser.value(heightOption).toInt();
39 |
40 | // Create and show the main window
41 | MainWindow mainWindow;
42 | mainWindow.setWindowTitle(title);
43 | mainWindow.resize(width, height);
44 | mainWindow.loadUrl(QUrl(url));
45 | mainWindow.show();
46 |
47 | return app.exec();
48 | }
49 |
--------------------------------------------------------------------------------
/packages/ui.deprecated/native/kde/mainwindow.h:
--------------------------------------------------------------------------------
1 | #ifndef MAINWINDOW_H
2 | #define MAINWINDOW_H
3 |
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include "webbridge.h"
9 |
10 | class MainWindow : public QMainWindow
11 | {
12 | Q_OBJECT
13 |
14 | public:
15 | explicit MainWindow(QWidget *parent = nullptr);
16 | ~MainWindow();
17 |
18 | void loadUrl(const QUrl &url);
19 |
20 | private:
21 | QWebEngineView *m_webView;
22 | WebBridge *m_webBridge;
23 | QWebChannel *m_webChannel;
24 |
25 | void setupWebView();
26 | void setupWebChannel();
27 | void setupMenus();
28 | };
29 |
30 | #endif // MAINWINDOW_H
31 |
--------------------------------------------------------------------------------
/packages/ui.deprecated/native/kde/resources.qrc:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/packages/ui.deprecated/native/kde/sans-ui-kde.pro:
--------------------------------------------------------------------------------
1 | QT += core gui webengine webenginewidgets
2 |
3 | greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
4 |
5 | CONFIG += c++11
6 |
7 | # You can make your code fail to compile if it uses deprecated APIs.
8 | # In order to do so, uncomment the following line.
9 | #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
10 |
11 | # KDE integration
12 | CONFIG += link_pkgconfig
13 | PKGCONFIG += knotifications
14 |
15 | SOURCES += \
16 | main.cpp \
17 | mainwindow.cpp \
18 | webbridge.cpp
19 |
20 | HEADERS += \
21 | mainwindow.h \
22 | webbridge.h
23 |
24 | # Default rules for deployment.
25 | qnx: target.path = /tmp/$${TARGET}/bin
26 | else: unix:!android: target.path = /opt/$${TARGET}/bin
27 | !isEmpty(target.path): INSTALLS += target
28 |
29 | # Include the qwebchannel.js file
30 | RESOURCES += \
31 | resources.qrc
32 |
--------------------------------------------------------------------------------
/packages/ui.deprecated/native/kde/webbridge.h:
--------------------------------------------------------------------------------
1 | #ifndef WEBBRIDGE_H
2 | #define WEBBRIDGE_H
3 |
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 |
10 | class WebBridge : public QObject
11 | {
12 | Q_OBJECT
13 |
14 | public:
15 | explicit WebBridge(QObject *parent = nullptr);
16 |
17 | public slots:
18 | // Method to receive messages from JavaScript
19 | void sendMessage(const QString &messageJson);
20 |
21 | // Native functionality exposed to JavaScript
22 | QString openFileDialog(const QVariantMap &options);
23 | bool showNotification(const QVariantMap &options);
24 |
25 | signals:
26 | // Signal to send messages to JavaScript
27 | void messageReceived(const QString &messageJson);
28 |
29 | // Signals for specific events
30 | void fileSelected(const QString &filePath);
31 |
32 | private:
33 | // Helper methods
34 | void sendResponse(const QString &id, const QVariant &data, const QString &error = QString());
35 | void processMessage(const QJsonObject &message);
36 | };
37 |
38 | #endif // WEBBRIDGE_H
39 |
--------------------------------------------------------------------------------
/packages/ui.deprecated/native/qt/main.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include "mainwindow.h"
5 |
6 | int main(int argc, char *argv[])
7 | {
8 | QApplication app(argc, argv);
9 | app.setApplicationName("Sans UI Qt WebEngine");
10 | app.setApplicationVersion("1.0.0");
11 |
12 | QCommandLineParser parser;
13 | parser.setApplicationDescription("Sans UI Qt WebEngine Bridge");
14 | parser.addHelpOption();
15 | parser.addVersionOption();
16 |
17 | // Add URL option
18 | QCommandLineOption urlOption(QStringList() << "u" << "url", "URL to load", "url", "http://localhost:3000");
19 | parser.addOption(urlOption);
20 |
21 | // Add title option
22 | QCommandLineOption titleOption(QStringList() << "t" << "title", "Window title", "title", "Sans UI Application");
23 | parser.addOption(titleOption);
24 |
25 | // Add window size options
26 | QCommandLineOption widthOption(QStringList() << "w" << "width", "Window width", "width", "800");
27 | QCommandLineOption heightOption(QStringList() << "h" << "height", "Window height", "height", "600");
28 | parser.addOption(widthOption);
29 | parser.addOption(heightOption);
30 |
31 | // Process the command line arguments
32 | parser.process(app);
33 |
34 | // Get values from command line
35 | QString url = parser.value(urlOption);
36 | QString title = parser.value(titleOption);
37 | int width = parser.value(widthOption).toInt();
38 | int height = parser.value(heightOption).toInt();
39 |
40 | // Create and show the main window
41 | MainWindow mainWindow;
42 | mainWindow.setWindowTitle(title);
43 | mainWindow.resize(width, height);
44 | mainWindow.loadUrl(QUrl(url));
45 | mainWindow.show();
46 |
47 | return app.exec();
48 | }
49 |
--------------------------------------------------------------------------------
/packages/ui.deprecated/native/qt/mainwindow.h:
--------------------------------------------------------------------------------
1 | #ifndef MAINWINDOW_H
2 | #define MAINWINDOW_H
3 |
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include "webbridge.h"
9 |
10 | class MainWindow : public QMainWindow
11 | {
12 | Q_OBJECT
13 |
14 | public:
15 | explicit MainWindow(QWidget *parent = nullptr);
16 | ~MainWindow();
17 |
18 | void loadUrl(const QUrl &url);
19 |
20 | private:
21 | QWebEngineView *m_webView;
22 | WebBridge *m_webBridge;
23 | QWebChannel *m_webChannel;
24 |
25 | void setupWebView();
26 | void setupWebChannel();
27 | void setupMenus();
28 | };
29 |
30 | #endif // MAINWINDOW_H
31 |
--------------------------------------------------------------------------------
/packages/ui.deprecated/native/qt/resources.qrc:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/packages/ui.deprecated/native/qt/sans-ui-qt.pro:
--------------------------------------------------------------------------------
1 | QT += core gui webengine webenginewidgets
2 |
3 | greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
4 |
5 | CONFIG += c++11
6 |
7 | # You can make your code fail to compile if it uses deprecated APIs.
8 | # In order to do so, uncomment the following line.
9 | #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
10 |
11 | # Optional KDE integration
12 | CONFIG += link_pkgconfig
13 | PKGCONFIG += knotifications
14 |
15 | SOURCES += \
16 | main.cpp \
17 | mainwindow.cpp \
18 | webbridge.cpp
19 |
20 | HEADERS += \
21 | mainwindow.h \
22 | webbridge.h
23 |
24 | # Default rules for deployment.
25 | qnx: target.path = /tmp/$${TARGET}/bin
26 | else: unix:!android: target.path = /opt/$${TARGET}/bin
27 | !isEmpty(target.path): INSTALLS += target
28 |
29 | # Include the qwebchannel.js file
30 | RESOURCES += \
31 | resources.qrc
32 |
--------------------------------------------------------------------------------
/packages/ui.deprecated/native/qt/webbridge.h:
--------------------------------------------------------------------------------
1 | #ifndef WEBBRIDGE_H
2 | #define WEBBRIDGE_H
3 |
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 |
10 | class WebBridge : public QObject
11 | {
12 | Q_OBJECT
13 |
14 | public:
15 | explicit WebBridge(QObject *parent = nullptr);
16 |
17 | public slots:
18 | // Method to receive messages from JavaScript
19 | void sendMessage(const QString &messageJson);
20 |
21 | // Native functionality exposed to JavaScript
22 | QString openFileDialog(const QVariantMap &options);
23 | bool showNotification(const QVariantMap &options);
24 |
25 | signals:
26 | // Signal to send messages to JavaScript
27 | void messageReceived(const QString &messageJson);
28 |
29 | // Signals for specific events
30 | void fileSelected(const QString &filePath);
31 |
32 | private:
33 | // Helper methods
34 | void sendResponse(const QString &id, const QVariant &data, const QString &error = QString());
35 | void processMessage(const QJsonObject &message);
36 | };
37 |
38 | #endif // WEBBRIDGE_H
39 |
--------------------------------------------------------------------------------
/packages/ui.deprecated/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@profullstackinc/sans-ui",
3 | "version": "1.0.0",
4 | "description": "A cross-platform native UI library which supports iOS, Android, Windows, macOS, and Linux using WebViewJS, Apple's WKWebView API, and KDE's Qt WebEngine. Built with Svelte 4 and web components.",
5 | "type": "module",
6 | "main": "dist/index.js",
7 | "module": "dist/index.js",
8 | "svelte": "src/index.js",
9 | "types": "dist/index.d.ts",
10 | "exports": {
11 | ".": {
12 | "types": "./dist/index.d.ts",
13 | "svelte": "./src/index.js",
14 | "import": "./dist/index.js",
15 | "require": "./dist/index.cjs"
16 | },
17 | "./html5": {
18 | "types": "./dist/html5/index.d.ts",
19 | "svelte": "./src/components/html5/index.js",
20 | "import": "./dist/html5/index.js",
21 | "require": "./dist/html5/index.cjs"
22 | },
23 | "./package.json": "./package.json"
24 | },
25 | "files": [
26 | "src",
27 | "dist"
28 | ],
29 | "scripts": {
30 | "dev": "pnpx vite",
31 | "build": "pnpx vite build && pnpm run build:components",
32 | "build:components": "node scripts/build-components.js",
33 | "build:types": "pnpx tsc --emitDeclarationOnly",
34 | "build:with-types": "pnpx vite build && pnpm run build:components && pnpm run build:types",
35 | "preview": "pnpx vite preview",
36 | "prepublishOnly": "pnpm run build",
37 | "test": "pnpx vitest run",
38 | "test:watch": "pnpx vitest",
39 | "lint": "pnpx eslint .",
40 | "format": "pnpx prettier --write .",
41 | "deno:build": "node scripts/build-deno.js",
42 | "publish:npm": "npm publish",
43 | "publish:bun": "bun publish",
44 | "publish:deno": "pnpm run deno:build && deno publish"
45 | },
46 | "dependencies": {
47 | "@webviewjs/webview": "^0.1.3"
48 | },
49 | "peerDependencies": {
50 | "svelte": "^4.0.0"
51 | },
52 | "devDependencies": {
53 | "@sveltejs/package": "^2.2.2",
54 | "@sveltejs/vite-plugin-svelte": "^2.5.3",
55 | "@types/node": "^22.13.10",
56 | "@typescript-eslint/eslint-plugin": "^6.0.0",
57 | "@typescript-eslint/parser": "^6.0.0",
58 | "eslint": "^8.45.0",
59 | "eslint-plugin-svelte": "^2.30.0",
60 | "prettier": "^3.0.0",
61 | "prettier-plugin-svelte": "^3.0.0",
62 | "svelte": "^4.2.19",
63 | "typescript": "^5.8.2",
64 | "vite": "^4.5.9",
65 | "vitest": "^0.34.0"
66 | },
67 | "keywords": [
68 | "svelte",
69 | "web-components",
70 | "ui-library",
71 | "cross-platform",
72 | "html5",
73 | "components"
74 | ],
75 | "author": "Profullstack",
76 | "license": "ISC",
77 | "repository": {
78 | "type": "git",
79 | "url": "https://github.com/profullstack/sans-ui.git"
80 | },
81 | "bugs": {
82 | "url": "https://github.com/profullstack/sans-ui/issues"
83 | },
84 | "homepage": "https://github.com/profullstack/sans-ui",
85 | "publishConfig": {
86 | "access": "public",
87 | "@profullstack:registry": "https://npm.pkg.github.com"
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/packages/ui.deprecated/releaase-package.yml:
--------------------------------------------------------------------------------
1 | name: sans-ui
2 |
3 | on:
4 | release:
5 | types: [created]
6 |
7 | jobs:
8 | build:
9 | runs-on: ubuntu-latest
10 | steps:
11 | - uses: actions/checkout@v4
12 | - uses: actions/setup-node@v4
13 | with:
14 | node-version: 20
15 | - run: npm ci
16 | - run: npm test
17 |
18 | publish-gpr:
19 | needs: build
20 | runs-on: ubuntu-latest
21 | permissions:
22 | packages: write
23 | contents: read
24 | steps:
25 | - uses: actions/checkout@v4
26 | - uses: actions/setup-node@v4
27 | with:
28 | node-version: 20
29 | registry-url: https://npm.pkg.github.com/
30 | - run: npm ci
31 | - run: npm publish
32 | env:
33 | NODE_AUTH_TOKEN: ${{secrets.GITHUB_TOKEN}}
34 |
--------------------------------------------------------------------------------
/packages/ui.deprecated/src/app.svelte:
--------------------------------------------------------------------------------
1 |
11 |
12 |
13 | Svelte 4 WebView with Platform Abstraction
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/packages/ui.deprecated/src/components/WebViewComponent.svelte:
--------------------------------------------------------------------------------
1 |
38 |
39 |
40 |
41 |
42 |
43 |
{currentUrl}
44 |
45 |
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/packages/ui.deprecated/src/components/html5/A.svelte:
--------------------------------------------------------------------------------
1 |
18 |
19 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/packages/ui.deprecated/src/components/html5/AComponent.js:
--------------------------------------------------------------------------------
1 | /**
2 | * AComponent.js
3 | * A reusable sans-a web component that can be used in any HTML context
4 | */
5 |
6 | class SansA extends HTMLElement {
7 | constructor() {
8 | super();
9 | this.attachShadow({ mode: 'open' });
10 | }
11 |
12 | static get observedAttributes() {
13 | return ['id', 'class', 'style', 'href', 'target', 'rel', 'download', 'role', 'tabindex', 'aria-label', 'data-testid'];
14 | }
15 |
16 | connectedCallback() {
17 | this.render();
18 | this.a = this.shadowRoot.querySelector('a');
19 | this.a.addEventListener('click', (e) => {
20 | // Dispatch a custom event
21 | this.dispatchEvent(new CustomEvent('a-click', {
22 | bubbles: true,
23 | composed: true,
24 | detail: { source: this }
25 | }));
26 | });
27 | }
28 |
29 | attributeChangedCallback(name, oldValue, newValue) {
30 | if (oldValue === newValue) return;
31 |
32 | if (this.shadowRoot) {
33 | this.render();
34 | }
35 | }
36 |
37 | render() {
38 | const id = this.getAttribute('id') || '';
39 | const className = this.getAttribute('class') || '';
40 | const style = this.getAttribute('style') || '';
41 | const href = this.getAttribute('href') || '#';
42 | const target = this.getAttribute('target') || '';
43 | const rel = this.getAttribute('rel') || '';
44 | const download = this.getAttribute('download') || '';
45 | const role = this.getAttribute('role') || '';
46 | const tabindex = this.getAttribute('tabindex') || '';
47 | const ariaLabel = this.getAttribute('aria-label') || '';
48 | const dataTestid = this.getAttribute('data-testid') || '';
49 |
50 | this.shadowRoot.innerHTML = `
51 |
70 |
83 |
84 |
85 | `;
86 | }
87 | }
88 |
89 | // Register the custom element if we're in a browser environment
90 | if (typeof window !== 'undefined' && window.customElements) {
91 | customElements.define('sans-a', SansA);
92 | }
93 |
94 | export default SansA;
95 |
--------------------------------------------------------------------------------
/packages/ui.deprecated/src/components/html5/Article.svelte:
--------------------------------------------------------------------------------
1 |
14 |
15 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/packages/ui.deprecated/src/components/html5/ArticleComponent.js:
--------------------------------------------------------------------------------
1 | /**
2 | * ArticleComponent.js
3 | * A reusable sans-article web component that can be used in any HTML context
4 | */
5 |
6 | class SansArticle extends HTMLElement {
7 | constructor() {
8 | super();
9 | this.attachShadow({ mode: 'open' });
10 | }
11 |
12 | static get observedAttributes() {
13 | return ['id', 'class', 'style', 'role', 'tabindex', 'aria-label', 'data-testid'];
14 | }
15 |
16 | connectedCallback() {
17 | this.render();
18 | this.article = this.shadowRoot.querySelector('article');
19 | this.article.addEventListener('click', (e) => {
20 | // Dispatch a custom event
21 | this.dispatchEvent(new CustomEvent('article-click', {
22 | bubbles: true,
23 | composed: true,
24 | detail: { source: this }
25 | }));
26 | });
27 | }
28 |
29 | attributeChangedCallback(name, oldValue, newValue) {
30 | if (oldValue === newValue) return;
31 |
32 | if (this.shadowRoot) {
33 | this.render();
34 | }
35 | }
36 |
37 | render() {
38 | const id = this.getAttribute('id') || '';
39 | const className = this.getAttribute('class') || '';
40 | const style = this.getAttribute('style') || '';
41 | const role = this.getAttribute('role') || '';
42 | const tabindex = this.getAttribute('tabindex') || '';
43 | const ariaLabel = this.getAttribute('aria-label') || '';
44 | const dataTestid = this.getAttribute('data-testid') || '';
45 |
46 | this.shadowRoot.innerHTML = `
47 |
56 |
65 |
66 |
67 | `;
68 | }
69 | }
70 |
71 | // Register the custom element if we're in a browser environment
72 | if (typeof window !== 'undefined' && window.customElements) {
73 | customElements.define('sans-article', SansArticle);
74 | }
75 |
76 | export default SansArticle;
77 |
--------------------------------------------------------------------------------
/packages/ui.deprecated/src/components/html5/Aside.svelte:
--------------------------------------------------------------------------------
1 |
14 |
15 |
27 |
--------------------------------------------------------------------------------
/packages/ui.deprecated/src/components/html5/AsideComponent.js:
--------------------------------------------------------------------------------
1 | /**
2 | * AsideComponent.js
3 | * A reusable sans-aside web component that can be used in any HTML context
4 | */
5 |
6 | class SansAside extends HTMLElement {
7 | constructor() {
8 | super();
9 | this.attachShadow({ mode: 'open' });
10 | }
11 |
12 | static get observedAttributes() {
13 | return ['id', 'class', 'style', 'role', 'tabindex', 'aria-label', 'data-testid'];
14 | }
15 |
16 | connectedCallback() {
17 | this.render();
18 | this.aside = this.shadowRoot.querySelector('aside');
19 | this.aside.addEventListener('click', (e) => {
20 | // Dispatch a custom event
21 | this.dispatchEvent(new CustomEvent('aside-click', {
22 | bubbles: true,
23 | composed: true,
24 | detail: { source: this }
25 | }));
26 | });
27 | }
28 |
29 | attributeChangedCallback(name, oldValue, newValue) {
30 | if (oldValue === newValue) return;
31 |
32 | if (this.shadowRoot) {
33 | this.render();
34 | }
35 | }
36 |
37 | render() {
38 | const id = this.getAttribute('id') || '';
39 | const className = this.getAttribute('class') || '';
40 | const style = this.getAttribute('style') || '';
41 | const role = this.getAttribute('role') || '';
42 | const tabindex = this.getAttribute('tabindex') || '';
43 | const ariaLabel = this.getAttribute('aria-label') || '';
44 | const dataTestid = this.getAttribute('data-testid') || '';
45 |
46 | this.shadowRoot.innerHTML = `
47 |
56 |
67 | `;
68 | }
69 | }
70 |
71 | // Register the custom element if we're in a browser environment
72 | if (typeof window !== 'undefined' && window.customElements) {
73 | customElements.define('sans-aside', SansAside);
74 | }
75 |
76 | export default SansAside;
77 |
--------------------------------------------------------------------------------
/packages/ui.deprecated/src/components/html5/Button.svelte:
--------------------------------------------------------------------------------
1 |
12 |
13 |
21 |
22 |
84 |
--------------------------------------------------------------------------------
/packages/ui.deprecated/src/components/html5/Div.svelte:
--------------------------------------------------------------------------------
1 |
14 |
15 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/packages/ui.deprecated/src/components/html5/DivComponent.js:
--------------------------------------------------------------------------------
1 | /**
2 | * DivComponent.js
3 | * A reusable sans-div web component that can be used in any HTML context
4 | */
5 |
6 | class SansDiv extends HTMLElement {
7 | constructor() {
8 | super();
9 | this.attachShadow({ mode: 'open' });
10 | }
11 |
12 | static get observedAttributes() {
13 | return ['id', 'class', 'style', 'role', 'tabindex', 'aria-label', 'data-testid'];
14 | }
15 |
16 | connectedCallback() {
17 | this.render();
18 | this.div = this.shadowRoot.querySelector('div');
19 | this.div.addEventListener('click', (e) => {
20 | // Dispatch a custom event
21 | this.dispatchEvent(new CustomEvent('div-click', {
22 | bubbles: true,
23 | composed: true,
24 | detail: { source: this }
25 | }));
26 | });
27 | }
28 |
29 | attributeChangedCallback(name, oldValue, newValue) {
30 | if (oldValue === newValue) return;
31 |
32 | if (this.shadowRoot) {
33 | this.render();
34 | }
35 | }
36 |
37 | render() {
38 | const id = this.getAttribute('id') || '';
39 | const className = this.getAttribute('class') || '';
40 | const style = this.getAttribute('style') || '';
41 | const role = this.getAttribute('role') || '';
42 | const tabindex = this.getAttribute('tabindex') || '';
43 | const ariaLabel = this.getAttribute('aria-label') || '';
44 | const dataTestid = this.getAttribute('data-testid') || '';
45 |
46 | this.shadowRoot.innerHTML = `
47 |
56 |
65 |
66 |
67 | `;
68 | }
69 | }
70 |
71 | // Register the custom element if we're in a browser environment
72 | if (typeof window !== 'undefined' && window.customElements) {
73 | customElements.define('sans-div', SansDiv);
74 | }
75 |
76 | export default SansDiv;
77 |
--------------------------------------------------------------------------------
/packages/ui.deprecated/src/components/html5/Footer.svelte:
--------------------------------------------------------------------------------
1 |
14 |
15 |
27 |
--------------------------------------------------------------------------------
/packages/ui.deprecated/src/components/html5/FooterComponent.js:
--------------------------------------------------------------------------------
1 | /**
2 | * FooterComponent.js
3 | * A reusable sans-footer web component that can be used in any HTML context
4 | */
5 |
6 | class SansFooter extends HTMLElement {
7 | constructor() {
8 | super();
9 | this.attachShadow({ mode: 'open' });
10 | }
11 |
12 | static get observedAttributes() {
13 | return ['id', 'class', 'style', 'role', 'tabindex', 'aria-label', 'data-testid'];
14 | }
15 |
16 | connectedCallback() {
17 | this.render();
18 | this.footer = this.shadowRoot.querySelector('footer');
19 | this.footer.addEventListener('click', (e) => {
20 | // Dispatch a custom event
21 | this.dispatchEvent(new CustomEvent('footer-click', {
22 | bubbles: true,
23 | composed: true,
24 | detail: { source: this }
25 | }));
26 | });
27 | }
28 |
29 | attributeChangedCallback(name, oldValue, newValue) {
30 | if (oldValue === newValue) return;
31 |
32 | if (this.shadowRoot) {
33 | this.render();
34 | }
35 | }
36 |
37 | render() {
38 | const id = this.getAttribute('id') || '';
39 | const className = this.getAttribute('class') || '';
40 | const style = this.getAttribute('style') || '';
41 | const role = this.getAttribute('role') || '';
42 | const tabindex = this.getAttribute('tabindex') || '';
43 | const ariaLabel = this.getAttribute('aria-label') || '';
44 | const dataTestid = this.getAttribute('data-testid') || '';
45 |
46 | this.shadowRoot.innerHTML = `
47 |
56 |
67 | `;
68 | }
69 | }
70 |
71 | // Register the custom element if we're in a browser environment
72 | if (typeof window !== 'undefined' && window.customElements) {
73 | customElements.define('sans-footer', SansFooter);
74 | }
75 |
76 | export default SansFooter;
77 |
--------------------------------------------------------------------------------
/packages/ui.deprecated/src/components/html5/FormComponent.js:
--------------------------------------------------------------------------------
1 | /**
2 | * FormComponent.js
3 | * A reusable sans-form web component that can be used in any HTML context
4 | */
5 |
6 | class SansForm extends HTMLElement {
7 | constructor() {
8 | super();
9 | this.attachShadow({ mode: 'open' });
10 | }
11 |
12 | static get observedAttributes() {
13 | return ['id', 'class', 'style', 'action', 'method', 'enctype', 'name', 'target', 'novalidate', 'autocomplete', 'data-testid'];
14 | }
15 |
16 | connectedCallback() {
17 | this.render();
18 | this.form = this.shadowRoot.querySelector('form');
19 |
20 | // Add event listeners
21 | this.form.addEventListener('submit', (e) => {
22 | // Prevent default form submission
23 | e.preventDefault();
24 |
25 | // Dispatch a custom event
26 | this.dispatchEvent(new CustomEvent('form-submit', {
27 | bubbles: true,
28 | composed: true,
29 | detail: {
30 | source: this,
31 | formData: new FormData(this.form)
32 | }
33 | }));
34 | });
35 | }
36 |
37 | attributeChangedCallback(name, oldValue, newValue) {
38 | if (oldValue === newValue) return;
39 |
40 | if (this.shadowRoot) {
41 | this.render();
42 | }
43 | }
44 |
45 | render() {
46 | const id = this.getAttribute('id') || '';
47 | const className = this.getAttribute('class') || '';
48 | const style = this.getAttribute('style') || '';
49 | const action = this.getAttribute('action') || '';
50 | const method = this.getAttribute('method') || 'get';
51 | const enctype = this.getAttribute('enctype') || '';
52 | const name = this.getAttribute('name') || '';
53 | const target = this.getAttribute('target') || '';
54 | const novalidate = this.hasAttribute('novalidate') ? 'novalidate' : '';
55 | const autocomplete = this.getAttribute('autocomplete') || '';
56 | const dataTestid = this.getAttribute('data-testid') || '';
57 |
58 | this.shadowRoot.innerHTML = `
59 |
68 |
83 | `;
84 | }
85 | }
86 |
87 | // Register the custom element if we're in a browser environment
88 | if (typeof window !== 'undefined' && window.customElements) {
89 | customElements.define('sans-form', SansForm);
90 | }
91 |
92 | export default SansForm;
93 |
--------------------------------------------------------------------------------
/packages/ui.deprecated/src/components/html5/H1.svelte:
--------------------------------------------------------------------------------
1 |
14 |
15 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/packages/ui.deprecated/src/components/html5/H1Component.js:
--------------------------------------------------------------------------------
1 | /**
2 | * H1Component.js
3 | * A reusable sans-h1 web component that can be used in any HTML context
4 | */
5 |
6 | class SansH1 extends HTMLElement {
7 | constructor() {
8 | super();
9 | this.attachShadow({ mode: 'open' });
10 | }
11 |
12 | static get observedAttributes() {
13 | return ['id', 'class', 'style', 'role', 'tabindex', 'aria-label', 'data-testid'];
14 | }
15 |
16 | connectedCallback() {
17 | this.render();
18 | this.h1 = this.shadowRoot.querySelector('h1');
19 | this.h1.addEventListener('click', (e) => {
20 | // Dispatch a custom event
21 | this.dispatchEvent(new CustomEvent('h1-click', {
22 | bubbles: true,
23 | composed: true,
24 | detail: { source: this }
25 | }));
26 | });
27 | }
28 |
29 | attributeChangedCallback(name, oldValue, newValue) {
30 | if (oldValue === newValue) return;
31 |
32 | if (this.shadowRoot) {
33 | this.render();
34 | }
35 | }
36 |
37 | render() {
38 | const id = this.getAttribute('id') || '';
39 | const className = this.getAttribute('class') || '';
40 | const style = this.getAttribute('style') || '';
41 | const role = this.getAttribute('role') || '';
42 | const tabindex = this.getAttribute('tabindex') || '';
43 | const ariaLabel = this.getAttribute('aria-label') || '';
44 | const dataTestid = this.getAttribute('data-testid') || '';
45 |
46 | this.shadowRoot.innerHTML = `
47 |
59 |
68 |
69 |
70 | `;
71 | }
72 | }
73 |
74 | // Register the custom element if we're in a browser environment
75 | if (typeof window !== 'undefined' && window.customElements) {
76 | customElements.define('sans-h1', SansH1);
77 | }
78 |
79 | export default SansH1;
80 |
--------------------------------------------------------------------------------
/packages/ui.deprecated/src/components/html5/Header.svelte:
--------------------------------------------------------------------------------
1 |
14 |
15 |
27 |
--------------------------------------------------------------------------------
/packages/ui.deprecated/src/components/html5/HeaderComponent.js:
--------------------------------------------------------------------------------
1 | /**
2 | * HeaderComponent.js
3 | * A reusable sans-header web component that can be used in any HTML context
4 | */
5 |
6 | class SansHeader extends HTMLElement {
7 | constructor() {
8 | super();
9 | this.attachShadow({ mode: 'open' });
10 | }
11 |
12 | static get observedAttributes() {
13 | return ['id', 'class', 'style', 'role', 'tabindex', 'aria-label', 'data-testid'];
14 | }
15 |
16 | connectedCallback() {
17 | this.render();
18 | this.header = this.shadowRoot.querySelector('header');
19 | this.header.addEventListener('click', (e) => {
20 | // Dispatch a custom event
21 | this.dispatchEvent(new CustomEvent('header-click', {
22 | bubbles: true,
23 | composed: true,
24 | detail: { source: this }
25 | }));
26 | });
27 | }
28 |
29 | attributeChangedCallback(name, oldValue, newValue) {
30 | if (oldValue === newValue) return;
31 |
32 | if (this.shadowRoot) {
33 | this.render();
34 | }
35 | }
36 |
37 | render() {
38 | const id = this.getAttribute('id') || '';
39 | const className = this.getAttribute('class') || '';
40 | const style = this.getAttribute('style') || '';
41 | const role = this.getAttribute('role') || '';
42 | const tabindex = this.getAttribute('tabindex') || '';
43 | const ariaLabel = this.getAttribute('aria-label') || '';
44 | const dataTestid = this.getAttribute('data-testid') || '';
45 |
46 | this.shadowRoot.innerHTML = `
47 |
56 |
67 | `;
68 | }
69 | }
70 |
71 | // Register the custom element if we're in a browser environment
72 | if (typeof window !== 'undefined' && window.customElements) {
73 | customElements.define('sans-header', SansHeader);
74 | }
75 |
76 | export default SansHeader;
77 |
--------------------------------------------------------------------------------
/packages/ui.deprecated/src/components/html5/Img.svelte:
--------------------------------------------------------------------------------
1 |
19 |
20 |
37 |
--------------------------------------------------------------------------------
/packages/ui.deprecated/src/components/html5/ImgComponent.js:
--------------------------------------------------------------------------------
1 | /**
2 | * ImgComponent.js
3 | * A reusable sans-img web component that can be used in any HTML context
4 | */
5 |
6 | class SansImg extends HTMLElement {
7 | constructor() {
8 | super();
9 | this.attachShadow({ mode: 'open' });
10 | }
11 |
12 | static get observedAttributes() {
13 | return ['id', 'class', 'style', 'src', 'alt', 'width', 'height', 'loading', 'decoding', 'role', 'aria-label', 'data-testid'];
14 | }
15 |
16 | connectedCallback() {
17 | this.render();
18 | this.img = this.shadowRoot.querySelector('img');
19 | this.img.addEventListener('click', (e) => {
20 | // Dispatch a custom event
21 | this.dispatchEvent(new CustomEvent('img-click', {
22 | bubbles: true,
23 | composed: true,
24 | detail: { source: this }
25 | }));
26 | });
27 | }
28 |
29 | attributeChangedCallback(name, oldValue, newValue) {
30 | if (oldValue === newValue) return;
31 |
32 | if (this.shadowRoot) {
33 | this.render();
34 | }
35 | }
36 |
37 | render() {
38 | const id = this.getAttribute('id') || '';
39 | const className = this.getAttribute('class') || '';
40 | const style = this.getAttribute('style') || '';
41 | const src = this.getAttribute('src') || '';
42 | const alt = this.getAttribute('alt') || '';
43 | const width = this.getAttribute('width') || '';
44 | const height = this.getAttribute('height') || '';
45 | const loading = this.getAttribute('loading') || '';
46 | const decoding = this.getAttribute('decoding') || '';
47 | const role = this.getAttribute('role') || '';
48 | const ariaLabel = this.getAttribute('aria-label') || '';
49 | const dataTestid = this.getAttribute('data-testid') || '';
50 |
51 | this.shadowRoot.innerHTML = `
52 |
62 |
76 | `;
77 | }
78 | }
79 |
80 | // Register the custom element if we're in a browser environment
81 | if (typeof window !== 'undefined' && window.customElements) {
82 | customElements.define('sans-img', SansImg);
83 | }
84 |
85 | export default SansImg;
86 |
--------------------------------------------------------------------------------
/packages/ui.deprecated/src/components/html5/LabelComponent.js:
--------------------------------------------------------------------------------
1 | /**
2 | * LabelComponent.js
3 | * A reusable sans-label web component that can be used in any HTML context
4 | */
5 |
6 | class SansLabel extends HTMLElement {
7 | constructor() {
8 | super();
9 | this.attachShadow({ mode: 'open' });
10 | }
11 |
12 | static get observedAttributes() {
13 | return ['id', 'class', 'style', 'for', 'form', 'data-testid'];
14 | }
15 |
16 | connectedCallback() {
17 | this.render();
18 | this.label = this.shadowRoot.querySelector('label');
19 |
20 | // Add event listeners
21 | this.label.addEventListener('click', (e) => {
22 | // Dispatch a custom event
23 | this.dispatchEvent(new CustomEvent('label-click', {
24 | bubbles: true,
25 | composed: true,
26 | detail: { source: this }
27 | }));
28 | });
29 | }
30 |
31 | attributeChangedCallback(name, oldValue, newValue) {
32 | if (oldValue === newValue) return;
33 |
34 | if (this.shadowRoot) {
35 | this.render();
36 | }
37 | }
38 |
39 | render() {
40 | const id = this.getAttribute('id') || '';
41 | const className = this.getAttribute('class') || '';
42 | const style = this.getAttribute('style') || '';
43 | const forAttr = this.getAttribute('for') || '';
44 | const form = this.getAttribute('form') || '';
45 | const dataTestid = this.getAttribute('data-testid') || '';
46 |
47 | this.shadowRoot.innerHTML = `
48 |
61 |
71 | `;
72 | }
73 | }
74 |
75 | // Register the custom element if we're in a browser environment
76 | if (typeof window !== 'undefined' && window.customElements) {
77 | customElements.define('sans-label', SansLabel);
78 | }
79 |
80 | export default SansLabel;
81 |
--------------------------------------------------------------------------------
/packages/ui.deprecated/src/components/html5/Main.svelte:
--------------------------------------------------------------------------------
1 |
14 |
15 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/packages/ui.deprecated/src/components/html5/MainComponent.js:
--------------------------------------------------------------------------------
1 | /**
2 | * MainComponent.js
3 | * A reusable sans-main web component that can be used in any HTML context
4 | */
5 |
6 | class SansMain extends HTMLElement {
7 | constructor() {
8 | super();
9 | this.attachShadow({ mode: 'open' });
10 | }
11 |
12 | static get observedAttributes() {
13 | return ['id', 'class', 'style', 'role', 'tabindex', 'aria-label', 'data-testid'];
14 | }
15 |
16 | connectedCallback() {
17 | this.render();
18 | this.main = this.shadowRoot.querySelector('main');
19 | this.main.addEventListener('click', (e) => {
20 | // Dispatch a custom event
21 | this.dispatchEvent(new CustomEvent('main-click', {
22 | bubbles: true,
23 | composed: true,
24 | detail: { source: this }
25 | }));
26 | });
27 | }
28 |
29 | attributeChangedCallback(name, oldValue, newValue) {
30 | if (oldValue === newValue) return;
31 |
32 | if (this.shadowRoot) {
33 | this.render();
34 | }
35 | }
36 |
37 | render() {
38 | const id = this.getAttribute('id') || '';
39 | const className = this.getAttribute('class') || '';
40 | const style = this.getAttribute('style') || '';
41 | const role = this.getAttribute('role') || '';
42 | const tabindex = this.getAttribute('tabindex') || '';
43 | const ariaLabel = this.getAttribute('aria-label') || '';
44 | const dataTestid = this.getAttribute('data-testid') || '';
45 |
46 | this.shadowRoot.innerHTML = `
47 |
56 |
65 |
66 |
67 | `;
68 | }
69 | }
70 |
71 | // Register the custom element if we're in a browser environment
72 | if (typeof window !== 'undefined' && window.customElements) {
73 | customElements.define('sans-main', SansMain);
74 | }
75 |
76 | export default SansMain;
77 |
--------------------------------------------------------------------------------
/packages/ui.deprecated/src/components/html5/Nav.svelte:
--------------------------------------------------------------------------------
1 |
14 |
15 |
27 |
--------------------------------------------------------------------------------
/packages/ui.deprecated/src/components/html5/NavComponent.js:
--------------------------------------------------------------------------------
1 | /**
2 | * NavComponent.js
3 | * A reusable sans-nav web component that can be used in any HTML context
4 | */
5 |
6 | class SansNav extends HTMLElement {
7 | constructor() {
8 | super();
9 | this.attachShadow({ mode: 'open' });
10 | }
11 |
12 | static get observedAttributes() {
13 | return ['id', 'class', 'style', 'role', 'tabindex', 'aria-label', 'data-testid'];
14 | }
15 |
16 | connectedCallback() {
17 | this.render();
18 | this.nav = this.shadowRoot.querySelector('nav');
19 | this.nav.addEventListener('click', (e) => {
20 | // Dispatch a custom event
21 | this.dispatchEvent(new CustomEvent('nav-click', {
22 | bubbles: true,
23 | composed: true,
24 | detail: { source: this }
25 | }));
26 | });
27 | }
28 |
29 | attributeChangedCallback(name, oldValue, newValue) {
30 | if (oldValue === newValue) return;
31 |
32 | if (this.shadowRoot) {
33 | this.render();
34 | }
35 | }
36 |
37 | render() {
38 | const id = this.getAttribute('id') || '';
39 | const className = this.getAttribute('class') || '';
40 | const style = this.getAttribute('style') || '';
41 | const role = this.getAttribute('role') || '';
42 | const tabindex = this.getAttribute('tabindex') || '';
43 | const ariaLabel = this.getAttribute('aria-label') || '';
44 | const dataTestid = this.getAttribute('data-testid') || '';
45 |
46 | this.shadowRoot.innerHTML = `
47 |
56 |
67 | `;
68 | }
69 | }
70 |
71 | // Register the custom element if we're in a browser environment
72 | if (typeof window !== 'undefined' && window.customElements) {
73 | customElements.define('sans-nav', SansNav);
74 | }
75 |
76 | export default SansNav;
77 |
--------------------------------------------------------------------------------
/packages/ui.deprecated/src/components/html5/OptionComponent.js:
--------------------------------------------------------------------------------
1 | /**
2 | * OptionComponent.js
3 | * A reusable sans-option web component that can be used within sans-select
4 | */
5 |
6 | class SansOption extends HTMLElement {
7 | constructor() {
8 | super();
9 | this.attachShadow({ mode: 'open' });
10 | }
11 |
12 | static get observedAttributes() {
13 | return ['id', 'class', 'style', 'value', 'disabled', 'selected', 'label', 'data-testid'];
14 | }
15 |
16 | connectedCallback() {
17 | this.render();
18 | }
19 |
20 | attributeChangedCallback(name, oldValue, newValue) {
21 | if (oldValue === newValue) return;
22 |
23 | if (this.shadowRoot) {
24 | this.render();
25 | }
26 | }
27 |
28 | render() {
29 | const id = this.getAttribute('id') || '';
30 | const className = this.getAttribute('class') || '';
31 | const style = this.getAttribute('style') || '';
32 | const value = this.getAttribute('value') || '';
33 | const disabled = this.hasAttribute('disabled') ? 'disabled' : '';
34 | const selected = this.hasAttribute('selected') ? 'selected' : '';
35 | const label = this.getAttribute('label') || '';
36 | const dataTestid = this.getAttribute('data-testid') || '';
37 |
38 | this.shadowRoot.innerHTML = `
39 |
44 |
56 | `;
57 | }
58 | }
59 |
60 | // Register the custom element if we're in a browser environment
61 | if (typeof window !== 'undefined' && window.customElements) {
62 | customElements.define('sans-option', SansOption);
63 | }
64 |
65 | export default SansOption;
66 |
--------------------------------------------------------------------------------
/packages/ui.deprecated/src/components/html5/P.svelte:
--------------------------------------------------------------------------------
1 |
14 |
15 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/packages/ui.deprecated/src/components/html5/PComponent.js:
--------------------------------------------------------------------------------
1 | /**
2 | * PComponent.js
3 | * A reusable sans-p web component that can be used in any HTML context
4 | */
5 |
6 | class SansP extends HTMLElement {
7 | constructor() {
8 | super();
9 | this.attachShadow({ mode: 'open' });
10 | }
11 |
12 | static get observedAttributes() {
13 | return ['id', 'class', 'style', 'role', 'tabindex', 'aria-label', 'data-testid'];
14 | }
15 |
16 | connectedCallback() {
17 | this.render();
18 | this.p = this.shadowRoot.querySelector('p');
19 | this.p.addEventListener('click', (e) => {
20 | // Dispatch a custom event
21 | this.dispatchEvent(new CustomEvent('p-click', {
22 | bubbles: true,
23 | composed: true,
24 | detail: { source: this }
25 | }));
26 | });
27 | }
28 |
29 | attributeChangedCallback(name, oldValue, newValue) {
30 | if (oldValue === newValue) return;
31 |
32 | if (this.shadowRoot) {
33 | this.render();
34 | }
35 | }
36 |
37 | render() {
38 | const id = this.getAttribute('id') || '';
39 | const className = this.getAttribute('class') || '';
40 | const style = this.getAttribute('style') || '';
41 | const role = this.getAttribute('role') || '';
42 | const tabindex = this.getAttribute('tabindex') || '';
43 | const ariaLabel = this.getAttribute('aria-label') || '';
44 | const dataTestid = this.getAttribute('data-testid') || '';
45 |
46 | this.shadowRoot.innerHTML = `
47 |
57 |
66 |
67 |
68 | `;
69 | }
70 | }
71 |
72 | // Register the custom element if we're in a browser environment
73 | if (typeof window !== 'undefined' && window.customElements) {
74 | customElements.define('sans-p', SansP);
75 | }
76 |
77 | export default SansP;
78 |
--------------------------------------------------------------------------------
/packages/ui.deprecated/src/components/html5/Section.svelte:
--------------------------------------------------------------------------------
1 |
14 |
15 |
27 |
--------------------------------------------------------------------------------
/packages/ui.deprecated/src/components/html5/SectionComponent.js:
--------------------------------------------------------------------------------
1 | /**
2 | * SectionComponent.js
3 | * A reusable sans-section web component that can be used in any HTML context
4 | */
5 |
6 | class SansSection extends HTMLElement {
7 | constructor() {
8 | super();
9 | this.attachShadow({ mode: 'open' });
10 | }
11 |
12 | static get observedAttributes() {
13 | return ['id', 'class', 'style', 'role', 'tabindex', 'aria-label', 'data-testid'];
14 | }
15 |
16 | connectedCallback() {
17 | this.render();
18 | this.section = this.shadowRoot.querySelector('section');
19 | this.section.addEventListener('click', (e) => {
20 | // Dispatch a custom event
21 | this.dispatchEvent(new CustomEvent('section-click', {
22 | bubbles: true,
23 | composed: true,
24 | detail: { source: this }
25 | }));
26 | });
27 | }
28 |
29 | attributeChangedCallback(name, oldValue, newValue) {
30 | if (oldValue === newValue) return;
31 |
32 | if (this.shadowRoot) {
33 | this.render();
34 | }
35 | }
36 |
37 | render() {
38 | const id = this.getAttribute('id') || '';
39 | const className = this.getAttribute('class') || '';
40 | const style = this.getAttribute('style') || '';
41 | const role = this.getAttribute('role') || '';
42 | const tabindex = this.getAttribute('tabindex') || '';
43 | const ariaLabel = this.getAttribute('aria-label') || '';
44 | const dataTestid = this.getAttribute('data-testid') || '';
45 |
46 | this.shadowRoot.innerHTML = `
47 |
56 |
67 | `;
68 | }
69 | }
70 |
71 | // Register the custom element if we're in a browser environment
72 | if (typeof window !== 'undefined' && window.customElements) {
73 | customElements.define('sans-section', SansSection);
74 | }
75 |
76 | export default SansSection;
77 |
--------------------------------------------------------------------------------
/packages/ui.deprecated/src/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Sans UI - Main entry point
3 | * A cross-platform UI library with Svelte and Web Components for HTML5 elements
4 | */
5 |
6 | // Export all HTML5 components
7 | export * from './components/html5/index.js';
8 |
9 | // Export version information
10 | export const VERSION = '1.0.0';
11 |
--------------------------------------------------------------------------------
/packages/ui.deprecated/src/lib/components/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Sans UI Component Abstraction Layer
3 | *
4 | * This module exports the component abstraction layer for Sans UI components,
5 | * making it easy to create and manage components across different platforms.
6 | */
7 |
8 | import ComponentAdapter from './ComponentAdapter';
9 | import ComponentFactory from './ComponentFactory';
10 |
11 | // Export the component abstraction layer
12 | export {
13 | ComponentAdapter,
14 | ComponentFactory
15 | };
16 |
17 | // Default export for convenience
18 | export default ComponentFactory;
19 |
--------------------------------------------------------------------------------
/packages/ui.deprecated/src/lib/webview/types.d.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Type definitions for Qt WebEngine and other platform-specific objects
3 | */
4 |
5 | // Qt WebEngine types
6 | interface QWebChannelTransport {
7 | send: (message: any) => void;
8 | onmessage: (callback: (event: MessageEvent) => void) => void;
9 | }
10 |
11 | interface QtObject {
12 | webChannelTransport: QWebChannelTransport;
13 | }
14 |
15 | interface QWebChannelObject {
16 | [key: string]: any;
17 | }
18 |
19 | declare class QWebChannel {
20 | constructor(transport: QWebChannelTransport, callback: (channel: { objects: QWebChannelObject }) => void);
21 | }
22 |
23 | // Extend Window interface to include platform-specific objects
24 | declare interface Window {
25 | // Qt WebEngine specific
26 | qt?: QtObject;
27 | QWebChannel?: typeof QWebChannel;
28 | bridge?: any;
29 | bridgeReady?: (bridge: any) => void;
30 |
31 | // iOS WKWebView specific
32 | webkit?: {
33 | messageHandlers: {
34 | [key: string]: {
35 | postMessage: (message: any) => void;
36 | };
37 | };
38 | };
39 | receiveNativeMessage?: (messageJson: string) => void;
40 |
41 | // Microsoft WebView2 specific
42 | chrome?: any;
43 | MSStream?: any;
44 | }
45 |
46 | // Declare the WebViewJS module
47 | declare module '@webviewjs/webview' {
48 | export default class WebViewJS {
49 | constructor(url: string, options?: any);
50 | element: HTMLElement;
51 | navigate(url: string): void;
52 | reload(): void;
53 | executeJavaScript(code: string): Promise;
54 | destroy(): void;
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/packages/ui.deprecated/static/logos/api/favicon.sans-api.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/packages/ui.deprecated/static/logos/api/favicon.sans-api.white.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/packages/ui.deprecated/static/logos/api/logo.sans-api.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/packages/ui.deprecated/static/logos/api/logo.sans-api.white.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/packages/ui.deprecated/static/logos/db/favicon.db.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/packages/ui.deprecated/static/logos/db/favicon.db.white.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/packages/ui.deprecated/static/logos/db/logo.sans-db.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/packages/ui.deprecated/static/logos/ui/favicon.sans-ui.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/packages/ui.deprecated/static/logos/ui/favicon.sans-ui.white.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/packages/ui.deprecated/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es2020",
4 | "module": "esnext",
5 | "moduleResolution": "node",
6 | "declaration": true,
7 | "declarationDir": "./dist",
8 | "emitDeclarationOnly": true,
9 | "strict": true,
10 | "esModuleInterop": true,
11 | "skipLibCheck": true,
12 | "forceConsistentCasingInFileNames": true,
13 | "resolveJsonModule": true,
14 | "allowJs": true,
15 | "checkJs": true,
16 | "isolatedModules": true,
17 | "types": ["svelte", "node"],
18 | "outDir": "./dist"
19 | },
20 | "include": ["src/**/*"],
21 | "exclude": ["node_modules", "dist"]
22 | }
23 |
--------------------------------------------------------------------------------
/packages/ui.deprecated/vite.config.js:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'vite';
2 | import { svelte } from '@sveltejs/vite-plugin-svelte';
3 |
4 | export default defineConfig({
5 | plugins: [svelte()],
6 | server: {
7 | port: 5173
8 | }
9 | });
--------------------------------------------------------------------------------
/packages/ui/.gitignore:
--------------------------------------------------------------------------------
1 | # Dependencies
2 | node_modules/
3 |
4 | # Environment variables
5 | .env*
6 |
7 | # Build artifacts
8 | /dist/
9 | /.svelte-kit/
10 | /build/
11 |
12 | # IDE and editor files
13 | .idea/
14 | .vscode/
15 | *.sublime-project
16 | *.sublime-workspace
17 |
18 | # OS files
19 | .DS_Store
20 | Thumbs.db
21 |
22 | # Logs
23 | npm-debug.log*
24 | yarn-debug.log*
25 | yarn-error.log*
26 | pnpm-debug.log*
27 |
28 | # Cache
29 | .cache/
30 | .pnpm-store/
31 |
--------------------------------------------------------------------------------
/packages/ui/bunfig.toml:
--------------------------------------------------------------------------------
1 | # Sans UI Bun Configuration
2 |
3 | [install]
4 | dry-run = false
5 | frozen-lockfile = false
6 |
7 | [install.cache]
8 | dir = ".bun/install/cache"
9 | enabled = true
10 |
11 | [test]
12 | coverage = false
13 |
14 | [build]
15 | entrypoints = ["src/index.js"]
16 | outdir = "dist"
17 | splitting = true
18 | minify = true
19 | modules = true
20 |
21 | [publish]
22 | access = "public"
23 | scope = "profullstack"
24 | registry = "https://registry.npmjs.org/"
25 |
--------------------------------------------------------------------------------
/packages/ui/examples/backend/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "sans-ui-backend-example",
3 | "version": "1.0.0",
4 | "description": "Backend API example for Sans UI using Elysia and Mailgun",
5 | "main": "index.js",
6 | "type": "module",
7 | "scripts": {
8 | "start": "node index.js",
9 | "dev": "node --watch index.js"
10 | },
11 | "keywords": [
12 | "sans-ui",
13 | "elysia",
14 | "mailgun",
15 | "api"
16 | ],
17 | "author": "",
18 | "license": "ISC",
19 | "dependencies": {
20 | "@elysiajs/cors": "^0.8.0",
21 | "@supabase/supabase-js": "^2.39.0",
22 | "dotenv": "^16.3.1",
23 | "elysia": "^0.8.9",
24 | "form-data": "^4.0.0",
25 | "mailgun.js": "^9.3.0"
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/packages/ui/examples/backend/sample.env:
--------------------------------------------------------------------------------
1 | # API Configuration
2 | PORT=3001
3 | API_KEY=your_api_key_here
4 |
5 | # Mailgun Configuration
6 | MAILGUN_API_KEY=your_mailgun_api_key_here
7 | MAILGUN_DOMAIN=your_mailgun_domain.com
8 | EMAIL_FROM=Sans UI
9 |
10 | # Supabase Configuration
11 | SUPABASE_URL=https://your-project-id.supabase.co
12 | SUPABASE_KEY=your_supabase_anon_key_here
13 | SUPABASE_TABLE=subscribers
14 |
15 | # CORS Configuration
16 | ALLOW_ORIGINS=http://localhost:3000,http://localhost:8000
17 |
--------------------------------------------------------------------------------
/packages/ui/examples/camera-subscribe-example/css/styles.css:
--------------------------------------------------------------------------------
1 | /* Camera & Subscribe Example Styles */
2 |
3 | .camera-container {
4 | margin: 20px 0;
5 | padding: 20px;
6 | background-color: #f9f9f9;
7 | border-radius: 8px;
8 | border: 1px solid var(--border-color);
9 | }
10 |
11 | #camera-placeholder {
12 | width: 100%;
13 | height: 300px;
14 | display: flex;
15 | align-items: center;
16 | justify-content: center;
17 | background-color: #eee;
18 | border-radius: 4px;
19 | color: #666;
20 | font-style: italic;
21 | }
22 |
23 | #video {
24 | width: 100%;
25 | max-width: 640px;
26 | height: auto;
27 | border-radius: 4px;
28 | background-color: #000;
29 | }
30 |
31 | .camera-controls {
32 | margin-top: 15px;
33 | display: flex;
34 | gap: 10px;
35 | }
36 |
37 | #photo-container {
38 | margin-top: 20px;
39 | padding: 15px;
40 | background-color: white;
41 | border-radius: 4px;
42 | border: 1px solid var(--border-color);
43 | }
44 |
45 | #photo {
46 | max-width: 100%;
47 | border-radius: 4px;
48 | display: block;
49 | margin: 10px 0;
50 | }
51 |
52 | .subscribe-container {
53 | margin: 20px 0;
54 | padding: 20px;
55 | background-color: white;
56 | border-radius: 8px;
57 | border: 1px solid var(--border-color);
58 | max-width: 500px;
59 | }
60 |
61 | .form-group {
62 | margin-bottom: 15px;
63 | }
64 |
65 | label {
66 | display: block;
67 | margin-bottom: 5px;
68 | font-weight: 500;
69 | }
70 |
71 | input[type="email"],
72 | input[type="text"] {
73 | width: 100%;
74 | padding: 10px;
75 | border: 1px solid var(--border-color);
76 | border-radius: 4px;
77 | font-size: 16px;
78 | }
79 |
80 | input[type="checkbox"] {
81 | margin-right: 8px;
82 | }
83 |
84 | .form-actions {
85 | margin-top: 20px;
86 | }
87 |
88 | /* Button styles */
89 | .btn {
90 | display: inline-block;
91 | padding: 8px 16px;
92 | border: none;
93 | border-radius: 4px;
94 | font-size: 16px;
95 | font-weight: 500;
96 | cursor: pointer;
97 | transition: background-color 0.2s, transform 0.1s;
98 | }
99 |
100 | .btn:hover:not(:disabled) {
101 | filter: brightness(1.1);
102 | }
103 |
104 | .btn:active:not(:disabled) {
105 | transform: scale(0.98);
106 | }
107 |
108 | .btn:disabled {
109 | opacity: 0.6;
110 | cursor: not-allowed;
111 | }
112 |
113 | .btn.primary {
114 | background-color: var(--primary-color);
115 | color: white;
116 | }
117 |
118 | .btn.secondary {
119 | background-color: var(--secondary-color);
120 | color: var(--text-color);
121 | }
122 |
123 | .btn.danger {
124 | background-color: var(--danger-color);
125 | color: white;
126 | }
127 |
--------------------------------------------------------------------------------
/packages/ui/examples/camera-subscribe-example/js/subscribe.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Subscribe Module
3 | * Handles subscription form submission and validation
4 | */
5 |
6 | /**
7 | * Handle subscription form submission
8 | * @param {Object} data - Subscription data
9 | * @param {string} data.email - Email address
10 | * @param {string} data.name - Full name
11 | * @param {boolean} data.terms - Terms acceptance
12 | * @returns {Promise