Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
b2d3f02
Added first part of styleguide to run a styleguide in browser
remko48 May 5, 2026
3e94b95
Removed @example from docblocks wich caused errors in styleguide run
remko48 May 5, 2026
f14ceee
First part of live demo update
remko48 May 5, 2026
7b9aef5
Eslint
remko48 May 5, 2026
69e96be
Second part of styleguide config
remko48 May 5, 2026
cf70264
Added component documentation
remko48 May 5, 2026
9fd6dd7
Made sure that doc coverage is tested on both types of docs
remko48 May 5, 2026
1a4b83c
Fixed styling for table and link
remko48 May 6, 2026
2064eb7
Fixed hover on table
remko48 May 6, 2026
2d0ac76
Fixed button styling
remko48 May 6, 2026
fd66224
Updated sidebar styling
remko48 May 6, 2026
d5c9775
Fixed main tag styling and made sure only selected items are shown in…
remko48 May 6, 2026
32cefa8
Added vue docs
remko48 May 6, 2026
6873171
Added favicon and fixed console errors for Data Display
remko48 May 6, 2026
d3bd1e0
Fixed console errors in cards
remko48 May 6, 2026
923917c
Fixed console errors in dialogs
remko48 May 6, 2026
f934a98
Fixed console errors in Dialogs
remko48 May 6, 2026
08746d8
Fixed console errors in Object Widgets
remko48 May 6, 2026
c7e02e5
Fixed console errors in Dashboard
remko48 May 6, 2026
cb8c009
Fixed console errors in Full pages
remko48 May 6, 2026
fa04e25
Fixed console errors in App Shell
remko48 May 6, 2026
7099d5b
Fixed console errors in Settings
remko48 May 6, 2026
d163647
Fixed console errors in Specialized
remko48 May 6, 2026
6c310f0
Updated code to go through the docs checker and added an introduction
remko48 May 6, 2026
23f4fbe
Quality flow, tests
remko48 May 7, 2026
2f1b189
Update styleguide/styleguide.config.js
remko48 May 7, 2026
e51392c
Requested changes
remko48 May 7, 2026
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
40 changes: 40 additions & 0 deletions .github/workflows/documentation-beta.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
name: Documentation (Beta)

on:
push:
branches:
- beta

jobs:
deploy-beta:
name: Deploy Beta Styleguide
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Setup Node.js 20
uses: actions/setup-node@v4
with:
node-version: '20'

- name: Install and build component styleguide
timeout-minutes: 10
run: |
cd styleguide
npm ci
npm run build

- name: Deploy styleguide to /beta/ on GitHub Pages
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./styleguide/build
publish_branch: gh-pages
destination_dir: beta/styleguide
user_name: 'github-actions[bot]'
user_email: 'github-actions[bot]@users.noreply.github.com'
keep_files: true
41 changes: 41 additions & 0 deletions .github/workflows/documentation-dev.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
name: Documentation (Dev)

on:
push:
branches:
- development

jobs:
deploy-dev:
name: Deploy Dev Styleguide
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Setup Node.js 20
uses: actions/setup-node@v4
with:
node-version: '20'

- name: Install and build component styleguide
timeout-minutes: 10
run: |
cd styleguide
npm ci
npm run build

- name: Deploy styleguide to /dev/ on GitHub Pages
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./styleguide/build

publish_branch: gh-pages
destination_dir: dev/styleguide
user_name: 'github-actions[bot]'
user_email: 'github-actions[bot]@users.noreply.github.com'
keep_files: true
15 changes: 14 additions & 1 deletion .github/workflows/documentation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,13 @@ jobs:
with:
node-version: '20'

- name: Install and build component styleguide
timeout-minutes: 10
run: |
cd styleguide
npm ci
npm run build

- name: Clear build cache and install dependencies
timeout-minutes: 3
run: |
Expand All @@ -43,6 +50,12 @@ jobs:
exit 1
fi

- name: Copy styleguide into Docusaurus build
run: |
mkdir -p docusaurus/build/styleguide
cp -r styleguide/build/. docusaurus/build/styleguide/


- name: Create .nojekyll file
run: |
cd docusaurus/build
Expand All @@ -58,7 +71,7 @@ jobs:
user_email: 'github-actions[bot]@users.noreply.github.com'
force_orphan: false
allow_empty_commit: true
keep_files: false
keep_files: true

