diff --git a/README.md b/README.md index 0466aab8b..13ef9cade 100644 --- a/README.md +++ b/README.md @@ -227,20 +227,6 @@ I want this all to be presented flexible in the component. * Raptor mini: when we are on layout mobile we do not want to display the help menu at all. -* Raptor mini: Create for me a footer Lit Component in tsy style of the components I have and under v2. Take the code from this index.ts to start with. - -* Raptor mini: Good. Now, I want the footer to be a rectangular with round corners, grey background and it should have an adjustable position. - -* Raptor mini: The content of the footer should be different upon loggedin or not. -If not logged in, it should say: -Title Public View -You are viewving this profile as a guest, -And if logged in: -Title: Logged in View -You are logged in as nameOfLoggedIn user. - -* Raptor mini: add a readme to the Footer component with example. - * Claude Sonnet 4.6: Make the drop down as a list under the input field and enlarge the pop up, make it higher, adjustable to fit the drop down. And make the drop down arrow area larger * GPT-5.4 Model: can you wire up the keyboard interactions and aria attributes for Select? diff --git a/package-lock.json b/package-lock.json index 799e1d7b4..64d6f2639 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5083,17 +5083,17 @@ "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.64.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.64.0.tgz", - "integrity": "sha512-CGvQPBxN3wZLu6Rz2kFUpZeoCm78xUic92ck39KPePkO1NPOwjCqdQnm5Q87tpWw9vcBvW8XLrDXjH9PWYtJ3Q==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.65.0.tgz", + "integrity": "sha512-IEgob78X12rHpUmtcwFsXhZdVGJtwTVP8FiCLZkR6GlYVrl2PcuB+KhCE5BlVC/eQpQnu8WXRtkHZuPar+gCRA==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.12.2", - "@typescript-eslint/scope-manager": "8.64.0", - "@typescript-eslint/type-utils": "8.64.0", - "@typescript-eslint/utils": "8.64.0", - "@typescript-eslint/visitor-keys": "8.64.0", + "@typescript-eslint/scope-manager": "8.65.0", + "@typescript-eslint/type-utils": "8.65.0", + "@typescript-eslint/utils": "8.65.0", + "@typescript-eslint/visitor-keys": "8.65.0", "ignore": "^7.0.5", "natural-compare": "^1.4.0", "ts-api-utils": "^2.5.0" @@ -5106,7 +5106,7 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.64.0", + "@typescript-eslint/parser": "^8.65.0", "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } @@ -5122,16 +5122,16 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.64.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.64.0.tgz", - "integrity": "sha512-KA0OshtlcCCXmbfqyZkM5pV3/WNraJf7DkJRLpyrmwPtud57H5BDX7C3k0LPSPxpprfRL+cJDGabF10mvNCoCw==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.65.0.tgz", + "integrity": "sha512-CZ4nMxWwgu1HEEFNkeaCptra9QCtkmKdgf3sWh1rl1trIhmxLilgTV4cwcbQ4wemnT4sWQN8CaKOmdYx+g2gMA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.64.0", - "@typescript-eslint/types": "8.64.0", - "@typescript-eslint/typescript-estree": "8.64.0", - "@typescript-eslint/visitor-keys": "8.64.0", + "@typescript-eslint/scope-manager": "8.65.0", + "@typescript-eslint/types": "8.65.0", + "@typescript-eslint/typescript-estree": "8.65.0", + "@typescript-eslint/visitor-keys": "8.65.0", "debug": "^4.4.3" }, "engines": { @@ -5147,14 +5147,14 @@ } }, "node_modules/@typescript-eslint/project-service": { - "version": "8.64.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.64.0.tgz", - "integrity": "sha512-tk4WpOJ6IEbGrVHaNmM0YRrwAD3exZlIK3iadQNAxh4YKk6jvUQ4ecq18n+v7+meh+cJ3j+D8nbk8sRKhlwLQg==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.65.0.tgz", + "integrity": "sha512-SxnPhbTsGahizDgbu7oqFH/xVtzIqMd/s+WtnSxNxJZJpLbdT5IPdzg8EZxO3+PoKahXmwJLeNQOpKJb3/bi7Q==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.64.0", - "@typescript-eslint/types": "^8.64.0", + "@typescript-eslint/tsconfig-utils": "^8.65.0", + "@typescript-eslint/types": "^8.65.0", "debug": "^4.4.3" }, "engines": { @@ -5169,14 +5169,14 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.64.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.64.0.tgz", - "integrity": "sha512-CXEaFdYXjSTgKhisNkwCcJwTP8Pl+fmRrEQrri4nm3vU743bALrxzLmq7fHG/7e6a5xO0lDYeURpZmBuhHk54w==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.65.0.tgz", + "integrity": "sha512-Esbl8OSYiVxBokYgWPf7VVWg/BE798wXhimnn9ML9Pt5qoDf8bfQlgjlKXR/k98+AcNzlLKYrpCcrcuZ9DZLgg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.64.0", - "@typescript-eslint/visitor-keys": "8.64.0" + "@typescript-eslint/types": "8.65.0", + "@typescript-eslint/visitor-keys": "8.65.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -5187,9 +5187,9 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.64.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.64.0.tgz", - "integrity": "sha512-2yo8rRNKuzbVWQp5kslhANqZ2uDAeROQHBRZNPu8JDsHmeFNj/XJJhX/FhNUWmkHHvoNsKa6+tHJiig87EzsQw==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.65.0.tgz", + "integrity": "sha512-j6GzGqCiRdA7Qhur2VVmKZAkBLfnHFQfx4TaJGL9RMveZqCo48jSHHO0DTgizEnGhtWnqmbtCUSrqSkdiY/0Hg==", "dev": true, "license": "MIT", "engines": { @@ -5204,15 +5204,15 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.64.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.64.0.tgz", - "integrity": "sha512-XWG4Fmmv/6SvyS9nH8jWrKs6terwJvE8cyRt1CzYYqzp9OrPhCT4cMc/f7C6RZCwG+qMmiffJS1/qJP8G1URtg==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.65.0.tgz", + "integrity": "sha512-YjaZ7PRI5qY7ax2L3PbvX0rRyGtipAReCWs0mhhDBHjH/vl0g0BonaGXrKdKpMbIIsMIwDgbk/xzkBTyAltS5g==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.64.0", - "@typescript-eslint/typescript-estree": "8.64.0", - "@typescript-eslint/utils": "8.64.0", + "@typescript-eslint/types": "8.65.0", + "@typescript-eslint/typescript-estree": "8.65.0", + "@typescript-eslint/utils": "8.65.0", "debug": "^4.4.3", "ts-api-utils": "^2.5.0" }, @@ -5229,9 +5229,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.64.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.64.0.tgz", - "integrity": "sha512-qjhfuTfLXjA4IOzXvz0rTjT01BqEiIgPoUeMwiEjnaHKJMTNo8rH5pYW1a2L/0Dnux2fPC85AeyJoWaGa8WxTA==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.65.0.tgz", + "integrity": "sha512-JSSwWNy+H0E/01jJEM+hrX6N0OFDzFzeIhHFSAS01tlVaevpG8cFyYRPhS5yjGOvBUx3sqQHVMjCL1CAZZMxBg==", "dev": true, "license": "MIT", "engines": { @@ -5243,16 +5243,16 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.64.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.64.0.tgz", - "integrity": "sha512-Pztpsn1aCE1oWDvDEfUk31nngvvF7vUB5SwHFEaZIFpvw7WJtqUHHL4plBZDA9HfWJJjL13BdG0YrJInTUvoVA==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.65.0.tgz", + "integrity": "sha512-JboAE2swaYt4tb1fHhHTABE2K+OLy09XfcTbhnk4Pw96f9dd2e9iYsJ28gBggHlo5z5x1rkyWvcPoTuNTd4oGg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.64.0", - "@typescript-eslint/tsconfig-utils": "8.64.0", - "@typescript-eslint/types": "8.64.0", - "@typescript-eslint/visitor-keys": "8.64.0", + "@typescript-eslint/project-service": "8.65.0", + "@typescript-eslint/tsconfig-utils": "8.65.0", + "@typescript-eslint/types": "8.65.0", + "@typescript-eslint/visitor-keys": "8.65.0", "debug": "^4.4.3", "minimatch": "^10.2.2", "semver": "^7.7.3", @@ -5284,16 +5284,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.64.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.64.0.tgz", - "integrity": "sha512-aJUGVB3+U0htrrCjoA8qukw8cm8fNCGAxK/tVoS70k8aeb7DETKeFozRiVFIwEeN9WJLsjaP3ph8I60tY2XZoQ==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.65.0.tgz", + "integrity": "sha512-gXiwIHsYreboxeJucHKPvgwl7dXt50mF8s1/c00cP/WoVTyWKFdtfhRWwZiXYFU5H2O8vVoSLNrexFZjYS/SGA==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", - "@typescript-eslint/scope-manager": "8.64.0", - "@typescript-eslint/types": "8.64.0", - "@typescript-eslint/typescript-estree": "8.64.0" + "@typescript-eslint/scope-manager": "8.65.0", + "@typescript-eslint/types": "8.65.0", + "@typescript-eslint/typescript-estree": "8.65.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -5308,13 +5308,13 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.64.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.64.0.tgz", - "integrity": "sha512-mrtuL8Nsn6gi2H4mo5KMTp823M+3Q19Ew/i+Zlikq20tIMm99C3Ez0dCmkWWnxut20esQvTg8aUSEhMcAOXhEw==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.65.0.tgz", + "integrity": "sha512-8C71BQkGjiMmXtop7pHVJu1l2NNShFdkCyD6a2ezzs5vU/L3LRtb69EtcteFwz0mYMPzIgOw0n6OV4VBUWZd7A==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.64.0", + "@typescript-eslint/types": "8.65.0", "eslint-visitor-keys": "^5.0.0" }, "engines": { @@ -6368,9 +6368,9 @@ "license": "MIT" }, "node_modules/baseline-browser-mapping": { - "version": "2.10.43", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.43.tgz", - "integrity": "sha512-AjYpR78kDWAY3Efj+cDTFH9t9SCoL7OoTp1BOb0mQV7S+6CiLwnWM3FyxhJtdPufDFKzmCSFoUncKjWgJEZTCQ==", + "version": "2.10.44", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.44.tgz", + "integrity": "sha512-T3ghW+sl/ZJ8w1v/yQx3qvJ9040DWoLBz8JT/CILbAKcFyG9b2MRe75v6W5uXjv6uH1lumK2Kv46y2zSkcej0Q==", "dev": true, "license": "Apache-2.0", "bin": { @@ -7264,9 +7264,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.5.393", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.393.tgz", - "integrity": "sha512-kiDJdIUawuEIcp9XoICKp1iTYDEbgguIPq526N1Q7jIQDeQ3CqoMx71025PI/7E48Ddtw2HuWsVjY7afEgNxmg==", + "version": "1.5.394", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.394.tgz", + "integrity": "sha512-Wmt2Gm0o8JWBuGgmc4XZ0u9s1RaCRqhxP47phplmfg04+qypTUurpeJGP45A7Fhv7jdrrVH44PLlR9qXo37cVQ==", "dev": true, "license": "ISC" }, @@ -7278,9 +7278,9 @@ "license": "MIT" }, "node_modules/enhanced-resolve": { - "version": "5.24.2", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.24.2.tgz", - "integrity": "sha512-rpsZEGT1jFuve6QlpyRp9ckQ+kN61hvF9BzCPyMdaKTm8UJce96KBn3sorXOFXlzjPrs3Vc4T1NsSroZ3PxlFw==", + "version": "5.24.3", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.24.3.tgz", + "integrity": "sha512-PwKooW9JUzh5chmYfHM3IQl5OkK2u2Nm011MgeZrss3JmFraUx/fqrf78kk8GUMYoibx/14MdwTl/1WKkG7TpQ==", "license": "MIT", "dependencies": { "graceful-fs": "^4.2.4", @@ -12056,9 +12056,9 @@ } }, "node_modules/postcss": { - "version": "8.5.19", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.19.tgz", - "integrity": "sha512-Mz8SaolMd8nB+G13WkORcxQKHZ/NE4xXevtkJHVuG+guo9/wYKlIMTKAqGdEmYOXR2ijPjTYNHssizdaVSUNdQ==", + "version": "8.5.21", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.21.tgz", + "integrity": "sha512-v4sDNP3fdNiWMfabO7OwOQdOX8TiQSztKyT1Wj0w+j7LDallJThJRBBBmzVGyYj0crMh7jlV4zepPkiNu9UwDQ==", "dev": true, "funding": [ { @@ -12076,7 +12076,7 @@ ], "license": "MIT", "dependencies": { - "nanoid": "^3.3.12", + "nanoid": "^3.3.16", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" }, @@ -13859,16 +13859,16 @@ } }, "node_modules/typescript-eslint": { - "version": "8.64.0", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.64.0.tgz", - "integrity": "sha512-0qg+pDNMnqYzqH9AnNK+39tejHvsShUOUUoRUgtnTGE7QuMZhiFDnozq8nHJVq+Wae6NMLKNWLg5WmkcC/ndyQ==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.65.0.tgz", + "integrity": "sha512-/ggrHAwyjENDusvyxbuqxAC2dTnZg/Z8F+fgQtYIz+L6n/9HfSlEZcFGV/NsMNa6CkGk0xUjUAFwC0vHOflvIA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/eslint-plugin": "8.64.0", - "@typescript-eslint/parser": "8.64.0", - "@typescript-eslint/typescript-estree": "8.64.0", - "@typescript-eslint/utils": "8.64.0" + "@typescript-eslint/eslint-plugin": "8.65.0", + "@typescript-eslint/parser": "8.65.0", + "@typescript-eslint/typescript-estree": "8.65.0", + "@typescript-eslint/utils": "8.65.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" diff --git a/src/components/footer/index.ts b/src/components/footer/index.ts deleted file mode 100644 index 3e833d8e5..000000000 --- a/src/components/footer/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from '../../v2/components/layout/footer' diff --git a/src/types/custom-elements.d.ts b/src/types/custom-elements.d.ts index 00ae89ef0..7366bab22 100644 --- a/src/types/custom-elements.d.ts +++ b/src/types/custom-elements.d.ts @@ -14,7 +14,6 @@ import type DialogFooter from '../components/dialog-footer/DialogFooter' import type DialogHeader from '../components/dialog-header/DialogHeader' import type DialogProvider from '../components/dialog-provider/DialogProvider' import type DialogsRoot from '../components/dialogs-root/DialogsRoot' -import type Footer from '../components/footer/Footer' import type Guard from '../components/guard/Guard' import type Header from '../components/header/Header' import type Input from '../components/input/Input' @@ -42,7 +41,6 @@ declare global { 'solid-ui-dialog-header': DialogHeader 'solid-ui-dialog-provider': DialogProvider 'solid-ui-dialogs-root': DialogsRoot - 'solid-ui-footer': Footer 'solid-ui-guard': Guard 'solid-ui-header': Header 'solid-ui-input': Input diff --git a/src/v2/components/layout/footer/Footer.test.ts b/src/v2/components/layout/footer/Footer.test.ts deleted file mode 100644 index 3c777a508..000000000 --- a/src/v2/components/layout/footer/Footer.test.ts +++ /dev/null @@ -1,63 +0,0 @@ -import { describe, expect, it, vi } from 'vitest' -import { Footer } from './Footer' -import './index' -import { authn } from 'solid-logic' - -describe('SolidUIFooterElement', () => { - it('is defined as a custom element', () => { - const defined = customElements.get('solid-ui-footer') - expect(defined).toBe(Footer) - }) - - it('renders a public view when not logged in', async () => { - const footer = new Footer() - document.body.appendChild(footer) - await footer.updateComplete - - const shadow = footer.shadowRoot - expect(shadow).not.toBeNull() - expect(shadow?.textContent).toContain('Public View') - expect(shadow?.textContent).toContain('You are viewing this profile as a guest.') - }) - - it('renders a logged in view when the user is authenticated', async () => { - const currentUser = { uri: 'https://alice.example/profile/card#me', equals: vi.fn(() => true) } - const currentUserSpy = vi.spyOn(authn, 'currentUser').mockReturnValue(currentUser as any) - - const footer = new Footer() - document.body.appendChild(footer) - await footer.updateComplete - - const shadow = footer.shadowRoot - expect(shadow).not.toBeNull() - expect(shadow?.textContent).toContain('Logged in View') - expect(shadow?.textContent).toContain('You are logged in as') - const link = shadow?.querySelector('a') - expect(link?.getAttribute('href')).toBe('https://alice.example/profile/card#me') - expect(link?.textContent).toBe('https://alice.example/profile/card#me') - - currentUserSpy.mockRestore() - }) - - it('defaults layout to desktop', async () => { - const footer = new Footer() - document.body.appendChild(footer) - await footer.updateComplete - - expect(footer.layout).toBe('desktop') - expect(footer.getAttribute('layout')).toBe('desktop') - }) - - it('applies mobile layout styles by removing border, box-shadow and border-radius', async () => { - const footer = new Footer() - footer.layout = 'mobile' - document.body.appendChild(footer) - await footer.updateComplete - - const style = footer.shadowRoot?.querySelector('style')?.textContent - expect(style).toContain(':host([layout=\'mobile\'])') - expect(style).toContain('border: none;') - expect(style).toContain('box-shadow: none;') - expect(footer.getAttribute('layout')).toBe('mobile') - }) -}) diff --git a/src/v2/components/layout/footer/Footer.ts b/src/v2/components/layout/footer/Footer.ts deleted file mode 100644 index cdbe3ff71..000000000 --- a/src/v2/components/layout/footer/Footer.ts +++ /dev/null @@ -1,168 +0,0 @@ -import { LitElement, html, css } from 'lit' -import type { LiveStore, NamedNode } from 'rdflib' -import { authSession, authn } from 'solid-logic' -import { getName } from '../../../../utils/headerFooterHelpers' - -export class Footer extends LitElement { - static properties = { - theme: { type: String, reflect: true }, - layout: { type: String, reflect: true }, - position: { type: String, reflect: true }, - top: { type: String, reflect: true }, - right: { type: String, reflect: true }, - bottom: { type: String, reflect: true }, - left: { type: String, reflect: true }, - store: { type: Object, attribute: false }, - _user: { state: true } - } - - static styles = css` - :host { - display: block; - position: var(--footer-position, static); - top: var(--footer-top, auto); - right: var(--footer-right, auto); - bottom: var(--footer-bottom, auto); - left: var(--footer-left, auto); - width: auto; - max-width: var(--footer-max-width, none); - margin: var(--footer-margin, 0); - box-sizing: border-box; - color: var(--footer-text, #4f4f4f); - background: transparent; - border: 1px solid var(--footer-border, rgba(0, 0, 0, 0.12)); - border-radius: var(--footer-border-radius, 1rem); - box-shadow: var(--footer-box-shadow, 0 1px 6px rgba(0, 0, 0, 0.08)); - font-family: var(--font-family-base, 'Segoe UI', 'Helvetica Neue', Arial, sans-serif); - } - - .footer { - display: flex; - justify-content: flex-start; - align-items: flex-start; - gap: 0.25rem; - font-size: 0.75rem; - line-height: 1.5; - text-align: left; - } - - .footer a { - color: var(--footer-link, #4b32a8); - text-decoration: none; - font-weight: 600; - } - - .footer a:hover { - text-decoration: underline; - } - - .footer span { - color: inherit; - } - - .footer div > strong { - display: block; - margin-bottom: 0.5rem; - } - - :host([layout='mobile']) { - border: none; - box-shadow: none; - border-radius: 0; - } - ` - - declare theme: 'light' | 'dark' - declare layout: 'desktop' | 'mobile' - declare position: 'static' | 'absolute' | 'relative' | 'fixed' | 'sticky' - declare top: string - declare right: string - declare bottom: string - declare left: string - declare store: LiveStore | null - declare _user: NamedNode | null - - constructor () { - super() - this.theme = 'light' - this.layout = 'desktop' - this.position = 'static' - this.top = 'auto' - this.right = 'auto' - this.bottom = 'auto' - this.left = 'auto' - this.store = null - this._user = null - this._updateFooter = this._updateFooter.bind(this) - } - - connectedCallback () { - super.connectedCallback() - authSession.events.on('login', this._updateFooter) - authSession.events.on('logout', this._updateFooter) - this._updateFooter() - } - - disconnectedCallback () { - if (typeof authSession.events.off === 'function') { - authSession.events.off('login', this._updateFooter) - authSession.events.off('logout', this._updateFooter) - } - super.disconnectedCallback() - } - - updated (changedProperties: Map) { - if ( - changedProperties.has('position') || - changedProperties.has('top') || - changedProperties.has('right') || - changedProperties.has('bottom') || - changedProperties.has('left') - ) { - this._updatePositionStyles() - } - } - - private _updatePositionStyles () { - this.style.setProperty('--footer-position', this.position) - this.style.setProperty('--footer-top', this.top) - this.style.setProperty('--footer-right', this.right) - this.style.setProperty('--footer-bottom', this.bottom) - this.style.setProperty('--footer-left', this.left) - } - - private _updateFooter () { - this._user = authn.currentUser() - } - - render () { - return html` - - ` - } - - private _renderFooterContent () { - if (!this._user) { - return html` -
- Public View -
You are viewing this profile as a guest.
-
- ` - } - - const userName = this.store ? getName(this.store, this._user) : this._user.uri - - return html` -
- Logged in View -
- You are logged in as - ${userName}. -
-
- ` - } -} diff --git a/src/v2/components/layout/footer/README.md b/src/v2/components/layout/footer/README.md deleted file mode 100644 index c868dba69..000000000 --- a/src/v2/components/layout/footer/README.md +++ /dev/null @@ -1,105 +0,0 @@ -# solid-ui-footer component - -A Lit-based custom element that renders a footer panel for Solid applications. It supports a rounded rectangle layout, grey background, and adjustable positioning via attributes. - -## Installation - -```bash -npm install solid-ui -``` - -## Usage in a bundled project (webpack, Vite, Rollup, etc.) - -Import once to register the custom element and get access to the type: - -```javascript -import { Footer } from 'solid-ui/components/footer' -``` - -Then use the element in HTML or in your framework templates: - -```html - - -``` - -If you need the footer to be relative to a container, use `position="relative"` or `position="absolute"` along with `top`, `left`, `right`, and `bottom` as needed. - -## Usage in a plain HTML page (CDN / script tag) - -Load `rdflib` and `solid-logic` first, then import the footer bundle: - -```html - - - - - -``` - -## TypeScript - -Types are included. Import the exported element class: - -```typescript -import { Footer } from 'solid-ui/components/footer' - -const footer = document.querySelector('solid-ui-footer') as Footer -footer.position = 'fixed' -footer.bottom = '1rem' -``` - -## API - -Properties / attributes: - -- `layout`: `desktop` (default) or `mobile`. In mobile layout, the border, box-shadow and border-radius are removed. -- `position`: `static`, `absolute`, `relative`, `fixed`, or `sticky`. -- `top`: CSS offset for the top edge when `position` is not `static`. -- `right`: CSS offset for the right edge when `position` is not `static`. -- `bottom`: CSS offset for the bottom edge when `position` is not `static`. -- `left`: CSS offset for the left edge when `position` is not `static`. -- `store`: an `rdflib` store instance used to resolve the logged-in user name from the current Solid session. - -## Display behavior - -- When no user is logged in, the footer displays a public-view message. -- When a user is logged in, the footer displays a logged-in message and links the current profile name to the user profile URI. - -## Styling - -Customize the footer using CSS variables: - -- `--footer-bg` — background color (default: `#e6e6e6`). -- `--footer-text` — text color (default: `#4f4f4f`). -- `--footer-border-radius` — corner radius (default: `1rem`). -- `--footer-box-shadow` — box shadow. -- `--footer-link` — link color. - -## Example - -```html - -``` - -```typescript -import { Footer } from 'solid-ui/components/footer' -import type { LiveStore } from 'rdflib' - -const footer = document.querySelector('solid-ui-footer') as Footer -footer.position = 'fixed' -footer.bottom = '1rem' -footer.left = '1rem' -footer.right = '1rem' -footer.store = myRdflibStore as LiveStore -``` - -## Testing - -The component is covered by unit tests under `src/v2/components/layout/footer/Footer.test.ts`. diff --git a/src/v2/components/layout/footer/index.ts b/src/v2/components/layout/footer/index.ts deleted file mode 100644 index 7df3d81d0..000000000 --- a/src/v2/components/layout/footer/index.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { Footer } from './Footer' - -export { Footer } - -const FOOTER_TAG_NAME = 'solid-ui-footer' - -if (!customElements.get(FOOTER_TAG_NAME)) { - customElements.define(FOOTER_TAG_NAME, Footer) -}