-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
perf(rich-text-editor): adding extra functionality to link
adding extra functionality to link ✅ Closes: COMUI-2981
- Loading branch information
1 parent
183ce38
commit ce98a6b
Showing
20 changed files
with
455 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
21 changes: 21 additions & 0 deletions
21
...text-editor-action/gux-rich-text-editor-action-link/gux-rich-text-editor-action-link.scss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
:host { | ||
display: block; | ||
} | ||
|
||
gux-popover { | ||
div.gux-popover-content-wrapper { | ||
display: flex; | ||
flex-direction: column; | ||
gap: var(--gse-ui-popover-gap); | ||
} | ||
} | ||
|
||
gux-button-slot { | ||
inline-size: var(--gse-ui-button-iconOnly-width); | ||
block-size: var(--gse-ui-button-default-height); | ||
|
||
button.gux-is-pressed { | ||
color: var(--gse-ui-button-ghost-active-foregroundColor); | ||
background-color: var(--gse-ui-button-ghost-active-backgroundColor); | ||
} | ||
} |
162 changes: 162 additions & 0 deletions
162
...-text-editor-action/gux-rich-text-editor-action-link/gux-rich-text-editor-action-link.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,162 @@ | ||
import { | ||
Component, | ||
Prop, | ||
State, | ||
Element, | ||
EventEmitter, | ||
Event, | ||
Listen, | ||
h, | ||
Host | ||
} from '@stencil/core'; | ||
import { OnClickOutside } from '@utils/decorator/on-click-outside'; | ||
import { trackComponent } from '@utils/tracking/usage'; | ||
import { buildI18nForComponent, GetI18nValue } from 'i18n'; | ||
import translationResources from '../i18n/en.json'; | ||
import { afterNextRender } from '@utils/dom/after-next-render'; | ||
|
||
@Component({ | ||
tag: 'gux-rich-text-editor-action-link', | ||
styleUrl: 'gux-rich-text-editor-action-link.scss', | ||
shadow: true | ||
}) | ||
export class GuxRichTextEditorActionLink { | ||
private i18n: GetI18nValue; | ||
actionButton: HTMLElement; | ||
linkAddressInputElement: HTMLInputElement; | ||
textToDisplayInputElement: HTMLInputElement; | ||
|
||
@Element() | ||
private root: HTMLElement; | ||
|
||
@Prop() | ||
disabled: boolean = false; | ||
|
||
@State() | ||
isOpen: boolean = false; | ||
|
||
@Event() linkOptions: EventEmitter<{ textToDisplay: string; href: string }>; | ||
|
||
@OnClickOutside({ triggerEvents: 'mousedown' }) | ||
onClickOutside(): void { | ||
this.isOpen = false; | ||
} | ||
|
||
@Listen('keydown') | ||
handleKeydown(event: KeyboardEvent): void { | ||
const composedPath = event.composedPath(); | ||
switch (event.key) { | ||
case 'Escape': | ||
this.isOpen = false; | ||
this.actionButton.focus(); | ||
break; | ||
case 'ArrowDown': | ||
case 'Enter': | ||
if (composedPath.includes(this.actionButton)) { | ||
event.preventDefault(); | ||
this.isOpen = true; | ||
this.focusTextToDisplayInputElement(); | ||
} | ||
break; | ||
} | ||
} | ||
|
||
async componentWillLoad(): Promise<void> { | ||
trackComponent(this.root); | ||
this.i18n = await buildI18nForComponent(this.root, translationResources); | ||
} | ||
|
||
private emitLinkOptions(): void { | ||
const linkOptions = { | ||
textToDisplay: this.textToDisplayInputElement.value, | ||
href: this.linkAddressInputElement.value | ||
}; | ||
this.linkOptions.emit(linkOptions); | ||
|
||
this.textToDisplayInputElement.value = null; | ||
this.linkAddressInputElement.value = null; | ||
|
||
this.isOpen = false; | ||
} | ||
|
||
private togglePopover(): void { | ||
this.isOpen = !this.isOpen; | ||
if (this.isOpen) { | ||
this.focusTextToDisplayInputElement(); | ||
} else { | ||
this.actionButton.focus(); | ||
} | ||
} | ||
|
||
private focusTextToDisplayInputElement(): void { | ||
afterNextRender(() => { | ||
this.textToDisplayInputElement.focus(); | ||
}); | ||
} | ||
|
||
private renderTooltip(): JSX.Element { | ||
if (!this.disabled) { | ||
return ( | ||
<gux-tooltip> | ||
<div slot="content">{this.i18n('link')}</div> | ||
</gux-tooltip> | ||
) as JSX.Element; | ||
} | ||
} | ||
|
||
render(): JSX.Element { | ||
return ( | ||
<Host> | ||
<gux-button-slot accent="ghost" icon-only> | ||
<button | ||
id="popover-target" | ||
class={{ 'gux-is-pressed': this.isOpen }} | ||
onClick={() => this.togglePopover()} | ||
ref={el => (this.actionButton = el)} | ||
type="button" | ||
disabled={this.disabled} | ||
aria-label={this.i18n('link')} | ||
aria-haspopup="true" | ||
aria-expanded={this.isOpen.toString()} | ||
> | ||
<gux-icon | ||
size="small" | ||
icon-name="fa/link-simple-regular" | ||
decorative | ||
></gux-icon> | ||
</button> | ||
{this.renderTooltip()} | ||
</gux-button-slot> | ||
<gux-popover is-open={this.isOpen} for="popover-target"> | ||
<div class="gux-popover-content-wrapper"> | ||
<gux-form-field-text-like> | ||
<input | ||
id="textToDisplay" | ||
ref={el => (this.textToDisplayInputElement = el)} | ||
slot="input" | ||
type="text" | ||
/> | ||
<label slot="label">{this.i18n('textToDisplay')}</label> | ||
</gux-form-field-text-like> | ||
<gux-form-field-text-like> | ||
<input | ||
ref={el => (this.linkAddressInputElement = el)} | ||
slot="input" | ||
type="text" | ||
/> | ||
<label slot="label">{this.i18n('linkAddress')}</label> | ||
</gux-form-field-text-like> | ||
<gux-cta-group align="end"> | ||
<gux-button onClick={() => this.emitLinkOptions()} slot="primary"> | ||
{this.i18n('insert')} | ||
</gux-button> | ||
<gux-button onClick={() => this.togglePopover()} slot="dismiss"> | ||
{this.i18n('cancel')} | ||
</gux-button> | ||
</gux-cta-group> | ||
</div> | ||
</gux-popover> | ||
</Host> | ||
) as JSX.Element; | ||
} | ||
} |
59 changes: 59 additions & 0 deletions
59
...t-editor/gux-rich-text-editor-action/gux-rich-text-editor-action-link/readme.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
# gux-rich-text-editor-action-link | ||
|
||
|
||
|
||
<!-- Auto Generated Below --> | ||
|
||
|
||
## Properties | ||
|
||
| Property | Attribute | Description | Type | Default | | ||
| ---------- | ---------- | ----------- | --------- | ------- | | ||
| `disabled` | `disabled` | | `boolean` | `false` | | ||
|
||
|
||
## Events | ||
|
||
| Event | Description | Type | | ||
| ------------- | ----------- | ------------------------------------------------------- | | ||
| `linkOptions` | | `CustomEvent<{ textToDisplay: string; href: string; }>` | | ||
|
||
|
||
## Dependencies | ||
|
||
### Depends on | ||
|
||
- [gux-tooltip](../../../../stable/gux-tooltip) | ||
- [gux-button-slot](../../../../stable/gux-button-slot) | ||
- [gux-icon](../../../../stable/gux-icon) | ||
- [gux-popover](../../../../stable/gux-popover) | ||
- [gux-form-field-text-like](../../../../stable/gux-form-field/components/gux-form-field-text-like) | ||
- [gux-cta-group](../../../gux-cta-group) | ||
- [gux-button](../../../../stable/gux-button) | ||
|
||
### Graph | ||
```mermaid | ||
graph TD; | ||
gux-rich-text-editor-action-link --> gux-tooltip | ||
gux-rich-text-editor-action-link --> gux-button-slot | ||
gux-rich-text-editor-action-link --> gux-icon | ||
gux-rich-text-editor-action-link --> gux-popover | ||
gux-rich-text-editor-action-link --> gux-form-field-text-like | ||
gux-rich-text-editor-action-link --> gux-cta-group | ||
gux-rich-text-editor-action-link --> gux-button | ||
gux-popover --> gux-dismiss-button | ||
gux-dismiss-button --> gux-button-slot | ||
gux-dismiss-button --> gux-icon | ||
gux-form-field-text-like --> gux-radial-loading | ||
gux-form-field-text-like --> gux-form-field-label-indicator | ||
gux-form-field-text-like --> gux-form-field-input-clear-button | ||
gux-form-field-text-like --> gux-icon | ||
gux-form-field-input-clear-button --> gux-icon | ||
gux-button --> gux-tooltip-beta | ||
gux-tooltip-beta --> gux-tooltip-base-beta | ||
style gux-rich-text-editor-action-link fill:#f9f,stroke:#333,stroke-width:4px | ||
``` | ||
|
||
---------------------------------------------- | ||
|
||
*Built with [StencilJS](https://stenciljs.com/)* |
3 changes: 3 additions & 0 deletions
3
...-text-editor-action-link/tests/__snapshots__/gux-rich-text-editor-action-link.e2e.ts.snap
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
// Jest Snapshot v1, https://goo.gl/fbAQLP | ||
|
||
exports[`gux-rich-text-editor-action-link #render should display component as expected (1) 1`] = `"<gux-rich-text-editor-action-link hydrated=""><template shadowrootmode="open"><gux-button-slot icon-only="" accent="ghost" aria-describedby="gux-tooltip-u8cxamafev" hydrated=""><button id="popover-target" type="button" aria-label="Link" aria-haspopup="true" aria-expanded="false"><gux-icon icon-name="fa/link-simple-regular" size="small" hydrated=""></gux-icon></button><gux-tooltip id="gux-tooltip-u8cxamafev" role="tooltip" hydrated=""><div slot="content">Link</div></gux-tooltip></gux-button-slot><gux-popover hydrated=""><div class="gux-popover-content-wrapper"><gux-form-field-text-like hydrated=""><input id="textToDisplay" slot="input" type="text"><label slot="label" for="textToDisplay">Text to display</label></gux-form-field-text-like><gux-form-field-text-like hydrated=""><input slot="input" type="text" id="gux-form-field-input-92s2uvdu4a"><label slot="label" for="gux-form-field-input-92s2uvdu4a">Link Address</label></gux-form-field-text-like><gux-cta-group hydrated=""><gux-button slot="primary" hydrated="">Insert</gux-button><gux-button slot="dismiss" hydrated="">Cancel</gux-button></gux-cta-group></div></gux-popover></template></gux-rich-text-editor-action-link>"`; |
Oops, something went wrong.