Skip to content

Commit

Permalink
first combobox commit
Browse files Browse the repository at this point in the history
  • Loading branch information
harleyjessop committed Apr 5, 2023
1 parent 7387bca commit 5d04f0a
Show file tree
Hide file tree
Showing 75 changed files with 2,712 additions and 69 deletions.
2 changes: 2 additions & 0 deletions docs/_sidebar.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
- [Buttons](/components/button)
- [Button Group](/components/button-group)
- [Checkbox](/components/checkbox)
- [Combobox](/components/combobox)
- [Dropdown](/components/dropdown)
- [Input](/components/input)
- [Icon Button](/components/icon-button)
Expand Down Expand Up @@ -99,6 +100,7 @@
- [Format Date](/utilities/format-date)
- [Format Number](/utilities/format-number)
- [Include](/utilities/include)
- [Intersection Observer](/utilities/intersection-observer)
- [Mutation Observer](/utilities/mutation-observer)
- [Popup](/utilities/popup)
- [Relative Time](/utilities/relative-time)
Expand Down
169 changes: 169 additions & 0 deletions docs/components/combobox.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
# Combobox

[component-header:lynk-combobox]

A combobox consist of a text input trigger and a popup containing a listbox. By default, interacting with the combobox via focus or input will expose the popup and interacting outside of the combobox will close it.

```html preview
<lynk-combobox label="Combobox Select" placeholder="Search" trigger="focus" clearable listbox-help>
<lynk-icon slot="prefix" name="search" library="default"></lynk-icon>
<lynk-option value="al">Alabama</lynk-option>
<lynk-option value="ak">Alaska</lynk-option>
<lynk-option value="az">Arizona</lynk-option>
<lynk-option value="ar">Arkansas</lynk-option>
<lynk-option value="ca">California</lynk-option>
<lynk-option value="co">Colorado</lynk-option>
<lynk-option value="ct">Connecticut</lynk-option>
<lynk-option value="de">Delaware</lynk-option>
<lynk-option value="dc">District of Columbia</lynk-option>
<lynk-option value="fl">Florida</lynk-option>
<lynk-option value="ga">Georgia</lynk-option>
<lynk-option value="hi">Hawaii</lynk-option>
<lynk-option value="id">Idaho</lynk-option>
<lynk-option value="il">Illinois</lynk-option>
<lynk-option value="in">Indiana</lynk-option>
<lynk-option value="ia">Iowa</lynk-option>
<lynk-option value="ks">Kansas</lynk-option>
<lynk-option value="ky">Kentucky</lynk-option>
<lynk-option value="la">Louisiana</lynk-option>
<lynk-option value="me">Maine</lynk-option>
<lynk-option value="mt">Montana</lynk-option>
<lynk-option value="ne">Nebraska</lynk-option>
<lynk-option value="nv">Nevada</lynk-option>
<lynk-option value="nh">New Hampshire</lynk-option>
<lynk-option value="nj">New Jersey</lynk-option>
<lynk-option value="nm">New Mexico</lynk-option>
<lynk-option value="ny">New York</lynk-option>
<lynk-option value="nc">North Carolina</lynk-option>
<lynk-option value="nd">North Dakota</lynk-option>
<lynk-option value="oh">Ohio</lynk-option>
<lynk-option value="ok">Oklahoma</lynk-option>
<lynk-option value="or">Oregon</lynk-option>
<lynk-option value="md">Maryland</lynk-option>
<lynk-option value="ma">Massachusetts</lynk-option>
<lynk-option value="mi">Michigan</lynk-option>
<lynk-option value="mn">Minnesota</lynk-option>
<lynk-option value="ms">Missippi</lynk-option>
<lynk-option value="mo">Missouri</lynk-option>
<lynk-option value="pa">Pennsylvania</lynk-option>
<lynk-option value="ri">Rhode Island</lynk-option>
<lynk-option value="sc">South Carolina</lynk-option>
<lynk-option value="sd">South Dakota</lynk-option>
<lynk-option value="tn">Tennessee</lynk-option>
<lynk-option value="tx">Texas</lynk-option>
<lynk-option value="ut">Utah</lynk-option>
<lynk-option value="vt">Vermont</lynk-option>
<lynk-option value="va">Virginia</lynk-option>
<lynk-option value="wa">Washington</lynk-option>
<lynk-option value="wv">West Viginia</lynk-option>
<lynk-option value="wi">Wisconsin</lynk-option>
<lynk-option value="wy">Wyoming</lynk-option>
</lynk-combobox>
```

## Trigger

