@meistrari/tela-build 1.33.0 → 1.34.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/tela/button/button.mdx +22 -0
- package/components/tela/card/card.mdx +31 -1
- package/components/tela/card/card.vue +4 -5
- package/components/tela/dropdown-menu/dropdown-menu.mdx +17 -0
- package/components/tela/header/header.mdx +10 -0
- package/components/tela/icon-button/icon-button.mdx +94 -0
- package/components/tela/input/input.mdx +18 -0
- package/components/tela/modal/modal.mdx +71 -0
- package/components/tela/select-menu/select-menu.mdx +30 -0
- package/components/tela/sidebar/sidebar.mdx +32 -0
- package/components/tela/status/status.mdx +5 -0
- package/components/tela/table/table-cell.vue +1 -1
- package/components/tela/table/table.mdx +4 -0
- package/lib/doc-generator.ts +49 -2
- package/lib/tela-build-skill.ts +1 -5
- package/package.json +1 -1
|
@@ -7,6 +7,28 @@ import * as ButtonStories from './button.stories.ts';
|
|
|
7
7
|
|
|
8
8
|
A versatile button component with multiple variants, sizes, and states. Supports icons, loading states, and can function as a link when provided with a `to` prop. Built for consistent UI interactions across the application.
|
|
9
9
|
|
|
10
|
+
## Rules
|
|
11
|
+
|
|
12
|
+
- **Never** use `variant="ghost"` — use `secondary` instead.
|
|
13
|
+
- **Never** use `size="sm"` — always `md` (default) or `lg`.
|
|
14
|
+
- Since `md` is the default, omit the `size` prop unless you need `lg`.
|
|
15
|
+
- When a `TelaButton` sits beside a `TelaInput` in the same row, both must use `size="md"` (default). Never mix sizes in the same row — it creates misaligned rows.
|
|
16
|
+
- **Icon API — two separate props, never one.** The icon **name** goes on `icon`; its **position** is toggled with the boolean `leading`. Default position is trailing. `leading` never takes a value.
|
|
17
|
+
|
|
18
|
+
```vue
|
|
19
|
+
<!-- ✅ Correct — icon on the leading side -->
|
|
20
|
+
<TelaButton icon="i-ph-export" leading>Export</TelaButton>
|
|
21
|
+
|
|
22
|
+
<!-- ✅ Correct — icon on the trailing side (default) -->
|
|
23
|
+
<TelaButton icon="i-ph-arrow-right">Next</TelaButton>
|
|
24
|
+
|
|
25
|
+
<!-- ❌ Wrong — `leading` is a boolean, not a slot for the icon name -->
|
|
26
|
+
<TelaButton leading="i-ph-export">Export</TelaButton>
|
|
27
|
+
|
|
28
|
+
<!-- ❌ Wrong — no `icon` prop means no icon renders -->
|
|
29
|
+
<TelaButton leading>Export</TelaButton>
|
|
30
|
+
```
|
|
31
|
+
|
|
10
32
|
## Examples
|
|
11
33
|
|
|
12
34
|
### All Sizes
|
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
A surface container component used to group related content with consistent visual boundaries.
|
|
4
4
|
|
|
5
|
+
## Rules
|
|
6
|
+
|
|
7
|
+
- **Always** use the `size` prop to control card padding and radius — do not use `content-padding` or `border-radius` props.
|
|
8
|
+
- Attributify spacing/radius props (`p-*`, `px-*`, `py-*`, `rounded-*`) are intentionally ignored on `<TelaCard>` to keep `size` deterministic. If you need a forced override, use `class` with the important modifier (e.g. `class="!p-0"`).
|
|
9
|
+
- Cards in grids must use `h-full` for consistent heights.
|
|
10
|
+
- **Never** wrap `TelaTable` in `TelaCard` — tables are their own surface.
|
|
11
|
+
- Small gaps look like accidents next to large typography. Use at least `gap-4px` when a card contains a large typographic element — prefer `gap-6px` when the large text is the primary content.
|
|
12
|
+
|
|
5
13
|
## Size Prop
|
|
6
14
|
|
|
7
15
|
Always use the `size` prop to control card padding — it maps directly to the standardized values. Never apply padding manually to `<TelaCard>` or its inner elements.
|
|
@@ -45,12 +53,34 @@ Always use the `size` prop to control card padding — it maps directly to the s
|
|
|
45
53
|
|
|
46
54
|
### Card Grid
|
|
47
55
|
|
|
56
|
+
Cards in grids must use `h-full` for consistent heights.
|
|
57
|
+
|
|
48
58
|
```vue
|
|
49
59
|
<div class="grid grid-cols-3 gap-4">
|
|
50
|
-
<TelaCard v-for="item in items" :key="item.id">...</TelaCard>
|
|
60
|
+
<TelaCard v-for="item in items" :key="item.id" h-full>...</TelaCard>
|
|
51
61
|
</div>
|
|
52
62
|
```
|
|
53
63
|
|
|
64
|
+
### Gap with Large Text
|
|
65
|
+
|
|
66
|
+
```vue
|
|
67
|
+
<!-- Wrong — too tight -->
|
|
68
|
+
<TelaCard size="sm">
|
|
69
|
+
<div flex flex-col gap-1>
|
|
70
|
+
<span body-12-medium text-secondary>Total Requests</span>
|
|
71
|
+
<span heading-h2-semibold text-primary>128,430</span>
|
|
72
|
+
</div>
|
|
73
|
+
</TelaCard>
|
|
74
|
+
|
|
75
|
+
<!-- Correct -->
|
|
76
|
+
<TelaCard size="sm" h-full>
|
|
77
|
+
<div flex flex-col gap-4px>
|
|
78
|
+
<span body-12-medium text-secondary>Total Requests</span>
|
|
79
|
+
<h1 heading-h1-semibold text-primary>128,430</h1>
|
|
80
|
+
</div>
|
|
81
|
+
</TelaCard>
|
|
82
|
+
```
|
|
83
|
+
|
|
54
84
|
## Props
|
|
55
85
|
|
|
56
86
|
| Prop | Type | Default | Description |
|
|
@@ -13,12 +13,11 @@ const props = withDefaults(defineProps<{
|
|
|
13
13
|
})
|
|
14
14
|
|
|
15
15
|
const sizeStyles = computed(() => (({
|
|
16
|
-
sm: { padding: 'p-24px'
|
|
17
|
-
md: { padding: 'p-32px
|
|
18
|
-
}) as Record<string, { padding: string
|
|
16
|
+
sm: { padding: 'p-24px' },
|
|
17
|
+
md: { padding: 'p-32px' },
|
|
18
|
+
}) as Record<string, { padding: string }>)[props.size ?? 'md'] ?? { padding: '' })
|
|
19
19
|
|
|
20
20
|
const paddingClass = computed(() => props.contentPadding ?? sizeStyles.value.padding)
|
|
21
|
-
const borderRadiusClass = computed(() => props.borderRadius ?? sizeStyles.value.rounded)
|
|
22
21
|
const rootEl = ref<HTMLElement | null>(null)
|
|
23
22
|
|
|
24
23
|
defineExpose({
|
|
@@ -27,7 +26,7 @@ defineExpose({
|
|
|
27
26
|
</script>
|
|
28
27
|
|
|
29
28
|
<template>
|
|
30
|
-
<div ref="rootEl" :class="cn('bg border-0.5px border', paddingClass,
|
|
29
|
+
<div ref="rootEl" :class="cn('rounded-16px bg border-0.5px border', paddingClass, props.class)">
|
|
31
30
|
<slot />
|
|
32
31
|
</div>
|
|
33
32
|
</template>
|
|
@@ -7,6 +7,23 @@ import * as DropdownMenuStories from './dropdown-menu.stories.ts';
|
|
|
7
7
|
|
|
8
8
|
A dropdown menu component built on radix-vue. Provides a flexible menu system with support for grouping, icons, tooltips, checkboxes, and search functionality. Items can be organized into groups and can include click handlers, disabled states, and custom styling.
|
|
9
9
|
|
|
10
|
+
## Rules
|
|
11
|
+
|
|
12
|
+
- **Always** include an `icon` on every item. Icons give each action a visual identity and make the menu scannable.
|
|
13
|
+
|
|
14
|
+
### DropdownMenu vs SelectMenu
|
|
15
|
+
|
|
16
|
+
Use `TelaDropdownMenu` when clicking triggers a side effect. Use `TelaSelectMenu` when the action updates a bound value.
|
|
17
|
+
|
|
18
|
+
| Scenario | Component |
|
|
19
|
+
|---|---|
|
|
20
|
+
| Export, duplicate, archive, configure | `TelaDropdownMenu` |
|
|
21
|
+
| Navigation links and actions | `TelaDropdownMenu` |
|
|
22
|
+
| Choose environment, select status, pick a model | `TelaSelectMenu` |
|
|
23
|
+
| Filtering or form field with options | `TelaSelectMenu` |
|
|
24
|
+
|
|
25
|
+
**The test:** If clicking triggers a side effect → `TelaDropdownMenu`. If it updates a bound value → `TelaSelectMenu`.
|
|
26
|
+
|
|
10
27
|
## Examples
|
|
11
28
|
|
|
12
29
|
### Basic Usage
|
|
@@ -7,6 +7,16 @@ import * as HeaderStories from './header.stories.ts';
|
|
|
7
7
|
|
|
8
8
|
A composable header component for fullscreen views. Provides a sticky top bar with three layout zones: leading (left), center, and trailing (right). Built with slot-based sub-components for maximum flexibility.
|
|
9
9
|
|
|
10
|
+
## Rules
|
|
11
|
+
|
|
12
|
+
- **Always** use `TelaHeader` on details pages (single resource, editor, settings) — never build page chrome from scratch.
|
|
13
|
+
- For root pages (index, list, dashboard) use `TelaSidebar` instead.
|
|
14
|
+
|
|
15
|
+
| Page type | Shell |
|
|
16
|
+
|---|---|
|
|
17
|
+
| Details page (single resource, editor, settings) | `TelaHeader` |
|
|
18
|
+
| Root page (index, list, dashboard) | `TelaSidebar` |
|
|
19
|
+
|
|
10
20
|
## Examples
|
|
11
21
|
|
|
12
22
|
### Basic Usage
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { Meta } from '@storybook/blocks';
|
|
2
|
+
|
|
3
|
+
<Meta title="Inputs/IconButton" />
|
|
4
|
+
|
|
5
|
+
# TelaIconButton
|
|
6
|
+
|
|
7
|
+
An icon-only button for compact actions (toolbars, modal close buttons, inline controls). Supports multiple sizes, colors, loading, and disabled states, and can render as a link when `to` is provided.
|
|
8
|
+
|
|
9
|
+
## Rules
|
|
10
|
+
|
|
11
|
+
- **Never** use `color="primary"` — always `color="secondary"`.
|
|
12
|
+
- The default is `primary`, so **always set `color` explicitly**.
|
|
13
|
+
|
|
14
|
+
## Examples
|
|
15
|
+
|
|
16
|
+
### Basic Usage
|
|
17
|
+
|
|
18
|
+
```vue
|
|
19
|
+
<TelaIconButton
|
|
20
|
+
icon="i-ph-gear"
|
|
21
|
+
color="secondary"
|
|
22
|
+
/>
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### As a Close Button (inside Modal)
|
|
26
|
+
|
|
27
|
+
```vue
|
|
28
|
+
<TelaIconButton
|
|
29
|
+
icon="i-ph-x"
|
|
30
|
+
size="md"
|
|
31
|
+
color="secondary"
|
|
32
|
+
outline-none
|
|
33
|
+
p-8px mt--12px mr--16px
|
|
34
|
+
@click="isOpen = false"
|
|
35
|
+
/>
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### As a Link
|
|
39
|
+
|
|
40
|
+
```vue
|
|
41
|
+
<TelaIconButton
|
|
42
|
+
icon="i-ph-arrow-up-right"
|
|
43
|
+
color="secondary"
|
|
44
|
+
to="https://example.com"
|
|
45
|
+
target="_blank"
|
|
46
|
+
/>
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Loading State
|
|
50
|
+
|
|
51
|
+
```vue
|
|
52
|
+
<TelaIconButton
|
|
53
|
+
icon="i-ph-gear"
|
|
54
|
+
color="secondary"
|
|
55
|
+
loading
|
|
56
|
+
/>
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Props
|
|
60
|
+
|
|
61
|
+
```typescript
|
|
62
|
+
type IconButtonSize = '3xs' | '2xs' | 'xs' | 'sm' | 'md'
|
|
63
|
+
type IconButtonColor = 'primary' | 'secondary'
|
|
64
|
+
|
|
65
|
+
type IconButtonProps = {
|
|
66
|
+
color?: IconButtonColor
|
|
67
|
+
icon: string
|
|
68
|
+
size?: IconButtonSize
|
|
69
|
+
outline?: boolean
|
|
70
|
+
disabled?: boolean
|
|
71
|
+
loading?: boolean
|
|
72
|
+
active?: boolean
|
|
73
|
+
iconClass?: string
|
|
74
|
+
buttonClass?: string
|
|
75
|
+
to?: string
|
|
76
|
+
target?: '_blank' | null
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Events
|
|
81
|
+
|
|
82
|
+
- `longpress` — emitted after a 700ms press-and-hold (ignored when `disabled`).
|
|
83
|
+
|
|
84
|
+
## Features
|
|
85
|
+
|
|
86
|
+
- **Compact**: Icon-only surface for dense layouts.
|
|
87
|
+
- **Link Functionality**: Renders as `NuxtLink` when `to` is provided.
|
|
88
|
+
- **Long-press**: Built-in long-press detection.
|
|
89
|
+
- **States**: `disabled`, `loading`, `active`, `outline`.
|
|
90
|
+
|
|
91
|
+
## Accessibility
|
|
92
|
+
|
|
93
|
+
- Renders as a `<button>` (or `<NuxtLink>` when `to` is set).
|
|
94
|
+
- Always pair with a visible label or tooltip so the action is discoverable by screen readers.
|
|
@@ -7,6 +7,24 @@ import * as InputStories from './input.stories.ts';
|
|
|
7
7
|
|
|
8
8
|
A flexible input component that supports both text input and textarea modes. Includes features like labels, error states, icons, clear buttons, and validation feedback. Supports v-model binding for two-way data binding.
|
|
9
9
|
|
|
10
|
+
## Rules
|
|
11
|
+
|
|
12
|
+
- **Always** use `size="md"` (default). When a `TelaInput` sits next to a `TelaButton` in the same row, both must be `md` — never mix sizes, it creates misaligned rows.
|
|
13
|
+
- Inside a `TelaModal`, the input must be `w-full`.
|
|
14
|
+
|
|
15
|
+
### Search
|
|
16
|
+
|
|
17
|
+
Search fields **never** have a submit button. Use an inline `TelaInput` that filters as the user types.
|
|
18
|
+
|
|
19
|
+
```vue
|
|
20
|
+
<!-- Correct -->
|
|
21
|
+
<TelaInput v-model="query" placeholder="Search..." hide-label />
|
|
22
|
+
|
|
23
|
+
<!-- Wrong — no submit button next to a search input -->
|
|
24
|
+
<TelaInput v-model="query" placeholder="Search..." hide-label />
|
|
25
|
+
<TelaButton>Search</TelaButton>
|
|
26
|
+
```
|
|
27
|
+
|
|
10
28
|
## Examples
|
|
11
29
|
|
|
12
30
|
### With Clear Button
|
|
@@ -6,6 +6,77 @@ import { Meta, ArgTypes } from '@storybook/blocks';
|
|
|
6
6
|
|
|
7
7
|
A modal dialog component that displays content in a centered overlay. Useful for important messages, confirmations, forms, and content that requires user attention.
|
|
8
8
|
|
|
9
|
+
`TelaDialog` is deprecated — **always** use `TelaModal`.
|
|
10
|
+
|
|
11
|
+
## Rules
|
|
12
|
+
|
|
13
|
+
- **Never** pass `title` to `TelaModal` — build the header yourself inside the slot.
|
|
14
|
+
- **Always** set `:compact="true"` and `:hide-dividers="true"`.
|
|
15
|
+
- **Always** set `:is-close-icon="false"` — build the close button manually with `TelaIconButton`.
|
|
16
|
+
- Close button negative margins must equal **half the modal padding** → `mt--{p/2} mr--{p/2}`.
|
|
17
|
+
- Footer layout: `flex justify-end gap-8px`.
|
|
18
|
+
- Every control inside a modal must fill the modal width. See [Width](#width) below.
|
|
19
|
+
|
|
20
|
+
### Recommended Structure
|
|
21
|
+
|
|
22
|
+
```vue
|
|
23
|
+
<TelaModal
|
|
24
|
+
v-model="isOpen"
|
|
25
|
+
modal-width="md"
|
|
26
|
+
:compact="true"
|
|
27
|
+
:hide-dividers="true"
|
|
28
|
+
:is-close-icon="false"
|
|
29
|
+
>
|
|
30
|
+
<div flex="~ col" w-full gap-16px>
|
|
31
|
+
<!-- Header -->
|
|
32
|
+
<div flex="~ row justify-between" items-start>
|
|
33
|
+
<div flex="~ col" gap-4px>
|
|
34
|
+
<h4 heading-h4-semibold text-primary>Dialog Title</h4>
|
|
35
|
+
<p body-14-regular text-secondary>Dialog subtitle or description.</p>
|
|
36
|
+
</div>
|
|
37
|
+
|
|
38
|
+
<!-- Close Button — negative margins = half the modal padding -->
|
|
39
|
+
<TelaIconButton
|
|
40
|
+
icon="i-ph-x"
|
|
41
|
+
size="md"
|
|
42
|
+
color="secondary"
|
|
43
|
+
outline-none
|
|
44
|
+
p-8px mt--12px mr--16px
|
|
45
|
+
@click="isOpen = false"
|
|
46
|
+
/>
|
|
47
|
+
</div>
|
|
48
|
+
|
|
49
|
+
<!-- Content -->
|
|
50
|
+
<div flex="~ col" gap-8px>
|
|
51
|
+
<!-- ... -->
|
|
52
|
+
</div>
|
|
53
|
+
|
|
54
|
+
<!-- Footer -->
|
|
55
|
+
<div flex gap-8px justify-end>
|
|
56
|
+
<TelaButton variant="secondary" @click="isOpen = false">Cancel</TelaButton>
|
|
57
|
+
<TelaButton>Submit</TelaButton>
|
|
58
|
+
</div>
|
|
59
|
+
</div>
|
|
60
|
+
</TelaModal>
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Width
|
|
64
|
+
|
|
65
|
+
Every control inside a modal must fill the modal width. `w-full` on the root of a compound component (`TelaSelectMenu`, `TelaCombobox`) does not reach the trigger — use `trigger-class="w-full"` instead.
|
|
66
|
+
|
|
67
|
+
```vue
|
|
68
|
+
<!-- Correct -->
|
|
69
|
+
<TelaInput v-model="val" label="Name" w-full />
|
|
70
|
+
<TelaTextarea v-model="val" w-full />
|
|
71
|
+
<TelaToggleGroup v-model="val" :options="opts" w-full />
|
|
72
|
+
<TelaSelectMenu v-model="val" :options="opts" trigger-class="w-full" />
|
|
73
|
+
<TelaCombobox v-model="val" :options="opts" trigger-class="w-full" />
|
|
74
|
+
|
|
75
|
+
<!-- Wrong — w-full on root doesn't reach the trigger -->
|
|
76
|
+
<TelaSelectMenu v-model="val" :options="opts" w-full />
|
|
77
|
+
<TelaCombobox v-model="val" :options="opts" w-full />
|
|
78
|
+
```
|
|
79
|
+
|
|
9
80
|
## Props
|
|
10
81
|
|
|
11
82
|
<ArgTypes />
|
|
@@ -7,6 +7,36 @@ import * as SelectMenuStories from './select-menu.stories.ts';
|
|
|
7
7
|
|
|
8
8
|
A flexible select menu component built on reka-ui. Allows users to select a single option from a dropdown list. Supports icons, descriptions, tooltips, grouping, and custom styling.
|
|
9
9
|
|
|
10
|
+
## Rules
|
|
11
|
+
|
|
12
|
+
- **Never** place icons before text in select options.
|
|
13
|
+
- **Always** set `trigger-class` to constrain the trigger width — never let it overflow or expand the layout.
|
|
14
|
+
|
|
15
|
+
| Context | Value |
|
|
16
|
+
|---|---|
|
|
17
|
+
| Inside modals and forms | `trigger-class="w-full"` |
|
|
18
|
+
| In toolbars | `trigger-class="w-160px"` (or a fixed width) |
|
|
19
|
+
|
|
20
|
+
### SelectMenu vs DropdownMenu
|
|
21
|
+
|
|
22
|
+
Use `TelaSelectMenu` when the action updates a bound value. Use `TelaDropdownMenu` when clicking triggers a side effect.
|
|
23
|
+
|
|
24
|
+
| Scenario | Component |
|
|
25
|
+
|---|---|
|
|
26
|
+
| Choose environment, select status, pick a model | `TelaSelectMenu` |
|
|
27
|
+
| Filtering or form field with options | `TelaSelectMenu` |
|
|
28
|
+
| Export, duplicate, archive, configure | `TelaDropdownMenu` |
|
|
29
|
+
| Navigation links and actions | `TelaDropdownMenu` |
|
|
30
|
+
|
|
31
|
+
**The test:** If clicking updates a bound value → `TelaSelectMenu`. If it triggers a side effect → `TelaDropdownMenu`.
|
|
32
|
+
|
|
33
|
+
### Filters
|
|
34
|
+
|
|
35
|
+
When building a filter panel, always use `TelaSelectMenu` for options with multiple choices — never toggles or checkboxes. Filter panels must include **Apply / Clear** actions and must never auto-apply on change:
|
|
36
|
+
|
|
37
|
+
- Apply: default primary `TelaButton`
|
|
38
|
+
- Clear: `variant="secondary"` `TelaButton`
|
|
39
|
+
|
|
10
40
|
## Examples
|
|
11
41
|
|
|
12
42
|
### Basic Usage
|
|
@@ -7,6 +7,38 @@ import * as SidebarStories from './sidebar.stories.ts';
|
|
|
7
7
|
|
|
8
8
|
A composable sidebar navigation system built from focused sub-components. Fixed 80px wide and full-height, designed for icon-based navigation with labels.
|
|
9
9
|
|
|
10
|
+
## Rules
|
|
11
|
+
|
|
12
|
+
- **Always** use `TelaSidebar` on root pages (index, list, dashboard) — never hand-roll a sidebar, `<nav>`, or custom rail.
|
|
13
|
+
- For details pages (single resource, editor, settings) use `TelaHeader` instead — the sidebar is not part of a details surface.
|
|
14
|
+
- **Always position the sidebar as `sticky`** (`sticky top-0 h-screen`). It must stay pinned to the viewport as the main content scrolls — never allow it to scroll away with the page.
|
|
15
|
+
|
|
16
|
+
| Page type | Shell |
|
|
17
|
+
|---|---|
|
|
18
|
+
| Root page (index, list, dashboard) | `TelaSidebar` |
|
|
19
|
+
| Details page (single resource, editor, settings) | `TelaHeader` |
|
|
20
|
+
|
|
21
|
+
### Layout
|
|
22
|
+
|
|
23
|
+
Place the sidebar and main content in a flex row. The sidebar is `sticky`; the `<main>` takes the remaining width with its own `max-width` + `mx-auto`.
|
|
24
|
+
|
|
25
|
+
```vue
|
|
26
|
+
<div flex>
|
|
27
|
+
<TelaSidebar sticky top-0 h-screen>
|
|
28
|
+
...
|
|
29
|
+
</TelaSidebar>
|
|
30
|
+
|
|
31
|
+
<main flex="~ col" w-full max-w-1380px mx-auto px-48px py-32px>
|
|
32
|
+
<!-- page content -->
|
|
33
|
+
</main>
|
|
34
|
+
</div>
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
**Never:**
|
|
38
|
+
- Let the sidebar scroll with the page (missing `sticky`)
|
|
39
|
+
- Use `h-screen` / `h-[calc(...)]` height hacks on the page wrapper — flex + the sticky sidebar handle sizing
|
|
40
|
+
- Replace `<main>` with a plain `<div>` — semantics matter
|
|
41
|
+
|
|
10
42
|
## Examples
|
|
11
43
|
|
|
12
44
|
### Full Sidebar
|
|
@@ -7,6 +7,11 @@ import * as StatusStories from './status.stories.ts';
|
|
|
7
7
|
|
|
8
8
|
A status component that displays different workflow and task statuses with appropriate icons, colors, and labels. Supports multiple status types including pending, running, completed, error, and review states. Features smooth animations and automatic width transitions for a polished user experience.
|
|
9
9
|
|
|
10
|
+
## Rules
|
|
11
|
+
|
|
12
|
+
- **Always** use `<TelaStatus />` for any status indicator (workflow status, event status, health state, etc.). Never build a custom status with icons + color classes.
|
|
13
|
+
- `text-success` and `text-error` are reserved for `<TelaStatus />` — never apply them to regular text content.
|
|
14
|
+
|
|
10
15
|
## Examples
|
|
11
16
|
|
|
12
17
|
### Default Status
|
|
@@ -206,6 +206,10 @@ The Table system consists of these components:
|
|
|
206
206
|
- `TelaTableCaption` - Accessible table description (`<caption>`)
|
|
207
207
|
- `TelaTableEmpty` - Empty state component for when no data is available
|
|
208
208
|
|
|
209
|
+
## Rules
|
|
210
|
+
|
|
211
|
+
- **Never use `items-end` + `text-right` on cells**, except when styling the last column. Right-alignment is reserved for the trailing column (typically numeric totals or actions); applying it to middle columns breaks visual scan order and column alignment.
|
|
212
|
+
|
|
209
213
|
## Features
|
|
210
214
|
|
|
211
215
|
- **Responsive**: Horizontal scrolling on smaller screens
|
package/lib/doc-generator.ts
CHANGED
|
@@ -566,8 +566,55 @@ export function generateDocsToDirectory(componentDocs: ComponentDoc[], typeResol
|
|
|
566
566
|
const body = dedent`
|
|
567
567
|
# Tela Build
|
|
568
568
|
|
|
569
|
-
|
|
570
|
-
Use
|
|
569
|
+
UI library and design engineering principles for building polished interfaces.
|
|
570
|
+
Always consult before making UI changes. Use when building UI components, reviewing frontend code, or polishing visual details — animations, hover states, shadows, borders, typography, micro-interactions,
|
|
571
|
+
spacing, border radius, optical alignment. Triggers on UI polish, "feels off", design details.
|
|
572
|
+
|
|
573
|
+
## Objective
|
|
574
|
+
|
|
575
|
+
**Tela Build skill exists to produce pixel-perfect UI.** Every output — new component, review, or polish pass — must be measured against that bar. "Close enough" is not acceptable. Concentric border radius, optical alignment, intentional gaps, exact tokens, clean negative space, precise typography — all of it must be correct, not approximate. If a detail is off by a pixel or a token is wrong, it is not done.
|
|
576
|
+
|
|
577
|
+
## Instructions
|
|
578
|
+
|
|
579
|
+
- IMPORTANT: Before making ANY UI change or introducing NEW UI, ALWAYS consult this Tela Build components index first.
|
|
580
|
+
- Prefer reusing existing Tela components and patterns. Only create new components when a clear gap exists.
|
|
581
|
+
- When a new component is needed, align with existing naming, props, events, and patterns documented here.
|
|
582
|
+
- Keep this documentation current when components are added or changed (update supporting files under \
|
|
583
|
+
\`components/\`).
|
|
584
|
+
|
|
585
|
+
## Quick Reference
|
|
586
|
+
|
|
587
|
+
| Category | When to use |
|
|
588
|
+
|---|---|
|
|
589
|
+
| Tokens | Choosing colors, text styles, backgrounds, borders, or icon colors |
|
|
590
|
+
| Interfaces | Layout decisions, component rules, spacing, styling patterns, do/don'ts |
|
|
591
|
+
| Surfaces | Border radius, depth strategy, elevation, outlines, hit areas |
|
|
592
|
+
| Typography | Heading tokens, body font sizes, font weights |
|
|
593
|
+
| Animations | Deciding when to animate, easing, duration, springs, and staggered enter animations |
|
|
594
|
+
|
|
595
|
+
## Common Mistakes
|
|
596
|
+
|
|
597
|
+
| Mistake | Fix |
|
|
598
|
+
|---|---|
|
|
599
|
+
| Same border radius on parent and child | Calculate \`outerRadius = innerRadius + padding\` |
|
|
600
|
+
| Icons look off-center | Adjust optically with padding or fix SVG directly |
|
|
601
|
+
| \`transition: all\` on elements | Specify exact properties |
|
|
602
|
+
| First-frame animation stutter | Add \`will-change: transform\` (sparingly) |
|
|
603
|
+
|
|
604
|
+
## Review Output Format
|
|
605
|
+
|
|
606
|
+
Always present changes as a markdown table with Before and After columns. Include every change you made — not just a subset. Never list findings as separate "Before:" / "After:" lines outside of a table. Group changes by principle using a heading above each table, and keep each row focused on a single diff so the reader can scan the whole list quickly.
|
|
607
|
+
|
|
608
|
+
## Review Checklist
|
|
609
|
+
|
|
610
|
+
- [ ] Nested rounded elements use concentric border radius
|
|
611
|
+
- [ ] Before building, scan the Components Index and reuse existing components — never hand-roll UI when a component exists
|
|
612
|
+
- [ ] Double-check negative space, gaps, and padding — squint at the layout and confirm it reads as clean and intentional, not cramped or accidental
|
|
613
|
+
- [ ] Typography follows the rules — semantic \`heading-*\` and \`body-*\` tokens only (no raw \`text-Xpx\`/\`font-*\`), the right token for each level (h1 page title, h2 section, h3/h4 subsection, body-14 supporting), and a mix of regular/medium/semibold weights so hierarchy isn't flat
|
|
614
|
+
- [ ] Icons are optically centered, not just geometrically
|
|
615
|
+
- [ ] Headings use text-wrap: balance
|
|
616
|
+
- [ ] No \`transition: all\` — only specific properties
|
|
617
|
+
- [ ] \`will-change\` only on transform/opacity/filter, never \`all\`
|
|
571
618
|
|
|
572
619
|
## Components Index
|
|
573
620
|
|
package/lib/tela-build-skill.ts
CHANGED
|
@@ -1,8 +1,4 @@
|
|
|
1
1
|
export const telaBuildSkill = {
|
|
2
2
|
name: 'tela-build',
|
|
3
|
-
description:
|
|
4
|
-
'Use when working on any UI in this repository. Ask for component props, slots, variants, and usage examples.',
|
|
5
|
-
'Always consult this Tela Build index BEFORE making any UI changes or creating new UI.',
|
|
6
|
-
'Use it for components, layouts, styling, interactions, and design-token decisions.',
|
|
7
|
-
].join('\n'),
|
|
3
|
+
description: 'Use when working on any UI in this repository. Ask for component props, slots, variants, and usage examples. Always consult this Tela Build index BEFORE making any UI changes or creating new UI. Use it for components, layouts, styling, interactions, and design-token decisions.',
|
|
8
4
|
} as const
|