diff --git a/src/row/index.ts b/src/row/index.ts
index 656dc23e..70d13182 100644
--- a/src/row/index.ts
+++ b/src/row/index.ts
@@ -1,14 +1,61 @@
-import { customElement } from "lit/decorators.js";
-import { Row } from "./row";
-import styles from "./row.style";
+import { customElement } from 'lit/decorators.js';
+import { Row } from './row';
+import styles from './row.style';
-@customElement("tap-row")
+/**
+ * ### Example
+ *
+ *
+ * ##### Simple
+ *
+ * ```html
+ *
+ * Leading content
+ * Main content
+ * Trailing content
+ *
+ * ```
+ *
+ * ##### Navigable Row
+ *
+ * ```html
+ *
+ * Leading content
+ * Main content
+ * Trailing content
+ *
+ * ```
+ *
+ * @summary A flexible row component with leading, content, and trailing slots.
+ *
+ * @prop {`'standard'` \| `'compact'`} [`size`=`'compact'`] - The size of the row. Defaults to `standard`.
+ * @prop {`boolean`} [`navigable`=`false`] - Indicates whether the row is navigable (clickable).
+ *
+ * @csspart [`row`] - The main container for the row.
+ * @csspart [`leading`] - The container for the leading slot.
+ * @csspart [`content`] - The container for the content slot.
+ * @csspart [`trailing`] - The container for the trailing slot.
+ * @csspart [`navigable`] - The container for the navigable icon.
+ *
+ * @cssprop [`--tap-font-family`=`--tap-sys-font-family`] - The font family used in the row.
+ * @cssprop [`--tap-row-background-color`=`--tap-palette-white`] - The background color of the row.
+ * @cssprop [`--tap-row-leading-vertical-padding`] - The vertical padding for the leading slot.
+ * @cssprop [`--tap-row-leading-horizontal-padding`=`--tap-sys-spacing-4`] - The horizontal padding for the leading slot.
+ * @cssprop [`--tap-row-content-padding`=`--tap-sys-spacing-4`] - The padding for the content slot.
+ * @cssprop [`--tap-row-trailing-vertical-padding`] - The vertical padding for the trailing slot.
+ * @cssprop [`--tap-row-trailing-horizontal-padding`=`--tap-sys-spacing-4`] - The horizontal padding for the trailing slot.
+ * @cssprop [`--tap-row-standard-height`=`--tap-sys-spacing-13`] - The height of the standard size row.
+ * @cssprop [`--tap-row-compact-height`=`--tap-sys-spacing-12`] - The height of the compact size row.
+ *
+ * @event slotchange - Dispatched when the content of any slot changes.
+ */
+@customElement('tap-row')
export class TapRow extends Row {
static readonly styles = [styles];
}
declare global {
interface HTMLElementTagNameMap {
- "tap-row": TapRow;
+ 'tap-row': TapRow;
}
}
diff --git a/src/row/row.stories.ts b/src/row/row.stories.ts
index 0d363ecc..1bd1c292 100644
--- a/src/row/row.stories.ts
+++ b/src/row/row.stories.ts
@@ -1,42 +1,42 @@
-import {html, nothing, TemplateResult} from "lit";
-import "./index";
-import "../button";
-import "../icons";
-import "../checkbox";
-import "../radio";
-import "../badge";
-import "../avatar";
+import { html, nothing, TemplateResult } from 'lit';
+import './index';
+import '../button';
+import '../icons';
+import '../checkbox';
+import '../radio';
+import '../badge';
+import '../avatar';
export default {
- title: "Row",
- component: "tap-row",
+ title: 'Row',
+ component: 'tap-row',
argTypes: {
size: {
- description: "Row size",
- control: {type: "inline-radio"},
+ description: 'Row size',
+ control: { type: 'inline-radio' },
options: ['standard', 'compact'],
defaultValue: 'standard',
},
navigable: {
- description: "Navigable (Show Chevron)",
- control: {type: "boolean"},
+ description: 'Navigable (Show Chevron)',
+ control: { type: 'boolean' },
defaultValue: false,
},
leading: {
- description: "Row leading slot",
- control: {type: "select"},
+ description: 'Row leading slot',
+ control: { type: 'select' },
options: ['icon', 'nothing', 'radio', 'checkbox', 'avatar'],
defaultValue: 'nothing',
},
trailing: {
- description: "Row trailing slot",
- control: {type: "select"},
+ description: 'Row trailing slot',
+ control: { type: 'select' },
options: ['icon', 'button', 'badge', 'ghost-button', 'price', 'nothing'],
defaultValue: 'nothing',
},
content: {
- description: "Row content slot.",
- control: {type: "select"},
+ description: 'Row content slot.',
+ control: { type: 'select' },
options: ['standard', 'reverse', 'address', 'customized', 'nothing'],
defaultValue: 'nothing',
},
@@ -58,58 +58,71 @@ interface ArgTypes {
navigable: boolean;
}
-const renderExampleSideSlot = (example: unknown, type: 'leading' | 'trailing') => {
+const renderExampleSideSlot = (
+ example: unknown,
+ type: 'leading' | 'trailing',
+) => {
switch (example) {
case 'badge':
- return html`
- `;
+ return html` `;
case 'icon':
- return html`
- `;
+ return html` `;
case 'button':
- return html`
- Button`;
+ return html` Button`;
case 'ghost-button':
- return html`
- Button`;
+ return html` Button`;
case 'checkbox':
- return html`
- `;
+ return html` `;
case 'radio':
- return html`
- `;
+ return html` `;
case 'avatar':
- return html`
- `;
+ return html` `;
case 'price':
return html`
۱۵۷٬۰۰۰ تومان
`;
default:
return nothing;
}
-}
+};
const renderExampleContentSlot = (example: unknown) => {
switch (example) {
- case "customized":
+ case 'customized':
return html`any content you want! 😉
`;
- case "standard":
+ case 'standard':
return html`
عنوان را وارد کنید
توضیحات لیست
-
`
- case "reverse":
+ `;
+ case 'reverse':
return html`
عنوان را وارد کنید
توضیحات لیست
-
`
- case "address":
- return html`سعادتآباد، بلوار بهزاد
`
+ `;
+ case 'address':
+ return html`سعادتآباد، بلوار بهزاد
`;
default:
return nothing;
}
-}
+};
-const Template: Story = ({size, leading, trailing, navigable, content}: ArgTypes) => html`
+const Template: Story = ({
+ size,
+ leading,
+ trailing,
+ navigable,
+ content,
+}: ArgTypes) => html`
${renderExampleSideSlot(leading, 'leading')}
${renderExampleContentSlot(content)}
diff --git a/src/row/row.style.ts b/src/row/row.style.ts
index c249ef63..4446d419 100644
--- a/src/row/row.style.ts
+++ b/src/row/row.style.ts
@@ -1,4 +1,4 @@
-import { css } from "lit";
+import { css } from 'lit';
export default css`
:host {
@@ -15,7 +15,7 @@ export default css`
display: none !important;
}
- .container{
+ .container {
display: flex;
align-items: stretch;
width: 100%;
@@ -25,14 +25,15 @@ export default css`
}
.leading {
- padding: var(--tap-row-leading-vertical-padding, 0) var(--tap-row-leading-horizontal-padding, var(--tap-sys-spacing-4));
+ padding: var(--tap-row-leading-vertical-padding, 0)
+ var(--tap-row-leading-horizontal-padding, var(--tap-sys-spacing-4));
display: flex;
align-items: center;
justify-content: center;
}
.content {
- padding: var(--tap-row-content-padding ,var(--tap-sys-spacing-4));
+ padding: var(--tap-row-content-padding, var(--tap-sys-spacing-4));
flex: 1;
display: flex;
flex-direction: column;
@@ -40,7 +41,8 @@ export default css`
}
.trailing {
- padding: var(--tap-row-trailing-vertical-padding, 0) var(--tap-row-trailing-horizontal-padding, var(--tap-sys-spacing-4));
+ padding: var(--tap-row-trailing-vertical-padding, 0)
+ var(--tap-row-trailing-horizontal-padding, var(--tap-sys-spacing-4));
display: flex;
align-items: center;
justify-content: center;
@@ -52,11 +54,11 @@ export default css`
justify-content: center;
}
- :host([size="standard"]) .container {
+ :host([size='standard']) .container {
height: var(--tap-row-standard-height, var(--tap-sys-spacing-13));
}
- :host([size="compact"]) .container {
+ :host([size='compact']) .container {
height: var(--tap-row-compact-height, var(--tap-sys-spacing-12));
}
diff --git a/src/row/row.ts b/src/row/row.ts
index 712c147b..f3187e1c 100644
--- a/src/row/row.ts
+++ b/src/row/row.ts
@@ -1,14 +1,16 @@
-import {html, LitElement, PropertyValues} from "lit";
-import {property} from "lit/decorators.js";
+import { html, LitElement, PropertyValues } from 'lit';
+import { property } from 'lit/decorators.js';
export class Row extends LitElement {
- @property({ reflect: true }) size: "standard" | "compact" = "standard";
+ @property({ reflect: true }) size: 'standard' | 'compact' = 'standard';
@property({ type: Boolean, reflect: true }) navigable: boolean = false;
private hasSlotContent(slotName: string): boolean {
- const slot = this.shadowRoot?.querySelector(`slot[name="${slotName}"]`) as HTMLSlotElement;
- return slot?.assignedNodes({flatten: true}).length > 0;
+ const slot = this.shadowRoot?.querySelector(
+ `slot[name="${slotName}"]`,
+ ) as HTMLSlotElement;
+ return slot?.assignedNodes({ flatten: true }).length > 0;
}
private hideSlotContainerIfNotExists(slotName: string) {
@@ -24,8 +26,11 @@ export class Row extends LitElement {
this.hideSlotContainerIfNotExists('trailing');
['title', 'subtitle'].forEach((id) => {
const element = this.shadowRoot?.getElementById(id);
- if (element) element.style.display = this.hasSlotContent('content') ? 'none' : 'block'
- })
+ if (element)
+ element.style.display = this.hasSlotContent('content')
+ ? 'none'
+ : 'block';
+ });
}
private getDirection() {
@@ -35,14 +40,15 @@ export class Row extends LitElement {
element = element.parentElement;
direction = getComputedStyle(element).direction;
}
- return direction
+ return direction;
}
private changeNavigableDirections() {
if (this.navigable) {
const direction = this.getDirection();
const navigableElement = this.shadowRoot?.getElementById('navigable');
- if (navigableElement) navigableElement.style.transform = `rotate(${direction === 'ltr' ? '180' : '0'}deg)`;
+ if (navigableElement)
+ navigableElement.style.transform = `rotate(${direction === 'ltr' ? '180' : '0'}deg)`;
}
}
@@ -54,28 +60,45 @@ export class Row extends LitElement {
private renderNavigableIcon() {
return html`
-