By default, the ComboBox's popup is opened when the user types into the input field `trigger="input"`. There are two other supported modes: one where the menu opens when the ComboBox is focused `trigger="focus"` and the other `trigger="manual"` where the listbox can be opened by clicking on the expand icon, using the `open` attribute or by calling the `show()` method.

```html preview
<lynk-combobox label="Input Trigger Combobox" trigger="input">
<lynk-option value="one">Item One</lynk-option>
<lynk-option value="two">Item Two</lynk-option>
<lynk-option value="three">Item Three</lynk-option>
</lynk-combobox>

<br />

<lynk-combobox label="Focus Trigger Combobox" trigger="focus">
<lynk-option value="one">Item One</lynk-option>
<lynk-option value="two">Item Two</lynk-option>
<lynk-option value="three">Item Three</lynk-option>
</lynk-combobox>

<br />

<lynk-combobox label="Manual Trigger Combobox" trigger="manual">
<lynk-option value="one">Item One</lynk-option>
<lynk-option value="two">Item Two</lynk-option>
<lynk-option value="three">Item Three</lynk-option>
</lynk-combobox>
```


## Autocomplete

Determines if the value in the input changes or not as the user navigates with the keyboard. If true, the value changes automatically, if false the value will only change when a selection is made.

Set this to false when you don't really need the value from the input but want to populate some other state (like the recipient selector in Gmail). But if your input is more like a normal text input, then leave the true default.

### List Autocomplete

This example illustrates the autocomplete behavior known as list autocomplete with manual selection. If the user types one or more characters in the combobox and the typed characters match the beginning of the name of one or more options, a listbox popup appears containing the matching names or values. When the listbox appears, a suggested option is not automatically selected. Thus, after typing, if the user tabs or clicks out of the combobox without choosing a value from the listbox, the typed string becomes the value of the combobox. Note that this implementation enables users to input the name or value of an option, but it does not prevent input of any other arbitrary value.

```html preview
<lynk-combobox label="Autocomplete List Combobox" autocomplete="list" placeholder="Search" clearable trigger="focus" listbox-help>
<lynk-icon slot="prefix" name="search" library="default"></lynk-icon>
<lynk-option value="al">Alabama</lynk-option>
<lynk-option value="ak">Alaska</lynk-option>
<lynk-option value="az">Arizona</lynk-option>
<lynk-option value="ar">Arkansas</lynk-option>
<lynk-option value="ca">California</lynk-option>
<lynk-option value="co">Colorado</lynk-option>
<lynk-option value="ct">Connecticut</lynk-option>
<lynk-option value="de">Delaware</lynk-option>
<lynk-option disabled value="dc">District of Columbia</lynk-option>
<lynk-option value="fl">Florida</lynk-option>
<lynk-option value="ga">Georgia</lynk-option>
<lynk-option value="hi">Hawaii</lynk-option>
<lynk-option value="id">Idaho</lynk-option>
<lynk-option value="il">Illinois</lynk-option>
<lynk-option value="in">Indiana</lynk-option>
<lynk-option value="ia">Iowa</lynk-option>
<lynk-option value="ks">Kansas</lynk-option>
<lynk-option value="ky">Kentucky</lynk-option>
<lynk-option value="la">Louisiana</lynk-option>
<lynk-option value="me">Maine</lynk-option>
<lynk-option value="mt">Montana</lynk-option>
<lynk-option value="ne">Nebraska</lynk-option>
<lynk-option value="nv">Nevada</lynk-option>
<lynk-option value="nh">New Hampshire</lynk-option>
<lynk-option value="nj">New Jersey</lynk-option>
<lynk-option value="nm">New Mexico</lynk-option>
<lynk-option value="ny">New York</lynk-option>
<lynk-option value="nc">North Carolina</lynk-option>
<lynk-option value="nd">North Dakota</lynk-option>
<lynk-option value="oh">Ohio</lynk-option>
<lynk-option value="ok">Oklahoma</lynk-option>
<lynk-option value="or">Oregon</lynk-option>
<lynk-option value="md">Maryland</lynk-option>
<lynk-option value="ma">Massachusetts</lynk-option>
<lynk-option value="mi">Michigan</lynk-option>
<lynk-option value="mn">Minnesota</lynk-option>
<lynk-option value="ms">Missippi</lynk-option>
<lynk-option value="mo">Missouri</lynk-option>
<lynk-option value="pa">Pennsylvania</lynk-option>
<lynk-option value="ri">Rhode Island</lynk-option>
<lynk-option value="sc">South Carolina</lynk-option>
<lynk-option value="sd">South Dakota</lynk-option>
<lynk-option value="tn">Tennessee</lynk-option>
<lynk-option value="tx">Texas</lynk-option>
<lynk-option value="ut">Utah</lynk-option>
<lynk-option value="vt">Vermont</lynk-option>
<lynk-option value="va">Virginia</lynk-option>
<lynk-option value="wa">Washington</lynk-option>
<lynk-option value="wv">West Viginia</lynk-option>
<lynk-option value="wi">Wisconsin</lynk-option>
<lynk-option value="wy">Wyoming</lynk-option>
</lynk-combobox>
```

