Skip to content

Commit

Permalink
Merge pull request #40 from fleetbase/dev-v0.2.9
Browse files Browse the repository at this point in the history
v0.2.9
  • Loading branch information
roncodes authored Jan 18, 2024
2 parents 550e965 + 24700bb commit a4efbfe
Show file tree
Hide file tree
Showing 19 changed files with 739 additions and 20 deletions.
12 changes: 7 additions & 5 deletions addon/components/content-panel.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,17 @@
<div class="next-content-panel {{if this.isOpen 'next-content-panel-is-open' 'next-content-panel-is-closed'}} {{@panelClass}} {{if @isLoading 'is-loading'}}">
<div class="next-content-panel-header next-content-panel-toggle {{if this.isOpen 'next-content-panel-is-open' 'next-content-panel-is-closed'}} {{@panelHeaderClass}} {{if @isLoading 'is-loading'}}">
<a href="javascript:;" aria-expanded={{this.isOpen}} class="next-content-panel-header-left {{@panelHeaderLeftClass}}" {{on "click" this.toggle}}>
<span class="icon-container">
<FaIcon @icon={{if this.isOpen "caret-down" "caret-right"}} @prefix="fas" />
</span>
{{#unless @hideCaret}}
<span class="icon-container" {{did-insert this.trackIconContainer}}>
<FaIcon @icon={{if this.isOpen "caret-down" "caret-right"}} @prefix="fas" />
</span>
{{/unless}}
{{#if @isLoading}}
<Spinner @iconClass="text-sky-500 fa-spin-800ms" class="flex mr-2i" />
{{/if}}
{{#if @titleIcon}}
<span class="icon-container {{@titleIconWrapperClass}}">
<FaIcon @icon={{@titleIcon}} @prefix={{@titleIconPrefix}} class={{@titleIconClass}} />
<span class="icon-container {{@titleIconWrapperClass}}" {{did-insert this.trackIconContainer}}>
<FaIcon @icon={{@titleIcon}} @prefix={{@titleIconPrefix}} @size={{or @titleIconSize "xs"}} class={{@titleIconClass}} />
</span>
{{/if}}
<div class="next-content-panel-title-container {{@titleContainerClass}}">
Expand Down
176 changes: 174 additions & 2 deletions addon/components/content-panel.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,148 @@ import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';
import { action } from '@ember/object';

/**
* Component representing a content panel with toggle functionality.
*
* @class ContentPanelComponent
* @extends Component
*/
export default class ContentPanelComponent extends Component {
/**
* Indicates whether the content panel is currently open.
*
* @property {boolean} isOpen - Whether the content panel is open or closed.
* @default false
* @public
*/
@tracked isOpen = false;

/**
* Determines whether the toggle action should be triggered only when clicking on the caret (icon-container).
*
* @property {boolean} toggleOnCaretOnly - Whether to toggle the content panel only when clicking on the caret.
* @default false
* @public
*/
@tracked toggleOnCaretOnly = false;

/**
* Array of icon containers used for checking if the user clicked on or within a caret.
*
* @property {HTMLElement[]} iconContainers - Array of icon containers.
* @default []
* @private
*/
@tracked iconContainers = [];

/**
* Initializes the content panel component.
*
* @constructor
* @public
*/
constructor() {
super(...arguments);

this.isOpen = this.args.open === true;
this.toggleOnCaretOnly = this.args.toggleOnCaretOnly === true;

if (typeof this.args.onInsert === 'function') {
this.args.onInsert(...arguments);
}
}

@action toggle() {
this.isOpen = !this.isOpen;
/**
* API context for content panel component
*
* @memberof ContentPanelComponent
*/
context = {
toggle: this.toggleDropdown.bind(this),
open: this.open.bind(this),
close: this.close.bind(this),
};

/**
* Toggles the content panel's open/closed state based on click events.
*
* @method toggle
* @param {Event} event - The click event.
* @returns {void}
* @public
*/
@action toggle(event) {
// Fire onclick
this.fireOnClick();

// Check if the click target is within any of the icon containers
const clickedOnCaret = this.iconContainers.length > 0 && this.iconContainers.some((iconContainerNode) => iconContainerNode.contains(event.target));

// If we only want to toggle via the caret (icon-container)
if (clickedOnCaret) {
this.fireOnClickCaret();

if (this.toggleOnCaretOnly) {
// Run toggle
this.toggleDropdown();
return;
}
} else {
this.fireOnClickPanelTitle();
}

// Do not toggle
if (this.toggleOnCaretOnly) {
return;
}

// Toggle dropdown
this.toggleDropdown();
}

/**
* Opens the content panel.
*
* @method open
* @returns {void}
* @public
*/
@action open() {
this.isOpen = true;
}

/**
* Closes the content panel.
*
* @method close
* @returns {void}
* @public
*/
@action close() {
this.isOpen = false;
}

/**
* Tracks an icon container node to be used for checking if the user clicked on or within a caret.
*
* @method trackIconContainer
* @param {HTMLElement} node - The icon container node.
* @returns {void}
* @public
*/
@action trackIconContainer(node) {
this.iconContainers.pushObject(node);
}

/**
* Handles the click event on a dropdown item.
*
* @method onDropdownItemClick
* @param {Object} action - The action associated with the clicked dropdown item.
* @param {Object} dd - The dropdown object.
* @returns {void}
* @public
*/
@action onDropdownItemClick(action, dd) {
if (typeof dd.actions === 'object' && typeof dd.actions.close === 'function') {
dd.actions.close();
Expand All @@ -40,4 +157,59 @@ export default class ContentPanelComponent extends Component {
action.onClick(action.context);
}
}

/**
* Toggles the content panel's open/closed state and fires a callback.
*
* @method toggleDropdown
* @returns {void}
* @private
*/
toggleDropdown() {
this.isOpen = !this.isOpen;

// Fire callback on toggle
if (typeof this.args.onToggle === 'function') {
this.args.onToggle(this.isOpen);
}
}

/**
* Fires the onClick callback if provided.
*
* @method fireOnClick
* @returns {void}
* @private
*/
fireOnClick() {
if (typeof this.args.onClick === 'function') {
this.args.onClick(this.context);
}
}

/**
* Fires the onClickCaret callback if provided.
*
* @method fireOnClickCaret
* @returns {void}
* @private
*/
fireOnClickCaret() {
if (typeof this.args.onClickCaret === 'function') {
this.args.onClickCaret(this.context);
}
}

/**
* Fires the onClickPanelTitle callback if provided.
*
* @method fireOnClickPanelTitle
* @returns {void}
* @private
*/
fireOnClickPanelTitle() {
if (typeof this.args.onClickPanelTitle === 'function') {
this.args.onClickPanelTitle(this.context);
}
}
}
3 changes: 3 additions & 0 deletions addon/components/countdown.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<div class="countdown-container {{@countdownContainerClass}}">
<p class="{{this.remainingClass}} {{@countdownClass}}">{{this.remaining}}</p>
</div>
Loading

0 comments on commit a4efbfe

Please sign in to comment.