@jig-ui/react 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 (109) hide show
  1. package/LICENSE +52 -0
  2. package/README.md +193 -0
  3. package/dist/adorn/adorn.d.ts +38 -0
  4. package/dist/adorn/index.d.ts +2 -0
  5. package/dist/box/box.d.ts +32 -0
  6. package/dist/box/index.d.ts +2 -0
  7. package/dist/breakpoints.d.ts +35 -0
  8. package/dist/button/button.d.ts +37 -0
  9. package/dist/button/index.d.ts +2 -0
  10. package/dist/codeblock/codeblock.d.ts +28 -0
  11. package/dist/codeblock/index.d.ts +2 -0
  12. package/dist/collapsible/collapsible.d.ts +116 -0
  13. package/dist/collapsible/index.d.ts +2 -0
  14. package/dist/combobox/combobox.d.ts +119 -0
  15. package/dist/combobox/index.d.ts +2 -0
  16. package/dist/dev.d.ts +14 -0
  17. package/dist/dialog/dialog.d.ts +80 -0
  18. package/dist/dialog/index.d.ts +2 -0
  19. package/dist/focus-ring.d.ts +15 -0
  20. package/dist/grid/grid.d.ts +54 -0
  21. package/dist/grid/index.d.ts +2 -0
  22. package/dist/icon/generated/arrow-down.d.ts +4 -0
  23. package/dist/icon/generated/arrow-left.d.ts +4 -0
  24. package/dist/icon/generated/arrow-right.d.ts +4 -0
  25. package/dist/icon/generated/arrow-square-out.d.ts +4 -0
  26. package/dist/icon/generated/arrow-up.d.ts +4 -0
  27. package/dist/icon/generated/bell.d.ts +4 -0
  28. package/dist/icon/generated/calendar.d.ts +4 -0
  29. package/dist/icon/generated/caret-down.d.ts +4 -0
  30. package/dist/icon/generated/caret-left.d.ts +4 -0
  31. package/dist/icon/generated/caret-right.d.ts +4 -0
  32. package/dist/icon/generated/caret-up.d.ts +4 -0
  33. package/dist/icon/generated/check-circle.d.ts +4 -0
  34. package/dist/icon/generated/check.d.ts +4 -0
  35. package/dist/icon/generated/clock.d.ts +4 -0
  36. package/dist/icon/generated/copy.d.ts +4 -0
  37. package/dist/icon/generated/dots-nine.d.ts +4 -0
  38. package/dist/icon/generated/dots-three.d.ts +4 -0
  39. package/dist/icon/generated/eye-slash.d.ts +4 -0
  40. package/dist/icon/generated/eye.d.ts +4 -0
  41. package/dist/icon/generated/gear.d.ts +4 -0
  42. package/dist/icon/generated/github-logo.d.ts +4 -0
  43. package/dist/icon/generated/heart.d.ts +4 -0
  44. package/dist/icon/generated/index.d.ts +151 -0
  45. package/dist/icon/generated/info.d.ts +4 -0
  46. package/dist/icon/generated/list.d.ts +4 -0
  47. package/dist/icon/generated/magnifying-glass.d.ts +4 -0
  48. package/dist/icon/generated/minus.d.ts +4 -0
  49. package/dist/icon/generated/moon.d.ts +4 -0
  50. package/dist/icon/generated/pencil-simple.d.ts +4 -0
  51. package/dist/icon/generated/plus.d.ts +4 -0
  52. package/dist/icon/generated/question.d.ts +4 -0
  53. package/dist/icon/generated/star.d.ts +4 -0
  54. package/dist/icon/generated/sun.d.ts +4 -0
  55. package/dist/icon/generated/trash.d.ts +4 -0
  56. package/dist/icon/generated/user.d.ts +4 -0
  57. package/dist/icon/generated/warning-circle.d.ts +4 -0
  58. package/dist/icon/generated/warning.d.ts +4 -0
  59. package/dist/icon/generated/x.d.ts +4 -0
  60. package/dist/icon/icon.d.ts +46 -0
  61. package/dist/icon/index.d.ts +2 -0
  62. package/dist/icon-BRHwInc5.js +165 -0
  63. package/dist/icon-B_NrwKaL.js +173 -0
  64. package/dist/iconbutton/iconbutton.d.ts +35 -0
  65. package/dist/iconbutton/index.d.ts +2 -0
  66. package/dist/icons.d.ts +17 -0
  67. package/dist/icons.js +2 -0
  68. package/dist/index.d.ts +56 -0
  69. package/dist/index.js +3061 -0
  70. package/dist/input/index.d.ts +2 -0
  71. package/dist/input/input.d.ts +63 -0
  72. package/dist/layout.d.ts +87 -0
  73. package/dist/link/index.d.ts +2 -0
  74. package/dist/link/link.d.ts +125 -0
  75. package/dist/listitem/index.d.ts +2 -0
  76. package/dist/listitem/listitem.d.ts +92 -0
  77. package/dist/polymorphic.d.ts +31 -0
  78. package/dist/reset.css +4 -0
  79. package/dist/responsive.d.ts +10 -0
  80. package/dist/scrollarea/index.d.ts +2 -0
  81. package/dist/scrollarea/scrollarea.d.ts +26 -0
  82. package/dist/separator/index.d.ts +2 -0
  83. package/dist/separator/separator.d.ts +48 -0
  84. package/dist/sidenav/index.d.ts +2 -0
  85. package/dist/sidenav/sidenav.d.ts +35 -0
  86. package/dist/sidenavsection/index.d.ts +2 -0
  87. package/dist/sidenavsection/sidenavsection.d.ts +44 -0
  88. package/dist/slider/index.d.ts +2 -0
  89. package/dist/slider/slider.d.ts +73 -0
  90. package/dist/spacing.d.ts +35 -0
  91. package/dist/stack/index.d.ts +2 -0
  92. package/dist/stack/stack.d.ts +52 -0
  93. package/dist/structuredlist/index.d.ts +2 -0
  94. package/dist/structuredlist/structuredlist.d.ts +104 -0
  95. package/dist/styles.css +911 -0
  96. package/dist/togglebutton/index.d.ts +2 -0
  97. package/dist/togglebutton/togglebutton.d.ts +93 -0
  98. package/dist/togglebuttongroup/index.d.ts +2 -0
  99. package/dist/togglebuttongroup/togglebuttongroup.d.ts +72 -0
  100. package/dist/token/index.d.ts +2 -0
  101. package/dist/token/token.d.ts +82 -0
  102. package/dist/tokens-vars.d.ts +579 -0
  103. package/dist/tokens.d.ts +24 -0
  104. package/dist/tokens.js +577 -0
  105. package/dist/tooltip/index.d.ts +2 -0
  106. package/dist/tooltip/tooltip.d.ts +52 -0
  107. package/dist/typography/index.d.ts +2 -0
  108. package/dist/typography/typography.d.ts +71 -0
  109. package/package.json +81 -0
