Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions declarations.d.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
/// <reference types="vite-plugin-lit-css/client" />
/// <reference types="unplugin-icons/types/web-components" />
797 changes: 233 additions & 564 deletions package-lock.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
"@types/mime-types": "^3.0.1",
"@types/node": "^22.20.0",
"@vitest/coverage-v8": "^4.0.18",
"@iconify-json/lucide": "^1.2.116",
"eslint": "^9.39.2",
"eslint-plugin-import": "^2.32.0",
"jsdom": "^28.1.0",
Expand Down
50 changes: 0 additions & 50 deletions src/Header.ts

This file was deleted.

12 changes: 12 additions & 0 deletions src/components/header/SourceHeader.styles.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
:host {
header {
display: flex;
justify-content: space-between;
align-items: center;
gap: 6px;
flex-wrap: nowrap;
width: 100%;
text-align: right;
padding: 15px;
}
}
29 changes: 29 additions & 0 deletions src/components/header/SourceHeader.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { WebComponent } from 'solid-ui'
import { customElement } from 'lit/decorators.js'
import { html } from 'lit'
import 'solid-ui/components/button'
import { consume } from '@lit/context'
import { sourceContext, SourceContext } from '../../primitives/context'
import '~icons/lucide/share-2'
import '~icons/lucide/pencil'
import '~icons/lucide/ellipsis-vertical'
import styles from './SourceHeader.styles.css'
import './SourceHeaderSummary'
import './SourceHeaderControls'

@customElement('source-pane-source-header')
export default class SourceHeader extends WebComponent {
static styles = styles

@consume({ context: sourceContext, subscribe: true })
accessor sourceContext: SourceContext = undefined as unknown as SourceContext

render () {
return html`
<header>
<source-pane-source-header-summary></source-pane-source-header-summary>
<source-pane-source-header-controls></source-pane-source-header-controls>
</header>
`
}
}
28 changes: 28 additions & 0 deletions src/components/header/SourceHeaderControls.styles.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
:host {
div {
display: flex;
justify-content: flex-end;
align-items: center;
gap: 6px;
flex: 0 0 auto;
text-align: right;
}

/* generative ai */
div > * {
flex: 0 1 auto;
}

@media (max-width: 900px) {
div {
padding-right: 3px;
}
}

@media (max-width: 600px) {
div {
justify-content: flex-start;
gap: 5px;
}
}
}
46 changes: 46 additions & 0 deletions src/components/header/SourceHeaderControls.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { WebComponent } from 'solid-ui'
import { customElement } from 'lit/decorators.js'
import { html } from 'lit'
import 'solid-ui/components/button'
import { consume } from '@lit/context'
import { sourceContext, SourceContext } from '../../primitives/context'
import '~icons/lucide/share-2'
import '~icons/lucide/pencil'
import '~icons/lucide/ellipsis-vertical'
import styles from './SourceHeaderControls.styles.css'
import './SourceHeaderSummary'

