@stealthscale/component-feedback 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.
- package/LICENSE +21 -0
- package/README.md +101 -0
- package/dist/cyclonedx/bom.json +1 -0
- package/dist/index.d.ts +142 -0
- package/dist/index.js +177 -0
- package/dist/recipe-0Xo90j3-.js +162 -0
- package/dist/rolldown-runtime-D7D4PA-g.js +13 -0
- package/dist/theme.d.ts +12 -0
- package/dist/theme.js +23 -0
- package/package.json +69 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Stealth Scale B.V.
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
# @stealthscale/component-feedback
|
|
2
|
+
|
|
3
|
+
Draws the system reporting on itself: what is loading, what went wrong, what state a thing is in.
|
|
4
|
+
Every component binds a recipe and draws nothing of its own, so a theme restyles all of them by
|
|
5
|
+
extending the recipe. The preset under `./theme` registers the recipes with an application's
|
|
6
|
+
compiler.
|
|
7
|
+
|
|
8
|
+
Every value a theme can change on a component is an axis of its recipe, so a caller sets it as a
|
|
9
|
+
prop and writes no style. A caller changes the element a component draws with `as`.
|
|
10
|
+
|
|
11
|
+
## Install
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
pnpm add @stealthscale/component-feedback
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
The package peers on `react` and `@stealthscale/theme`. An application lists the preset under
|
|
18
|
+
`./theme` among the presets its compiler installs.
|
|
19
|
+
|
|
20
|
+
## Skeleton
|
|
21
|
+
|
|
22
|
+
Stands in for content that has not arrived. It wraps that content rather than replacing it, so a
|
|
23
|
+
caller writes one tree and sets one prop, and the stand-in comes out the size of the thing it stands
|
|
24
|
+
in for without anybody stating a width. While it waits it hides everything inside it. Once the
|
|
25
|
+
content arrives the stand-in fades out and the content is shown.
|
|
26
|
+
|
|
27
|
+
```tsx
|
|
28
|
+
import { Skeleton } from "@stealthscale/component-feedback";
|
|
29
|
+
|
|
30
|
+
<Skeleton loading={pending}>
|
|
31
|
+
<Avatar src={person.photo} />
|
|
32
|
+
</Skeleton>;
|
|
33
|
+
<Skeleton motion="shimmer" radius="full" />;
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
| Axis | Values | Default |
|
|
37
|
+
| --------- | -------------------------- | ------- |
|
|
38
|
+
| `loading` | `true`, `false` | `true` |
|
|
39
|
+
| `motion` | `none`, `pulse`, `shimmer` | `pulse` |
|
|
40
|
+
| `radius` | `l1`, `l2`, `l3`, `full` | `l2` |
|
|
41
|
+
|
|
42
|
+
The element carries no role. A reader learns more from being told the region is busy than from being
|
|
43
|
+
told each box is, so a page states `aria-busy` on whatever is waiting and each bar announces nothing
|
|
44
|
+
of its own.
|
|
45
|
+
|
|
46
|
+
## SkeletonText
|
|
47
|
+
|
|
48
|
+
Stands in for a paragraph of text. Every length is read off the line it stands in for, so a bar is
|
|
49
|
+
one line tall and the space between two is half a line. Place it where text is read and it comes out
|
|
50
|
+
the size of that text, so the page does not jump when the real words replace it.
|
|
51
|
+
|
|
52
|
+
```tsx
|
|
53
|
+
import { SkeletonText } from "@stealthscale/component-feedback";
|
|
54
|
+
|
|
55
|
+
<SkeletonText />;
|
|
56
|
+
<SkeletonText lines={5} motion="shimmer" />;
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
The last bar of several is short, because a paragraph rarely fills its final line and a block of
|
|
60
|
+
bars all one width reads as a table rather than as writing. `lines` defaults to three and never
|
|
61
|
+
draws fewer than one. Draw this while the text is loading and draw the text itself once it arrives,
|
|
62
|
+
so nothing here takes a loading state.
|
|
63
|
+
|
|
64
|
+
## EmptyState
|
|
65
|
+
|
|
66
|
+
Draws the panel a page shows where there is nothing to show, composed as `EmptyState.Root` holding a
|
|
67
|
+
mark, a heading and a line saying what would be here.
|
|
68
|
+
|
|
69
|
+
```tsx
|
|
70
|
+
import { EmptyState } from "@stealthscale/component-feedback";
|
|
71
|
+
|
|
72
|
+
<EmptyState.Root size="lg">
|
|
73
|
+
<EmptyState.Content>
|
|
74
|
+
<EmptyState.Indicator aria-hidden>
|
|
75
|
+
<InboxIcon />
|
|
76
|
+
</EmptyState.Indicator>
|
|
77
|
+
<EmptyState.Title>No invoices yet</EmptyState.Title>
|
|
78
|
+
<EmptyState.Description>Send your first one to get started.</EmptyState.Description>
|
|
79
|
+
</EmptyState.Content>
|
|
80
|
+
</EmptyState.Root>;
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
| Axis | Values | Default |
|
|
84
|
+
| ------ | ------------------------------------------------- | ------- |
|
|
85
|
+
| `size` | `xs`, `sm`, `md`, `lg`, `xl`, `2xl`, `3xl`, `4xl` | `md` |
|
|
86
|
+
|
|
87
|
+
One axis sets four parts together. The room inside the panel, the gap in the content, the box of the
|
|
88
|
+
mark and the size of the title each read the scale of that name, so a small panel in a sidebar and a
|
|
89
|
+
large one filling a page are one name apart. The description holds its size, because a line of
|
|
90
|
+
explanation is read at the size the rest of the page is read at however big the panel is.
|
|
91
|
+
|
|
92
|
+
The mark fills whatever box its size states, so a caller passes a glyph without sizing it. Hide it
|
|
93
|
+
with `aria-hidden`, since the title beneath says the same thing in words. The title is an `h2`,
|
|
94
|
+
which suits a panel standing in for a section's content. A page whose outline puts it deeper states
|
|
95
|
+
its own level with `as`.
|
|
96
|
+
|
|
97
|
+
The root carries no role. A page of empty panels would otherwise be a page of landmarks.
|
|
98
|
+
|
|
99
|
+
## Licence
|
|
100
|
+
|
|
101
|
+
MIT. See [LICENSE](LICENSE).
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"$schema":"http://cyclonedx.org/schema/bom-1.7.schema.json","bomFormat":"CycloneDX","specVersion":"1.7","version":1,"metadata":{"lifecycles":[{"phase":"build"}],"tools":{"components":[{"type":"application","name":"rolldown","version":"1.2.7"},{"type":"application","name":"vite","version":"8.2.2"},{"type":"library","name":"core","group":"@arethetypeswrong","version":"0.18.5","bom-ref":"pkg:npm/%40arethetypeswrong/core@0.18.5","author":"Andrew Branch","description":"The API behind arethetypeswrong.github.io","hashes":[{"alg":"SHA-512","content":"f72b63cc6c318e6f54cfb23d6af7dbb79be542deae93db914444b3263aabce797a58abc8e9dc184e8faf277534d96aeafe64778aa97f3f386f1e129d2480230d"}],"licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/%40arethetypeswrong/core@0.18.5","externalReferences":[{"url":"https://github.com/arethetypeswrong/arethetypeswrong.github.io.git#packages/core","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""}],"properties":[{"name":"cdx:npm:package:constraint:engine:node","value":">=20"}]},{"type":"library","name":"theme","group":"@stealthscale","version":"0.3.0","bom-ref":"pkg:npm/%40stealthscale/theme@0.3.0","description":"Publishes the foundation every recipe is written against, the runtime every component binds its recipe with, and the vocabulary a theme is written in.","licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/%40stealthscale/theme@0.3.0","externalReferences":[{"url":"https://github.com/stealth-scale/config/issues","type":"issue-tracker","comment":"as detected from PackageJson property \"bugs\""},{"url":"git+https://github.com/stealth-scale/config.git#foundations/theme","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""},{"url":"https://github.com/stealth-scale/config/tree/main/foundations/theme#readme","type":"website","comment":"as detected from PackageJson property \"homepage\""}],"properties":[{"name":"cdx:npm:package:constraint:engine:node","value":">=26.0.0"}]},{"type":"library","name":"vite-config-react","group":"@stealthscale","version":"0.8.0","bom-ref":"pkg:npm/%40stealthscale/vite-config-react@0.8.0","description":"Adds the JSX transform, the React lint rules, a test document and an MDX compiler to a package that renders.","licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/%40stealthscale/vite-config-react@0.8.0","externalReferences":[{"url":"https://github.com/stealth-scale/config/issues","type":"issue-tracker","comment":"as detected from PackageJson property \"bugs\""},{"url":"git+https://github.com/stealth-scale/config.git#packages/vite-config-react","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""},{"url":"https://github.com/stealth-scale/config/tree/main/packages/vite-config-react#readme","type":"website","comment":"as detected from PackageJson property \"homepage\""}],"properties":[{"name":"cdx:npm:package:constraint:engine:node","value":">=26.0.0"}]},{"type":"library","name":"vite-config-theme","group":"@stealthscale","version":"0.1.0","bom-ref":"pkg:npm/%40stealthscale/vite-config-theme@0.1.0","description":"Adds the runtime generator to a design-system package and the stylesheet compiler to an application.","licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/%40stealthscale/vite-config-theme@0.1.0","externalReferences":[{"url":"https://github.com/stealth-scale/config/issues","type":"issue-tracker","comment":"as detected from PackageJson property \"bugs\""},{"url":"git+https://github.com/stealth-scale/config.git#packages/vite-config-theme","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""},{"url":"https://github.com/stealth-scale/config/tree/main/packages/vite-config-theme#readme","type":"website","comment":"as detected from PackageJson property \"homepage\""}],"properties":[{"name":"cdx:npm:package:constraint:engine:node","value":">=26.0.0"}]},{"type":"library","name":"vite-config-typescript","group":"@stealthscale","version":"0.3.0","bom-ref":"pkg:npm/%40stealthscale/vite-config-typescript@0.3.0","description":"Sets the TypeScript options every stealthscale package compiles with.","licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/%40stealthscale/vite-config-typescript@0.3.0","externalReferences":[{"url":"https://github.com/stealth-scale/config/issues","type":"issue-tracker","comment":"as detected from PackageJson property \"bugs\""},{"url":"git+https://github.com/stealth-scale/config.git#packages/vite-config-typescript","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""},{"url":"https://github.com/stealth-scale/config/tree/main/packages/vite-config-typescript#readme","type":"website","comment":"as detected from PackageJson property \"homepage\""}],"properties":[{"name":"cdx:npm:package:constraint:engine:node","value":">=26.0.0"}]},{"type":"library","name":"vite-config","group":"@stealthscale","version":"0.6.0","bom-ref":"pkg:npm/%40stealthscale/vite-config@0.6.0","description":"Configures a package from five Vite+ tiers and a named layer for every block.","licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/%40stealthscale/vite-config@0.6.0","externalReferences":[{"url":"https://github.com/stealth-scale/config/issues","type":"issue-tracker","comment":"as detected from PackageJson property \"bugs\""},{"url":"git+https://github.com/stealth-scale/config.git#packages/vite-config","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""},{"url":"https://github.com/stealth-scale/config/tree/main/packages/vite-config#readme","type":"website","comment":"as detected from PackageJson property \"homepage\""}],"properties":[{"name":"cdx:npm:package:constraint:engine:node","value":">=26.0.0"}]},{"type":"library","name":"react","group":"@testing-library","version":"16.3.3","bom-ref":"pkg:npm/%40testing-library/react@16.3.3","author":"Kent C. Dodds <me@kentcdodds.com> (https://kentcdodds.com)","description":"Simple and complete React DOM testing utilities that encourage good testing practices.","hashes":[{"alg":"SHA-512","content":"528d7ddcd8106cf333ea5aeb86d45040570c0ba45efc42cb15b6ee54bdf4583959c65a597fdfe53074c05713d12f0d6ad62bbd389991d5cd812e210d46cb5d06"}],"licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/%40testing-library/react@16.3.3","externalReferences":[{"url":"https://github.com/testing-library/react-testing-library/issues","type":"issue-tracker","comment":"as detected from PackageJson property \"bugs.url\""},{"url":"https://github.com/testing-library/react-testing-library","type":"vcs","comment":"as detected from PackageJson property \"repository.url\""},{"url":"https://github.com/testing-library/react-testing-library#readme","type":"website","comment":"as detected from PackageJson property \"homepage\""}],"properties":[{"name":"cdx:npm:package:constraint:engine:node","value":">=18"}]},{"type":"library","name":"react-dom","group":"@types","version":"19.3.0","bom-ref":"pkg:npm/%40types/react-dom@19.3.0","description":"TypeScript definitions for react-dom","hashes":[{"alg":"SHA-512","content":"648edb538da66575ca1e7fea34b130d88adb888354ed7e7ebdf81d8b10479023696165e32a07d0fcffaec866f90a338b07d51c9d37a0debca542d5768729b8e1"}],"licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/%40types/react-dom@19.3.0","externalReferences":[{"url":"https://github.com/DefinitelyTyped/DefinitelyTyped.git#types/react-dom","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""},{"url":"https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/react-dom","type":"website","comment":"as detected from PackageJson property \"homepage\""}]},{"type":"library","name":"react","group":"@types","version":"19.3.0","bom-ref":"pkg:npm/%40types/react@19.3.0","description":"TypeScript definitions for react","hashes":[{"alg":"SHA-512","content":"374ac50ae1fd628c46f7f9bad65f4c7e924a7e62ce554d1e9bb8a9233e9346049292f45e2c1f6f2fce4607ecabf01b3995eaa9be0f7a252c05e194b5b38be242"}],"licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/%40types/react@19.3.0","externalReferences":[{"url":"https://github.com/DefinitelyTyped/DefinitelyTyped.git#types/react","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""},{"url":"https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/react","type":"website","comment":"as detected from PackageJson property \"homepage\""}]},{"type":"library","name":"babel-plugin-react-compiler","version":"1.0.0","bom-ref":"pkg:npm/babel-plugin-react-compiler@1.0.0","description":"Babel plugin for React Compiler.","hashes":[{"alg":"SHA-512","content":"2319bcb457e828a20f61d0822984ecaaff85778209d0342a3321229a8fa9c5438c511f5c54f9704eb16df40beefb771be99a77980ce5fadd4cac6d9fc712acc7"}],"licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/babel-plugin-react-compiler@1.0.0","externalReferences":[{"url":"git+https://github.com/facebook/react.git#compiler/packages/babel-plugin-react-compiler","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""}]},{"type":"library","name":"happy-dom","version":"20.14.5","bom-ref":"pkg:npm/happy-dom@20.14.5","author":"David Ortner","description":"Happy DOM is a JavaScript implementation of a web browser without its graphical user interface. It includes many web standards from WHATWG DOM and HTML.","hashes":[{"alg":"SHA-512","content":"c7f47392958ee346d38c8a13df4890b6deb814b2e61ff89171408dd97fff6cbc7b1f789f91d7cf5f2aacae8fce62dab32008622cc300ee69a2391f42dcd38a8d"}],"licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/happy-dom@20.14.5","externalReferences":[{"url":"https://github.com/capricorn86/happy-dom","type":"vcs","comment":"as detected from PackageJson property \"repository\""},{"url":"https://github.com/capricorn86/happy-dom","type":"website","comment":"as detected from PackageJson property \"homepage\""}],"properties":[{"name":"cdx:npm:package:constraint:engine:node","value":">=20.0.0"}]},{"type":"library","name":"oxc-transform-react","version":"0.149.0","bom-ref":"pkg:npm/oxc-transform-react@0.149.0","author":"Boshen and oxc contributors","description":"Oxc React Compiler Node API","hashes":[{"alg":"SHA-512","content":"69bdddc5c3ed90349f211f6d35dc4752d9a974bd258479ddb010fd214014e41c6d26dc061bff39367473b367f62b0a2e3641e5edc692b3030b41e52fc3714447"}],"licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/oxc-transform-react@0.149.0","externalReferences":[{"url":"https://github.com/oxc-project/oxc/issues","type":"issue-tracker","comment":"as detected from PackageJson property \"bugs\""},{"url":"git+https://github.com/oxc-project/oxc.git#napi/transform-react","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""},{"url":"https://oxc.rs","type":"website","comment":"as detected from PackageJson property \"homepage\""}],"properties":[{"name":"cdx:npm:package:constraint:engine:node","value":"^20.19.0 || >=22.12.0"}]},{"type":"library","name":"react-dom","version":"19.3.0","bom-ref":"pkg:npm/react-dom@19.3.0","description":"React package for working with the DOM.","hashes":[{"alg":"SHA-512","content":"24393c76089fe753a31680c4ef4f8e4fd202c98afeebd1e59a284dc29d7e36c7db9dadede6c22209af59264b43990e3fd5bfeb9f6ea1200476b985c332be6bd1"}],"licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/react-dom@19.3.0","externalReferences":[{"url":"https://github.com/react/react/issues","type":"issue-tracker","comment":"as detected from PackageJson property \"bugs.url\""},{"url":"https://github.com/react/react.git#packages/react-dom","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""},{"url":"https://react.dev/","type":"website","comment":"as detected from PackageJson property \"homepage\""}]},{"type":"library","name":"react","version":"19.3.0","bom-ref":"pkg:npm/react@19.3.0","description":"React is a JavaScript library for building user interfaces.","hashes":[{"alg":"SHA-512","content":"13c2d471bb415addb46db9766281dfc7864305dc554df38ab42667f5c0d227897afe7ba8029729201723e3bb76c19a155fc836647b8c1db892860091d53e52a2"}],"licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/react@19.3.0","externalReferences":[{"url":"https://github.com/react/react/issues","type":"issue-tracker","comment":"as detected from PackageJson property \"bugs\""},{"url":"https://github.com/react/react.git#packages/react","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""},{"url":"https://react.dev/","type":"website","comment":"as detected from PackageJson property \"homepage\""}],"properties":[{"name":"cdx:npm:package:constraint:engine:node","value":">=0.10.0"}]},{"type":"library","name":"typescript","version":"7.0.2","bom-ref":"pkg:npm/typescript@7.0.2","author":"Microsoft Corp.","description":"TypeScript is a language for application scale JavaScript development","hashes":[{"alg":"SHA-512","content":"f0561abbdea8dcd28e85b8ca8bfa8dbc6fd6e63873c646dd9b9b23f406d9ff94f9b16aa7de12602df1b1dbbb11299593bf2cc23fc74b4414dfe6d05349155434"}],"licenses":[{"license":{"id":"Apache-2.0"}}],"purl":"pkg:npm/typescript@7.0.2","externalReferences":[{"url":"https://github.com/microsoft/TypeScript/issues","type":"issue-tracker","comment":"as detected from PackageJson property \"bugs.url\""},{"url":"https://github.com/microsoft/TypeScript.git","type":"vcs","comment":"as detected from PackageJson property \"repository.url\""},{"url":"https://www.typescriptlang.org/","type":"website","comment":"as detected from PackageJson property \"homepage\""}],"properties":[{"name":"cdx:npm:package:constraint:engine:node","value":">=16.20.0"}]},{"type":"library","name":"vitest","version":"4.1.11","bom-ref":"pkg:npm/vitest@4.1.11","author":"Anthony Fu <anthonyfu117@hotmail.com>","description":"Next generation testing framework powered by Vite","hashes":[{"alg":"SHA-512","content":"7e1002acd5d489d21b19206be4595bb8190eed5582d59c8b9740cee025360eb42800fc57f3862cc6cf877864298a2e656565754388016534eee3d985f80e8477"}],"licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/vitest@4.1.11","externalReferences":[{"url":"https://github.com/vitest-dev/vitest/issues","type":"issue-tracker","comment":"as detected from PackageJson property \"bugs.url\""},{"url":"git+https://github.com/vitest-dev/vitest.git#packages/vitest","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""},{"url":"https://vitest.dev","type":"website","comment":"as detected from PackageJson property \"homepage\""}],"properties":[{"name":"cdx:npm:package:constraint:engine:node","value":"^20.0.0 || ^22.0.0 || >=24.0.0"}]}]},"component":{"type":"library","name":"component-feedback","group":"@stealthscale","version":"0.1.0","bom-ref":"pkg:npm/%40stealthscale/component-feedback@0.1.0","description":"Draws the system reporting on itself: what is loading, what went wrong, what state a thing is in.","licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/%40stealthscale/component-feedback@0.1.0","externalReferences":[{"url":"https://github.com/stealth-scale/config/issues","type":"issue-tracker","comment":"as detected from PackageJson property \"bugs\""},{"url":"git+https://github.com/stealth-scale/config.git#components/feedback","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""},{"url":"https://github.com/stealth-scale/config/tree/main/components/feedback#readme","type":"website","comment":"as detected from PackageJson property \"homepage\""}],"properties":[{"name":"cdx:npm:package:constraint:engine:node","value":">=26.0.0"}],"evidence":{"licenses":[{"license":{"name":"file: LICENSE","text":{"content":"TUlUIExpY2Vuc2UKCkNvcHlyaWdodCAoYykgMjAyNiBTdGVhbHRoIFNjYWxlIEIuVi4KClBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHkKb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgIlNvZnR3YXJlIiksIHRvIGRlYWwKaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cwp0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsCmNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcwpmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOgoKVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW4gYWxsCmNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuCgpUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgIkFTIElTIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUgpJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSwKRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFCkFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVIKTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwKT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUKU09GVFdBUkUuCg==","contentType":"text/plain","encoding":"base64"}}}]}},"supplier":{"name":"Stealth Scale B.V.","url":["https://stealthscale.io"]}},"components":[],"dependencies":[{"ref":"pkg:npm/%40stealthscale/component-feedback@0.1.0"}]}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { ComponentProps, ReactElement } from "react";
|
|
2
|
+
//#region src/empty-state/content.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* Centres what it holds, in a column, at the gap its size states.
|
|
5
|
+
*/
|
|
6
|
+
declare const Content: import("@stealthscale/theme").StyledComponent<"div", {}>;
|
|
7
|
+
/**
|
|
8
|
+
* Describes what the content takes.
|
|
9
|
+
*/
|
|
10
|
+
type ContentProps = ComponentProps<typeof Content>;
|
|
11
|
+
//#endregion
|
|
12
|
+
//#region src/empty-state/description.d.ts
|
|
13
|
+
/**
|
|
14
|
+
* Draws the explanation, quieter than the title and at one size whatever the panel's is.
|
|
15
|
+
*/
|
|
16
|
+
declare const Description: import("@stealthscale/theme").StyledComponent<"p", {}>;
|
|
17
|
+
/**
|
|
18
|
+
* Describes what the description takes.
|
|
19
|
+
*/
|
|
20
|
+
type DescriptionProps = ComponentProps<typeof Description>;
|
|
21
|
+
//#endregion
|
|
22
|
+
//#region src/empty-state/indicator.d.ts
|
|
23
|
+
/**
|
|
24
|
+
* Draws the mark at the box its size states.
|
|
25
|
+
*/
|
|
26
|
+
declare const Indicator: import("@stealthscale/theme").StyledComponent<"div", {}>;
|
|
27
|
+
/**
|
|
28
|
+
* Describes what the indicator takes.
|
|
29
|
+
*/
|
|
30
|
+
type IndicatorProps = ComponentProps<typeof Indicator>;
|
|
31
|
+
//#endregion
|
|
32
|
+
//#region src/empty-state/root.d.ts
|
|
33
|
+
/**
|
|
34
|
+
* Draws the panel and sets the size every part below it reads.
|
|
35
|
+
*/
|
|
36
|
+
declare const Root: import("@stealthscale/theme").StyledComponent<"div", {
|
|
37
|
+
readonly size?: "2xl" | "3xl" | "4xl" | "lg" | "md" | "sm" | "xl" | "xs";
|
|
38
|
+
}>;
|
|
39
|
+
/**
|
|
40
|
+
* Describes what the panel takes.
|
|
41
|
+
*/
|
|
42
|
+
type RootProps = ComponentProps<typeof Root>;
|
|
43
|
+
//#endregion
|
|
44
|
+
//#region src/empty-state/title.d.ts
|
|
45
|
+
/**
|
|
46
|
+
* Draws the title at the size the panel states.
|
|
47
|
+
*/
|
|
48
|
+
declare const Title: import("@stealthscale/theme").StyledComponent<"h2", {}>;
|
|
49
|
+
/**
|
|
50
|
+
* Describes what the title takes.
|
|
51
|
+
*/
|
|
52
|
+
type TitleProps = ComponentProps<typeof Title>;
|
|
53
|
+
declare namespace index_d_exports {
|
|
54
|
+
export { Content, ContentProps, Description, DescriptionProps, Indicator, IndicatorProps, Root, RootProps, Title, TitleProps };
|
|
55
|
+
}
|
|
56
|
+
//#endregion
|
|
57
|
+
//#region src/skeleton-text/context.d.ts
|
|
58
|
+
/**
|
|
59
|
+
* Binds the skeleton paragraph's recipe to the element that draws it.
|
|
60
|
+
*
|
|
61
|
+
* @remarks
|
|
62
|
+
* Apart from the recipe, because an application's compiler reads the recipe at build time and
|
|
63
|
+
* the binding needs the runtime.
|
|
64
|
+
*/
|
|
65
|
+
/**
|
|
66
|
+
* Binds the recipe once, for the column the bars are drawn in.
|
|
67
|
+
*/
|
|
68
|
+
declare const PropsProvider$1: import("react").Provider<import("@stealthscale/theme").DataAttrs & Partial<{}>>, withContext$1: <Tag extends import("react").ElementType>(Component: Tag, options?: import("@stealthscale/theme").JsxFactoryOptions<import("@stealthscale/theme").ComponentProps<Tag> & Partial<{}>> | undefined) => import("@stealthscale/theme").StyledComponent<Tag, {}>;
|
|
69
|
+
//#endregion
|
|
70
|
+
//#region src/skeleton/skeleton.d.ts
|
|
71
|
+
/**
|
|
72
|
+
* Stands in for content that has not arrived, taking the box of whatever it wraps.
|
|
73
|
+
*/
|
|
74
|
+
export declare const Skeleton: import("@stealthscale/theme").StyledComponent<"div", {
|
|
75
|
+
readonly loading?: boolean;
|
|
76
|
+
readonly motion?: "none" | "pulse" | "shimmer";
|
|
77
|
+
readonly radius?: import("@stealthscale/theme/authoring").Corner;
|
|
78
|
+
}>;
|
|
79
|
+
/**
|
|
80
|
+
* Describes what a skeleton takes: the variants its recipe offers, and everything a styled div
|
|
81
|
+
* takes.
|
|
82
|
+
*/
|
|
83
|
+
type SkeletonProps = ComponentProps<typeof Skeleton>;
|
|
84
|
+
//#endregion
|
|
85
|
+
//#region src/skeleton-text/skeleton-text.d.ts
|
|
86
|
+
/**
|
|
87
|
+
* Draws the column the bars sit in.
|
|
88
|
+
*/
|
|
89
|
+
declare const Column: import("@stealthscale/theme").StyledComponent<"div", {}>;
|
|
90
|
+
/**
|
|
91
|
+
* Describes what a paragraph of skeleton takes.
|
|
92
|
+
*/
|
|
93
|
+
interface SkeletonTextProps extends ComponentProps<typeof Column> {
|
|
94
|
+
/**
|
|
95
|
+
* How many lines of text it stands in for.
|
|
96
|
+
*/
|
|
97
|
+
readonly lines?: number | undefined;
|
|
98
|
+
/**
|
|
99
|
+
* How each bar moves while it waits, which every bar takes together.
|
|
100
|
+
*/
|
|
101
|
+
readonly motion?: SkeletonProps["motion"] | undefined;
|
|
102
|
+
/**
|
|
103
|
+
* The corner each bar is drawn with.
|
|
104
|
+
*/
|
|
105
|
+
readonly radius?: SkeletonProps["radius"] | undefined;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Stands in for a paragraph of text that has not arrived.
|
|
109
|
+
*
|
|
110
|
+
* @param props - The column's own, plus the count and what each bar is drawn like.
|
|
111
|
+
* @returns The column, holding one bar per line.
|
|
112
|
+
*/
|
|
113
|
+
export declare function SkeletonText({ lines, motion, radius, ...rest }: SkeletonTextProps): ReactElement;
|
|
114
|
+
//#endregion
|
|
115
|
+
//#region src/skeleton/context.d.ts
|
|
116
|
+
/**
|
|
117
|
+
* Binds the skeleton's recipe to the element that draws it.
|
|
118
|
+
*
|
|
119
|
+
* @remarks
|
|
120
|
+
* Apart from the recipe, because an application's compiler reads the recipe at build time and
|
|
121
|
+
* the binding needs the runtime. A recipe file that also bound one would put the runtime behind
|
|
122
|
+
* every compiler configuration that reads it.
|
|
123
|
+
*/
|
|
124
|
+
/**
|
|
125
|
+
* Binds the recipe once, for the skeleton, for the lines a paragraph of them draws, and for
|
|
126
|
+
* whatever sets their variants from above.
|
|
127
|
+
*/
|
|
128
|
+
declare const PropsProvider: import("react").Provider<import("@stealthscale/theme").DataAttrs & Partial<{
|
|
129
|
+
readonly loading?: boolean;
|
|
130
|
+
readonly motion?: "none" | "pulse" | "shimmer";
|
|
131
|
+
readonly radius?: import("@stealthscale/theme/authoring").Corner;
|
|
132
|
+
}>>, withContext: <Tag extends import("react").ElementType>(Component: Tag, options?: import("@stealthscale/theme").JsxFactoryOptions<import("@stealthscale/theme").ComponentProps<Tag> & Partial<{
|
|
133
|
+
readonly loading?: boolean;
|
|
134
|
+
readonly motion?: "none" | "pulse" | "shimmer";
|
|
135
|
+
readonly radius?: import("@stealthscale/theme/authoring").Corner;
|
|
136
|
+
}>> | undefined) => import("@stealthscale/theme").StyledComponent<Tag, {
|
|
137
|
+
readonly loading?: boolean;
|
|
138
|
+
readonly motion?: "none" | "pulse" | "shimmer";
|
|
139
|
+
readonly radius?: import("@stealthscale/theme/authoring").Corner;
|
|
140
|
+
}>;
|
|
141
|
+
//#endregion
|
|
142
|
+
export { index_d_exports as EmptyState, type SkeletonProps, PropsProvider as SkeletonPropsProvider, type SkeletonTextProps, PropsProvider$1 as SkeletonTextPropsProvider };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
|
|
2
|
+
import { n as recipe$1, r as recipe, t as recipe$2 } from "./recipe-0Xo90j3-.js";
|
|
3
|
+
import "react";
|
|
4
|
+
import { createRecipeContext, createSlotRecipeContext } from "@stealthscale/theme";
|
|
5
|
+
import { c } from "react/compiler-runtime";
|
|
6
|
+
import { jsx } from "react/jsx-runtime";
|
|
7
|
+
//#region src/empty-state/context.ts
|
|
8
|
+
/**
|
|
9
|
+
* Binds the empty state's recipe to the elements that draw its parts.
|
|
10
|
+
*
|
|
11
|
+
* @remarks
|
|
12
|
+
* Apart from the recipe, because an application's compiler reads the recipe at build time and
|
|
13
|
+
* the binding needs the runtime.
|
|
14
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* Binds the recipe once. The root provides the variants and every other part reads them.
|
|
17
|
+
*/
|
|
18
|
+
const { withContext: withContext$2, withProvider } = createSlotRecipeContext(recipe);
|
|
19
|
+
//#endregion
|
|
20
|
+
//#region src/empty-state/content.ts
|
|
21
|
+
/**
|
|
22
|
+
* Centres what it holds, in a column, at the gap its size states.
|
|
23
|
+
*/
|
|
24
|
+
const Content = withContext$2("div", "content");
|
|
25
|
+
//#endregion
|
|
26
|
+
//#region src/empty-state/description.ts
|
|
27
|
+
/**
|
|
28
|
+
* Draws the explanation, quieter than the title and at one size whatever the panel's is.
|
|
29
|
+
*/
|
|
30
|
+
const Description = withContext$2("p", "description");
|
|
31
|
+
//#endregion
|
|
32
|
+
//#region src/empty-state/indicator.ts
|
|
33
|
+
/**
|
|
34
|
+
* Draws the mark at the box its size states.
|
|
35
|
+
*/
|
|
36
|
+
const Indicator = withContext$2("div", "indicator");
|
|
37
|
+
//#endregion
|
|
38
|
+
//#region src/empty-state/root.ts
|
|
39
|
+
/**
|
|
40
|
+
* Draws the panel and sets the size every part below it reads.
|
|
41
|
+
*/
|
|
42
|
+
const Root = withProvider("div", "root");
|
|
43
|
+
//#endregion
|
|
44
|
+
//#region src/empty-state/title.ts
|
|
45
|
+
/**
|
|
46
|
+
* Draws the title at the size the panel states.
|
|
47
|
+
*/
|
|
48
|
+
const Title = withContext$2("h2", "title");
|
|
49
|
+
//#endregion
|
|
50
|
+
//#region src/empty-state/index.ts
|
|
51
|
+
var empty_state_exports = /* @__PURE__ */ __exportAll({
|
|
52
|
+
Content: () => Content,
|
|
53
|
+
Description: () => Description,
|
|
54
|
+
Indicator: () => Indicator,
|
|
55
|
+
Root: () => Root,
|
|
56
|
+
Title: () => Title
|
|
57
|
+
});
|
|
58
|
+
//#endregion
|
|
59
|
+
//#region src/skeleton-text/context.ts
|
|
60
|
+
/**
|
|
61
|
+
* Binds the skeleton paragraph's recipe to the element that draws it.
|
|
62
|
+
*
|
|
63
|
+
* @remarks
|
|
64
|
+
* Apart from the recipe, because an application's compiler reads the recipe at build time and
|
|
65
|
+
* the binding needs the runtime.
|
|
66
|
+
*/
|
|
67
|
+
/**
|
|
68
|
+
* Binds the recipe once, for the column the bars are drawn in.
|
|
69
|
+
*/
|
|
70
|
+
const { PropsProvider: PropsProvider$1, withContext: withContext$1 } = createRecipeContext(recipe$1);
|
|
71
|
+
//#endregion
|
|
72
|
+
//#region src/skeleton/context.ts
|
|
73
|
+
/**
|
|
74
|
+
* Binds the skeleton's recipe to the element that draws it.
|
|
75
|
+
*
|
|
76
|
+
* @remarks
|
|
77
|
+
* Apart from the recipe, because an application's compiler reads the recipe at build time and
|
|
78
|
+
* the binding needs the runtime. A recipe file that also bound one would put the runtime behind
|
|
79
|
+
* every compiler configuration that reads it.
|
|
80
|
+
*/
|
|
81
|
+
/**
|
|
82
|
+
* Binds the recipe once, for the skeleton, for the lines a paragraph of them draws, and for
|
|
83
|
+
* whatever sets their variants from above.
|
|
84
|
+
*/
|
|
85
|
+
const { PropsProvider, withContext } = createRecipeContext(recipe$2);
|
|
86
|
+
//#endregion
|
|
87
|
+
//#region src/skeleton/skeleton.ts
|
|
88
|
+
/**
|
|
89
|
+
* Stands in for content that has not arrived, taking the box of whatever it wraps.
|
|
90
|
+
*/
|
|
91
|
+
const Skeleton = withContext("div");
|
|
92
|
+
//#endregion
|
|
93
|
+
//#region src/skeleton-text/skeleton-text.tsx
|
|
94
|
+
/**
|
|
95
|
+
* Draws the column the bars sit in.
|
|
96
|
+
*/
|
|
97
|
+
const Column = withContext$1("div");
|
|
98
|
+
/**
|
|
99
|
+
* Stands in for a paragraph of text that has not arrived.
|
|
100
|
+
*
|
|
101
|
+
* @param props - The column's own, plus the count and what each bar is drawn like.
|
|
102
|
+
* @returns The column, holding one bar per line.
|
|
103
|
+
*/
|
|
104
|
+
function SkeletonText(t0) {
|
|
105
|
+
const $ = c(21);
|
|
106
|
+
if ($[0] !== "3e498a8a62cfbdc6b1a8f49a0d7face7f241ed07bd456e29510103fe19bfc79d") {
|
|
107
|
+
for (let $i = 0; $i < 21; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
|
|
108
|
+
$[0] = "3e498a8a62cfbdc6b1a8f49a0d7face7f241ed07bd456e29510103fe19bfc79d";
|
|
109
|
+
}
|
|
110
|
+
let motion;
|
|
111
|
+
let radius;
|
|
112
|
+
let rest;
|
|
113
|
+
let t1;
|
|
114
|
+
if ($[1] !== t0) {
|
|
115
|
+
({lines: t1, motion, radius, ...rest} = t0);
|
|
116
|
+
$[1] = t0;
|
|
117
|
+
$[2] = motion;
|
|
118
|
+
$[3] = radius;
|
|
119
|
+
$[4] = rest;
|
|
120
|
+
$[5] = t1;
|
|
121
|
+
} else {
|
|
122
|
+
motion = $[2];
|
|
123
|
+
radius = $[3];
|
|
124
|
+
rest = $[4];
|
|
125
|
+
t1 = $[5];
|
|
126
|
+
}
|
|
127
|
+
const lines = t1 === void 0 ? 3 : t1;
|
|
128
|
+
let t2;
|
|
129
|
+
if ($[6] !== motion) {
|
|
130
|
+
t2 = motion === void 0 ? {} : { motion };
|
|
131
|
+
$[6] = motion;
|
|
132
|
+
$[7] = t2;
|
|
133
|
+
} else t2 = $[7];
|
|
134
|
+
let t3;
|
|
135
|
+
if ($[8] !== radius) {
|
|
136
|
+
t3 = radius === void 0 ? {} : { radius };
|
|
137
|
+
$[8] = radius;
|
|
138
|
+
$[9] = t3;
|
|
139
|
+
} else t3 = $[9];
|
|
140
|
+
let t4;
|
|
141
|
+
if ($[10] !== t2 || $[11] !== t3) {
|
|
142
|
+
t4 = {
|
|
143
|
+
...t2,
|
|
144
|
+
...t3
|
|
145
|
+
};
|
|
146
|
+
$[10] = t2;
|
|
147
|
+
$[11] = t3;
|
|
148
|
+
$[12] = t4;
|
|
149
|
+
} else t4 = $[12];
|
|
150
|
+
const drawn = t4;
|
|
151
|
+
let t5;
|
|
152
|
+
if ($[13] !== drawn || $[14] !== lines) {
|
|
153
|
+
let t6;
|
|
154
|
+
if ($[16] !== drawn) {
|
|
155
|
+
t6 = (_, at) => /* @__PURE__ */ jsx(Skeleton, { ...drawn }, at);
|
|
156
|
+
$[16] = drawn;
|
|
157
|
+
$[17] = t6;
|
|
158
|
+
} else t6 = $[17];
|
|
159
|
+
t5 = Array.from({ length: Math.max(lines, 1) }, t6);
|
|
160
|
+
$[13] = drawn;
|
|
161
|
+
$[14] = lines;
|
|
162
|
+
$[15] = t5;
|
|
163
|
+
} else t5 = $[15];
|
|
164
|
+
let t6;
|
|
165
|
+
if ($[18] !== rest || $[19] !== t5) {
|
|
166
|
+
t6 = /* @__PURE__ */ jsx(Column, {
|
|
167
|
+
...rest,
|
|
168
|
+
children: t5
|
|
169
|
+
});
|
|
170
|
+
$[18] = rest;
|
|
171
|
+
$[19] = t5;
|
|
172
|
+
$[20] = t6;
|
|
173
|
+
} else t6 = $[20];
|
|
174
|
+
return t6;
|
|
175
|
+
}
|
|
176
|
+
//#endregion
|
|
177
|
+
export { empty_state_exports as EmptyState, Skeleton, PropsProvider as SkeletonPropsProvider, SkeletonText, PropsProvider$1 as SkeletonTextPropsProvider };
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import { cornerVariants, defineRecipe, defineSlotRecipe, gapSizes, iconSizes, insetSizes, onSlots, textSizes } from "@stealthscale/theme/authoring";
|
|
2
|
+
//#region src/empty-state/recipe.ts
|
|
3
|
+
/**
|
|
4
|
+
* States what an empty state is: the panel a page draws where there is nothing to show, holding a
|
|
5
|
+
* mark, a heading and a line saying what would be here.
|
|
6
|
+
*
|
|
7
|
+
* @remarks
|
|
8
|
+
* Five parts, because each is styled and a caller composes them in whatever order a page wants.
|
|
9
|
+
* The root is the panel, the content centres what is inside it, the indicator draws the mark, and
|
|
10
|
+
* the title and the description carry the words.
|
|
11
|
+
* One axis moves all of them together. The room inside the panel, the gap in the content, the box
|
|
12
|
+
* of the mark and the size of the title each read the scale of the same name, so a small empty
|
|
13
|
+
* state in a side panel and a large one filling a page are one name apart. The description holds
|
|
14
|
+
* its size, because a line of explanation is read at the size the rest of the page is read at
|
|
15
|
+
* however big the panel is.
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* Draws a centred panel at the middle size until a caller says otherwise.
|
|
19
|
+
*/
|
|
20
|
+
const recipe$2 = defineSlotRecipe({
|
|
21
|
+
base: {
|
|
22
|
+
content: {
|
|
23
|
+
alignItems: "center",
|
|
24
|
+
display: "flex",
|
|
25
|
+
flexDirection: "column",
|
|
26
|
+
justifyContent: "center",
|
|
27
|
+
textAlign: "center"
|
|
28
|
+
},
|
|
29
|
+
description: {
|
|
30
|
+
color: "fg.muted",
|
|
31
|
+
textStyle: "body.sm"
|
|
32
|
+
},
|
|
33
|
+
indicator: {
|
|
34
|
+
"& svg": { boxSize: "100%" },
|
|
35
|
+
alignItems: "center",
|
|
36
|
+
color: "fg.muted",
|
|
37
|
+
display: "flex",
|
|
38
|
+
justifyContent: "center"
|
|
39
|
+
},
|
|
40
|
+
root: {
|
|
41
|
+
alignItems: "center",
|
|
42
|
+
display: "flex",
|
|
43
|
+
justifyContent: "center",
|
|
44
|
+
width: "full"
|
|
45
|
+
},
|
|
46
|
+
title: { fontWeight: "semibold" }
|
|
47
|
+
},
|
|
48
|
+
className: "empty-state",
|
|
49
|
+
defaultVariants: { size: "md" },
|
|
50
|
+
jsx: [/^EmptyState(\.\w+)?$/u],
|
|
51
|
+
slots: [
|
|
52
|
+
"root",
|
|
53
|
+
"content",
|
|
54
|
+
"indicator",
|
|
55
|
+
"title",
|
|
56
|
+
"description"
|
|
57
|
+
],
|
|
58
|
+
variants: {
|
|
59
|
+
/**
|
|
60
|
+
* How much room the panel takes, which every part steps with.
|
|
61
|
+
*/
|
|
62
|
+
size: onSlots({
|
|
63
|
+
content: gapSizes(),
|
|
64
|
+
indicator: iconSizes(),
|
|
65
|
+
root: insetSizes(),
|
|
66
|
+
title: textSizes("heading")
|
|
67
|
+
}) }
|
|
68
|
+
});
|
|
69
|
+
//#endregion
|
|
70
|
+
//#region src/skeleton-text/recipe.ts
|
|
71
|
+
/**
|
|
72
|
+
* States what a paragraph of skeleton is: a column of bars standing in for lines of text that have
|
|
73
|
+
* not arrived.
|
|
74
|
+
*
|
|
75
|
+
* @remarks
|
|
76
|
+
* Every length here is read off the line the bars stand in for. A bar is one line tall and the
|
|
77
|
+
* space between two is half a line, so a column of stand-ins occupies what the real paragraph
|
|
78
|
+
* will occupy and the page does not jump when the words land. Nothing states a size of its own,
|
|
79
|
+
* which is what lets a caller drop a paragraph of stand-ins wherever text is read and have it
|
|
80
|
+
* come out the size of that text.
|
|
81
|
+
* The last bar of several is short. A paragraph rarely fills its final line, and a block of bars
|
|
82
|
+
* all the same width reads as a table rather than as prose.
|
|
83
|
+
*/
|
|
84
|
+
/**
|
|
85
|
+
* Draws a column of bars, each the height of the line it stands in for.
|
|
86
|
+
*/
|
|
87
|
+
const recipe$1 = defineRecipe({
|
|
88
|
+
base: {
|
|
89
|
+
"& > *": { height: "1lh" },
|
|
90
|
+
"& > *:last-child:not(:only-child)": { maxWidth: "80%" },
|
|
91
|
+
display: "flex",
|
|
92
|
+
flexDirection: "column",
|
|
93
|
+
gap: "0.5lh",
|
|
94
|
+
width: "full"
|
|
95
|
+
},
|
|
96
|
+
className: "skeleton-text",
|
|
97
|
+
jsx: [/^SkeletonText$/u]
|
|
98
|
+
});
|
|
99
|
+
//#endregion
|
|
100
|
+
//#region src/skeleton/recipe.ts
|
|
101
|
+
/**
|
|
102
|
+
* States what a skeleton is: a box standing in for content that has not arrived, drawn in one of
|
|
103
|
+
* the theme's own motions and revealed once the content does.
|
|
104
|
+
*
|
|
105
|
+
* @remarks
|
|
106
|
+
* A skeleton wraps the content it stands in for rather than replacing it, so a caller writes one
|
|
107
|
+
* tree and flips one prop. While it is loading it takes the content's own box and hides
|
|
108
|
+
* everything inside it, which is what makes the stand-in the size of the thing it stands in for
|
|
109
|
+
* without anybody stating a width. Once it has loaded it fades the content in and gets out of
|
|
110
|
+
* the way.
|
|
111
|
+
* Every motion is an animation style the theme owns, so a reader who asked for less motion is
|
|
112
|
+
* answered once in the theme rather than in every recipe. Nothing here states a colour, a length
|
|
113
|
+
* or a duration of its own.
|
|
114
|
+
*/
|
|
115
|
+
/**
|
|
116
|
+
* Draws a pulsing stand-in at the middle corner until a caller says otherwise.
|
|
117
|
+
*/
|
|
118
|
+
const recipe = defineRecipe({
|
|
119
|
+
base: {},
|
|
120
|
+
className: "skeleton",
|
|
121
|
+
defaultVariants: {
|
|
122
|
+
loading: true,
|
|
123
|
+
motion: "pulse",
|
|
124
|
+
radius: "l2"
|
|
125
|
+
},
|
|
126
|
+
jsx: [/^Skeleton$/u],
|
|
127
|
+
variants: {
|
|
128
|
+
/**
|
|
129
|
+
* Whether the content it stands in for has arrived.
|
|
130
|
+
*/
|
|
131
|
+
loading: {
|
|
132
|
+
false: { animationStyle: "fade.in" },
|
|
133
|
+
true: {
|
|
134
|
+
"&::before, &::after, *": { visibility: "hidden" },
|
|
135
|
+
backgroundClip: "padding-box",
|
|
136
|
+
boxShadow: "none",
|
|
137
|
+
color: "transparent",
|
|
138
|
+
flexShrink: "0",
|
|
139
|
+
pointerEvents: "none",
|
|
140
|
+
userSelect: "none"
|
|
141
|
+
}
|
|
142
|
+
},
|
|
143
|
+
/**
|
|
144
|
+
* How it moves while it waits.
|
|
145
|
+
*/
|
|
146
|
+
motion: {
|
|
147
|
+
none: { animation: "none" },
|
|
148
|
+
pulse: {
|
|
149
|
+
animationStyle: "pulse",
|
|
150
|
+
background: "bg.emphasized"
|
|
151
|
+
},
|
|
152
|
+
shimmer: {
|
|
153
|
+
animationStyle: "shimmer",
|
|
154
|
+
backgroundImage: "linear-gradient(270deg, {colors.bg.muted}, {colors.bg.emphasized})",
|
|
155
|
+
backgroundSize: "400% 100%"
|
|
156
|
+
}
|
|
157
|
+
},
|
|
158
|
+
radius: cornerVariants()
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
//#endregion
|
|
162
|
+
export { recipe$1 as n, recipe$2 as r, recipe as t };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
//#region \0rolldown/runtime.js
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __exportAll = (all, no_symbols) => {
|
|
4
|
+
let target = {};
|
|
5
|
+
for (var name in all) __defProp(target, name, {
|
|
6
|
+
get: all[name],
|
|
7
|
+
enumerable: true
|
|
8
|
+
});
|
|
9
|
+
if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
|
|
10
|
+
return target;
|
|
11
|
+
};
|
|
12
|
+
//#endregion
|
|
13
|
+
export { __exportAll as t };
|
package/dist/theme.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
//#region src/theme.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Publishes the preset that registers every recipe in this package, for an application's compiler
|
|
4
|
+
* to install.
|
|
5
|
+
*
|
|
6
|
+
* @remarks
|
|
7
|
+
* The list is written by hand. The package's own specification reports a recipe file the list
|
|
8
|
+
* leaves out, so no generator runs here.
|
|
9
|
+
*/
|
|
10
|
+
declare const _default: import("@stealthscale/theme/authoring").Preset;
|
|
11
|
+
//#endregion
|
|
12
|
+
export { _default as default };
|
package/dist/theme.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { n as recipe$1, r as recipe$2, t as recipe } from "./recipe-0Xo90j3-.js";
|
|
2
|
+
import { definePreset } from "@stealthscale/theme/authoring";
|
|
3
|
+
//#region src/theme.ts
|
|
4
|
+
/**
|
|
5
|
+
* Publishes the preset that registers every recipe in this package, for an application's compiler
|
|
6
|
+
* to install.
|
|
7
|
+
*
|
|
8
|
+
* @remarks
|
|
9
|
+
* The list is written by hand. The package's own specification reports a recipe file the list
|
|
10
|
+
* leaves out, so no generator runs here.
|
|
11
|
+
*/
|
|
12
|
+
var theme_default = definePreset({
|
|
13
|
+
name: "@stealthscale/component-feedback",
|
|
14
|
+
theme: { extend: {
|
|
15
|
+
recipes: {
|
|
16
|
+
skeleton: recipe,
|
|
17
|
+
skeletonText: recipe$1
|
|
18
|
+
},
|
|
19
|
+
slotRecipes: { emptyState: recipe$2 }
|
|
20
|
+
} }
|
|
21
|
+
});
|
|
22
|
+
//#endregion
|
|
23
|
+
export { theme_default as default };
|
package/package.json
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@stealthscale/component-feedback",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Draws the system reporting on itself: what is loading, what went wrong, what state a thing is in.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"components",
|
|
7
|
+
"feedback",
|
|
8
|
+
"react",
|
|
9
|
+
"status"
|
|
10
|
+
],
|
|
11
|
+
"homepage": "https://github.com/stealth-scale/config/tree/main/components/feedback#readme",
|
|
12
|
+
"bugs": "https://github.com/stealth-scale/config/issues",
|
|
13
|
+
"license": "MIT",
|
|
14
|
+
"repository": {
|
|
15
|
+
"type": "git",
|
|
16
|
+
"url": "git+https://github.com/stealth-scale/config.git",
|
|
17
|
+
"directory": "components/feedback"
|
|
18
|
+
},
|
|
19
|
+
"files": [
|
|
20
|
+
"dist",
|
|
21
|
+
"LICENSE",
|
|
22
|
+
"README.md"
|
|
23
|
+
],
|
|
24
|
+
"type": "module",
|
|
25
|
+
"sideEffects": false,
|
|
26
|
+
"imports": {
|
|
27
|
+
"#*": "./src/*"
|
|
28
|
+
},
|
|
29
|
+
"exports": {
|
|
30
|
+
".": "./dist/index.js",
|
|
31
|
+
"./theme": "./dist/theme.js",
|
|
32
|
+
"./package.json": "./package.json"
|
|
33
|
+
},
|
|
34
|
+
"publishConfig": {
|
|
35
|
+
"access": "public"
|
|
36
|
+
},
|
|
37
|
+
"devDependencies": {
|
|
38
|
+
"@arethetypeswrong/core": "^0.18.5",
|
|
39
|
+
"@rolldown/plugin-babel": "^0.2.4",
|
|
40
|
+
"@stealthscale/theme": "^0.3.0",
|
|
41
|
+
"@stealthscale/vite-config": "^0.6.0",
|
|
42
|
+
"@stealthscale/vite-config-react": "^0.8.0",
|
|
43
|
+
"@stealthscale/vite-config-theme": "^0.1.0",
|
|
44
|
+
"@stealthscale/vite-config-typescript": "^0.3.0",
|
|
45
|
+
"@testing-library/react": "^16.3.0",
|
|
46
|
+
"@types/react": "^19.3.0",
|
|
47
|
+
"@types/react-dom": "^19.3.0",
|
|
48
|
+
"babel-plugin-react-compiler": "^1.0.0",
|
|
49
|
+
"happy-dom": "^20.14.3",
|
|
50
|
+
"oxc-transform-react": "^0.149.0",
|
|
51
|
+
"publint": "^0.3.24",
|
|
52
|
+
"react": "^19.3.0",
|
|
53
|
+
"react-dom": "^19.3.0",
|
|
54
|
+
"typescript": "^7.0.2",
|
|
55
|
+
"vitest": "4.1.11"
|
|
56
|
+
},
|
|
57
|
+
"peerDependencies": {
|
|
58
|
+
"@stealthscale/theme": "^0.3.0",
|
|
59
|
+
"react": "^19.3.0"
|
|
60
|
+
},
|
|
61
|
+
"engines": {
|
|
62
|
+
"node": ">=26.0.0"
|
|
63
|
+
},
|
|
64
|
+
"scripts": {
|
|
65
|
+
"build": "vp pack",
|
|
66
|
+
"check": "vp check",
|
|
67
|
+
"test": "vp test"
|
|
68
|
+
}
|
|
69
|
+
}
|