- name: Verify deployment
run: |
Expand Down
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,7 @@ dist/
# Docusaurus build output
docusaurus/build
.docusaurus

# Styleguide build output
styleguide/build
.styleguide
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,7 @@
"[php]": {
"editor.defaultFormatter": "DEVSENSE.phptools-vscode"
},
"[markdown]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
}
49 changes: 45 additions & 4 deletions docs/components/cn-advanced-form-dialog.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,11 +129,52 @@ This means the directive is self-contained — it works even if the consuming ap

---

## Live demo

```vue
<template>
<div>
<button @click="open = true" style="padding: 6px 16px; border-radius: 4px; background: var(--color-primary-element); color: white; border: none; cursor: pointer;">Edit contact</button>
<CnAdvancedFormDialog
v-if="open"
ref="dlg"
:schema="schema"
:item="item"
@confirm="onConfirm"
@close="open = false" />
</div>
</template>
<script>
export default {
data() {
return {
open: false,
schema: {
title: 'Contact',
properties: {
name: { type: 'string', title: 'Name' },
email: { type: 'string', format: 'email', title: 'Email' },
notes: { type: 'string', title: 'Notes' },
},
},
item: { id: 1, name: 'Jane Doe', email: 'jane@example.com', notes: '' },
}
},
methods: {
async onConfirm(payload) {
await new Promise(r => setTimeout(r, 800))
this.$refs.dlg.setResult({ success: true })
},
},
}
</script>
```

## Usage examples

### Standalone (emit confirm, parent saves)

