@threelight/ui 0.2.0-alpha.0 → 0.2.0-alpha.1

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/README.md CHANGED
@@ -1,9 +1,10 @@
1
1
  # @threelight/ui
2
2
 
3
- Framework-neutral governed UI primitives for readable HTML/CSS interfaces.
3
+ Framework-neutral governed HTML/CSS core for readable UI foundations.
4
4
 
5
- This package is an early alpha for the ThreeLight UI grammar. It publishes CSS
6
- primitives, safe default theme tokens, examples, and typed registry metadata.
5
+ `@threelight/ui` ships CSS, tokens, examples, and typed metadata. It does not
6
+ depend on React, Vue, Svelte, routing, data fetching, or application business
7
+ logic.
7
8
 
8
9
  ```bash
9
10
  pnpm add @threelight/ui@alpha
@@ -13,149 +14,177 @@ pnpm add @threelight/ui@alpha
13
14
  import "@threelight/ui/base.css"
14
15
  ```
15
16
 
16
- Import this once from the application entrypoint or global stylesheet entry
17
- before project-specific override CSS:
17
+ Import the CSS once from an application entrypoint or global stylesheet before
18
+ project-specific overrides:
18
19
 
19
20
  ```ts
20
21
  import "@threelight/ui/base.css"
21
22
  import "./app.css"
22
23
  ```
23
24
 
24
- ThreeLight uses low-specificity selectors and cascade layers, so application CSS
25
- loaded later can intentionally override project-specific details.
26
-
27
- ## Applying The Styles
28
-
29
- Importing the CSS loads ThreeLight styles globally, but primitives only apply
30
- inside an explicit `data-tl-root` scope. This keeps existing project CSS from
31
- being changed by import alone.
32
-
33
- Apply ThreeLight to the whole app by putting the root attributes on `body`:
25
+ ThreeLight styles apply only inside an explicit `data-tl-root` scope:
34
26
 
35
27
  ```html
36
28
  <body data-tl-root data-tl-theme="default" data-tl-mode="light">
37
- <main class="tl-section tl-stack">
38
- <h1 class="tl-display">Project archive</h1>
39
- <p class="tl-body">Readable governed UI primitives.</p>
29
+ <main class="tl-layout-section tl-layout-stack">
30
+ <header class="tl-pattern-page-header">
31
+ <div class="tl-pattern-page-header__content">
32
+ <h1 class="tl-component-display">Project archive</h1>
33
+ <p class="tl-component-body">Readable governed UI foundations.</p>
34
+ </div>
35
+ <div class="tl-pattern-page-header__actions">
36
+ <button class="tl-component-button" data-tl-tone="primary" type="button">
37
+ New report
38
+ </button>
39
+ </div>
40
+ </header>
40
41
  </main>
41
42
  </body>
42
43
  ```
43
44
 
44
- Apply ThreeLight to only one area by putting the root attributes on a subtree:
45
-
46
- ```html
47
- <body>
48
- <main>
49
- <section data-tl-root data-tl-theme="default" data-tl-mode="dark">
50
- <article class="tl-card tl-stack" data-tl-tone="info">
51
- <h2 class="tl-heading">Scoped preview</h2>
52
- <p class="tl-body">Only this subtree uses ThreeLight primitives.</p>
53
- </article>
54
- </section>
55
- </main>
56
- </body>
57
- ```
45
+ ## Public Contract
58
46
 
59
- `tl-*` classes outside `data-tl-root` are intentionally not styled.
47
+ `className` is not an implementation leak in `@threelight/ui`. Approved
48
+ `tl-*` class names, `data-tl-*` attributes, and `--tl-*` tokens are the core
49
+ public contract.
60
50
 
61
- ## Overriding Styles
51
+ Future adapters such as `@threelight/ui-react`, `@threelight/ui-vue`, or
52
+ `@threelight/ui-svelte` can wrap these approved class/data/token combinations
53
+ with thin component APIs. This package remains the framework-neutral HTML/CSS
54
+ core.
62
55
 
63
- Prefer overriding `--tl-*` tokens when customizing theme color, border, focus,
64
- or component role values. Token overrides keep primitive structure, spacing, and
65
- readability defaults intact:
56
+ Class names follow a layer-prefixed alpha contract:
66
57
 
