Skip to content

Commit d1a02ae

Browse files
authored
Merge pull request #54 from LibreSign/fix/themeable-actions-toolbar
feat: add stable toolbar theming hooks
2 parents 0678075 + a662b5d commit d1a02ae

3 files changed

Lines changed: 120 additions & 22 deletions

File tree

README.md

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,3 +69,55 @@ Example:
6969
- `element-{type}` - Custom element rendering (e.g., `element-signature`)
7070
- `custom` - Fallback for elements without specific type
7171
- `actions` - Custom action buttons
72+
73+
#### `actions` slot props
74+
75+
The `actions` slot receives:
76+
77+
- `object`
78+
- `onDelete`
79+
- `onDuplicate`
80+
- `toolbarClass` (`pdf-elements-actions-toolbar`)
81+
- `actionClass` (`pdf-elements-action-btn`)
82+
- `actionAttrs` (`{ 'data-pdf-elements-action': 'true' }`)
83+
84+
Use these hooks to style third-party button components consistently (for example, Nextcloud `NcButton`) without relying on internal scoped selectors.
85+
86+
Example:
87+
88+
```vue
89+
<template #actions="slotProps">
90+
<NcButton
91+
:class="slotProps.actionClass"
92+
v-bind="slotProps.actionAttrs"
93+
type="button"
94+
variant="tertiary"
95+
@click.stop="slotProps.onDuplicate"
96+
>
97+
Duplicate
98+
</NcButton>
99+
</template>
100+
```
101+
102+
### Theme variables
103+
104+
Action toolbar and action buttons can be themed via CSS variables and follow host theme tokens by default.
105+
106+
| Variable | Description |
107+
|---|---|
108+
| `--pdf-elements-toolbar-gap` | Toolbar button gap |
109+
| `--pdf-elements-toolbar-padding` | Toolbar padding |
110+
| `--pdf-elements-toolbar-background` | Toolbar background color |
111+
| `--pdf-elements-toolbar-color` | Toolbar text/icon color |
112+
| `--pdf-elements-toolbar-border-color` | Toolbar border color |
113+
| `--pdf-elements-toolbar-border-radius` | Toolbar border radius |
114+
| `--pdf-elements-toolbar-shadow` | Toolbar shadow |
115+
| `--pdf-elements-action-btn-border` | Action button border |
116+
| `--pdf-elements-action-btn-background` | Action button background |
117+
| `--pdf-elements-action-btn-color` | Action button text/icon color |
118+
| `--pdf-elements-action-btn-padding` | Action button padding |
119+
| `--pdf-elements-action-btn-radius` | Action button border radius |
120+
| `--pdf-elements-action-btn-min-height` | Action button min height |
121+
| `--pdf-elements-action-btn-min-width` | Action button min width |
122+
| `--pdf-elements-action-btn-shadow` | Action button shadow |
123+
| `--pdf-elements-action-btn-hover-background` | Action button hover background |

src/components/DraggableElement.vue

