@toyu-ui/elements 0.1.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.
Files changed (57) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +79 -0
  3. package/button/tyui-button.d.ts +27 -0
  4. package/button.d.ts +1 -0
  5. package/button.js +339 -0
  6. package/center/tyui-center.d.ts +13 -0
  7. package/center.d.ts +1 -0
  8. package/center.js +39 -0
  9. package/checkbox/tyui-checkbox.d.ts +25 -0
  10. package/checkbox.d.ts +1 -0
  11. package/checkbox.js +288 -0
  12. package/cluster/tyui-cluster.d.ts +16 -0
  13. package/cluster.d.ts +1 -0
  14. package/cluster.js +53 -0
  15. package/container/tyui-container.d.ts +14 -0
  16. package/container.d.ts +1 -0
  17. package/container.js +44 -0
  18. package/custom-elements.json +1651 -0
  19. package/flex/tyui-flex.d.ts +22 -0
  20. package/flex.d.ts +1 -0
  21. package/flex.js +66 -0
  22. package/frame/tyui-frame.d.ts +13 -0
  23. package/frame.d.ts +1 -0
  24. package/frame.js +35 -0
  25. package/grid/tyui-grid.d.ts +20 -0
  26. package/grid.d.ts +1 -0
  27. package/grid.js +59 -0
  28. package/index.d.ts +12 -0
  29. package/index.js +26 -0
  30. package/input/tyui-input.d.ts +40 -0
  31. package/input.d.ts +1 -0
  32. package/input.js +345 -0
  33. package/layout/layout-helpers.d.ts +9 -0
  34. package/layout-helpers-C2WgKm6F.js +171 -0
  35. package/package.json +91 -0
  36. package/radio/tyui-radio.d.ts +21 -0
  37. package/radio-group/tyui-radio-group.d.ts +28 -0
  38. package/radio-group.d.ts +1 -0
  39. package/radio-group.js +234 -0
  40. package/radio.d.ts +1 -0
  41. package/radio.js +239 -0
  42. package/sidebar/tyui-sidebar.d.ts +17 -0
  43. package/sidebar.d.ts +1 -0
  44. package/sidebar.js +53 -0
  45. package/skills/button/SKILL.md +49 -0
  46. package/skills/center/SKILL.md +45 -0
  47. package/skills/checkbox/SKILL.md +39 -0
  48. package/skills/cluster/SKILL.md +44 -0
  49. package/skills/components/SKILL.md +53 -0
  50. package/skills/container/SKILL.md +42 -0
  51. package/skills/flex/SKILL.md +45 -0
  52. package/skills/frame/SKILL.md +42 -0
  53. package/skills/grid/SKILL.md +44 -0
  54. package/skills/input/SKILL.md +59 -0
  55. package/skills/radio/SKILL.md +49 -0
  56. package/skills/radio-group/SKILL.md +51 -0
  57. package/skills/sidebar/SKILL.md +43 -0
