timvir 0.2.51 → 0.2.52

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/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # timvir
2
2
 
3
+ ## 0.2.52
4
+
5
+ ### Patch Changes
6
+
7
+ - **Mark sub-path imports of dependencies as external** ([#3783](https://github.com/timvir/timvir/pull/3783)) - Due to a mistake in our Rollup config, we were inlining the `bytestring` package into our code. The `bytestring` package is declared as dependency and should be kept external. This change slightly decreases the bundle size of the `timvir/blocks/Arbitrary` module.
8
+
3
9
  ## 0.2.51
4
10
 
5
11
  ### Patch Changes
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Tomáś Čarnecký
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.
@@ -3,22 +3,31 @@ import { Exhibit } from "timvir/blocks";
3
3
 
4
4
  # Arbitrary
5
5
 
6
- The `<Arbitrary>` component manages a React context that contains a seed. This seed is displayed
7
- in an input field where users can copy it from.
8
-
9
- The component renders its children in an `<Exhibit>`. The children can make use of the seed in the
10
- React context to render themselves in a predictable way.
6
+ > Renders children with a controllable random seed exposed via React context.
11
7
 
12
8
  <Sample variant="basic" />
13
9
 
10
+ Use `<Arbitrary>` when you want to feed randomly generated props into a component.
11
+ This is particularly useful for exploring edge cases or stress-testing a component's appearance without hand-authoring every combination.
12
+ The block exposes a numeric seed via React context, so children can produce a stable, reproducible set of inputs for any given seed value.
13
+
14
+ Libraries like [fast-check](https://fast-check.dev) provide composable random value generators.
15
+ They provide generators for all basic types such as strings, numbers, arrays, and objects.
16
+ You can combine those builtin generators to produce random values for your own types.
17
+
18
+ ## Features
19
+
20
+ The seed is displayed in an input field where users can copy it or set a specific value.
21
+ Children can consume it to render themselves in a predictable, reproducible way.
22
+
14
23
  ## Usage
15
24
 
16
25
  Given a component-under-test:
17
26
 
18
27
  ```jsx
19
- import { useContext } from "timvir/blocks/Arbitrary"
28
+ import { useContext } from "timvir/blocks/Arbitrary";
20
29
 
21
- function Component() {
30
+ function Sample() {
22
31
  const { seed } = useContext();
23
32
  return <div>{seed}</div>;
24
33
  }
@@ -26,11 +35,49 @@ function Component() {
26
35
 
27
36
  We can take it and display it inside an `<Arbitrary>` in a timvir doc page:
28
37
 
29
- ```jsx
30
- import { Arbitrary } from "timvir/blocks"
31
- import { Component } from ".."
38
+ ```tsx
39
+ import { Arbitrary } from "timvir/blocks";
40
+ import { Component } from "../Component";
32
41
 
33
42
  <Arbitrary>
34
43
  <Component />
35
44
  </Arbitrary>
36
45
  ```
46
+
47
+ ## fast-check
48
+
49
+ Let's assume you have a component that takes this Props shape.
50
+
51
+ ```ts
52
+ interface Props {
53
+ enabled: boolean;
54
+ label: string;
55
+ }
56
+
57
+ export function Component(props: Props) {
58
+ // React component implementation
59
+ }
60
+ ```
61
+
62
+ First define a generator that produces values of that type.
63
+ Then use the seed from the Arbitrary context to generate props for your component.
64
+
65
+ ```tsx
66
+ import fc from "fast-check";
67
+ import { useContext } from "timvir/blocks/Arbitrary";
68
+ import { Component } from "../Component";
69
+
70
+ const arbProps = fc.object({
71
+ enabled: fc.boolean(),
72
+ label: fc.string(),
73
+ });
74
+
75
+ function Sample() {
76
+ const { seed } = useContext();
77
+
78
+ const engine = new fc.Random(fc.xoroshiro128plus(seed));
79
+ const props = arbProps.generate(engine, undefined);
80
+
81
+ return <Component {...props} />;
82
+ }
83
+ ```
@@ -1,4 +1,5 @@
1
1
  'use client';
2
+ import * as base58 from 'bytestring/base58';
2
3
  import * as React from 'react';
3
4
  import { Exhibit } from 'timvir/blocks';
4
5
  import { useBlock } from 'timvir/core';
@@ -166,62 +167,6 @@ function props(...styles) {
166
167
  return result;
167
168
  }
168
169
 
169
- const bytesToHex = (() => {
170
- const s = Array.from({
171
- length: 256
172
- }).map((_, i) => i.toString(16).padStart(2, "0"));
173
- return uint8a => [...uint8a].map(o => s[o]).join("");
174
- })();
175
- const alphabet = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
176
- function encode(input) {
177
- if (input.length === 0) {
178
- return "";
179
- }
180
- // Uint8Array -> BigInt (Big Endian)
181
- let x = BigInt("0x" + bytesToHex(input));
182
- const output = [];
183
- while (x > 0n) {
184
- const mod = x % 58n;
185
- x = x / 58n;
186
- output.push(alphabet[Number(mod)]);
187
- }
188
- for (let i = 0; input[i] === 0; i++) {
189
- output.push(alphabet[0]);
190
- }
191
- return output.reverse().join("");
192
- }
193
- function decode(output) {
194
- if (output.length === 0) {
195
- return new Uint8Array();
196
- }
197
- const bytes = [0];
198
- const letters = alphabet;
199
- for (const char of output) {
200
- const value = letters.indexOf(char);
201
- if (value === undefined) {
202
- throw new Error(`base58.decode received invalid input. Character '${char}' is not in the base58 alphabet.`);
203
- }
204
- for (let j = 0; j < bytes.length; j++) {
205
- bytes[j] *= 58;
206
- }
207
- bytes[0] += value;
208
- let carry = 0;
209
- for (let j = 0; j < bytes.length; j++) {
210
- bytes[j] += carry;
211
- carry = bytes[j] >> 8;
212
- bytes[j] &= 0xff;
213
- }
214
- while (carry > 0) {
215
- bytes.push(carry & 0xff);
216
- carry >>= 8;
217
- }
218
- }
219
- for (let i = 0; i < output.length - 1 && output[i] === "1"; i++) {
220
- bytes.push(0);
221
- }
222
- return new Uint8Array(bytes.reverse());
223
- }
224
-
225
170
  const layoutStyles = {
226
171
  block: {
227
172
  kBCFzs: "timvir-s-htle6",
@@ -245,13 +190,16 @@ function Arbitrary(props$1) {
245
190
  ...rest
246
191
  } = block.props;
247
192
  const [value, setValue] = React.useState({
193
+ settled: false,
248
194
  seed: 0
249
195
  });
250
- React.useEffect(() => {
196
+ const refreshSeed = React.useCallback(() => {
251
197
  setValue({
198
+ settled: true,
252
199
  seed: crypto.getRandomValues(new Uint32Array(1))[0]
253
200
  });
254
201
  }, []);
202
+ React.useEffect(refreshSeed, [refreshSeed]);
255
203
  React.useEffect(() => {
256
204
  if (props$1.id) {
257
205
  block.bus.next({
@@ -265,12 +213,14 @@ function Arbitrary(props$1) {
265
213
  }, [props$1.id, block.bus, value.seed]);
266
214
  const rootStyleProps = props(layoutStyles.block, styles.root);
267
215
  return /*#__PURE__*/jsx(Context, {
268
- value: value,
216
+ value: React.useMemo(() => ({
217
+ seed: value.seed
218
+ }), [value.seed]),
269
219
  children: /*#__PURE__*/jsxs(Root, {
270
220
  "data-timvir-b-arbitrary": true,
271
221
  ...rest,
272
222
  ...rootStyleProps,
273
- className: cx(rootStyleProps.className, className),
223
+ className: cx(!value.settled && "timvir-unsettled", rootStyleProps.className, className),
274
224
  style: {
275
225
  margin: "1em 0",
276
226
  ...rootStyleProps.style,
@@ -287,12 +237,13 @@ function Arbitrary(props$1) {
287
237
  "data-timvir-b-arbitrary-seed": true,
288
238
  className: "timvir-s-c342km timvir-s-1a2a7pz timvir-s-ln7xf2 timvir-s-jbqb8w timvir-s-kh2ocl timvir-s-1717udv timvir-s-h8yej3 timvir-s-1heor9g",
289
239
  placeholder: "Seed",
290
- value: encode(new TextEncoder().encode(`${value.seed}`)),
240
+ value: base58.encode(new TextEncoder().encode(`${value.seed}`)),
291
241
  readOnly: true,
292
242
  onPaste: ev => {
293
243
  const v = ev.clipboardData.getData("text/plain");
294
244
  setValue({
295
- seed: +new TextDecoder().decode(decode(v))
245
+ settled: true,
246
+ seed: +new TextDecoder().decode(base58.decode(v))
296
247
  });
297
248
  },
298
249
  onFocus: ev => {
@@ -302,11 +253,7 @@ function Arbitrary(props$1) {
302
253
  }), /*#__PURE__*/jsx("button", {
303
254
  type: "button",
304
255
  className: "timvir-s-1a2a7pz timvir-s-u0aao5 timvir-s-mkeg23 timvir-s-1y0btm7 timvir-s-j7gikm timvir-s-1cum3z5 timvir-s-1d0dlzq timvir-s-1cdhzux timvir-s-ln7xf2 timvir-s-49kzi4 timvir-s-1dc5b4e timvir-s-13m658e timvir-s-1bx2y69",
305
- onClick: () => {
306
- setValue({
307
- seed: crypto.getRandomValues(new Uint32Array(1))[0]
308
- });
309
- },
256
+ onClick: refreshSeed,
310
257
  children: "Refresh"
311
258
  })]
312
259
  }), /*#__PURE__*/jsx(Exhibit, {
@@ -77,7 +77,7 @@
77
77
  outline: none;
78
78
  }
79
79
 
80
- .timvir-s-hqgf4x:hover:after, .timvir-s-1o0ppuw:focus-within:after, .timvir-s-49kzi4:hover, .timvir-s-13m658e:active {
80
+ .timvir-s-49kzi4:hover, .timvir-s-13m658e:active {
81
81
  border-color: var(--timvir-text-color);
82
82
  }
83
83
  }
@@ -127,8 +127,8 @@
127
127
  grid-auto-rows: min-content;
128
128
  }
129
129
 
130
- .timvir-s-12c0rpe {
131
- grid-template-columns: [le] var(--timvir-page-margin) [lex lc] 1fr[rc rex] var(--timvir-page-margin) [re];
130
+ .timvir-s-1u7e2r6 {
131
+ grid-template-columns: [le]var(--timvir-page-margin)[lex lc]1fr[rc rex]var(--timvir-page-margin)[re];
132
132
  }
133
133
 
134
134
  .timvir-s-9flyx0 {
@@ -148,14 +148,14 @@
148
148
  }
149
149
 
150
150
  @media (width >= 72rem) {
151
- .timvir-s-1mxrek7.timvir-s-1mxrek7 {
152
- grid-template-columns: [le] 1fr var(--timvir-page-margin) [lex] minmax(0, 12rem) [lc] 48rem[rc] minmax(0, 12rem) [rex] var(--timvir-page-margin) 1fr[re];
151
+ .timvir-s-5diife.timvir-s-5diife {
152
+ grid-template-columns: [le]1fr var(--timvir-page-margin)[lex]minmax(0,12rem)[lc]48rem[rc]minmax(0,12rem)[rex]var(--timvir-page-margin) 1fr[re];
153
153
  }
154
154
  }
155
155
 
156
156
  @media (width >= 48rem) {
157
- .timvir-s-9q0i6z.timvir-s-9q0i6z {
158
- grid-template-columns: [le] var(--timvir-page-margin) [lex] 1fr[lc] minmax(0, 48rem) [rc] 1fr[rex] var(--timvir-page-margin) [re];
157
+ .timvir-s-1s3i72i.timvir-s-1s3i72i {
158
+ grid-template-columns: [le]var(--timvir-page-margin)[lex]1fr[lc]minmax(0,48rem)[rc]1fr[rex]var(--timvir-page-margin)[re];
159
159
  }
160
160
  }
161
161
  }
@@ -204,6 +204,10 @@
204
204
  .timvir-s-5hscyn:after {
205
205
  border-width: 1px;
206
206
  }
207
+
208
+ .timvir-s-1o0ppuw:focus-within:after, .timvir-s-hqgf4x:hover:after {
209
+ border-color: var(--timvir-text-color);
210
+ }
207
211
  }
208
212
 
209
213
  @layer priority8 {
@@ -3,7 +3,7 @@ import { Exhibit } from "../../Exhibit";
3
3
 
4
4
  # Code
5
5
 
6
- The `<Code>` component provides syntax highlighting for code blocks.
6
+ > Syntax highlighting for code blocks.
7
7
 
8
8
  The component supports many different languages such as
9
9
  <Sample variant="toggle" language="javascript">JavaScript</Sample>,
@@ -4,7 +4,7 @@
4
4
  }
5
5
 
6
6
  .timvir-s-idmeni {
7
- --timvir-b-Code-inlinePadding: max(var(--timvir-b-Code-bleed), 8px);
7
+ --timvir-b-Code-inlinePadding: max(var(--timvir-b-Code-bleed),8px);
8
8
  }
9
9
 
10
10
  .timvir-s-1f9b50e {
@@ -28,7 +28,7 @@
28
28
  }
29
29
 
30
30
  .timvir-s-1etwjqo {
31
- margin: 0 calc(-1 * var(--timvir-b-Code-bleed));
31
+ margin: 0 calc(-1*var(--timvir-b-Code-bleed));
32
32
  }
33
33
 
34
34
  .timvir-s-1ghz6dp {
@@ -119,8 +119,8 @@
119
119
  grid-auto-rows: min-content;
120
120
  }
121
121
 
122
- .timvir-s-12c0rpe {
123
- grid-template-columns: [le] var(--timvir-page-margin) [lex lc] 1fr[rc rex] var(--timvir-page-margin) [re];
122
+ .timvir-s-1u7e2r6 {
123
+ grid-template-columns: [le]var(--timvir-page-margin)[lex lc]1fr[rc rex]var(--timvir-page-margin)[re];
124
124
  }
125
125
 
126
126
  .timvir-s-jkpybl {
@@ -128,14 +128,14 @@
128
128
  }
129
129
 
130
130
  @media (width >= 72rem) {
131
- .timvir-s-1mxrek7.timvir-s-1mxrek7 {
132
- grid-template-columns: [le] 1fr var(--timvir-page-margin) [lex] minmax(0, 12rem) [lc] 48rem[rc] minmax(0, 12rem) [rex] var(--timvir-page-margin) 1fr[re];
131
+ .timvir-s-5diife.timvir-s-5diife {
132
+ grid-template-columns: [le]1fr var(--timvir-page-margin)[lex]minmax(0,12rem)[lc]48rem[rc]minmax(0,12rem)[rex]var(--timvir-page-margin) 1fr[re];
133
133
  }
134
134
  }
135
135
 
136
136
  @media (width >= 48rem) {
137
- .timvir-s-9q0i6z.timvir-s-9q0i6z {
138
- grid-template-columns: [le] var(--timvir-page-margin) [lex] 1fr[lc] minmax(0, 48rem) [rc] 1fr[rex] var(--timvir-page-margin) [re];
137
+ .timvir-s-1s3i72i.timvir-s-1s3i72i {
138
+ grid-template-columns: [le]var(--timvir-page-margin)[lex]1fr[lc]minmax(0,48rem)[rc]1fr[rex]var(--timvir-page-margin)[re];
139
139
  }
140
140
  }
141
141
  }
@@ -3,7 +3,7 @@ import { Code, Exhibit } from "timvir/blocks";
3
3
 
4
4
  # ColorBar
5
5
 
6
- A `ColorBar` is a horizontal arrangement of swatches.
6
+ > A horizontal arrangement of color swatches.
7
7
 
8
8
  <Sample variant="basic" />
9
9
 
@@ -91,8 +91,8 @@
91
91
  grid-auto-rows: min-content;
92
92
  }
93
93
 
94
- .timvir-s-12c0rpe {
95
- grid-template-columns: [le] var(--timvir-page-margin) [lex lc] 1fr[rc rex] var(--timvir-page-margin) [re];
94
+ .timvir-s-1u7e2r6 {
95
+ grid-template-columns: [le]var(--timvir-page-margin)[lex lc]1fr[rc rex]var(--timvir-page-margin)[re];
96
96
  }
97
97
 
98
98
  .timvir-s-dz4c1r {
@@ -124,14 +124,14 @@
124
124
  }
125
125
 
126
126
  @media (width >= 72rem) {
127
- .timvir-s-1mxrek7.timvir-s-1mxrek7 {
128
- grid-template-columns: [le] 1fr var(--timvir-page-margin) [lex] minmax(0, 12rem) [lc] 48rem[rc] minmax(0, 12rem) [rex] var(--timvir-page-margin) 1fr[re];
127
+ .timvir-s-5diife.timvir-s-5diife {
128
+ grid-template-columns: [le]1fr var(--timvir-page-margin)[lex]minmax(0,12rem)[lc]48rem[rc]minmax(0,12rem)[rex]var(--timvir-page-margin) 1fr[re];
129
129
  }
130
130
  }
131
131
 
132
132
  @media (width >= 48rem) {
133
- .timvir-s-9q0i6z.timvir-s-9q0i6z {
134
- grid-template-columns: [le] var(--timvir-page-margin) [lex] 1fr[lc] minmax(0, 48rem) [rc] 1fr[rex] var(--timvir-page-margin) [re];
133
+ .timvir-s-1s3i72i.timvir-s-1s3i72i {
134
+ grid-template-columns: [le]var(--timvir-page-margin)[lex]1fr[lc]minmax(0,48rem)[rc]1fr[rex]var(--timvir-page-margin)[re];
135
135
  }
136
136
  }
137
137
  }
@@ -1,3 +1,4 @@
1
+ 'use client';
1
2
  import { jsx, jsxs } from 'react/jsx-runtime';
2
3
 
3
4
  var styleq = {};
@@ -83,8 +83,8 @@
83
83
  grid-auto-rows: min-content;
84
84
  }
85
85
 
86
- .timvir-s-12c0rpe {
87
- grid-template-columns: [le] var(--timvir-page-margin) [lex lc] 1fr[rc rex] var(--timvir-page-margin) [re];
86
+ .timvir-s-1u7e2r6 {
87
+ grid-template-columns: [le]var(--timvir-page-margin)[lex lc]1fr[rc rex]var(--timvir-page-margin)[re];
88
88
  }
89
89
 
90
90
  .timvir-s-o5v014 {
@@ -99,27 +99,15 @@
99
99
  text-align: center;
100
100
  }
101
101
 
102
- .timvir-s-115iamj:hover:before {
103
- box-shadow: 0 0 0 2px #00000040;
104
- }
105
-
106
- .timvir-s-ach7vw:hover:before {
107
- box-shadow: 0 0 0 2px var(--c-p-5);
108
- }
109
-
110
- .timvir-s-s2hnm7:hover:before {
111
- opacity: 1;
112
- }
113
-
114
102
  @media (width >= 72rem) {
115
- .timvir-s-1mxrek7.timvir-s-1mxrek7 {
116
- grid-template-columns: [le] 1fr var(--timvir-page-margin) [lex] minmax(0, 12rem) [lc] 48rem[rc] minmax(0, 12rem) [rex] var(--timvir-page-margin) 1fr[re];
103
+ .timvir-s-5diife.timvir-s-5diife {
104
+ grid-template-columns: [le]1fr var(--timvir-page-margin)[lex]minmax(0,12rem)[lc]48rem[rc]minmax(0,12rem)[rex]var(--timvir-page-margin) 1fr[re];
117
105
  }
118
106
  }
119
107
 
120
108
  @media (width >= 48rem) {
121
- .timvir-s-9q0i6z.timvir-s-9q0i6z {
122
- grid-template-columns: [le] var(--timvir-page-margin) [lex] 1fr[lc] minmax(0, 48rem) [rc] 1fr[rex] var(--timvir-page-margin) [re];
109
+ .timvir-s-1s3i72i.timvir-s-1s3i72i {
110
+ grid-template-columns: [le]var(--timvir-page-margin)[lex]1fr[lc]minmax(0,48rem)[rc]1fr[rex]var(--timvir-page-margin)[re];
123
111
  }
124
112
  }
125
113
  }
@@ -204,6 +192,18 @@
204
192
  .timvir-s-1hmns74:before {
205
193
  position: absolute;
206
194
  }
195
+
196
+ .timvir-s-115iamj:hover:before {
197
+ box-shadow: 0 0 0 2px #00000040;
198
+ }
199
+
200
+ .timvir-s-ach7vw:hover:before {
201
+ box-shadow: 0 0 0 2px var(--c-p-5);
202
+ }
203
+
204
+ .timvir-s-s2hnm7:hover:before {
205
+ opacity: 1;
206
+ }
207
207
  }
208
208
 
209
209
  @layer priority8 {
@@ -47,8 +47,8 @@
47
47
  grid-auto-rows: min-content;
48
48
  }
49
49
 
50
- .timvir-s-12c0rpe {
51
- grid-template-columns: [le] var(--timvir-page-margin) [lex lc] 1fr[rc rex] var(--timvir-page-margin) [re];
50
+ .timvir-s-1u7e2r6 {
51
+ grid-template-columns: [le]var(--timvir-page-margin)[lex lc]1fr[rc rex]var(--timvir-page-margin)[re];
52
52
  }
53
53
 
54
54
  .timvir-s-l1xv1r {
@@ -56,14 +56,14 @@
56
56
  }
57
57
 
58
58
  @media (width >= 72rem) {
59
- .timvir-s-1mxrek7.timvir-s-1mxrek7 {
60
- grid-template-columns: [le] 1fr var(--timvir-page-margin) [lex] minmax(0, 12rem) [lc] 48rem[rc] minmax(0, 12rem) [rex] var(--timvir-page-margin) 1fr[re];
59
+ .timvir-s-5diife.timvir-s-5diife {
60
+ grid-template-columns: [le]1fr var(--timvir-page-margin)[lex]minmax(0,12rem)[lc]48rem[rc]minmax(0,12rem)[rex]var(--timvir-page-margin) 1fr[re];
61
61
  }
62
62
  }
63
63
 
64
64
  @media (width >= 48rem) {
65
- .timvir-s-9q0i6z.timvir-s-9q0i6z {
66
- grid-template-columns: [le] var(--timvir-page-margin) [lex] 1fr[lc] minmax(0, 48rem) [rc] 1fr[rex] var(--timvir-page-margin) [re];
65
+ .timvir-s-1s3i72i.timvir-s-1s3i72i {
66
+ grid-template-columns: [le]var(--timvir-page-margin)[lex]1fr[lc]minmax(0,48rem)[rc]1fr[rex]var(--timvir-page-margin)[re];
67
67
  }
68
68
  }
69
69
  }
@@ -1,22 +1,19 @@
1
- import { Grid } from "timvir/blocks";
1
+ import { Code, Grid } from "timvir/blocks";
2
2
 
3
3
  # Exhibit
4
4
 
5
- The `<Exhibit>` is a block which presents something–usually a React component–in a nice way.
5
+ > Presents a component on a checkered background with optional caption and controls.
6
6
 
7
- The presented element is placed on top of a checkered background.
8
- This helps illustrating which parts of the element are transparent, or if the element comes with a specific background color.
7
+ <Sample variant="basic" />
9
8
 
10
- A bit of padding is included all around the presented element.
11
- Together with the checkered background, it makes the `<Exhibit>` block stand out next plain text or other blocks.
9
+ The presented element is placed on a checkered background with padding all around.
10
+ The checkered pattern makes transparency and background colors immediately visible, while the padding helps the block stand out from surrounding text or other blocks.
12
11
  You can tweak the bleed size, or disable the bleed altogether if you want to draw attention to the exact box size of the presented element itself.
13
12
 
14
13
  The caption, if provided, is placed below the block.
15
14
  Use it to explain what is being presented, or provide contex around it.
16
15
  Think of the `<Exhibit>` block as a `<figure>` + `<figcaption>` for React components.
17
16
 
18
- <Sample variant="basic" />
19
-
20
17
  ## Usage
21
18
 
22
19
  Import `Exhibit` from the `timvir/blocks` module, then use in a Timvir mdx page like so:
@@ -57,3 +54,9 @@ In those cases, you can force a light or dark theme with the `theme` prop.
57
54
  <Sample variant="theme" props={{ theme: "dark" }} />
58
55
  </div>
59
56
  </Grid>
57
+
58
+ <Code language="jsx" caption="Use the theme prop to force a light or dark background, regardless of the user's color scheme preference.">
59
+ {`<Exhibit theme="light">
60
+ This component requires a light background.
61
+ </Exhibit>`}
62
+ </Code>
@@ -66,7 +66,7 @@
66
66
  }
67
67
 
68
68
  .timvir-s-zqqpyx {
69
- margin-inline: calc(-1 * var(--timvir-b-Exhibit-bleed));
69
+ margin-inline: calc(-1*var(--timvir-b-Exhibit-bleed));
70
70
  }
71
71
  }
72
72
 
@@ -103,8 +103,8 @@
103
103
  grid-auto-rows: min-content;
104
104
  }
105
105
 
106
- .timvir-s-12c0rpe {
107
- grid-template-columns: [le] var(--timvir-page-margin) [lex lc] 1fr[rc rex] var(--timvir-page-margin) [re];
106
+ .timvir-s-1u7e2r6 {
107
+ grid-template-columns: [le]var(--timvir-page-margin)[lex lc]1fr[rc rex]var(--timvir-page-margin)[re];
108
108
  }
109
109
 
110
110
  .timvir-s-jkpybl {
@@ -112,14 +112,14 @@
112
112
  }
113
113
 
114
114
  @media (width >= 72rem) {
115
- .timvir-s-1mxrek7.timvir-s-1mxrek7 {
116
- grid-template-columns: [le] 1fr var(--timvir-page-margin) [lex] minmax(0, 12rem) [lc] 48rem[rc] minmax(0, 12rem) [rex] var(--timvir-page-margin) 1fr[re];
115
+ .timvir-s-5diife.timvir-s-5diife {
116
+ grid-template-columns: [le]1fr var(--timvir-page-margin)[lex]minmax(0,12rem)[lc]48rem[rc]minmax(0,12rem)[rex]var(--timvir-page-margin) 1fr[re];
117
117
  }
118
118
  }
119
119
 
120
120
  @media (width >= 48rem) {
121
- .timvir-s-9q0i6z.timvir-s-9q0i6z {
122
- grid-template-columns: [le] var(--timvir-page-margin) [lex] 1fr[lc] minmax(0, 48rem) [rc] 1fr[rex] var(--timvir-page-margin) [re];
121
+ .timvir-s-1s3i72i.timvir-s-1s3i72i {
122
+ grid-template-columns: [le]var(--timvir-page-margin)[lex]1fr[lc]minmax(0,48rem)[rc]1fr[rex]var(--timvir-page-margin)[re];
123
123
  }
124
124
  }
125
125
  }
@@ -91,8 +91,8 @@
91
91
  grid-auto-rows: min-content;
92
92
  }
93
93
 
94
- .timvir-s-12c0rpe {
95
- grid-template-columns: [le] var(--timvir-page-margin) [lex lc] 1fr[rc rex] var(--timvir-page-margin) [re];
94
+ .timvir-s-1u7e2r6 {
95
+ grid-template-columns: [le]var(--timvir-page-margin)[lex lc]1fr[rc rex]var(--timvir-page-margin)[re];
96
96
  }
97
97
 
98
98
  .timvir-s-1mzt3pk {
@@ -104,6 +104,7 @@
104
104
  }
105
105
 
106
106
  .timvir-s-1hx0egp {
107
+ -webkit-user-select: text;
107
108
  user-select: text;
108
109
  }
109
110
 
@@ -120,14 +121,14 @@
120
121
  }
121
122
 
122
123
  @media (width >= 72rem) {
123
- .timvir-s-1mxrek7.timvir-s-1mxrek7 {
124
- grid-template-columns: [le] 1fr var(--timvir-page-margin) [lex] minmax(0, 12rem) [lc] 48rem[rc] minmax(0, 12rem) [rex] var(--timvir-page-margin) 1fr[re];
124
+ .timvir-s-5diife.timvir-s-5diife {
125
+ grid-template-columns: [le]1fr var(--timvir-page-margin)[lex]minmax(0,12rem)[lc]48rem[rc]minmax(0,12rem)[rex]var(--timvir-page-margin) 1fr[re];
125
126
  }
126
127
  }
127
128
 
128
129
  @media (width >= 48rem) {
129
- .timvir-s-9q0i6z.timvir-s-9q0i6z {
130
- grid-template-columns: [le] var(--timvir-page-margin) [lex] 1fr[lc] minmax(0, 48rem) [rc] 1fr[rex] var(--timvir-page-margin) [re];
130
+ .timvir-s-1s3i72i.timvir-s-1s3i72i {
131
+ grid-template-columns: [le]var(--timvir-page-margin)[lex]1fr[lc]minmax(0,48rem)[rc]1fr[rex]var(--timvir-page-margin)[re];
131
132
  }
132
133
  }
133
134
  }
@@ -4,7 +4,7 @@ import { fullWidth } from "timvir/core";
4
4
 
5
5
  # Grid
6
6
 
7
- > CSS grid with a predefined template (columns, gaps etc)
7
+ > CSS grid with a predefined template (columns, gaps etc).
8
8
 
9
9
  ```
10
10
  <Grid>
@@ -51,8 +51,8 @@
51
51
  grid-auto-rows: min-content;
52
52
  }
53
53
 
54
- .timvir-s-12c0rpe {
55
- grid-template-columns: [le] var(--timvir-page-margin) [lex lc] 1fr[rc rex] var(--timvir-page-margin) [re];
54
+ .timvir-s-1u7e2r6 {
55
+ grid-template-columns: [le]var(--timvir-page-margin)[lex lc]1fr[rc rex]var(--timvir-page-margin)[re];
56
56
  }
57
57
 
58
58
  .timvir-s-1ayh3g3 {
@@ -60,14 +60,14 @@
60
60
  }
61
61
 
62
62
  @media (width >= 72rem) {
63
- .timvir-s-1mxrek7.timvir-s-1mxrek7 {
64
- grid-template-columns: [le] 1fr var(--timvir-page-margin) [lex] minmax(0, 12rem) [lc] 48rem[rc] minmax(0, 12rem) [rex] var(--timvir-page-margin) 1fr[re];
63
+ .timvir-s-5diife.timvir-s-5diife {
64
+ grid-template-columns: [le]1fr var(--timvir-page-margin)[lex]minmax(0,12rem)[lc]48rem[rc]minmax(0,12rem)[rex]var(--timvir-page-margin) 1fr[re];
65
65
  }
66
66
  }
67
67
 
68
68
  @media (width >= 48rem) {
69
- .timvir-s-9q0i6z.timvir-s-9q0i6z {
70
- grid-template-columns: [le] var(--timvir-page-margin) [lex] 1fr[lc] minmax(0, 48rem) [rc] 1fr[rex] var(--timvir-page-margin) [re];
69
+ .timvir-s-1s3i72i.timvir-s-1s3i72i {
70
+ grid-template-columns: [le]var(--timvir-page-margin)[lex]1fr[lc]minmax(0,48rem)[rc]1fr[rex]var(--timvir-page-margin)[re];
71
71
  }
72
72
  }
73
73
  }
@@ -88,6 +88,7 @@
88
88
  }
89
89
 
90
90
  .timvir-s-87ps6o {
91
+ -webkit-user-select: none;
91
92
  user-select: none;
92
93
  }
93
94