Skip to content

Commit

Permalink
feat: navigation components allow composition (#242)
Browse files Browse the repository at this point in the history
* update menu style

* wip update styles for main nav and nav link

* clean up

* rename parseItems to parseJsonProp

* clean up function update

* update current link style

* data driven nav link

* rename go-main-nav to go-nav-bar

* refactor go-nav-bar into go-nav-item

* nav item add columns option

* add columns option to nav item object

* refactor go-nav-item, go-nav-submenu-trigger and  go-nav-submenu to allow composability

* header slot check

* footer update

* fix nav list in footer

* update go-nav-bar examples
  • Loading branch information
seanwuapps authored Mar 11, 2024
1 parent b144eca commit d8c7bbb
Show file tree
Hide file tree
Showing 40 changed files with 1,552 additions and 1,056 deletions.
2 changes: 1 addition & 1 deletion packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
"clean": "rm -rf dist",
"build": "pnpm run clean && stencil build",
"build.component-docs": "stencil build --docs-readme --docs-json",
"start": "stencil build --dev --watch --serve",
"start": "pnpm run clean && stencil build --dev --watch --serve",
"watch.components": "stencil build --docs-json --watch",
"test.spec": "stencil test --spec",
"test.spec.watch": "stencil test --spec --watchAll",
Expand Down
236 changes: 145 additions & 91 deletions packages/core/src/components.d.ts

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Component, h, Prop, Element, State, Watch, EventEmitter, Event } from '@stencil/core';
import { uniqueId } from 'lodash-es';
import '@duetds/date-picker';
import { fieldSlotNames, loadFieldProps, loadFieldSlots, parseItems } from '../../../utils';
import { fieldSlotNames, loadFieldProps, loadFieldSlots, parseJsonProp } from '../../../utils';
import { FormFieldProps, GoChangeEventDetail } from '../../../interfaces';
import { DuetDatePickerProps } from './duet-date-picker';
import dayjs from 'dayjs';
Expand Down Expand Up @@ -56,7 +56,7 @@ export class GoDatepicker implements FormFieldProps {

@Watch('options')
loadOptions() {
this.parsedOptions = parseItems(this.options);
this.parsedOptions = parseJsonProp(this.options);
const dateFormat = this.format;
this.parsedOptions = {
...this.parsedOptions,
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/components/form/go-select/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*/

import { SelectOption } from '@/interfaces';
import { parseItems } from '@/utils';
import { parseJsonProp } from '@/utils';

export enum Keys {
Backspace = 'Backspace',
Expand Down Expand Up @@ -190,7 +190,7 @@ export const parseSelectOptions = (options: string | string[] | SelectOption[]):
options = options.split(',');
}

const parsedOptions = parseItems<SelectOption[] | string[]>(options);
const parsedOptions = parseJsonProp<SelectOption[] | string[]>(options);
if (parsedOptions) {
// format parsed options into SelectOption[]
return parsedOptions.map((option) =>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Component, Host, h, Element, Prop, State, Watch } from '@stencil/core';
import { INavItem } from '../../interfaces';
import { parseItems } from '../../utils';
import { parseJsonProp } from '../../utils';

@Component({
tag: 'go-breadcrumbs',
Expand Down Expand Up @@ -38,7 +38,7 @@ export class GoBreadcrumb {
}

getItems(items: INavItem[] | string) {
const navItems = parseItems(items);
const navItems = parseJsonProp(items);
if (!this.hideCurrent) {
return navItems;
}
Expand Down
17 changes: 9 additions & 8 deletions packages/core/src/components/go-dropdown-menu/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,41 +12,43 @@ title: Dropdown menu

::: info

For a list of navigational items, please refer to the following components:
- [Main navigation](/docs/components/navigation/go-main-nav)
- [Nav drawer](/docs/components/navigation/go-nav-drawer)
For a list of navigational items, please refer to the following components:

- [Nav bar](/docs/components/navigation/go-nav-bar)
- [Nav drawer](/docs/components/navigation/go-nav-drawer)

:::

## Trigger button

A dropdown menu requires a trigger element, this can be set by using `trigger-selector` similar to [`go-dropdown`](go-dropdown).


## Persistent

A dropdown menu can be `persistent` in order to allow users to interact with the widget continuously.


## Accessibility

WAI [Menu button](https://www.w3.org/WAI/ARIA/apg/patterns/menubutton/) pattern aligns closely to the `go-dropdown-menu` component.

### Menu button

- Use a button element (`go-button`, `button` or `input type="button"`) as the trigger element.
- `aria-haspopup` will be set automatically on the trigger element to the id of the menu.
- When the menu is displayed, the trigger element has `aria-expanded` set to true. When the menu is hidden, `aria-expanded` is removed. If `aria-expanded` is specified when the menu is hidden, it is set to false.
- The trigger element has a value specified for `aria-controls` that refers to the element with role menu.


#### Keyboard

When trigger button has focus:

- <kbd>Enter</kbd>: opens the menu and places focus on the first menu item.
- <kbd>Space</kbd>: opens the menu and places focus on the first menu item.
- <kbd>Down Arrow</kbd>: opens the menu and moves focus to the first menu item.
- <kbd>Up Arrow</kbd>: opens the menu and moves focus to the last menu item.

When focus is inside the dropdown menu:

- <kbd>Down Arrow</kbd>: move focus to the next menu item, if current item is the last one, move focus to the first menu item.
- <kbd>Up Arrow</kbd>: move focus to the previous menu item, if current item is the first one, move focus to the last menu item.
- <kbd>Esc</kbd>: closes the menu.
Expand All @@ -56,10 +58,9 @@ When focus is inside the dropdown menu:
The keyboard interaction of the menu follows the WAI guideline for [Keyboard navigation inside components](https://www.w3.org/WAI/ARIA/apg/practices/keyboard-interface/#kbd_general_within), which means <kbd>Tab</kbd> and <kbd>Shift + Tab</kbd> do not move focus between menu items, instead, they are only used to focus in and out of the dropdown menu.

> the tab sequence should include only one focusable element of a composite UI component. Once a composite contains focus, keys other than <kbd>Tab</kbd> and <kbd>Shift + Tab</kbd> enable the user to move focus among its focusable elements
>
> - [Developing a Keyboard Interface](https://www.w3.org/WAI/ARIA/apg/practices/keyboard-interface/#kbd_general_within) by WAI APG


## Demo

<demo-frame component="go-dropdown-menu" demo="go-dropdown-menu"></demo-frame>
Expand Down
10 changes: 5 additions & 5 deletions packages/core/src/components/go-dropdown/go-dropdown.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Component, Host, h, Element, Prop, Method, Watch, Event, EventEmitter } from '@stencil/core';
import { uniqueId, debounce } from 'lodash-es';
import { computePosition, offset, flip, autoUpdate } from '@floating-ui/dom';
import { onClickOutside, removeClickOutsideListener } from '../../utils';
import { onClickOutside } from '../../utils';

@Component({
tag: 'go-dropdown',
Expand Down Expand Up @@ -105,7 +105,7 @@ export class GoDropdown {

private escapeHandler;
private focusOutHandler;
private clickOutHandler;
private clickOutsideCleanUp;

async componentDidLoad() {
if (!this.triggerEl) {
Expand Down Expand Up @@ -139,8 +139,8 @@ export class GoDropdown {
if (this.focusOutHandler) {
this.el.removeEventListener('focusout', this.focusOutHandler);
}
if (this.clickOutHandler) {
removeClickOutsideListener(this.clickOutHandler);
if (this.clickOutsideCleanUp) {
this.clickOutsideCleanUp();
}
if (this.cleanupAutoUpdate) {
this.cleanupAutoUpdate();
Expand All @@ -157,7 +157,7 @@ export class GoDropdown {
this.triggerEl.addEventListener('click', () => this.toggle());
}

this.clickOutHandler = onClickOutside(this.el, (e) => {
this.clickOutsideCleanUp = onClickOutside(this.el, (e) => {
if (!this.triggerEl.contains(e.target as Node) && this.isActive) {
this.close();
}
Expand Down
10 changes: 7 additions & 3 deletions packages/core/src/components/go-icon/go-icon.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import { Component, Host, h, Element, Prop } from '@stencil/core';
import { IconProps } from '../../interfaces';
import { inheritAttributes } from '../../utils/helper';
export type MaterialIconVariants = `material-icons` | `material-icons-outlined` | `material-icons-round` | `material-icons-sharp`;
import { $attrs } from '../../utils/helper';
export type MaterialIconVariants =
| `material-icons`
| `material-icons-outlined`
| `material-icons-round`
| `material-icons-sharp`;
/**
* https://fontawesome.com/v5.15/how-to-use/on-the-web/referencing-icons/basic-use
*/
Expand Down Expand Up @@ -48,7 +52,7 @@ export class GoIcon implements IconProps {

private attrs = {} as any;
componentWillLoad() {
this.attrs = inheritAttributes(this.el, [], false);
this.attrs = $attrs.bind(this)(false);
}

render() {
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/components/go-tabs/go-tablist.scss
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ go-tablist {
/**
@prop --tab-active-color:
Text color for active tab
- default: var(--go-color-primary-800)
- default: var(--go-color-primary-600)
*/
--tab-active-color: var(--go-color-primary-600);
/**
Expand Down
Loading

0 comments on commit d8c7bbb

Please sign in to comment.