package/radio.js ADDED
@@ -0,0 +1,239 @@
1
+ const a = new CSSStyleSheet();
2
+ a.replaceSync(`
3
+ @layer ty.component-base {
4
+ :host {
5
+ display: inline-flex;
6
+ align-items: center;
7
+ color: var(--ty-radio-foreground, var(--ty-color-text, CanvasText));
8
+ font-family: var(--ty-font-family, inherit);
9
+ font-size: var(--ty-radio-font-size, var(--ty-control-font-size, 0.875rem));
10
+ line-height: var(--ty-radio-line-height, 1.25rem);
11
+ cursor: pointer;
12
+ user-select: none;
13
+ -webkit-tap-highlight-color: transparent;
14
+ }
15
+
16
+ :host([disabled]),
17
+ :host([aria-disabled='true']) {
18
+ color: var(--ty-radio-disabled-foreground, var(--ty-color-disabled-text, GrayText));
19
+ cursor: not-allowed;
20
+ }
21
+
22
+ [part='root'] {
23
+ display: inline-flex;
24
+ align-items: center;
25
+ gap: var(--ty-radio-gap, var(--ty-control-gap, 0.5rem));
26
+ cursor: inherit;
27
+ }
28
+
29
+ [part='root'][data-label-position='below'] {
30
+ flex-direction: column;
31
+ align-items: center;
32
+ gap: var(--ty-radio-gap-below, var(--ty-space-1, 0.25rem));
33
+ text-align: center;
34
+ }
35
+
36
+ [part='indicator'] {
37
+ position: relative;
38
+ display: inline-flex;
39
+ flex: none;
40
+ align-items: center;
41
+ justify-content: center;
42
+ }
43
+
44
+ [part='input'] {
45
+ position: absolute;
46
+ inline-size: 1px;
47
+ block-size: 1px;
48
+ margin: -1px;
49
+ padding: 0;
50
+ overflow: hidden;
51
+ clip: rect(0 0 0 0);
52
+ clip-path: inset(50%);
53
+ white-space: nowrap;
54
+ border: 0;
55
+ }
56
+
57
+ [part='circle'] {
58
+ box-sizing: border-box;
59
+ display: inline-flex;
60
+ align-items: center;
61
+ justify-content: center;
62
+ inline-size: var(--ty-radio-size, 1rem);
63
+ block-size: var(--ty-radio-size, 1rem);
64
+ border:
65
+ var(--ty-radio-border-width, var(--ty-control-border-width, 1px))
66
+ solid
67
+ var(--ty-radio-border-color, var(--ty-color-border-strong, ButtonText));
68
+ border-radius: var(--ty-radius-pill, 9999px);
69
+ background: var(--ty-radio-background, var(--ty-color-surface, Canvas));
70
+ transition:
71
+ background-color var(--ty-motion-feedback-duration, 120ms) var(--ty-motion-easing, ease),
72
+ border-color var(--ty-motion-feedback-duration, 120ms) var(--ty-motion-easing, ease),
73
+ box-shadow var(--ty-motion-feedback-duration, 120ms) var(--ty-motion-easing, ease);
74
+ }
75
+
76
+ :host(:hover:not([disabled]):not([aria-disabled='true'])) [part='circle'],
77
+ :host([checked]) [part='circle'] {
78
+ border-color: var(--ty-radio-checked-color, var(--ty-color-accent, Highlight));
79
+ }
80
+
81
+ :host([checked]) [part='circle'] {
82
+ background: var(--ty-radio-checked-color, var(--ty-color-accent, Highlight));
83
+ }
84
+
85
+ [part='dot'] {
86
+ inline-size: var(--ty-radio-dot-size, 0.5rem);
87
+ block-size: var(--ty-radio-dot-size, 0.5rem);
88
+ border-radius: var(--ty-radius-pill, 9999px);
89
+ background: var(--ty-radio-checked-dot-color, var(--ty-color-on-accent, HighlightText));
90
+ opacity: 0;
91
+ transition: opacity var(--ty-motion-feedback-duration, 120ms) var(--ty-motion-easing, ease);
92
+ }
93
+
94
+ :host([checked]) [part='dot'] {
95
+ opacity: 1;
96
+ }
97
+
98
+ [part='label'] {
99
+ min-inline-size: 0;
100
+ }
101
+
102
+ :host(:focus-within) [part='circle'] {
103
+ outline: var(--ty-focus-width, 2px) solid var(--ty-focus-color, Highlight);
104
+ outline-offset: var(--ty-focus-offset, 2px);
105
+ box-shadow: 0 0 0 2px var(--ty-focus-inner-color, Canvas);
106
+ }
107
+
108
+ @media (forced-colors: active) {
109
+ [part='circle'] {
110
+ forced-color-adjust: none;
111
+ background: ButtonFace;
112
+ border-color: ButtonText;
113
+ }
114
+
115
+ :host([checked]) [part='circle'] {
116
+ background: Highlight;
117
+ border-color: Highlight;
118
+ }
119
+
120
+ [part='dot'] {
121
+ background: HighlightText;
122
+ }
123
+
124
+ :host([disabled]),
125
+ :host([aria-disabled='true']) {
126
+ color: GrayText;
127
+ }
128
+ }
129
+
130
+ @media (prefers-reduced-motion: reduce) {
131
+ [part='circle'],
132
+ [part='dot'] {
133
+ transition-duration: 0ms;
134
+ }
135
+ }
136
+ }
137
+ `);
138
+ const s = document.createElement("template");
139
+ s.innerHTML = `
140
+ <label part="root">
141
+ <span part="indicator">
142
+ <input part="input" type="radio" tabindex="-1" />
143
+ <span part="circle" aria-hidden="true"><span part="dot"></span></span>
144
+ </span>
145
+ <span part="label"><slot></slot></span>
146
+ </label>
147
+ `;
148
+ function o(r, t) {
149
+ return r.hasAttribute(t);
150
+ }
151
+ function n(r) {
152
+ return r === "below" ? "below" : "after";
153
+ }
154
+ class l extends HTMLElement {
155
+ static observedAttributes = [
156
+ "checked",
157
+ "disabled",
158
+ "label-position",
159
+ "name",
160
+ "required",
161
+ "tabindex",
162
+ "value"
163
+ ];
164
+ #t;
165
+ #o;
166
+ #e = "";
167
+ #i = "";
168
+ constructor() {
169
+ super();
170
+ const t = this.attachShadow({ mode: "open", delegatesFocus: !0 });
171
+ t.adoptedStyleSheets = [a], t.append(s.content.cloneNode(!0));
172
+ const e = t.querySelector("input"), i = t.querySelector('[part="root"]');
173
+ if (!(e instanceof HTMLInputElement) || !(i instanceof HTMLElement))
174
+ throw new Error("TyuiRadioElement template is missing expected controls.");
175
+ this.#t = e, this.#o = i, this.#t.addEventListener("change", this.#n);
176
+ }
177
+ get checked() {
178
+ return o(this, "checked");
179
+ }
180
+ set checked(t) {
181
+ this.toggleAttribute("checked", t);
182
+ }
183
+ get disabled() {
184
+ return o(this, "disabled");
185
+ }
186
+ set disabled(t) {
187
+ this.toggleAttribute("disabled", t);
188
+ }
189
+ get labelPosition() {
190
+ return n(this.getAttribute("label-position"));
191
+ }
192
+ set labelPosition(t) {
193
+ this.setAttribute("label-position", t);
194
+ }
195
+ get name() {
196
+ return this.#e;
197
+ }
198
+ set name(t) {
199
+ this.#e = String(t), this.#e ? this.setAttribute("name", this.#e) : this.removeAttribute("name");
200
+ }
201
+ get required() {
202
+ return o(this, "required");
203
+ }
204
+ set required(t) {
205
+ this.toggleAttribute("required", t);
206
+ }
207
+ get value() {
208
+ return this.#i;
209
+ }
210
+ set value(t) {
211
+ this.#i = String(t), this.setAttribute("value", this.#i);
212
+ }
213
+ connectedCallback() {
214
+ this.#r("checked"), this.#r("disabled"), this.#r("labelPosition"), this.#r("name"), this.#r("required"), this.#r("value"), this.#s(), !this.hasAttribute("tabindex") && this.tabIndex < 0 && (this.tabIndex = -1), this.#a();
215
+ }
216
+ attributeChangedCallback(t, e, i) {
217
+ t === "name" ? this.#e = i ?? "" : t === "value" && (this.#i = i ?? ""), this.#a();
218
+ }
219
+ focus(t) {
220
+ this.#t.focus(t);
221
+ }
222
+ #s() {
223
+ this.#e = this.getAttribute("name") ?? this.#e, this.#i = this.getAttribute("value") ?? this.#i;
224
+ }
225
+ #r(t) {
226
+ if (!Object.prototype.hasOwnProperty.call(this, t)) return;
227
+ const e = this[t];
228
+ delete this[t], this[t] = e;
229
+ }
230
+ #n = (t) => {
231
+ t.stopPropagation(), this.checked = this.#t.checked;
232
+ };
233
+ #a() {
234
+ this.disabled && this.tabIndex !== -1 && (this.tabIndex = -1), this.#t.checked = this.checked, this.#t.disabled = this.disabled, this.#t.required = this.required, this.#t.name = this.#e, this.#t.value = this.#i, this.#t.tabIndex = !this.disabled && this.tabIndex === 0 ? 0 : -1, this.#o.dataset.labelPosition = this.labelPosition;
235
+ }
236
+ }
237
+ export {
238
+ l as TyuiRadioElement
239
+ };
@@ -0,0 +1,17 @@
1
+ export type TyuiSidebarSide = 'start' | 'end';
2
+ export declare class TyuiSidebarElement extends HTMLElement {
3
+ #private;
4
+ static observedAttributes: string[];
5
+ connectedCallback(): void;
6
+ attributeChangedCallback(): void;
7
+ get side(): TyuiSidebarSide;
8
+ set side(value: TyuiSidebarSide);
9
+ get sideSize(): string;
10
+ set sideSize(value: string);
11
+ get contentMin(): string;
12
+ set contentMin(value: string);
13
+ get gap(): string;
14
+ set gap(value: string);
15
+ get noStretch(): boolean;
16
+ set noStretch(value: boolean);
17
+ }
package/sidebar.d.ts ADDED
@@ -0,0 +1 @@
1
+ export * from './sidebar/tyui-sidebar';
package/sidebar.js ADDED
@@ -0,0 +1,53 @@
1
+ import { i as n, n as r, s as e, a as s, l as i, b as a } from "./layout-helpers-C2WgKm6F.js";
2
+ const h = ["start", "end"];
3
+ class l extends HTMLElement {
4
+ static observedAttributes = ["content-min", "gap", "no-stretch", "side", "side-size"];
5
+ connectedCallback() {
6
+ n(), this.#t(), this.#e();
7
+ }
8
+ attributeChangedCallback() {
9
+ this.#t();
10
+ }
11
+ get side() {
12
+ return r(this.getAttribute("side"), h, "start");
13
+ }
14
+ set side(t) {
15
+ e(this, "side", t);
16
+ }
17
+ get sideSize() {
18
+ return this.getAttribute("side-size") ?? "18rem";
19
+ }
20
+ set sideSize(t) {
21
+ e(this, "side-size", t);
22
+ }
23
+ get contentMin() {
24
+ return this.getAttribute("content-min") ?? "50%";
25
+ }
26
+ set contentMin(t) {
27
+ e(this, "content-min", t);
28
+ }
29
+ get gap() {
30
+ return this.getAttribute("gap") ?? "3";
31
+ }
32
+ set gap(t) {
33
+ e(this, "gap", t);
34
+ }
35
+ get noStretch() {
36
+ return this.hasAttribute("no-stretch");
37
+ }
38
+ set noStretch(t) {
39
+ e(this, "no-stretch", t);
40
+ }
41
+ #t() {
42
+ s(this, "--ty-sidebar-direction", this.side === "end" ? "row-reverse" : "row"), s(this, "--ty-sidebar-size", i(this.sideSize, "18rem")), s(
43
+ this,
44
+ "--ty-sidebar-content-min-inline-size",
45
+ i(this.contentMin, "50%")
46
+ ), s(this, "--ty-sidebar-gap", a(this.getAttribute("gap"), "3")), s(this, "--ty-sidebar-align", this.noStretch ? "flex-start" : "stretch");
47
+ }
48
+ #e() {
49
+ }
50
+ }
51
+ export {
52
+ l as TyuiSidebarElement
53
+ };
@@ -0,0 +1,49 @@
1
+ ---
2
+ name: button
3
+ description: Use and integrate the tyui-button custom element correctly, including registration, intent, states, events, and anti-patterns.
4
+ license: Apache-2.0
5
+ metadata:
6
+ type: library
7
+ library: '@toyu-ui/elements'
8
+ library_version: '0.1.0'
9
+ source: src/button/tyui-button.ts
10
+ manifest: ../../custom-elements.json
11
+ ---
12
+
13
+ # tyui-button
14
+
15
+ ## Intent
16
+
17
+ Use `tyui-button` to trigger an immediate in-page action. Use a link for navigation.
18
+
19
+ ## API Source
20
+
21
+ Authoritative API facts live in `@toyu-ui/elements/custom-elements.json`. Do not copy
22
+ attribute or event types from memory.
23
+
24
+ ## Registration
25
+
26
+ ```ts
27
+ import { defineTyuiButton } from '@toyu-ui/define/button';
28
+
29
+ defineTyuiButton();
30
+ ```
31
+
32
+ ## Correct Usage
33
+
34
+ ```html
35
+ <tyui-button appearance="primary">Save</tyui-button>
36
+ ```
37
+
38
+ ## Selection Guidance
39
+
40
+ - Use one primary button for the dominant local action.
41
+ - Use default or secondary styling for ordinary commands.
42
+ - Use subtle or transparent styling for dense toolbars and repeated row actions.
43
+ - Icon-only buttons must have an accessible name.
44
+
45
+ ## Anti-Patterns
46
+
47
+ - Do not use button activation for navigation.
48
+ - Do not place focusable controls inside the button label.
49
+ - Do not restyle private shadow DOM; use public tokens, attributes, and parts.
@@ -0,0 +1,45 @@
1
+ ---
2
+ name: center
3
+ description: Use tyui-center to constrain readable content to a centered measure with tokenized gutters.
4
+ license: Apache-2.0
5
+ metadata:
6
+ type: library
7
+ library: '@toyu-ui/elements'
8
+ library_version: '0.1.0'
9
+ source: src/center/tyui-center.ts
10
+ manifest: ../../custom-elements.json
11
+ ---
12
+
13
+ # tyui-center
14
+
15
+ ## Intent
16
+
17
+ Use `tyui-center` to constrain readable content to a maximum inline measure and center it inside the available space.
18
+
19
+ ## API Source
20
+
21
+ Authoritative API facts live in `@toyu-ui/elements/custom-elements.json`.
22
+
23
+ ## Correct Usage
24
+
25
+ ```html
26
+ <tyui-center measure="60ch" gutter="page">
27
+ <tyui-flex direction="column" gap="3">
28
+ <h1>Profile</h1>
29
+ <tyui-input label="Display name"></tyui-input>
30
+ </tyui-flex>
31
+ </tyui-center>
32
+ ```
33
+
34
+ ## Selection Guidance
35
+
36
+ - Use Center for prose, forms, narrow settings pages, and focused empty states.
37
+ - Use Container for page or section rails.
38
+ - Use Grid or Sidebar when the content has multiple peer regions.
39
+ - Use the `intrinsic` attribute when children should also center as a column.
40
+
41
+ ## Anti-Patterns
42
+
43
+ - Do not wrap every individual control in Center.
44
+ - Do not use Center as a card or surface.
45
+ - Do not nest Center repeatedly without a specific measure change.
@@ -0,0 +1,39 @@
1
+ ---
2
+ name: checkbox
3
+ description: Use and integrate the tyui-checkbox custom element for independent boolean choices and avoid radio or command-button misuse.
4
+ license: Apache-2.0
5
+ metadata:
6
+ type: library
7
+ library: '@toyu-ui/elements'
8
+ library_version: '0.1.0'
9
+ source: src/checkbox/tyui-checkbox.ts
10
+ manifest: ../../custom-elements.json
11
+ ---
12
+
13
+ # tyui-checkbox
14
+
15
+ ## Intent
16
+
17
+ Use `tyui-checkbox` for an independent yes/no or on/off choice.
18
+
19
+ ## API Source
20
+
21
+ Authoritative API facts live in `@toyu-ui/elements/custom-elements.json`.
22
+
23
+ ## Correct Usage
24
+
25
+ ```html
26
+ <tyui-checkbox name="notifications" value="enabled">Email notifications</tyui-checkbox>
27
+ ```
28
+
29
+ ## Selection Guidance
30
+
31
+ - Use checkbox for independent choices.
32
+ - Use radio group when exactly one option must be chosen from a set.
33
+ - Use a switch component, when available, for immediate setting toggles.
34
+
35
+ ## Anti-Patterns
36
+
37
+ - Do not use checkbox as a command button.
38
+ - Do not use checkbox for mutually exclusive options.
39
+ - Do not hide the label without providing an accessible name.
@@ -0,0 +1,44 @@
1
+ ---
2
+ name: cluster
3
+ description: Use tyui-cluster for compact wrapping rows of intrinsic items such as actions, tags, chips, and toolbar-like groups.
4
+ license: Apache-2.0
5
+ metadata:
6
+ type: library
7
+ library: '@toyu-ui/elements'
8
+ library_version: '0.1.0'
9
+ source: src/cluster/tyui-cluster.ts
10
+ manifest: ../../custom-elements.json
11
+ ---
12
+
13
+ # tyui-cluster
14
+
15
+ ## Intent
16
+
17
+ Use `tyui-cluster` for compact groups of peer items that keep their intrinsic size and wrap to new lines when space runs out.
18
+
19
+ ## API Source
20
+
21
+ Authoritative API facts live in `@toyu-ui/elements/custom-elements.json`.
22
+
23
+ ## Correct Usage
24
+
25
+ ```html
26
+ <tyui-cluster gap="2">
27
+ <tyui-button appearance="primary">Save</tyui-button>
28
+ <tyui-button>Cancel</tyui-button>
29
+ <tyui-button appearance="subtle">Reset</tyui-button>
30
+ </tyui-cluster>
31
+ ```
32
+
33
+ ## Selection Guidance
34
+
35
+ - Use Cluster for action rows, tags, chips, checkbox rows, radio rows, and short metadata groups.
36
+ - Use Flex when one-axis distribution, direction, or optional wrapping matters more than wrap-first behavior.
37
+ - Use Grid when children should form equal responsive tracks.
38
+ - Preserve list markup when the items are a semantic list.
39
+
40
+ ## Anti-Patterns
41
+
42
+ - Do not use Cluster for table rows or data grids.
43
+ - Do not remove list semantics just to get a wrapping row.
44
+ - Do not make Cluster responsible for toolbar keyboard behavior.
@@ -0,0 +1,53 @@
1
+ ---
2
+ name: components
3
+ description: Load the TYUI component guidance set for choosing and using shipped custom elements and layout primitives.
4
+ license: Apache-2.0
5
+ requires:
6
+ - '@toyu-ui/elements#button'
7
+ - '@toyu-ui/elements#input'
8
+ - '@toyu-ui/elements#checkbox'
9
+ - '@toyu-ui/elements#radio'
10
+ - '@toyu-ui/elements#radio-group'
11
+ - '@toyu-ui/elements#flex'
12
+ - '@toyu-ui/elements#cluster'
13
+ - '@toyu-ui/elements#grid'
14
+ - '@toyu-ui/elements#center'
15
+ - '@toyu-ui/elements#container'
16
+ - '@toyu-ui/elements#frame'
17
+ - '@toyu-ui/elements#sidebar'
18
+ metadata:
19
+ type: library
20
+ library: '@toyu-ui/elements'
21
+ library_version: '0.1.0'
22
+ source: skills/components/SKILL.md
23
+ manifest: ../../custom-elements.json
24
+ ---
25
+
26
+ # TYUI components
27
+
28
+ ## Intent
29
+
30
+ Use `@toyu-ui/elements#components` when an agent or developer needs the complete shipped TYUI component guidance set before choosing controls or layout primitives.
31
+
32
+ ## API Source
33
+
34
+ Authoritative API facts live in `@toyu-ui/elements/custom-elements.json`. This aggregate skill only gathers intent and selection guidance; individual component skills remain the source for component-specific advice.
35
+
36
+ ## Correct Usage
37
+
38
+ ```sh
39
+ yarn dlx @tanstack/intent@latest load @toyu-ui/elements#components
40
+ ```
41
+
42
+ ## Selection Guidance
43
+
44
+ - Load this skill at the start of a TYUI UI task when the component choice is not known yet.
45
+ - Use the required component skills for exact intent, selection guidance, anti-patterns, and usage examples.
46
+ - Use `@toyu-ui/solid#setup` as the companion setup skill for Solid apps.
47
+ - Use `custom-elements.json` for exact attributes, events, slots, CSS parts, and CSS custom properties.
48
+
49
+ ## Anti-Patterns
50
+
51
+ - Do not duplicate component selection rules in app docs when this aggregate skill can load the versioned component guidance.
52
+ - Do not treat this skill as an API reference; use the manifest for exact API facts.
53
+ - Do not load every component at runtime just because every component skill was loaded for agent guidance.
@@ -0,0 +1,42 @@
1
+ ---
2
+ name: container
3
+ description: Use tyui-container to constrain page or section width with named rails and tokenized gutters.
4
+ license: Apache-2.0
5
+ metadata:
6
+ type: library
7
+ library: '@toyu-ui/elements'
8
+ library_version: '0.1.0'
9
+ source: src/container/tyui-container.ts
10
+ manifest: ../../custom-elements.json
11
+ ---
12
+
13
+ # tyui-container
14
+
15
+ ## Intent
16
+
17
+ Use `tyui-container` to create a page or section rail that controls maximum inline size and horizontal gutter.
18
+
19
+ ## API Source
20
+
21
+ Authoritative API facts live in `@toyu-ui/elements/custom-elements.json`.
22
+
23
+ ## Correct Usage
24
+
25
+ ```html
26
+ <tyui-container size="wide" gutter="page">
27
+ <tyui-grid min-item-size="18rem" gap="4"></tyui-grid>
28
+ </tyui-container>
29
+ ```
30
+
31
+ ## Selection Guidance
32
+
33
+ - Use Container for page shells, section rails, dashboard content bounds, and full-width page regions.
34
+ - Use Center for readable single-column content.
35
+ - Use Frame for aspect-ratio media.
36
+ - Use `bleed` only when content intentionally reaches the container edge.
37
+
38
+ ## Anti-Patterns
39
+
40
+ - Do not use Container to set a button or input width.
41
+ - Do not use card padding as page gutters.
42
+ - Do not nest containers without a named rail change.
@@ -0,0 +1,45 @@
1
+ ---
2
+ name: flex
3
+ description: Use tyui-flex for one-axis sibling composition with tokenized direction, alignment, wrapping, and gap.
4
+ license: Apache-2.0
5
+ metadata:
6
+ type: library
7
+ library: '@toyu-ui/elements'
8
+ library_version: '0.1.0'
9
+ source: src/flex/tyui-flex.ts
10
+ manifest: ../../custom-elements.json
11
+ ---
12
+
13
+ # tyui-flex
14
+
15
+ ## Intent
16
+
17
+ Use `tyui-flex` when sibling content follows one axis and the parent owns direction, wrapping, alignment, justification, and gap.
18
+
19
+ ## API Source
20
+
21
+ Authoritative API facts live in `@toyu-ui/elements/custom-elements.json`.
22
+
23
+ ## Correct Usage
24
+
25
+ ```html
26
+ <tyui-flex direction="column" gap="3">
27
+ <h2>Settings</h2>
28
+ <tyui-input label="Name"></tyui-input>
29
+ <tyui-button appearance="primary">Save</tyui-button>
30
+ </tyui-flex>
31
+ ```
32
+
33
+ ## Selection Guidance
34
+
35
+ - Use Flex for row or column composition of siblings.
36
+ - Use Flex when the design may switch direction or wrapping through attributes.
37
+ - Use Cluster for wrap-first action rows, chips, and tags.
38
+ - Use Grid for repeated peer cards or panels.
39
+ - Use native block flow for simple prose.
40
+
41
+ ## Anti-Patterns
42
+
43
+ - Do not use Flex to create data tables or two-dimensional card grids.
44
+ - Do not force every child to `flex: 1` unless equal distribution is the container intent.
45
+ - Do not use visual reverse direction to fix incorrect DOM reading order.
@@ -0,0 +1,42 @@
1
+ ---
2
+ name: frame
3
+ description: Use tyui-frame to reserve aspect ratio for media, previews, charts, thumbnails, and embeds.
4
+ license: Apache-2.0
5
+ metadata:
6
+ type: library
7
+ library: '@toyu-ui/elements'
8
+ library_version: '0.1.0'
9
+ source: src/frame/tyui-frame.ts
10
+ manifest: ../../custom-elements.json
11
+ ---
12
+
13
+ # tyui-frame
14
+
15
+ ## Intent
16
+
17
+ Use `tyui-frame` to reserve a stable aspect ratio for one primary child while the parent owns width.
18
+
19
+ ## API Source
20
+
21
+ Authoritative API facts live in `@toyu-ui/elements/custom-elements.json`.
22
+
23
+ ## Correct Usage
24
+
25
+ ```html
26
+ <tyui-frame ratio="16/9" fit="cover">
27
+ <img src="/preview.jpg" alt="Project preview" />
28
+ </tyui-frame>
29
+ ```
30
+
31
+ ## Selection Guidance
32
+
33
+ - Use Frame for images, video, canvas, iframe embeds, charts, thumbnails, and preview surfaces.
34
+ - Use natural block flow for text-heavy cards.
35
+ - Use Grid for collections of framed peers.
36
+ - Apply `fit` and `position` only when the direct child is replaced media.
37
+
38
+ ## Anti-Patterns
39
+
40
+ - Do not place full forms or complex scrollable interactive regions inside Frame.
41
+ - Do not use Frame to crop text cards.
42
+ - Do not expect `object-fit` to affect non-replaced elements.