67
- ```css
68
- [data-tl-root][data-tl-theme="studio"][data-tl-mode="light"] {
69
- --tl-primary-fill: #55ffff;
70
- --tl-primary-on-fill: #061010;
71
- --tl-primary-border: #27757c;
72
- }
58
+ ```text
59
+ tl-[layer]-[name]
60
+ tl-[layer]-[name]__[part]
73
61
  ```
74
62
 
75
- Directly overriding `.tl-*` classes is allowed, but it can intentionally replace
76
- primitive structure. For example, later app CSS such as `.my-page .tl-button {
77
- padding: 0; border: 0; }` will change how that button renders.
63
+ - `component`: one meaningful UI part, such as `tl-component-button`.
64
+ - `pattern`: repeated structures that combine components/layout, such as
65
+ `tl-pattern-page-header`.
66
+ - `layout`: structure without product meaning, such as `tl-layout-stack`.
67
+ - `utility`: small single-purpose adjustments, such as
68
+ `tl-utility-truncate`.
78
69
 
79
- ## Primitive Contract
70
+ Do not put product or documentation-app names such as Lab, Studio, or MapBridge
71
+ in public class names.
80
72
 
81
- ThreeLight UI exposes opt-in, framework-neutral HTML/CSS primitives. Compose
82
- with `tl-*` classes and namespaced `data-tl-*` attributes.
73
+ ## Adapter-Ready Foundations
83
74
 
84
- - Layout: `tl-section`, `tl-stack`, `tl-cluster`, `tl-grid`
85
- - Surface: `tl-surface`, `tl-card`, `tl-panel`
86
- - Text: `tl-display`, `tl-heading`, `tl-body`, `tl-caption`, `tl-meta`, `tl-label`, `tl-action-text`, `tl-metric`, `tl-code`
87
- - Action/status: `tl-button`, `tl-badge`, `tl-alert`
88
- - Form: `tl-field`, `tl-input`, `tl-help`
75
+ The first adapter-ready foundations are:
89
76
 
90
- Supported tones are `neutral`, `primary`, `info`, `success`, `warning`, and
91
- `danger`. Omit `data-tl-tone` for neutral behavior.
77
+ - PageHeader: `tl-pattern-page-header`,
78
+ `tl-pattern-page-header__content`,
79
+ `tl-pattern-page-header__actions`
80
+ - EmptyState: `tl-pattern-empty-state`,
81
+ `tl-pattern-empty-state__content`,
82
+ `tl-pattern-empty-state__actions`
83
+ - Button: `tl-component-button`
84
+
85
+ Button is a component foundation, not a pattern.
92
86
 
93
- Primitives keep body and input text at 16px or larger, keep helper and caption
94
- text at the 14px readable floor, and expose spacing overrides through CSS custom
95
- properties such as `--tl-gap`, `--tl-grid-min`, and `--tl-surface-padding`.
87
+ ## Data Attributes
96
88
 
97
- ## Theme Contract
89
+ `data-tl-root` opts a subtree into ThreeLight styles. `data-tl-theme` selects a
90
+ theme family, currently `default`. `data-tl-mode` selects `light` or `dark`.
98
91
 
99
- ThreeLight UI separates theme family, mode, and semantic tone.
92
+ `data-tl-tone` expresses semantic color intent:
100
93
 
101
94
  ```html
102
- <body data-tl-root data-tl-theme="default" data-tl-mode="light">
103
- <article class="tl-card" data-tl-tone="warning">
104
- ...
105
- </article>
106
- </body>
95
+ <article class="tl-component-alert" data-tl-tone="warning" role="status">
96
+ <p class="tl-component-body">This warning uses semantic tone tokens.</p>
97
+ </article>
107
98
  ```
108
99
 
109
- - `data-tl-root` opts an app or subtree into ThreeLight theme variables.
110
- - `data-tl-theme` selects palette family, initially `default`.
111
- - `data-tl-mode` selects lightness mode, initially `light` or `dark`.
112
- - `data-tl-tone` expresses component meaning and stays stable across themes.
100
+ Supported tones are `neutral`, `primary`, `info`, `success`, `warning`, and
101
+ `danger`. Omit `data-tl-tone` for neutral behavior.
102
+
103
+ `data-tl-state` is a UI state marker, not business logic. Applications decide
104
+ when content is loading, empty, or error; `@threelight/ui` provides safe
105
+ structure and readable defaults when those states are displayed.
106
+
107
+ Supported states are `loading`, `empty`, and `error`.
113
108
 
114
- Theme tokens are role-centric. Prefer `content` roles over text-only roles:
109
+ ## Tokens
110
+
111
+ Color is expressed through `data-tl-tone` and `--tl-color-*` tokens, not color
112
+ utility classes. Do not add `tl-color-*` classes.
113
+
114
+ Global color tokens use an explicit namespace:
115
115
 
116
116
  ```text