Lines changed: 67 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,36 @@ SPDX-License-Identifier: AGPL-3.0-or-later
77
<div class="draggable-wrapper">
88
<div
99
v-if="isSelected && !isBeingDraggedGlobally && showSelectionUi && showDefaultActions"
10-
class="actions-toolbar"
10+
class="actions-toolbar pdf-elements-actions-toolbar"
1111
:style="toolbarStyle"
1212
>
13-
<slot name="actions" :object="object" :onDelete="onDelete" :onDuplicate="onDuplicate">
14-
<button class="action-btn" type="button" title="Duplicate" @click.stop="onDuplicate">
13+
<slot
14+
name="actions"
15+
:object="object"
16+
:onDelete="onDelete"
17+
:onDuplicate="onDuplicate"
18+
:toolbarClass="toolbarClass"
19+
:actionClass="actionClass"
20+
:actionAttrs="actionAttrs"
21+
>
22+
<button
23+
class="action-btn pdf-elements-action-btn"
24+
type="button"
25+
title="Duplicate"
26+
v-bind="actionAttrs"
27+
@click.stop="onDuplicate"
28+
>
1529
<svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
1630
<path d="M16 1H6a2 2 0 0 0-2 2v12h2V3h10V1zm3 4H10a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h9a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2zm0 16H10V7h9v14z"/>
1731
</svg>
1832
</button>
19-
<button class="action-btn" type="button" title="Delete" @click.stop="onDelete">
33+
<button
34+
class="action-btn pdf-elements-action-btn"
35+
type="button"
36+
title="Delete"
37+
v-bind="actionAttrs"
38+
@click.stop="onDelete"
39+
>
2040
<svg width="16" height="16" viewBox="0 0 16 16" fill="currentColor">
2141
<path d="M6.5 1h3a.5.5 0 0 1 .5.5v1H6v-1a.5.5 0 0 1 .5-.5ZM11 2.5v-1A1.5 1.5 0 0 0 9.5 0h-3A1.5 1.5 0 0 0 5 1.5v1H2.5a.5.5 0 0 0 0 1h.5v10.5A1.5 1.5 0 0 0 4.5 15h7a1.5 1.5 0 0 0 1.5-1.5V3.5h.5a.5.5 0 0 0 0-1H11Zm1 1v10.5a.5.5 0 0 1-.5.5h-7a.5.5 0 0 1-.5-.5V3.5h8Z"/>
2242
</svg>
@@ -223,6 +243,17 @@ export default defineComponent({
223243
pointerEvents: 'none',
224244
} as CSSProperties
225245
},
246+
toolbarClass() {
247+
return 'pdf-elements-actions-toolbar'
248+
},
249+
actionClass() {
250+
return 'pdf-elements-action-btn'
251+
},
252+
actionAttrs() {
253+
return {
254+
'data-pdf-elements-action': 'true',
255+
}
256+
},
226257
},
227258
mounted() {
228259
this.handleClickOutside = this.handleClickOutside.bind(this)
@@ -487,28 +518,48 @@ export default defineComponent({
487518
.actions-toolbar {
488519
position: absolute;
489520
display: flex;
490-
gap: 4px;
491-
background: #1f2937;
492-
border-radius: 6px;
493-
padding: 6px 8px;
494-
box-shadow: 0 4px 12px -2px rgba(0, 0, 0, 0.15), 0 2px 6px -2px rgba(0, 0, 0, 0.1);
521+
gap: var(--pdf-elements-toolbar-gap, 4px);
522+
background: var(--pdf-elements-toolbar-background, var(--color-main-background, #ffffff));
523+
color: var(--pdf-elements-toolbar-color, var(--color-main-text, #222222));
524+
border: 1px solid var(--pdf-elements-toolbar-border-color, var(--color-border, #d1d5db));
525+
border-radius: var(--pdf-elements-toolbar-border-radius, 6px);
526+
padding: var(--pdf-elements-toolbar-padding, 6px 8px);
527+
box-shadow: var(--pdf-elements-toolbar-shadow, 0 4px 12px -2px rgba(0, 0, 0, 0.15), 0 2px 6px -2px rgba(0, 0, 0, 0.1));
495528
z-index: 5;
496529
white-space: nowrap;
497530
}
498531
.action-btn {
499-
border: none;
500-
background: transparent;
501-
color: #ffffff;
502-
padding: 4px;
503-
border-radius: 4px;
532+
border: var(--pdf-elements-action-btn-border, none);
533+
background: var(--pdf-elements-action-btn-background, transparent);
534+
color: var(--pdf-elements-action-btn-color, currentColor);
535+
padding: var(--pdf-elements-action-btn-padding, 4px);
536+
border-radius: var(--pdf-elements-action-btn-radius, 4px);
537+
min-height: var(--pdf-elements-action-btn-min-height, auto);
538+
min-width: var(--pdf-elements-action-btn-min-width, auto);
504539
cursor: pointer;
505540
display: flex;
506541
align-items: center;
507542
justify-content: center;
508-
transition: background 120ms ease;
543+
transition: background-color 120ms ease;
509544
}
510545
.action-btn:hover {
511-
background: rgba(255, 255, 255, 0.1);
546+
background: var(--pdf-elements-action-btn-hover-background, var(--color-background-hover, rgba(0, 0, 0, 0.08)));
547+
}
548+
549+
.actions-toolbar :deep(.pdf-elements-action-btn),
550+
.actions-toolbar :deep([data-pdf-elements-action]) {
551+
border: var(--pdf-elements-action-btn-border, none);
552+
background: var(--pdf-elements-action-btn-background, transparent);
553+
color: var(--pdf-elements-action-btn-color, currentColor);
554+
border-radius: var(--pdf-elements-action-btn-radius, 4px);
555+
min-height: var(--pdf-elements-action-btn-min-height, auto);
556+
min-width: var(--pdf-elements-action-btn-min-width, auto);
557+
box-shadow: var(--pdf-elements-action-btn-shadow, none);
558+
}
559+
560+
.actions-toolbar :deep(.pdf-elements-action-btn:hover),
561+
.actions-toolbar :deep([data-pdf-elements-action]:hover) {
562+
background: var(--pdf-elements-action-btn-hover-background, var(--color-background-hover, rgba(0, 0, 0, 0.08)));
512563
}
513564
.draggable-element {
514565
position: absolute;

src/components/PDFElements.vue

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -97,12 +97,7 @@ SPDX-License-Identifier: AGPL-3.0-or-later
9797
</slot>
9898
</template>
9999
<template #actions="slotProps">
100-
<slot
101-
name="actions"
102-
:object="slotProps.object"
103-
:onDelete="slotProps.onDelete"
104-
:onDuplicate="slotProps.onDuplicate"
105-
/>
100+
<slot name="actions" v-bind="slotProps" />
106101
</template>
107102
</DraggableElement>
108103
</div>

0 commit comments

Comments
 (0)