## Allow Custom Values

By default on blur, a ComboBox will either reset its input value to match the selected option's text or clear its input value if an option has not been selected. If you would like to allow the end user to provide a custom input value to the ComboBox, the `allow-custom` property can be used to override the default behavior.

## Multiple Selections

Allow more than one option to be selected by adding the `multiple` attribute. By default, each additional option will be appended to the text input as a `lynk-tag` element. You can change this default behavior and append the options as a csv by using the `separator` attribute set to an string value like 'separator=", "'.


[component-metadata:lynk-combobox]
29 changes: 29 additions & 0 deletions docs/components/dropdown.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,35 @@ Alternatively, you can listen for the `click` event on individual menu items. No
</script>
```

### Using a lynk-input as the trigger

```html preview
<div class="dropdown-selection-alt">
<lynk-dropdown>
<lynk-input slot="trigger" type="search" placeholder="Search" autocomplete="off" clearable>
<lynk-icon slot="prefix" name="search" library="default"></lynk-icon>
</lynk-input>
<lynk-menu>
<lynk-menu-item value="cut">Cut</lynk-menu-item>
<lynk-menu-item value="copy">Copy</lynk-menu-item>
<lynk-menu-item value="paste">Paste</lynk-menu-item>
</lynk-menu>
</lynk-dropdown>
</div>

<script>
const container = document.querySelector('.dropdown-selection-alt');
const cut = container.querySelector('lynk-menu-item[value="cut"]');
const copy = container.querySelector('lynk-menu-item[value="copy"]');
const paste = container.querySelector('lynk-menu-item[value="paste"]');
cut.addEventListener('click', () => console.log('cut'));
copy.addEventListener('click', () => console.log('copy'));
paste.addEventListener('click', () => console.log('paste'));
</script>
```


### Placement

The preferred placement of the dropdown can be set with the `placement` attribute. Note that the actual position may vary to ensure the panel remains in the viewport.
Expand Down
2 changes: 1 addition & 1 deletion docs/components/nav-item.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<lynk-nav-item>Getting Started</lynk-nav-item>
<lynk-nav-item>Usage</lynk-nav-item>
<lynk-nav-item>Contributing</lynk-nav-item>
<lynk-nav-item>
<lynk-nav-item expanded>
Components
<lynk-nav-item>Button</lynk-nav-item>
<lynk-nav-item>Checkbox</lynk-nav-item>
Expand Down
1 change: 1 addition & 0 deletions docs/components/option.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ Use the `disabled` attribute to disable an option and prevent it from being sele
<lynk-option value="option-1">Option 1</lynk-option>
<lynk-option value="option-2" disabled>Option 2</lynk-option>
<lynk-option value="option-3">Option 3</lynk-option>
<lynk-option value="option-4" hidden>Option 4</lynk-option>
</lynk-select>
```

Expand Down
6 changes: 6 additions & 0 deletions docs/getting-started/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ Components with the <lynk-badge type="warning" pill>Experimental</lynk-badge> ba

<lynk-alert type="info" open>During the beta period, these restrictions may be relaxed in the event of a mission-critical bug. 🐛</lynk-alert>

## 0.6.5

- 🎉 NEW: Added experimental `<lynk-intersection-observer>` component
- Improved `<lynk-option>` so it converts non-string values to strings for convenience
- Improved styles for `<lynk-input>` and `<lynk-spinner>` slotted into a `<lynk-menu>`

## 0.6.4

- Added `href` property to `<lynk-tab>` to support router navigation
Expand Down
2 changes: 1 addition & 1 deletion docs/getting-started/contributing.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ After the initial build, a browser will open automatically to a local version of
To scaffold a new component, run the following command, replacing `lynk-tag-name` with the desired tag name.

```bash
yarn create lynk-tag-name
yarn run create lynk-tag-name
```