117
- --tl-canvas
118
- --tl-surface
119
- --tl-layer
120
- --tl-content-primary
121
- --tl-content-secondary
122
- --tl-content-subtle
123
- --tl-border-subtle
124
- --tl-border-strong
125
- --tl-focus
117
+ --tl-color-canvas
118
+ --tl-color-surface
119
+ --tl-color-layer
120
+ --tl-color-content-primary
121
+ --tl-color-content-secondary
122
+ --tl-color-content-subtle
123
+ --tl-color-border-subtle
124
+ --tl-color-border-strong
125
+ --tl-color-focus
126
+ --tl-color-primary-fill
127
+ --tl-color-primary-content
128
+ --tl-color-primary-soft
129
+ --tl-color-primary-border
126
130
  ```
127
131
 
128
- Theme and mode changes swap token values behind each role. Consumers should not
129
- rewrite a component from `warning` to another tone unless the component meaning
130
- changes.
132
+ Tone tokens follow `--tl-color-[tone]-[role]`, for example
133
+ `--tl-color-info-fill`, `--tl-color-success-content`, and
134
+ `--tl-color-danger-border`.
135
+
136
+ Component-local tokens such as `--tl-button-background`,
137
+ `--tl-button-content`, `--tl-button-disabled-content`, and
138
+ `--tl-component-border` may remain local to a component contract, but color
139
+ values should resolve to global `--tl-color-*` tokens.
131
140
 
132
- ## Registry Metadata
141
+ Spacing, radius, font, font-size, and shadow tokens remain separately
142
+ namespaced: `--tl-space-*`, `--tl-radius-*`, `--tl-font-*`,
143
+ `--tl-font-size-*`, and `--tl-shadow-*`. Font-size tokens provide predictable
144
+ component scale without viewport-width font sizing.
133
145
 
134
- The package exports readonly registry metadata for adapters and migration tools:
146
+ ## Metadata
147
+
148
+ Use the package metadata exports to avoid hard-coding public contract names in
149
+ adapters or migration tools:
135
150
 
136
151
  ```ts
137
152
  import {
153
+ componentClasses,
154
+ layoutClasses,
155
+ patternClasses,
156
+ patternPartClasses,
138
157
  primitiveClasses,
139
- semanticTokenNames,
158
+ stateNames,
140
159
  themeAttributes,
141
- themeFamilies,
142
- themeModes,
160
+ tokenNames,
143
161
  toneNames,
162
+ utilityClasses,
144
163
  } from "@threelight/ui"
145
164
  ```
146
165
 
147
- Use these exports to avoid hard-coding the public `tl-*`, `data-tl-*`, tone, and
148
- token contract in downstream packages.
166
+ ## Alpha Migration Boundary
167
+
168
+ Earlier alpha builds used short class names such as `tl-button`, `tl-card`, and
169
+ `tl-section`, plus unnamespaced color tokens such as `--tl-primary-fill` and
170
+ `--tl-primary-on-fill`.
171
+
172
+ Those short alpha class names are not the stable contract. They are not exported
173
+ from metadata, they are not used by primary examples, and future adapters should
174
+ not wrap them.
149
175
 
150
- ## Status
176
+ The primary class contract is the layer-prefixed naming:
177
+ `tl-component-*`, `tl-pattern-*`, `tl-layout-*`, and `tl-utility-*`.
151
178
 
152
- `@threelight/ui` is experimental. Public APIs may change before the first stable
153
- release.
179
+ The primary color token contract is `--tl-color-*`. Old unnamespaced color
180
+ tokens may exist temporarily inside CSS as alpha compatibility aliases to reduce
181
+ breakage, but they are not the preferred public contract and are not exported as
182
+ metadata. Consumers should migrate to the new class and token contract before
183
+ stable.
154
184
 
155
185
  ## Publishing
156
186
 
157
- Publish alpha releases from the repository root with the scripted command. The
158
- script runs package publish with an explicit `alpha` dist-tag.
187
+ Publish alpha releases from the repository root with the scripted command:
159
188
 
160
189
  ```bash
161
190
  pnpm release:ui:alpha