Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
58 changes: 58 additions & 0 deletions app/components/copy-button.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';
import { action } from '@ember/object';

export default class CopyButtonComponent extends Component {
@tracked isCopied = false;
@tracked copyError = false;

@action
async copyText() {
try {
await navigator.clipboard.writeText(this.args.textToCopy);
this.isCopied = true;
this.copyError = false;

setTimeout(() => {
this.isCopied = false;
}, 2000);
} catch (err) {
console.error('Failed to copy text:', err);
this.copyError = true;

setTimeout(() => {
this.copyError = false;
}, 2000);
}
}

get buttonLabel() {
if (this.isCopied) {
return 'ROR ID copied to clipboard';
}
if (this.copyError) {
return 'Failed to copy ROR ID';
}
return 'Copy ROR ID to clipboard';
}

get buttonTitle() {
if (this.isCopied) {
return 'Copied!';
}
if (this.copyError) {
return 'Copy failed';
}
return 'Copy ROR ID';
}

get iconClass() {
if (this.isCopied) {
return 'fa-solid fa-check';
}
if (this.copyError) {
return 'fa-solid fa-exclamation-triangle';
}
return 'fa-solid fa-copy';
}
}
1 change: 1 addition & 0 deletions app/styles/app.scss
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
@import 'ember-power-select';
@import "components/organizations/api-client-registration-form";
@import "components/copy-button";

$green: #53baa1;
$dark-grey: #505759;
Expand Down
65 changes: 65 additions & 0 deletions app/styles/components/copy-button.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
.copy-button {
display: inline-block;
margin-left: 0.5rem;
margin-bottom: 0.25rem;
padding: 0;
background-color: transparent;
border: none;
color: #293030;
font-size: 1.25rem;
line-height: 1;
cursor: pointer;
transition: color 0.2s ease, opacity 0.2s ease;
vertical-align: middle;
opacity: 0.7;

&:hover {
color: #53baa1;
opacity: 1;
}

&:focus {
outline: none;
}

&:focus-visible {
outline: 2px solid #53baa1;
outline-offset: 2px;
border-radius: 2px;
opacity: 1;
}

&:active {
transform: scale(0.95);
}

&.copy-button--success {
opacity: 1;
}

&.copy-button--error {
color: #da3200;
opacity: 1;
}

i {
pointer-events: none;
}

@media screen and (max-width: 420px) {
font-size: 1rem;
margin-left: 0.35rem;
}
}

.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border: 0;
}
14 changes: 14 additions & 0 deletions app/templates/components/copy-button.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<button
type="button"
class="copy-button {{if this.isCopied 'copy-button--success'}} {{if this.copyError 'copy-button--error'}}"
aria-label={{this.buttonLabel}}
title="Copy ROR ID"
{{on "click" this.copyText}}
>
<i class={{this.iconClass}} aria-hidden="true"></i>
</button>
<span class="sr-only" role="status" aria-live="polite" aria-atomic="true">
{{#if this.isCopied}}
ROR ID copied to clipboard
{{/if}}
</span>
1 change: 1 addition & 0 deletions app/templates/components/organization-item.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
<div class="col-lg-9 col-sm-12">
<h1>
<img class="ror-id mb-1" src="/assets/ror-logo-small.png" alt="ROR ID"> <LinkTo @route="organizations.show" @model={{this.model.id}} class="card-link logo-link">https://ror.org/{{this.model.id}}</LinkTo>
<CopyButton @textToCopy="https://ror.org/{{this.model.id}}" />
</h1>
</div>
<div class="col-lg-3 col-sm-12">
Expand Down
Loading