package/LICENSE ADDED
@@ -0,0 +1,52 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Nate Bridi
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.
22
+
23
+
24
+ ===============================================================================
25
+ THIRD-PARTY NOTICES
26
+ ===============================================================================
27
+
28
+ This software includes icon artwork derived from Phosphor Icons
29
+ (https://phosphoricons.com), redistributed as SVG path data. Phosphor Icons is
30
+ licensed as follows:
31
+
32
+ MIT License
33
+
34
+ Copyright (c) 2023 Phosphor Icons
35
+
36
+ Permission is hereby granted, free of charge, to any person obtaining a copy
37
+ of this software and associated documentation files (the "Software"), to deal
38
+ in the Software without restriction, including without limitation the rights
39
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
40
+ copies of the Software, and to permit persons to whom the Software is
41
+ furnished to do so, subject to the following conditions:
42
+
43
+ The above copyright notice and this permission notice shall be included in all
44
+ copies or substantial portions of the Software.
45
+
46
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
47
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
48
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
49
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
50
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
51
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
52
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,193 @@
1
+ # @jig-ui/react
2
+
3
+ React components for the Jig design system.
4
+
5
+ Ships as plain ESM plus a stylesheet — no Vanilla Extract, PostCSS, or other
6
+ build tooling is required in the consuming project.
7
+
8
+ ## Install
9
+
10
+ ```sh
11
+ npm install @jig-ui/react
12
+ ```
13
+
14
+ `react` and `react-dom` (>=19) are peer dependencies. React 19 is required
15
+ because components take `ref` as an ordinary prop rather than through
16
+ `forwardRef`.
17
+
18
+ ## Use
19
+
20
+ Import the stylesheet once, at your app's entry point:
21
+
22
+ ```js
23
+ import '@jig-ui/react/styles.css';
24
+ ```
25
+
26
+ Then use the components anywhere:
27
+
28
+ ```jsx
29
+ import { Button, Stack, Typography } from '@jig-ui/react';
30
+
31
+ export function Example() {
32
+ return (
33
+ <Stack direction={{ xs: 'column', md: 'row' }} spacing="400">
34
+ <Typography as="h1" with="heading01">Hello</Typography>
35
+ <Button variant="primary">Click me</Button>
36
+ </Stack>
37
+ );
38
+ }
39
+ ```
40
+
41
+ ### Fonts
42
+
43
+ Jig's type tokens name three families but deliberately do not load them, so that
44
+ the package makes no network requests of its own and you stay in control of how
45
+ the fonts are served. You must make them available yourself, or text will fall
46
+ back to `sans-serif` / `monospace` / `serif`:
47
+
48
+ | Token | Family |
49
+ | ----------------- | ---------------- |
50
+ | `type.family.sans` | Work Sans |
51
+ | `type.family.mono` | Source Code Pro |
52
+ | `type.family.display` | Amarna |
53
+
54
+ All three are variable fonts covering weights 400–700, which is the full range
55
+ the weight tokens use. The quickest option is Google Fonts — add to your
56
+ `<head>`:
57
+
58
+ ```html
59
+ <link rel="preconnect" href="https://fonts.googleapis.com" />
60
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
61
+ <link
62
+ href="https://fonts.googleapis.com/css2?family=Amarna:wght@400..700&family=Source+Code+Pro:wght@400..700&family=Work+Sans:wght@400..700&display=swap"
63
+ rel="stylesheet"
64
+ />
65
+ ```
66
+
67
+ To avoid the third-party request, self-host instead — via `@fontsource-variable`
68
+ packages or your own `@font-face` rules — using the exact family names above.
69
+
70
+ To substitute your own typefaces, override the custom properties rather than
71
+ loading these at all:
72
+
73
+ ```css
74
+ :root {
75
+ --type-family-sans: 'Inter', sans-serif;
76
+ }
77
+ ```
78
+
79
+ ### Reset
80
+
81
+ An optional reset is available separately. Import it before `styles.css`:
82
+
83
+ ```js
84
+ import '@jig-ui/react/reset.css';
85
+ ```
86
+
87
+ ### Tokens
88
+
89
+ The design tokens are exported as CSS custom property references, for inline
90
+ styles or your own CSS-in-JS:
91
+
92
+ ```jsx
93
+ import { color, spacing } from '@jig-ui/react/tokens';
94
+
95
+ <div style={{ background: color.surfaces[100], padding: spacing[500] }} />
96
+ ```
97
+
98
+ Theming is done entirely through CSS custom properties, so you can override any
99
+ token in your own stylesheet without touching the package.
100
+
101
+ ## Theming
102
+
103
+ ### Cascade layers
104
+
105
+ All of Jig's CSS ships inside cascade layers, declared in this order:
106
+
107
+ ```css
108
+ @layer jig.reset, jig.tokens, jig.base, jig.components;
109
+ ```
110
+
111
+ Both `styles.css` and `reset.css` state this order, so importing them in either
112
+ order gives the same cascade.
113
+
114
+ Because every Jig rule sits in a layer, **any unlayered CSS you write beats all
115
+ of it**, regardless of selector specificity. Overriding a token is therefore
116
+ just:
117
+
118
+ ```css
119
+ :root {
120
+ --color-text-primary: #111;
121
+ }
122
+ ```
123
+
124
+ You do not need to out-specify Jig's own `:root[data-theme="dark"]` selectors —
125
+ layer order settles it first. If your app uses layers itself, name Jig's in your
126
+ own `@layer` statement to place your rules deliberately:
127
+
128
+ ```css
129
+ @layer jig.reset, jig.tokens, jig.base, jig.components, app;
130
+ ```
131
+
132
+ `jig.base` currently emits nothing. It is declared so that adding base styles
133
+ later does not renumber an order you have already written against.
134
+
135
+ `jig.reset` is lowest on purpose. A reset exists to beat the *browser's* default
136
+ styles, and those lose to author CSS at any layer — so layering it takes nothing
137
+ away. It also has to sit below `jig.components`, or its `h1`–`h6` rules would
138
+ override the components' own typography.
139
+
140
+ ### Light and dark
141
+
142
+ By default Jig follows the operating system via `prefers-color-scheme`. To take
143
+ control, set `data-theme` on the root element:
144
+
145
+ ```html
146
+ <html data-theme="dark">
147
+ ```
148
+
149
+ Both directions are supported: `data-theme="light"` forces light even when the
150
+ OS is dark, and vice versa.
151
+
152
+ Theme selectors are scoped to `:root`, and deliberately so: a Jig theme is a
153
+ property of the document, not of a subtree. Jig is built for full-document
154
+ applications, where exactly one theme is in effect at a time.
155
+
156
+ That means these are out of scope by design rather than pending:
157
+
158
+ - a dark section inside a light page,
159
+ - side-by-side light and dark previews on one page,
160
+ - independently themed embedded widgets or microfrontends.
161
+
162
+ Subtree theming is not a selector change — primitives and semantic aliases
163
+ inherit differently, and the tooltip's top-layer popover escapes its ancestors
164
+ entirely. If you need any of the above, own the theme at the document level and
165
+ render the two states on separate pages.
166
+
167
+ ### Avoiding a flash of the wrong theme
168
+
169
+ Following the OS needs no JavaScript and is correct before first paint, because
170
+ it is pure CSS.
171
+
172
+ A **persisted** preference is different. If you read a stored theme and apply
173
+ `data-theme` after hydration, the user sees the OS theme first and yours a moment
174
+ later. Jig deliberately ships no runtime for this — it is your app's data, and a
175
+ library-injected script cannot know where you keep it. Either render the
176
+ attribute server-side:
177
+
178
+ ```html
179
+ <html data-theme="{{ user.theme }}">
180
+ ```
181
+
182
+ or set it from a small blocking script in `<head>`, before the stylesheet:
183
+
184
+ ```html
185
+ <script>
186
+ const t = localStorage.getItem('theme');
187
+ if (t) document.documentElement.dataset.theme = t;
188
+ </script>
189
+ ```
190
+
191
+ ## License
192
+
193
+ MIT
@@ -0,0 +1,38 @@
1
+ import { PolymorphicProps } from '../polymorphic';
2
+ /**
3
+ * The inline elements Adorn is willing to render as. Restricted rather than
4
+ * open: `as` changes the semantics of the text, and an arbitrary ElementType
5
+ * would let it render as something that has no business holding a phrase.
6
+ */
7
+ export type AdornElement = 'span' | 'strong' | 'em' | 'b' | 'i' | 'code' | 'mark' | 'abbr';
8
+ /**
9
+ * Which semantic colour the text takes. Weight and slant come from `as`.
10
+ *
11
+ * `mono` is named for what it does — switch to the monospace family — rather
12
+ * than for `<code>`, which it does not imply. Styling text as code without
13
+ * marking it up as code is a legitimate thing to want (a keyboard shortcut, a
14
+ * column of figures); pair it with `as="code"` when the semantics apply too.
15
+ */
16
+ export type AdornStyle = 'muted' | 'accent' | 'danger' | 'mono';
17
+ /** Adorn's own props. The element's own attributes are added by PolymorphicProps. */
18
+ export interface AdornOwnProps {
19
+ with?: AdornStyle;
20
+ }
21
+ export type AdornProps<E extends AdornElement = 'span'> = PolymorphicProps<E, AdornOwnProps>;
22
+ /**
23
+ * Colours or emphasises a phrase inside a run of text.
24
+ *
25
+ * `with` sets the semantic colour; `as` sets the meaning and brings the
26
+ * matching weight or slant with it, so use `as="strong"` for importance and
27
+ * `as="em"` for stress rather than reaching for a visual-only prop.
28
+ *
29
+ * `with="mono"` switches to the monospace family without implying code — pair
30
+ * it with `as="code"` when the content really is code.
31
+ *
32
+ * @example
33
+ * <Typography as="p">
34
+ * Deleting this is <Adorn as="strong" with="danger">permanent</Adorn>.
35
+ * Run <Adorn as="code" with="mono">pnpm build</Adorn> first.
36
+ * </Typography>
37
+ */
38
+ export declare function Adorn<E extends AdornElement = 'span'>({ as, with: adornStyle, className, children, ...props }: AdornProps<E>): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,2 @@
1
+ export { Adorn } from './adorn';
2
+ export type { AdornProps, AdornStyle, AdornElement } from './adorn';
@@ -0,0 +1,32 @@
1
+ import { SpacingProps } from '../spacing';
2
+ import { LayoutChildProps } from '../layout';
3
+ import { PolymorphicProps } from '../polymorphic';
4
+ /** The elements a Box is willing to render as. See StackElement. */
5
+ export type BoxElement = 'div' | 'span' | 'section' | 'article' | 'aside' | 'nav' | 'header' | 'footer' | 'main' | 'ul' | 'ol' | 'li';
6
+ /**
7
+ * Box's own props. All three are the shared child-side set — Box adds nothing
8
+ * of its own, because being a child is the whole of what it does. The
9
+ * element's own attributes are added by PolymorphicProps.
10
+ */
11
+ export interface BoxOwnProps extends SpacingProps, LayoutChildProps {
12
+ }
13
+ export type BoxProps<E extends BoxElement = 'div'> = PolymorphicProps<E, BoxOwnProps>;
14
+ /**
15
+ * A layout child: an element that positions itself inside a Stack or a Grid.
16
+ *
17
+ * Reach for it when the thing you are placing is not itself a layout
18
+ * container — a bare div, a Typography, a form control that needs to claim a
19
+ * column span. Stack and Grid already accept these props directly, so nesting
20
+ * one inside another needs no Box.
21
+ *
22
+ * `span` applies inside a Grid, `grow` inside a Stack, and `alignSelf` in
23
+ * either. A prop that does not apply to the parent is ignored rather than an
24
+ * error, and all three take responsive values.
25
+ *
26
+ * @example
27
+ * <Grid columns={12} spacing="400">
28
+ * <Box span={8}><Article /></Box>
29
+ * <Box span={4}><Sidebar /></Box>
30
+ * </Grid>
31
+ */
32
+ export declare function Box<E extends BoxElement = 'div'>({ as, span, grow, alignSelf, className, children, ...props }: BoxProps<E>): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,2 @@
1
+ export { Box } from './box';
2
+ export type { BoxProps, BoxElement } from './box';
@@ -0,0 +1,35 @@
1
+ export declare const breakpoints: {
2
+ readonly xs: 0;
3
+ readonly sm: 480;
4
+ readonly md: 768;
5
+ readonly lg: 1024;
6
+ readonly xl: 1280;
7
+ };
8
+ export type Breakpoint = keyof typeof breakpoints;
9
+ export declare const mediaQueries: {
10
+ readonly sm: "screen and (min-width: 480px)";
11
+ readonly md: "screen and (min-width: 768px)";
12
+ readonly lg: "screen and (min-width: 1024px)";
13
+ readonly xl: "screen and (min-width: 1280px)";
14
+ };
15
+ /**
16
+ * The Sprinkles conditions every responsive prop in the system is built from.
17
+ * Shared so spacing and layout cannot drift into two different sets of
18
+ * breakpoints, and so `Responsive<T>` describes all of them at once.
19
+ */
20
+ export declare const responsiveConditions: {
21
+ xs: {};
22
+ sm: {
23
+ '@media': "screen and (min-width: 480px)";
24
+ };
25
+ md: {
26
+ '@media': "screen and (min-width: 768px)";
27
+ };
28
+ lg: {
29
+ '@media': "screen and (min-width: 1024px)";
30
+ };
31
+ xl: {
32
+ '@media': "screen and (min-width: 1280px)";
33
+ };
34
+ };
35
+ export declare const defaultCondition = "xs";
@@ -0,0 +1,37 @@
1
+ import { ButtonHTMLAttributes, Ref } from 'react';
2
+ import { IconName } from '../icon';
3
+ export type ButtonVariant = 'primary' | 'secondary' | 'danger' | 'ghost' | 'smoke';
4
+ export type ButtonSize = 'sm' | 'md' | 'lg';
5
+ export interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
6
+ variant?: ButtonVariant;
7
+ size?: ButtonSize;
8
+ /**
9
+ * An icon from the curated set, sized and spaced by the button rather than
10
+ * by the caller. Decorative — the label names the button.
11
+ */
12
+ icon?: IconName;
13
+ /** Which side of the label the icon sits on. */
14
+ iconPosition?: 'start' | 'end';
15
+ ref?: Ref<HTMLButtonElement>;
16
+ }
17
+ /**
18
+ * A button.
19
+ *
20
+ * `variant` sets how loud it is: `primary` for the main action in a view,
21
+ * `secondary` beside it, `danger` for destructive actions, `ghost` for utility
22
+ * actions on another surface, and `smoke` for controls over imagery or video,
23
+ * where a translucent blurred pane keeps the content behind visible.
24
+ *
25
+ * `icon` takes a name from the curated set and is sized and spaced by the
26
+ * button; it is decorative, so the label is what names the control. For a
27
+ * button with no visible label, use `IconButton`, which requires one.
28
+ *
29
+ * Defaults to `type="button"`. Pass `type="submit"` explicitly to submit a
30
+ * form. To navigate rather than act, use `Link` with a button variant.
31
+ *
32
+ * @example
33
+ * <Button variant="primary" icon="arrow-right" iconPosition="end" onClick={save}>
34
+ * Save changes
35
+ * </Button>
36
+ */
37
+ export declare function Button({ variant, size, icon, iconPosition, type, className, children, ...props }: ButtonProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,2 @@
1
+ export { Button } from './button';
2
+ export type { ButtonProps, ButtonVariant, ButtonSize } from './button';
@@ -0,0 +1,28 @@
1
+ import { ComponentPropsWithoutRef, Ref } from 'react';
2
+ export interface CodeBlockProps extends Omit<ComponentPropsWithoutRef<'div'>, 'children'> {
3
+ /** Display a script name, language, etc. at top of block. */
4
+ label?: string;
5
+ /** Content to display as a plain string. */
6
+ children: string;
7
+ ref?: Ref<HTMLDivElement>;
8
+ }
9
+ /**
10
+ * A block of source code with a copy button.
11
+ *
12
+ * `children` is the code as a plain string — not markup, and not a
13
+ * `<pre>`/`<code>` pair, which the component renders for you. Indentation is
14
+ * preserved exactly, so template literals should be trimmed before they are
15
+ * passed.
16
+ *
17
+ * `label` names the snippet in the bar above it: a file path, a language, or
18
+ * whatever identifies it. The copy button confirms in place for two seconds
19
+ * and needs a secure context, since it uses the async clipboard API.
20
+ *
21
+ * Long lines scroll horizontally rather than wrapping.
22
+ *
23
+ * @example
24
+ * <CodeBlock label="vite.config.ts">
25
+ * {`export default defineConfig({\n plugins: [react()],\n})`}
26
+ * </CodeBlock>
27
+ */
28
+ export declare function CodeBlock({ label, className, children, ...props }: CodeBlockProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,2 @@
1
+ export { CodeBlock } from './codeblock';
2
+ export type { CodeBlockProps } from './codeblock';
@@ -0,0 +1,116 @@
1
+ import { CSSProperties, HTMLAttributes, ReactNode, Ref } from 'react';
2
+ import { TypeStyles } from '../typography';
3
+ /**
4
+ * What a handler receives alongside the new open state.
5
+ *
6
+ * Declared here rather than re-exported from Base UI: 0001 settled that
7
+ * consumers import from `@jig-ui/react` and should not need to know Base UI
8
+ * exists. This is the subset of its change details that is useful to call —
9
+ * the object passed at runtime carries more, and passing it through unchanged
10
+ * is what makes the cancellation reach Base UI.
11
+ *
12
+ * Deliberately the same shape as `ToggleChangeDetails`. 0013 D5's outcome
13
+ * notes that a third consumer should collapse these into one shared type
14
+ * rather than adding a third near-copy.
15
+ */
16
+ export interface CollapsibleChangeDetails {
17
+ /** Cancels the change. The panel does not move. */
18
+ cancel: () => void;
19
+ /** The native event behind the change. */
20
+ readonly event: Event;
21
+ /** Whether something has already cancelled this change. */
22
+ readonly isCanceled: boolean;
23
+ }
24
+ export interface CollapsibleProps extends Omit<HTMLAttributes<HTMLDivElement>, 'className' | 'style' | 'children'> {
25
+ /**
26
+ * The trigger's visible content — the words that name what is inside.
27
+ *
28
+ * Called `label` rather than `trigger` on purpose: `Dialog`'s `trigger`
29
+ * means "an element that opens this", and a Collapsible owns its button
30
+ * rather than accepting one. Reusing the name for a different idea is how a
31
+ * system stops being learnable.
32
+ */
33
+ label: ReactNode;
34
+ /** The panel's contents. */
35
+ children?: ReactNode;
36
+ /**
37
+ * A Typography preset for the trigger's label. Defaults to `body01`, so a
38
+ * trigger with nothing passed matches the body copy around it; a section
39
+ * disclosure usually wants `heading05`.
40
+ *
41
+ * The same presets `Typography` and `Link` name, from one shared map — so
42
+ * this is the type style, not a size ramp. Decided in 0013 D2.
43
+ */
44
+ with?: TypeStyles;
45
+ /**
46
+ * The glyph marking the trigger: `plus` while closed, `minus` while open, at
47
+ * the trailing edge, sized in `em` so it tracks `with`.
48
+ *
49
+ * `false` removes it, for a trigger that is already obviously one. There is
50
+ * no way to substitute a different glyph — the indicator is the component's,
51
+ * like every other icon Jig places rather than accepts. Decided in 0013 D3,
52
+ * whose outcome records that this pair cannot animate: two SVG paths cannot
53
+ * be tweened, so the indicator cuts rather than transitions.
54
+ */
55
+ indicator?: boolean;
56
+ /** Controlled open state. Omit to let the collapsible manage its own. */
57
+ open?: boolean;
58
+ defaultOpen?: boolean;
59
+ /**
60
+ * Fires before the change is applied. Call `details.cancel()` to veto it —
61
+ * which is what makes "do not collapse over a dirty form" expressible.
62
+ *
63
+ * Base UI's signature, kept rather than narrowed to `(open) => void` the way
64
+ * Dialog's is. Decided in 0013 D5.
65
+ */
66
+ onOpenChange?: (open: boolean, details: CollapsibleChangeDetails) => void;
67
+ /** Prevents the panel from being opened or closed. */
68
+ disabled?: boolean;
69
+ /**
70
+ * Keeps the closed panel in the DOM behind `hidden="until-found"`, so the
71
+ * browser's find-in-page can match text inside it and open the panel.
72
+ *
73
+ * Off by default, which is Base UI's default and 0013 D4's decision: a
74
+ * closed panel's children are not rendered at all and cost nothing until it
75
+ * opens. Turn this on for content a reader would expect to search — an FAQ,
76
+ * a reference page.
77
+ *
78
+ * Overrides `keepMounted`. In a browser that does not know the value, the
79
+ * element falls back to plain `hidden`, which is `keepMounted`'s behaviour
80
+ * rather than a broken one.
81
+ */
82
+ hiddenUntilFound?: boolean;
83
+ /**
84
+ * Keeps the closed panel in the DOM behind a plain `hidden`. Off by default.
85
+ *
86
+ * Reach for it when state inside the panel has to survive being collapsed —
87
+ * a partly filled form — and findability is not wanted.
88
+ */
89
+ keepMounted?: boolean;
90
+ /** Applied to the root, which is the element a caller would size. */
91
+ className?: string;
92
+ style?: CSSProperties;
93
+ ref?: Ref<HTMLDivElement>;
94
+ }
95
+ /**
96
+ * A button that shows and hides a panel below it.
97
+ *
98
+ * `label` names what is inside and `children` are the contents. Manages its
99
+ * own state by default; pass `open` and `onOpenChange` to drive it from
100
+ * elsewhere. `onOpenChange` fires before the change is applied, so calling
101
+ * `details.cancel()` inside it vetoes the toggle.
102
+ *
103
+ * `with` sets the trigger's type from the Typography presets — `body01` by
104
+ * default, `heading05` for a section disclosure.
105
+ *
106
+ * A closed panel is not in the DOM at all, so find-in-page cannot reach it.
107
+ * Pass `hiddenUntilFound` for content a reader would expect to search.
108
+ *
109
+ * Spacing around it comes from the parent, like every other component.
110
+ *
111
+ * @example
112
+ * <Collapsible label="Shipping and returns" with="heading05">
113
+ * <Typography as="p">Orders ship within two business days.</Typography>
114
+ * </Collapsible>
115
+ */
116
+ export declare function Collapsible({ label, children, with: typeStyle, indicator, open, defaultOpen, onOpenChange, disabled, hiddenUntilFound, keepMounted, className, style, ref, ...props }: CollapsibleProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,2 @@
1
+ export { Collapsible } from './collapsible';
2
+ export type { CollapsibleProps, CollapsibleChangeDetails } from './collapsible';
@@ -0,0 +1,119 @@
1
+ import { CSSProperties, ReactNode, Ref } from 'react';
2
+ export type ComboboxSize = 'sm' | 'md' | 'lg';
3
+ /**
4
+ * One option. `label` is what the user reads and what the internal filter
5
+ * matches against; `value` is what comes back.
6
+ */
7
+ export interface ComboboxItem<Value = string> {
8
+ value: Value;
9
+ label: string;
10
+ disabled?: boolean;
11
+ }
12
+ /**
13
+ * A labelled set of options.
14
+ *
15
+ * Groups are a shape inside `items` rather than a separate prop, because that
16
+ * is the shape Base UI's own `items` already reads — its `Group<Item>` is
17
+ * `{ [key: string]: unknown; items: readonly Item[] }`, so this is handed over
18
+ * without a mapping layer. Decided in apps/docs/decisions/0011-combobox.html
19
+ * (D2), which also records the cost: flat data has to be reshaped by the caller.
20
+ */
21
+ export interface ComboboxGroup<Value = string> {
22
+ label: string;
23
+ items: readonly ComboboxItem<Value>[];
24
+ }
25
+ interface ComboboxOwnProps<Value> {
26
+ /**
27
+ * The options, flat or grouped. A grouped entry is `{ label, items }`; the
28
+ * two shapes can be mixed in one array, and the type discriminates on the
29
+ * presence of `items`.
30
+ */
31
+ items: readonly (ComboboxItem<Value> | ComboboxGroup<Value>)[];
32
+ /**
33
+ * The field's label. Rendered as a real `<label>` bound to the control, so
34
+ * this is how the combobox gets its accessible name — one without it is
35
+ * announced as unlabelled.
36
+ */
37
+ label?: ReactNode;
38
+ /** Hint text below the control, associated via `aria-describedby`. */
39
+ description?: ReactNode;
40
+ /**
41
+ * An error message from outside the component. Passing it marks the field
42
+ * invalid and shows the message unconditionally.
43
+ */
44
+ error?: ReactNode;
45
+ /** Shown in the popup when the query matches nothing. */
46
+ emptyMessage?: ReactNode;
47
+ /**
48
+ * A floor for the popup's width, as any CSS length. The popup matches the
49
+ * field by default, which is too narrow when the options are longer than the
50
+ * control — set this to let it grow past the field rather than truncate.
51
+ */
52
+ popupMinWidth?: string | number;
53
+ placeholder?: string;
54
+ size?: ComboboxSize;
55
+ disabled?: boolean;
56
+ required?: boolean;
57
+ /** Identifies the field when a form is submitted. */
58
+ name?: string;
59
+ /**
60
+ * Applied to the field wrapper, not the control — the wrapper is the element
61
+ * the surrounding layout sees. Same reasoning Input records.
62
+ */
63
+ className?: string;
64
+ /** Applied to the field wrapper, for the same reason as `className`. */
65
+ style?: CSSProperties;
66
+ /** The input — the element you would focus or measure. */
67
+ ref?: Ref<HTMLInputElement>;
68
+ }
69
+ /** Single selection: one value, or `null` for none. */
70
+ export type ComboboxSingleProps<Value> = ComboboxOwnProps<Value> & {
71
+ multiple?: false;
72
+ value?: Value | null;
73
+ defaultValue?: Value | null;
74
+ onValueChange?: (value: Value | null) => void;
75
+ };
76
+ /**
77
+ * Multiple selection. Selected options render as `Token`s inside the field —
78
+ * 0011 D3, which finally consumes the height 0006 derived from `size.control`
79
+ * so a Token nests inside a field of the same size.
80
+ */
81
+ export type ComboboxMultipleProps<Value> = ComboboxOwnProps<Value> & {
82
+ multiple: true;
83
+ value?: readonly Value[];
84
+ defaultValue?: readonly Value[];
85
+ onValueChange?: (value: Value[]) => void;
86
+ };
87
+ export type ComboboxProps<Value = string> = ComboboxSingleProps<Value> | ComboboxMultipleProps<Value>;
88
+ /**
89
+ * A text field that filters a list of options as you type.
90
+ *
91
+ * Options are passed as `items` rather than as children. Each is
92
+ * `{ value, label }`, where `label` is shown and matched against the query and
93
+ * `value` is what `onValueChange` reports. To group them, pass
94
+ * `{ label, items }` entries instead; the two shapes can be mixed in one array.
95
+ *
96
+ * `multiple` turns the value into an array and renders each selection as a
97
+ * removable chip inside the field, which grows as chips wrap.
98
+ *
99
+ * `label` is the accessible name and should always be set. `description` and
100
+ * `error` are wired to the control for you; passing `error` also marks the
101
+ * field invalid.
102
+ *
103
+ * Filtering happens inside the component, so `items` should be the full set of
104
+ * options rather than a pre-filtered result.
105
+ *
106
+ * @example
107
+ * <Combobox
108
+ * label="Reviewers"
109
+ * multiple
110
+ * items={[
111
+ * { label: 'Engineering', items: [{ value: 'ada', label: 'Ada Lovelace' }] },
112
+ * { label: 'Design', items: [{ value: 'grace', label: 'Grace Hopper' }] },
113
+ * ]}
114
+ * value={reviewers}
115
+ * onValueChange={setReviewers}
116
+ * />
117
+ */
118
+ export declare function Combobox<Value = string>({ items, label, description, error, emptyMessage, popupMinWidth, placeholder, size, disabled, required, name, multiple, value, defaultValue, onValueChange, className, style, ref, }: ComboboxProps<Value>): import("react/jsx-runtime").JSX.Element;
119
+ export {};