@customElement('source-pane-source-header-controls')
export default class SourceHeaderControls extends WebComponent {
static styles = styles

@consume({ context: sourceContext, subscribe: true })
accessor sourceContext: SourceContext = undefined as unknown as SourceContext

/* private canEditSource (subject: NamedNode, sourcePaneState: SourcePaneState) {
const { allowed } = sourcePaneState
return !subject.uri.endsWith('/') && (!allowed || allowed.includes('PUT'))
} */

private setEditable() {
const sourcePaneState = this.sourceContext?.sourcePaneState
if (!sourcePaneState || sourcePaneState.broken) return
this.sourceContext?.setEditing?.()
}
Comment thread
SharonStrats marked this conversation as resolved.

render () {
return html`
<div>
<solid-ui-button class="sourcePanePrettyButton" variant="ghost" title="Share">
<icon-lucide-share-2 slot="icon"></icon-lucide-share-2>
</solid-ui-button>
<solid-ui-button class="sourcePanePrettyButton" variant="ghost" @click=${() => this.setEditable()}>
<icon-lucide-pencil slot="icon"></icon-lucide-pencil>
</solid-ui-button>
<solid-ui-button class="sourcePanePrettyButton" variant="ghost" title="More options">
<icon-lucide-ellipsis-vertical slot="icon"></icon-lucide-ellipsis-vertical>
</solid-ui-button>
</div>
`
}
}
82 changes: 82 additions & 0 deletions src/components/header/SourceHeaderSummary.styles.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
:host {
.source-pane-header-summary {
display: flex;
justify-content: flex-start;
align-items: center;
gap: 6px;
flex-wrap: wrap;
flex: 1 1 auto;
min-width: 0;
text-align: left;
}

h1 {
color: var(--solid-ui-color-gray-700, #364153);
font-size: var(--solid-ui-font-size-2xl, 1.5rem);
font-weight: 500;
}

.source-pane-icon {
display: flex;
width: 40px;
height: 40px;
padding: 7.5px 7px 6.5px 7px;
justify-content: center;
align-items: center;
aspect-ratio: 1/1;
border-radius: 100px;
background: var(--slate-600, #45556C);
}

p {
display: flex;
align-items: center;
gap: 5px;
color: var(--solid-ui-gray-500, #6A7282);
font-size: var(--solid-ui-font-size-xs, .75rem);
font-weight: 500;
}

.source-pane-public {
display: flex;
padding: 2px 5px;
justify-content: center;
align-items: center;
gap: 3px;
color: var(--blue-400, #51A2FF);
border-radius: 5px;
background: var(--blue-50, #EFF6FF);
}

icon-lucide-globe {
stroke-width: 1.021px;
stroke: var(--blue-400, #51A2FF);
}

.source-pane-private {
display: flex;
padding: 2px 5px;
justify-content: center;
align-items: center;
gap: 3px;
color: var(--yellow-600, #D08700);
border-radius: 5px;
background: var(--yellow-100, #FEF9C2);
}

icon-lucide-lock-keyhole {
stroke-width: 1.021px;
stroke: var(--yellow-600, #D08700);
}

icon-lucide-globe,
icon-lucide-lock-keyhole {
width: 0.875rem;
height: 0.875rem;
}

icon-lucide-arrow-left {
width: 1.125rem;
height: 1.125rem;
}
}
67 changes: 67 additions & 0 deletions src/components/header/SourceHeaderSummary.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { utils, WebComponent } from 'solid-ui'
import 'solid-ui/components/button'
import { customElement } from 'lit/decorators.js'
import { html } from 'lit'
import { consume } from '@lit/context'
import { sym } from 'rdflib'
import { sourceContext, SourceContext } from '../../primitives/context'
import '~icons/lucide/globe'
import '~icons/lucide/lock-keyhole'
import '~icons/lucide/arrow-left'
import styles from './SourceHeaderSummary.styles.css'
import { sourcePaneIcon } from '../../icons/sourcePaneIcon'

@customElement('source-pane-source-header-summary')
export default class SourceHeaderSummary extends WebComponent {
static styles = styles

@consume({ context: sourceContext, subscribe: true })
accessor sourceContext: SourceContext = undefined as unknown as SourceContext

private formatModifiedDate (modified: string | undefined) {
if (!modified) return ''

const date = new Date(modified)
if (Number.isNaN(date.getTime())) return modified

const parts = new Intl.DateTimeFormat('en-GB', {
day: '2-digit',
month: 'short',
year: 'numeric',
hour: '2-digit',
minute: '2-digit',
hour12: true
}).formatToParts(date)

const getPart = (type: Intl.DateTimeFormatPartTypes) => parts.find(part => part.type === type)?.value ?? ''
const day = getPart('day')
const month = getPart('month')
const year = getPart('year')
const hour = getPart('hour')
const minute = getPart('minute')
const dayPeriod = getPart('dayPeriod').toUpperCase()

return `${day} ${month}, ${year} at ${hour}:${minute} ${dayPeriod}`
}

render () {
const subject = this.sourceContext?.subject ? sym(this.sourceContext.subject) : undefined
const label = subject ? utils.label(subject) : ''
const modified = this.formatModifiedDate(this.sourceContext?.headerMetadata?.modified)
const isPublic = this.sourceContext?.headerMetadata?.isPublic ?? false

return html`
<div class="source-pane-header-summary">
<solid-ui-button
variant="ghost">
<icon-lucide-arrow-left></icon-lucide-arrow-left>
</solid-ui-button>
<span class="source-pane-icon">${sourcePaneIcon}</span>
<div>
<h1>${label}</h1>
<p>${modified} ${isPublic ? html`<span class="source-pane-public"><icon-lucide-globe></icon-lucide-globe> Public</span>` : html`<span class="source-pane-private"><icon-lucide-lock-keyhole></icon-lucide-lock-keyhole> Private</span>`}</p>
</div>
</div>
`
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
flex-direction: column;
width: 100%;
align-items: stretch;
padding: 0px 40px;
}

.sourcePaneEditor {
Expand Down
Loading
Loading