```vue
```vue {static}
<CnAdvancedFormDialog
ref="advancedForm"
:schema="schema"
Expand All @@ -156,7 +197,7 @@ async onConfirm(payload) {

### With CnIndexPage (useAdvancedFormDialog)

```vue
```vue {static}
<CnIndexPage
title="Items"
:schema="schema"
Expand All @@ -172,7 +213,7 @@ async onConfirm(payload) {

### Custom Properties tab

```vue
```vue {static}
<CnAdvancedFormDialog :schema="schema" :item="item" @confirm="onConfirm" @close="close">
<template #tab-properties="{ formData, updateField, objectProperties }">
<MyCustomPropertyGrid
Expand All @@ -186,7 +227,7 @@ async onConfirm(payload) {

### Full form override

```vue
```vue {static}
<CnAdvancedFormDialog :schema="schema" :item="item" @confirm="onConfirm" @close="close">
<template #form="{ formData, updateField, jsonData, updateJson, isValidJson }">
<MyCustomForm :data="formData" @update="updateField" />
Expand Down
9 changes: 5 additions & 4 deletions docs/components/cn-app-root.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ CnAppRoot is the full-shell convenience for the JSON manifest renderer. Apps tha
|-------|------|-------------------|---------------|
| `loading` | While `isLoading` is `true` | `<CnAppLoading />` | `#loading` |
| `dependency-missing` | After loading; any entry in `manifest.dependencies` is not installed/enabled | `<CnDependencyMissing />` | `#dependency-missing` |
| `shell` | Manifest loaded + dependencies satisfied | `<CnAppNav />` + `<router-view />` | `#menu`, `#header-actions`, `#sidebar`, `#footer` |
| `shell` | Manifest loaded + dependencies satisfied | `<CnAppNav />` + default slot content | `#menu`, default slot, `#header-actions`, `#sidebar`, `#footer` |

Dependency status is resolved by [`useAppStatus`](../utilities/composables/use-app-status.md) — one call per id in `manifest.dependencies`, cached for the page lifetime.

## Usage

```vue
```vue {static}
<template>
<CnAppRoot
:manifest="manifest"
Expand Down Expand Up @@ -85,12 +85,13 @@ CnAppRoot calls `provide()` with the following keys; descendants `inject` these:

| Slot | Scope | Default | Description |
|------|-------|---------|-------------|
| *(default)* | — | — | Page content area inside `NcAppContent`. In real apps, pass `<router-view />` here. |
| `loading` | — | `<CnAppLoading />` | Shown during the loading phase |
| `dependency-missing` | `{ dependencies }` | `<CnDependencyMissing :dependencies />` | Shown when any dependency is missing or disabled |
| `menu` | — | `<CnAppNav :permissions />` | Replaces the default app navigation |
| `header-actions` | — | — | Mounted inside `NcAppContent`, alongside `<router-view />` |
| `header-actions` | — | — | Mounted inside `NcAppContent`, alongside the default slot |
| `sidebar` | — | — | Mounted next to `NcAppContent` (e.g. for `NcAppSidebar`) |
| `footer` | — | — | Mounted inside `NcAppContent`, after `<router-view />` |
| `footer` | — | — | Mounted inside `NcAppContent`, after the default slot |

## Related

Expand Down
59 changes: 30 additions & 29 deletions docs/components/cn-context-menu.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,57 +34,58 @@ Right-click context menu component that wraps NcActions with cursor positioning.

### With actions array (common case)

Right-click one of the rows below:

```vue
<template>
<table>
<tr
<div>
<div
v-for="row in rows"
:key="row.id"
@contextmenu.prevent="onContextMenu({ item: row, event: $event })">
<!-- cells -->
</tr>
</table>

<CnContextMenu
:open.sync="contextMenuOpen"
:actions="actions"
:target-item="contextMenuRow"
@action="onAction"
@close="closeContextMenu" />
style="padding: 10px 12px; border: 1px solid var(--color-border); border-radius: 4px; margin-bottom: 4px; cursor: context-menu; user-select: none;"
@contextmenu.prevent="e => onContextMenu({ item: row, event: e })">
{{ row.title }}
</div>
<CnContextMenu
:open.sync="contextMenuOpen"
:actions="actions"
:target-item="contextMenuRow"
@close="closeContextMenu" />
<p v-if="lastAction" style="margin-top: 8px; font-size: 13px; color: var(--color-text-maxcontrast);">Last: {{ lastAction }}</p>
</div>
</template>

<script>
import { CnContextMenu, useContextMenu } from '@conduction/nextcloud-vue'

import { useContextMenu } from '@conduction/nextcloud-vue'
export default {
components: { CnContextMenu },

setup() {
const {
isOpen: contextMenuOpen,
targetItem: contextMenuRow,
open: onContextMenu,
close: closeContextMenu,
} = useContextMenu()

return { contextMenuOpen, contextMenuRow, onContextMenu, closeContextMenu }
},

computed: {
actions() {
return [
{ label: 'Edit', icon: PencilIcon, handler: (row) => this.editRow(row) },
{ label: 'Delete', icon: TrashIcon, handler: (row) => this.deleteRow(row), destructive: true },
]
},
data() {
return {
lastAction: '',
rows: [
{ id: 1, title: 'Item one — right-click me' },
{ id: 2, title: 'Item two — right-click me' },
],
actions: [
{ label: 'Edit', handler: (row) => { this.lastAction = 'Edit: ' + row.title } },
{ label: 'Delete', handler: (row) => { this.lastAction = 'Delete: ' + row.title }, destructive: true },
],
}
},
}
</script>
```

### With custom slot content

```vue
```vue {static}
<CnContextMenu
:open.sync="contextMenuOpen"
@close="closeContextMenu">
Expand All @@ -101,7 +102,7 @@ export default {

### Mixed (actions array + slot)

```vue
```vue {static}
<CnContextMenu
:open.sync="contextMenuOpen"
:actions="commonActions"
Expand Down
27 changes: 27 additions & 0 deletions docs/components/cn-copy-dialog.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,30 @@ Two-phase single-item copy dialog with naming pattern selector. User picks a nam
| Method | Description |
|--------|-------------|
| `setResult(\{ success?, error? \})` | Set operation result |

## Live demo

```vue
<template>
<div>
<button @click="open = true" style="padding: 6px 16px; border-radius: 4px; background: var(--color-primary-element); color: white; border: none; cursor: pointer;">Copy item</button>
<CnCopyDialog
v-if="open"
ref="dlg"
:item="{ id: 1, title: 'Annual Report 2024' }"
@confirm="onConfirm"
@close="open = false" />
</div>
</template>
<script>
export default {
data() { return { open: false } },
methods: {
async onConfirm({ id, newName }) {
await new Promise(r => setTimeout(r, 800))
this.$refs.dlg.setResult({ success: true })
},
},
}
</script>
```
Loading
Loading