diff --git a/docs/src/content/docs/experimental/a-pager.mdx b/docs/src/content/docs/experimental/a-pager.mdx deleted file mode 100644 index 5b39399fa315f58fb39ee69f0f7285f23697725e..0000000000000000000000000000000000000000 --- a/docs/src/content/docs/experimental/a-pager.mdx +++ /dev/null @@ -1,18 +0,0 @@ ---- -title: a-pager -description: A reference page in my new Starlight docs site. ---- - -import { Elements, Pills, Lit, TypeDoc } from "package:/components" - -<Pills> - <Lit /> -</Pills> - -<Elements /> - -<TypeDoc source="../packages/elements/packages/pager" symbol="Pager" /> - -<div class="not-content box"> - <a-pager count="12" current="3"></a-pager> -</div> diff --git a/packages/elements/package.json b/packages/elements/package.json index fc258bf9b2523e82d755494527162f6e500e084a..964549573ff4d01cd4955c6f420d3719630bb4f1 100644 --- a/packages/elements/package.json +++ b/packages/elements/package.json @@ -51,11 +51,6 @@ "require": "./packages/expandable/dist/index.cjs", "types": "./packages/expandable/src/index.ts" }, - "./dropdown": { - "import": "./packages/dropdown/dist/index.js", - "require": "./packages/dropdown/dist/index.cjs", - "types": "./packages/dropdown/src/index.ts" - }, "./track": { "import": "./packages/track/dist/index.js", "require": "./packages/track/dist/index.cjs", @@ -132,4 +127,4 @@ "types": "./packages/chart/src/index.ts" } } -} \ No newline at end of file +} diff --git a/packages/elements/packages/dropdown/.gitignore b/packages/elements/packages/dropdown/.gitignore deleted file mode 100644 index f9d2ca4bfd885bf993d2768cb9b61acc8180010d..0000000000000000000000000000000000000000 --- a/packages/elements/packages/dropdown/.gitignore +++ /dev/null @@ -1,17 +0,0 @@ -# Logs -npm-debug.log* - -# Dependency directories -node_modules/ - -# Optional npm cache directory -.npm - -# mac os -**/.DS_Store - -# bundles -**/*.bundle.js -**/*.min.js -dist -lib diff --git a/packages/elements/packages/dropdown/.npmignore b/packages/elements/packages/dropdown/.npmignore deleted file mode 100644 index 024bf06fa2b604da85a857907cd329c2ef7e2c1f..0000000000000000000000000000000000000000 --- a/packages/elements/packages/dropdown/.npmignore +++ /dev/null @@ -1,18 +0,0 @@ -# git -.git -.gitignore - -# logs -npm-debug.log - -# configs -rollup.config.js -.eslintrc -.editorconfig -.gitlab-ci.yml -.prettierrc -.npmrc - -# other -.DS_Store -.storybook diff --git a/packages/elements/packages/dropdown/README.md b/packages/elements/packages/dropdown/README.md deleted file mode 100644 index ad8d37cfa05b52e7bf634ed3d6d21be9fa7a0231..0000000000000000000000000000000000000000 --- a/packages/elements/packages/dropdown/README.md +++ /dev/null @@ -1,60 +0,0 @@ -# a-dropdown - -Universal dropdown component - -## Properties - -```typescript -// If the dropdown should open upwards or downwards -<a-dropdown direction: 'down' | 'up'; /> -``` - -```typescript -// The value or index of the selected option -// If the option does not have a 'value' attribute, indexes will be used. -<a-dropdown selected: String; /> -``` - -```typescript -// Open state of the dropdown -<a-dropdown opened: Boolean; /> -``` - -```typescript -// Prevents the dropdown from opening -<a-dropdown disabled: Boolean; /> -``` - -## Events - -```typescript -// Emitted after the dropdown closed -<a-dropdown @close /> -``` - -```typescript -// Emitted *before* the dropdown opens -<a-dropdown @open /> -``` - -```typescript -// Emitted after a option has been slected by Click or Enter key -<a-dropdown @select: ({ option: OptionElement; }) => void /> -``` - -```tsx -const dropdown = ( - <a-dropdown - @select={(e) => { - this.value = e.option.value; - }} - > - <button slot="input">{{ this.value || 'Select' }}</button> - - <a-option>Option 1</a-option> - <a-option>Option 2</a-option> - <a-option>Option 3</a-option> - <a-option>Option 4</a-option> - </a-dropdown> -); -``` diff --git a/packages/elements/packages/dropdown/index.html b/packages/elements/packages/dropdown/index.html deleted file mode 100644 index 30ac51037b8466cad06608efe1ba7511abeaeb09..0000000000000000000000000000000000000000 --- a/packages/elements/packages/dropdown/index.html +++ /dev/null @@ -1,58 +0,0 @@ -<!DOCTYPE html> -<html lang="en"> - -<head> - <meta charset="UTF-8"> - <meta name="viewport" content="width=device-width, initial-scale=1.0"> - <title>Document</title> - - <script type="module"> - import "../src/index.js"; - import "../styles/default.scss"; - - import { logEvent } from "histoire/client"; - import { reactive } from "vue"; - - const state = reactive({ - value: "", - }); - - const handleSelect = (e) => { - state.value = e.option.innerText; - logEvent("Select Option", e); - }; - - const exampleOptions = [ - "Option 1", - "Option 2", - "Option 3", - "Some Option", - "Another Option", - "Another Option 2", - "Another Option 3", - "Option 6", - "Item 7", - "Item 8", - ]; - </script> -</head> - -<body> - <a-dropdown @select="handleSelect" @open="logEvent('Open', e)" @close="logEvent('Close', e)" - style="margin-bottom: 200px"> - <button slot="input">{{ state.value || "Select" }}</button> - - <a-option>Option 1</a-option> - <a-option>Option 2</a-option> - <a-option>Option 3</a-option> - <a-option>Option 4</a-option> - <a-option>Option 5</a-option> - <a-option>Option 6</a-option> - <a-option>Option 7</a-option> - <a-option>Option 8</a-option> - <a-option>Option 9</a-option> - <a-option>Option 10</a-option> - </a-dropdown> -</body> - -</html> diff --git a/packages/elements/packages/dropdown/package.json b/packages/elements/packages/dropdown/package.json deleted file mode 100644 index cbf7da2aa93998adf4b6c36fdaba91678a7d92fa..0000000000000000000000000000000000000000 --- a/packages/elements/packages/dropdown/package.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "name": "@atrium-ui/dropdown", - "author": "atrium", - "contributors": [], - "private": true, - "description": "", - "type": "module", - "main": "dist/index.js", - "types": "src/index.ts", - "scripts": { - "build": "tsup", - "dev": "tsup --watch" - }, - "tsup": { - "entry": ["src/index.ts"], - "format": ["esm", "cjs"], - "external": [ - "lit", - "@sv/elements" - ], - "sourcemap": true, - "clean": true - } -} diff --git a/packages/elements/packages/dropdown/src/components/dropdown/DoropDownSelectEvent.ts b/packages/elements/packages/dropdown/src/components/dropdown/DoropDownSelectEvent.ts deleted file mode 100644 index bf246409cadff9ee5408f1ce18dda998778fc2f0..0000000000000000000000000000000000000000 --- a/packages/elements/packages/dropdown/src/components/dropdown/DoropDownSelectEvent.ts +++ /dev/null @@ -1,9 +0,0 @@ -export class DoropDownSelectEvent extends Event { - option?: HTMLElement; - - constructor(selectedItem) { - super("select", { bubbles: true }); - - this.option = selectedItem; - } -} diff --git a/packages/elements/packages/dropdown/src/components/dropdown/Dropdown.ts b/packages/elements/packages/dropdown/src/components/dropdown/Dropdown.ts deleted file mode 100644 index 18ae8f682f72b975ce1ebdef8d13bd553ca52ac7..0000000000000000000000000000000000000000 --- a/packages/elements/packages/dropdown/src/components/dropdown/Dropdown.ts +++ /dev/null @@ -1,316 +0,0 @@ -import { LitElement, css, html } from "lit"; -import { property, query } from "lit/decorators.js"; -import { DoropDownSelectEvent } from "./DoropDownSelectEvent"; -import type { OptionElement } from "./Option"; - -declare global { - interface HTMLElementTagNameMap { - "a-dropdown": Dropdown; - } -} - -/** - * - Accessible and styleable dropdown component - * - Wraps the content in an a-expandable - * - * @attribute direction (default: "down") - In what direction the dropdown openes - * @attribute opened (default: false) - Whether the dropdown is open - * @attribute disabled (default: false) - Whether the dropdown is disabled. - * @attribute selected (default: undefined) - The selected option. - * - * @example - * ```html - * <a-dropdown> - * <Button slot="input"> - * <div class="w-[150px] text-left">{props.value}</div> - * </Button> - * - * <div class="mt-1 rounded-md border border-zinc-700 bg-zinc-800 p-1"> - * <a-option>Option 1</a-option> - * <a-option>Option 2</a-option> - * </div> - * </a-dropdown> - * ``` - * - * @see https://svp.pages.s-v.de/atrium/elements/a-dropdown/ - */ -export class Dropdown extends LitElement { - static get styles() { - return css` - :host { - display: inline-block; - position: relative; - outline: none; - - --dropdown-max-height: 200px; - --dropdown-speed: 75ms; - --dropdown-position: absolute; - } - :host([opened]) { - z-index: 10; - } - .dropdown-container { - position: var(--dropdown-position); - top: 100%; - width: 100%; - background: inherit; - } - :host([direction="up"]) .dropdown-container { - bottom: 100%; - top: auto; - width: 100%; - } - a-expandable { - display: block; - - --transition-speed: var(--dropdown-speed); - } - .dropdown { - max-height: var(--dropdown-max-height); - overflow: auto; - width: 100%; - } - `; - } - - @property({ type: String, reflect: true }) - public direction: "up" | "down" = "down"; - - @property({ type: String, reflect: true }) - public selected?: string; - - @property({ type: Boolean, reflect: true }) - public opened = false; - - @property({ type: Boolean, reflect: true }) - public disabled = false; - - @query(".dropdown") - public dropdown!: HTMLElement; - - private options: OptionElement[] = []; - - public connectedCallback(): void { - super.connectedCallback(); - - this.addEventListener("focusout", this.onBlur); - this.addEventListener("keydown", this.onKeyDown); - this.addEventListener("keyup", this.onKeyUp); - } - - public disconnectedCallback(): void { - super.disconnectedCallback(); - - this.removeEventListener("focusout", this.onBlur); - this.removeEventListener("keydown", this.onKeyDown); - this.removeEventListener("keyup", this.onKeyUp); - } - - public selectNext() { - const selectedElement = this.getOptionByValue(this.selected); - const index = selectedElement ? this.options.indexOf(selectedElement) : -1; - const nextIndex = Math.max(index - 1, 0); - const opt = this.options[nextIndex]; - if (opt) { - this.selected = this.getValueOfOption(opt); - this.updateOptionSelection(); - } - } - - public selectPrev() { - const selectedElement = this.getOptionByValue(this.selected); - const index = selectedElement ? this.options.indexOf(selectedElement) : -1; - const nextIndex = Math.min(index + 1, this.options.length - 1); - const opt = this.options[nextIndex]; - if (opt) { - this.selected = this.getValueOfOption(opt); - this.updateOptionSelection(); - } - } - - public reset() { - this.selected = undefined; - this.updateOptionSelection(); - } - - private submitSelected() { - if (this.selected) { - const selectedOptionElement = this.getOptionByValue(this.selected); - if (selectedOptionElement) { - this.close(); - this.dispatchEvent(new DoropDownSelectEvent(selectedOptionElement)); - } - } - } - - public close() { - this.opened = false; - this.requestUpdate(); - this.dispatchEvent(new Event("close")); - } - - public open() { - if (this.disabled) return; - - this.dispatchEvent(new Event("open")); - this.opened = true; - this.requestUpdate(); - - const inputElement = this.querySelector(`[slot="input"]`) as HTMLElement; - if (inputElement) inputElement.focus(); - - if (this.direction === "up") { - this.dropdown.scrollTo(0, this.dropdown.scrollHeight); - } - } - - private onBlur(e) { - const blurOnNextMouseUp = () => { - window.removeEventListener("pointerup", blurOnNextMouseUp); - - if (!this.querySelector("*:focus-within")) { - this.close(); - } - }; - window.addEventListener("pointerup", blurOnNextMouseUp); - } - - private onClick(event: PointerEvent) { - if (this.opened) { - this.close(); - } else { - this.open(); - } - } - - private scrollToSelected() { - if (this.selected) { - const selectedOption = this.getOptionByValue(this.selected); - selectedOption?.scrollIntoView({ block: "nearest" }); - } - } - - private onKeyDown(event: KeyboardEvent) { - switch (event.key) { - case "ArrowUp": - if (this.querySelector("*:focus")) { - if (this.direction === "up") { - this.selectPrev(); - } else { - this.selectNext(); - } - this.scrollToSelected(); - event.preventDefault(); - } - break; - case "ArrowDown": - if (this.querySelector("*:focus")) { - if (this.direction === "up") { - this.selectNext(); - } else { - this.selectPrev(); - } - this.scrollToSelected(); - event.preventDefault(); - } - break; - case "Tab": - setTimeout(() => { - if (!this.querySelector("*:focus-within")) { - this.close(); - } - }, 10); - break; - case "Enter": - event.preventDefault(); - break; - } - } - - private onKeyUp(event: KeyboardEvent) { - switch (event.key) { - case "Enter": - if (this.opened && this.selected !== undefined) { - this.submitSelected(); - } - break; - case "Escape": - this.close(); - break; - case "Tab": - if (!this.opened) { - this.open(); - } - break; - } - } - - private onSlotChange() { - // update dom image - this.options = [...this.querySelectorAll("a-option")] as OptionElement[]; - - if (this.direction === "up") { - this.options.reverse(); - } - } - - private onOptionsClick(e: MouseEvent) { - let index = 0; - for (const child of this.options) { - if (child === e.target || child.contains(e.target as HTMLElement)) { - const value = child.getAttribute("value") || index.toString(); - this.selected = value; - this.submitSelected(); - break; - } - index++; - } - } - - private getValueOfOption(optionElement: OptionElement) { - return ( - optionElement.getAttribute("value") || - this.options.indexOf(optionElement).toString() - ); - } - - private getOptionByValue(value: string | undefined) { - if (value === undefined) return; - - for (const option of this.options) { - const optionValue = this.getValueOfOption(option); - if (optionValue === value) return option; - } - - return; - } - - protected updated(): void { - this.updateOptionSelection(); - } - - private updateOptionSelection() { - const options = this.options; - for (const option of options) { - const optionValue = this.getValueOfOption(option); - if (optionValue === this.selected) { - option.setAttribute("selected", ""); - } else { - option.removeAttribute("selected"); - } - } - } - - render() { - return html` - <slot name="input" @click=${this.onClick}></slot> - <div class="dropdown-container" part="dropdown"> - <a-expandable ?opened="${this.opened}"> - <div class="dropdown" part="options"> - <slot @click=${this.onOptionsClick} @slotchange=${this.onSlotChange}></slot> - </div> - </a-expandable> - </div> - `; - } -} diff --git a/packages/elements/packages/dropdown/src/components/dropdown/Option.ts b/packages/elements/packages/dropdown/src/components/dropdown/Option.ts deleted file mode 100644 index 422235ef9af5cd195a1b996c39562e2a08c9ea73..0000000000000000000000000000000000000000 --- a/packages/elements/packages/dropdown/src/components/dropdown/Option.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { LitElement, css, html } from "lit"; -import { property } from "lit/decorators.js"; - -declare global { - interface HTMLElementTagNameMap { - "a-option": OptionElement; - } -} - -export class OptionElement extends LitElement { - static get styles() { - return css` - :host { - display: block; - } - `; - } - - @property({ type: String, reflect: true }) - public value!: string; - - render() { - return html`<slot></slot>`; - } -} diff --git a/packages/elements/packages/dropdown/src/index.ts b/packages/elements/packages/dropdown/src/index.ts deleted file mode 100644 index d6cb9bb4e25fa6b893ce5c8b1ff5e56024ad6086..0000000000000000000000000000000000000000 --- a/packages/elements/packages/dropdown/src/index.ts +++ /dev/null @@ -1,18 +0,0 @@ -/** - * @license - * Copyright (c) 2024 Atrium Contributors - * SPDX-License-Identifier: MIT - */ - -import "@sv/elements/expandable"; -import { Dropdown } from "./components/dropdown/Dropdown"; -import { OptionElement } from "./components/dropdown/Option"; - -try { - customElements.define("a-option", OptionElement); - customElements.define("a-dropdown", Dropdown); -} catch (err) { - console.warn("a-dropdown already defined"); -} - -export { Dropdown, OptionElement }; diff --git a/packages/elements/packages/dropdown/tsconfig.json b/packages/elements/packages/dropdown/tsconfig.json deleted file mode 100644 index 4082f16a5d91ce6f21a9092b14170eeecc8f1d75..0000000000000000000000000000000000000000 --- a/packages/elements/packages/dropdown/tsconfig.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "extends": "../../tsconfig.json" -} diff --git a/packages/elements/packages/pager/README.md b/packages/elements/packages/pager/README.md deleted file mode 100644 index e8be8c4720f3d02519b9f0f85b9a724cc7d42d99..0000000000000000000000000000000000000000 --- a/packages/elements/packages/pager/README.md +++ /dev/null @@ -1 +0,0 @@ -# pager diff --git a/packages/elements/packages/pager/index.html b/packages/elements/packages/pager/index.html deleted file mode 100644 index a5daee62e6b416aa6f2250e03fbb38226c6ac670..0000000000000000000000000000000000000000 --- a/packages/elements/packages/pager/index.html +++ /dev/null @@ -1,18 +0,0 @@ -<!DOCTYPE html> -<html lang="en"> - -<head> - <meta charset="UTF-8"> - <meta name="viewport" content="width=device-width, initial-scale=1.0"> - <title>Document</title> - - <script> - import "./src/index.js"; - </script> -</head> - -<body> - <a-pager count="12" current="3"></a-pager> -</body> - -</html> diff --git a/packages/elements/packages/pager/package.json b/packages/elements/packages/pager/package.json deleted file mode 100644 index b1d167940c08495a6dbb4a68a259c13cd9432897..0000000000000000000000000000000000000000 --- a/packages/elements/packages/pager/package.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "name": "@atrium-ui/pager", - "author": "atrium", - "contributors": [], - "private": true, - "description": "", - "type": "module", - "main": "dist/index.js", - "types": "src/index.ts", - "scripts": { - "build": "tsup" - }, - "tsup": { - "entry": ["src/index.ts"], - "format": ["esm", "cjs"], - "external": [ - "lit", - "@sv/elements" - ], - "sourcemap": true, - "clean": true - } -} diff --git a/packages/elements/packages/pager/src/Pager.ts b/packages/elements/packages/pager/src/Pager.ts deleted file mode 100644 index b033188a33428fc95b02b1d08b59c7b4ce39003f..0000000000000000000000000000000000000000 --- a/packages/elements/packages/pager/src/Pager.ts +++ /dev/null @@ -1,190 +0,0 @@ -import { type HTMLTemplateResult, LitElement, css, html } from "lit"; -import { customElement, property } from "lit/decorators.js"; - -declare global { - interface HTMLElementTagNameMap { - "a-pager": Pager; - } -} - -@customElement("a-pager") -export class Pager extends LitElement { - public static styles = css` - .pagination { - display: flex; - justify-content: center; - } - - .pagination__spacer { - opacity: 0.5; - pointer-events: none; - user-select: none; - } - - .pagination__item { - display: inline-block; - padding: 0 8px; - margin: 0 2px; - opacity: 0.5; - cursor: pointer; - user-select: none; - transition: font-weight 0.2s ease, transform 0.33s ease-out; - } - - .pagination__item:hover { - opacity: 0.75; - } - - .pagination__item:active { - } - - .pagination__item[active="true"] { - font-weight: 600; - opacity: 1; - } - - .pagination__arrow { - cursor: pointer; - margin: 0 20px; - opacity: 0; - pointer-events: none; - transition: opacity 0.15s ease; - } - - .pagination__arrow:focus, - .pagination__arrow:hover { - } - - .pagination__arrow:active { - } - - .pagination__arrow--shown { - opacity: 1; - pointer-events: all; - } - - button { - all: unset; - } - `; - - @property({ type: Number, reflect: true }) - public count = 1; - - @property({ type: Number, reflect: true }) - public current = 1; - - pagerChunkSize = 4; - - lastPageIndex() { - return this.count - 1; - } - - currentPageIndex() { - return +this.current - 1; - } - - pagerChunk() { - return Math.max(0, Math.floor(this.current / this.pagerChunkSize)); - } - - pagesToShow() { - const pages: number[] = []; - const firstPage = this.pagerChunk() * this.pagerChunkSize; - - for (let p = -2; p < this.pagerChunkSize; p++) { - const page = firstPage + p; - - if (page >= 0 && page <= this.lastPageIndex()) { - pages.push(page); - } - } - - return pages; - } - - showPrefix() { - return this.pagerChunk() > 0; - } - - showSuffix() { - const pages = Math.floor(this.lastPageIndex() / this.pagerChunkSize); - return this.pagerChunk() < pages; - } - - prevPage() { - const page = Math.max(1, +this.current - 1); - this.dispatchEvent(new CustomEvent("page-change", { detail: page })); - this.requestUpdate(); - } - - nextPage() { - const page = Math.min(+this.current + 1, +this.count); - this.dispatchEvent(new CustomEvent("page-change", { detail: page })); - this.requestUpdate(); - } - - goToPage(index) { - const page = index + 1; - this.dispatchEvent(new CustomEvent("page-change", { detail: page })); - this.requestUpdate(); - } - - protected render(): HTMLTemplateResult { - return html` - <div class="pagination c4"> - <button - class=${`pagination__arrow ${ - +this.current > 1 ? "pagination__arrow--shown" : "" - }`} - @click=${() => this.prevPage()} - > - <slot name="arrow-left"> < </slot> - </button> - - <div class="pagination__pages"> - ${ - this.showPrefix() - ? html` - <span class="pagination__item" @click=${() => this.goToPage(0)}> 1 </span> - <span class="pagination__spacer"> ... </span> - ` - : null - } - ${this.pagesToShow().map((page) => { - return html` - <span - class="pagination__item" - active=${page === this.currentPageIndex()} - @click=${() => this.goToPage(page)} - >${page + 1} - </span> - `; - })} - ${ - this.showSuffix() - ? html` - <span class="pagination__spacer"> ... </span> - <span - class="pagination__item" - @click=${() => this.goToPage(this.lastPageIndex())} - > - ${this.count} - </span> - ` - : null - } - </div> - - <button - class=${`pagination__arrow ${ - +this.current < +this.count ? "pagination__arrow--shown" : "" - }`} - @click=${() => this.nextPage()} - > - <slot name="arrow-right"> > </slot> - </button> - </div> - `; - } -} diff --git a/packages/elements/packages/pager/src/index.ts b/packages/elements/packages/pager/src/index.ts deleted file mode 100644 index 20206f6d9a80aa7e4d60a23adbc84312aa619c54..0000000000000000000000000000000000000000 --- a/packages/elements/packages/pager/src/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -/** - * @license - * Copyright (c) 2024 Atrium Contributors - * SPDX-License-Identifier: MIT - */ - -export { Pager } from "./Pager"; diff --git a/packages/elements/packages/pager/tsconfig.json b/packages/elements/packages/pager/tsconfig.json deleted file mode 100644 index 4082f16a5d91ce6f21a9092b14170eeecc8f1d75..0000000000000000000000000000000000000000 --- a/packages/elements/packages/pager/tsconfig.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "extends": "../../tsconfig.json" -} diff --git a/packages/elements/packages/select/src/Select.ts b/packages/elements/packages/select/src/Select.ts index 74bfacb6cbc45da24ccca2c0ab79ae64de837e43..e8437f09a8d7cd51f62e0bd35778ce0463ce9e2c 100644 --- a/packages/elements/packages/select/src/Select.ts +++ b/packages/elements/packages/select/src/Select.ts @@ -85,6 +85,7 @@ export class Select extends LitElement { .dropdown { max-height: var(--dropdown-max-height); overflow: auto; + height: 100%; width: 100%; } `;