This will generate a source file, a stylesheet, and a docs page for you. When you start the dev server, you'll find the new component in the "Components" section of the sidebar.
Expand Down
23 changes: 22 additions & 1 deletion docs/layout/app-layout-sidebar.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,28 @@
</aside>
<div class="lynk-app__main">
<lynk-page-layout>
<lynk-page-sidebar toggle="contents" heading="Left Sidebar" open>
<lynk-page-sidebar toggle="contents" style="--body-spacing: 8px" open>
<lynk-nav>
<lynk-nav-item>
All Video Content
</lynk-nav-item>
<lynk-nav-item>
Static Graphics
</lynk-nav-item>
<lynk-nav-item>
Playlists
</lynk-nav-item>
<lynk-nav-group heading="Libraries">
<lynk-nav-item>My Library</lynk-nav-item>
<lynk-nav-item>
Messages
<lynk-icon slot="suffix" name="share"></lynk-icon>
<lynk-button slot="suffix" square size="tiny">
<lynk-icon name="gear"></lynk-icon>
</lynk-button>
</lynk-nav-item>
</lynk-nav-group>
</lynk-nav>
</lynk-page-sidebar>
<lynk-page-header>
<lynk-button slot="aux" size="tiny" square></lynk-button>
Expand Down
43 changes: 43 additions & 0 deletions docs/utilities/intersection-observer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Intersection Observer

[component-header:lynk-intersection-observer]

The intersection observer will report the elements it wraps enters and exits the viewport through the `on:enter` and `on:exit` events.

```html preview
<div class="observer-wrapper">
Scroll down and watch the console...
<lynk-intersection-observer>
<div>Hello, I'm a div!</div>
<div>Hello, I'm another div!</div>
</lynk-intersection-observer>
</div>

<script>
const container = document.querySelector('.observer-wrapper');
const intersectionObserver = container.querySelector('lynk-intersection-observer');
intersectionObserver.addEventListener('on:enter', event => {
console.log('Div entered view', event);
});
intersectionObserver.addEventListener('on:exit', event => {
console.log('Div exited view', event);
});
</script>

<style>
.observer-wrapper {
height: 480px;
overflow: auto;
padding: 4rem 2rem;
}
.observer-wrapper div {
height: 48px;
margin-top: 768px;
margin-bottom: 768px;
}
</style>
```

[component-metadata:lynk-intersection-observer]
2 changes: 1 addition & 1 deletion docs/utilities/resize-observer.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ The resize observer will report changes to the dimensions of the elements it wra
const container = document.querySelector('.resize-observer-overview');
const resizeObserver = container.querySelector('lynk-resize-observer');
resizeObserver.addEventListener('lynk-resize', event => {
resizeObserver.addEventListener('on:resize', event => {
console.log(event.detail);
});
</script>
Expand Down
8 changes: 4 additions & 4 deletions src/components/button-group/button-group.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,22 +25,22 @@ export default class LynkButtonGroup extends LynkElement {
/** A label to use for the button group's `aria-label` attribute. */
@property() label = '';

handleFocus(event: CustomEvent) {
handleFocus(event: Event) {
const button = findButton(event.target as HTMLElement);
button?.classList.add('lynk-button-group__button--focus');
}

handleBlur(event: CustomEvent) {
handleBlur(event: Event) {
const button = findButton(event.target as HTMLElement);
button?.classList.remove('lynk-button-group__button--focus');
}

handleMouseOver(event: CustomEvent) {
handleMouseOver(event: Event) {
const button = findButton(event.target as HTMLElement);
button?.classList.add('lynk-button-group__button--hover');
}

handleMouseOut(event: CustomEvent) {
handleMouseOut(event: Event) {
const button = findButton(event.target as HTMLElement);
button?.classList.remove('lynk-button-group__button--hover');
}
Expand Down
5 changes: 5 additions & 0 deletions src/components/button/button.ts
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,11 @@ export default class LynkButton extends LynkElement implements LynkFormControl {
return true;
}

/** Gets the associated form, if one exists. */
getForm(): HTMLFormElement | null {
return this.formControlController.getForm();
}

/** Checks for validity and shows the browser's validation message if the control is invalid. */
reportValidity() {
if (this.isButton()) {
Expand Down
5 changes: 5 additions & 0 deletions src/components/checkbox/checkbox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,11 @@ export default class LynkCheckbox extends LynkElement implements LynkFormControl
return this.input.checkValidity();
}

/** Gets the associated form, if one exists. */
getForm(): HTMLFormElement | null {
return this.formControlController.getForm();
}

/** Checks for validity and shows a validation message if the control is invalid. */
reportValidity() {
return this.input.reportValidity();
Expand Down
Loading

0 comments on commit 5d04f0a

Please sign in to comment.