@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
@@ -0,0 +1,2 @@
1
+ export { Input } from './input';
2
+ export type { InputProps, InputSize } from './input';
@@ -0,0 +1,63 @@
1
+ import { CSSProperties, InputHTMLAttributes, ReactNode, Ref } from 'react';
2
+ export type InputSize = 'sm' | 'md' | 'lg';
3
+ export interface InputProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'size'> {
4
+ /**
5
+ * The field's label. Rendered as a real `<label>` bound to the control, so
6
+ * this is how the input gets its accessible name — an input without one is
7
+ * announced as unlabelled.
8
+ */
9
+ label?: ReactNode;
10
+ /** Hint text below the control, associated via `aria-describedby`. */
11
+ description?: ReactNode;
12
+ /**
13
+ * An error message from outside the component — a server response, or a form
14
+ * library. Passing it marks the field invalid and shows the message
15
+ * unconditionally. Leave it undefined to let the browser's own constraint
16
+ * validation (`required`, `type="email"`, `pattern`) drive the invalid state
17
+ * instead.
18
+ */
19
+ error?: ReactNode;
20
+ size?: InputSize;
21
+ /**
22
+ * Applied to the field wrapper, not the control.
23
+ *
24
+ * The wrapper is the element the surrounding layout sees — it is the flex or
25
+ * grid child, and it is what holds the label and the description as well as
26
+ * the input. Styling the control instead meant a `flexGrow` or a `gridColumn`
27
+ * landed on an element the parent layout never touches, and silently did
28
+ * nothing. `Slider` has always worked this way; Input was the outlier.
29
+ *
30
+ * Everything else spreads onto the control, so `placeholder`, `onChange`,
31
+ * `id` and the rest reach the `<input>` as they read.
32
+ */
33
+ className?: string;
34
+ /** Applied to the field wrapper, for the same reason as `className`. */
35
+ style?: CSSProperties;
36
+ /** The control — the element you would focus, select or measure. */
37
+ ref?: Ref<HTMLInputElement>;
38
+ }
39
+ /**
40
+ * A single-line text field.
41
+ *
42
+ * `label` is the accessible name and should always be set; it renders a real
43
+ * `<label>` bound to the control. `description` and `error` are wired to it
44
+ * with `aria-describedby` for you.
45
+ *
46
+ * Passing `error` marks the field invalid and shows the message
47
+ * unconditionally — use it for a server response or a form library. Leave it
48
+ * undefined to let native constraint validation (`required`, `type="email"`,
49
+ * `pattern`) drive the invalid state instead.
50
+ *
51
+ * `className` and `style` land on the field wrapper, which is the element the
52
+ * surrounding layout sees; every other prop reaches the `<input>`.
53
+ *
54
+ * @example
55
+ * <Input
56
+ * label="Email"
57
+ * type="email"
58
+ * required
59
+ * description="We'll only use this to sign you in."
60
+ * error={serverError}
61
+ * />
62
+ */
63
+ export declare function Input({ label, description, error, size, disabled, name, className, style, ...props }: InputProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,87 @@
1
+ import { Responsive } from './responsive';
2
+ /**
3
+ * Twenty-four is the whole grid, and it is fixed — a Grid always lays out on
4
+ * the same 24 tracks, so two grids of the same width share column positions
5
+ * without a shared template. Children say how much of it they occupy.
6
+ *
7
+ * Decided in apps/docs/decisions/0003-layout-children.html.
8
+ */
9
+ export type GridSpan = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24;
10
+ /**
11
+ * The column counts a Grid can distribute its children across — the divisors
12
+ * of 24, and nothing else. `columns={5}` would need tracks of 4.8, so it is a
13
+ * type error rather than a silent rounding.
14
+ */
15
+ export type GridColumns = 1 | 2 | 3 | 4 | 6 | 8 | 12 | 24;
16
+ /** The number of tracks in the grid. */
17
+ export declare const GRID_COLUMNS = 24;
18
+ export type LayoutAlign = 'start' | 'center' | 'end' | 'stretch' | 'baseline';
19
+ export type LayoutJustify = 'start' | 'center' | 'end' | 'between' | 'around';
20
+ export type LayoutDirection = 'row' | 'column' | 'row-reverse' | 'column-reverse';
21
+ export type LayoutSpacing = '100' | '200' | '300' | '400' | '500' | '600' | '700' | '800' | '900';
22
+ /**
23
+ * The props that describe how a component sits inside its parent, rather than
24
+ * how it arranges its own children.
25
+ *
26
+ * Every layout primitive carries all three, because every layout primitive can
27
+ * be a child of any other — a Grid nested in a Grid, a Stack inside a Stack, a
28
+ * Box in either. Which of them does anything depends on the parent: `span`
29
+ * applies inside a Grid, `grow` inside a Stack, `alignSelf` in either. A prop
30
+ * that does not apply is inert rather than an error, which is the same
31
+ * contract `Box` has had since 0003.
32
+ *
33
+ * Deliberately not on content components. Button and Input still get their
34
+ * position from a layout wrapper; this is the line 0003 drew and it has not
35
+ * moved — what changed is that the containers are on the child side of it too.
36
+ */
37
+ export interface LayoutChildProps {
38
+ /**
39
+ * How many of a parent Grid's 24 columns to occupy. Overrides the
40
+ * distribution the Grid set with `columns`.
41
+ *
42
+ * @example
43
+ * <Grid columns={3}>
44
+ * <Stack span={16}>...</Stack>
45
+ * <Box span={8}>...</Box>
46
+ * </Grid>
47
+ */
48
+ span?: Responsive<GridSpan>;
49
+ /** Take the space left over by siblings. Only meaningful inside a Stack. */
50
+ grow?: Responsive<boolean>;
51
+ /**
52
+ * Override the parent's `align` for this child alone. Works in both Stack
53
+ * and Grid.
54
+ *
55
+ * Stack's `align` defaults to `start`, so this is how a single child says it
56
+ * should fill the cross axis without changing the whole row. Note the pair
57
+ * on a container: `align` is what it does to its children, `alignSelf` is
58
+ * what it does to itself.
59
+ */
60
+ alignSelf?: Responsive<LayoutAlign>;
61
+ }
62
+ /** Sprinkles keys its span values by string; the prop reads better as a number. */
63
+ export declare const toSpanKey: (value: Responsive<GridSpan>) => Responsive<`${GridSpan}`>;
64
+ /** Sprinkles keys its values by string; `grow` reads better as a boolean. */
65
+ export declare const toGrowKey: (value: Responsive<boolean>) => Responsive<"0" | "1">;
66
+ /**
67
+ * `LayoutChildProps` with every key present and possibly undefined, which is
68
+ * what the props look like once a component has destructured them. The
69
+ * optional form would be rejected under `exactOptionalPropertyTypes`.
70
+ */
71
+ type ChildLayoutValues = {
72
+ [K in keyof LayoutChildProps]-?: LayoutChildProps[K] | undefined;
73
+ };
74
+ /**
75
+ * The child-side props as arguments for `layoutSprinkles`, so each primitive
76
+ * folds them into the single sprinkles call it already makes rather than
77
+ * emitting a second class string.
78
+ *
79
+ * Returned as an argument fragment rather than a class name to keep this
80
+ * module free of a dependency on `layout.css.ts`.
81
+ */
82
+ export declare const childLayout: ({ span, grow, alignSelf }: ChildLayoutValues) => {
83
+ alignSelf?: Responsive<LayoutAlign>;
84
+ flexGrow?: Responsive<"0" | "1">;
85
+ gridColumn?: Responsive<"1" | "2" | "3" | "14" | "4" | "5" | "6" | "7" | "8" | "9" | "10" | "11" | "12" | "13" | "15" | "16" | "17" | "18" | "19" | "20" | "21" | "22" | "23" | "24">;
86
+ };
87
+ export {};
@@ -0,0 +1,2 @@
1
+ export { Link } from './link';
2
+ export type { LinkProps, LinkVariant } from './link';
@@ -0,0 +1,125 @@
1
+ import { useRender } from '@base-ui/react/use-render';
2
+ import { AnchorHTMLAttributes, Ref } from 'react';
3
+ import { IconName } from '../icon';
4
+ import { ButtonSize, ButtonVariant } from '../button';
5
+ import { TypeStyles } from '../typography';
6
+ /**
7
+ * How loud the link is.
8
+ *
9
+ * `text` is the ordinary underlined link in a sentence; the other five are
10
+ * Button's, and mean exactly what they mean there. One axis rather than two
11
+ * components, decided in apps/docs/decisions/0009-link.html (D1) — a caller
12
+ * who starts with a text link and later wants it to look like a button changes
13
+ * a prop, not a component.
14
+ */
15
+ export type LinkVariant = 'text' | ButtonVariant;
16
+ /** What Link owns, whichever variant is in play. */
17
+ interface LinkOwnProps {
18
+ /**
19
+ * Required. A Link without a target is not a link — it is text, or a Button.
20
+ * There is deliberately no `disabled`: `:disabled` never matches an anchor,
21
+ * and an anchor without `href` is not focusable or activatable, so a
22
+ * "disabled link" can only be announced, never reached (0009, settled list).
23
+ */
24
+ href: string;
25
+ variant?: LinkVariant;
26
+ /**
27
+ * Sizes the five box variants. No effect on `variant="text"`, whose type
28
+ * comes from the parent or from `with` rather than from this ramp (0009 D3).
29
+ */
30
+ size?: ButtonSize;
31
+ /**
32
+ * Names a Typography preset, for a text link with no typographic parent to
33
+ * inherit from. When passed it beats the inherited type — an explicit prop
34
+ * at the call site outranks an ambient value the caller did not set (0009
35
+ * D3's outcome). Ignored by the box variants, which take Button's sizing.
36
+ */
37
+ with?: TypeStyles;
38
+ /**
39
+ * Underlines the text variant. On by default: with an inherited colour the
40
+ * underline is the only thing distinguishing a link from the words around
41
+ * it, so colour alone would be carrying the meaning (WCAG 1.4.1).
42
+ *
43
+ * `false` means never — there is no hover underline behind it. That makes it
44
+ * right for somewhere the link is already obviously a link (a nav row, a
45
+ * breadcrumb) and wrong in running text, which 0009 D5 accepted knowingly.
46
+ */
47
+ underline?: boolean;
48
+ /**
49
+ * Marks a link that leaves the app: the `arrow-square-out` glyph after the
50
+ * label, `target="_blank"`, `rel="noopener noreferrer"`, and a visually
51
+ * hidden "(opens in a new tab)" so the announcement matches what happens.
52
+ *
53
+ * The new tab is the component's opinion here, not the call site's — 0009 D6
54
+ * chose the whole convention over a marker alone, which means a caller who
55
+ * wants the glyph *without* a new tab wants `icon="arrow-square-out"` and
56
+ * `iconPosition="end"` instead.
57
+ */
58
+ external?: boolean;
59
+ /**
60
+ * An icon from the curated set, sized and spaced by the component rather
61
+ * than by the caller. Decorative — the label names the link.
62
+ */
63
+ icon?: IconName;
64
+ /** Which side of the label the icon sits on. */
65
+ iconPosition?: 'start' | 'end';
66
+ /**
67
+ * An element to render instead of the bare anchor — a router's link, so that
68
+ * client-side navigation works without Jig depending on a router.
69
+ *
70
+ * Not an `as` prop wearing a different hat. `as` asks a component to *be*
71
+ * another element and to take that element's prop types; this hands Link's
72
+ * own props and classes to an element the caller already constructed, and
73
+ * merges rather than overwrites, so Jig's `className` and the router's
74
+ * `onClick` both survive. Link is an anchor either way. Decided in 0009 D4.
75
+ */
76
+ render?: useRender.RenderProp;
77
+ ref?: Ref<HTMLAnchorElement>;
78
+ }
79
+ /** Attributes React declares that Link decides for itself. */
80
+ type Reserved = keyof LinkOwnProps | 'color';
81
+ /**
82
+ * `iconPosition="end"` is a type error alongside `external`, which owns that
83
+ * slot. A glyph at each end is legitimate, so `icon` at the default `start`
84
+ * still works — it is only the collision that is refused. Carried from 0009
85
+ * D6's outcome.
86
+ */
87
+ type ExternalProps = {
88
+ external: true;
89
+ iconPosition?: 'start' | undefined;
90
+ };
91
+ type LocalProps = {
92
+ external?: false | undefined;
93
+ iconPosition?: 'start' | 'end' | undefined;
94
+ };
95
+ export type LinkProps = LinkOwnProps & Omit<AnchorHTMLAttributes<HTMLAnchorElement>, Reserved | 'iconPosition'> & (ExternalProps | LocalProps);
96
+ /**
97
+ * A link.
98
+ *
99
+ * `href` is required. Defaults to `variant="text"` — an underlined link that
100
+ * takes the colour and size of the text around it, so it fits whatever it is
101
+ * dropped into. Set `with` to name a type preset when there is no surrounding
102
+ * text to inherit from, or `underline={false}` where the link is already
103
+ * obviously one, such as a nav row.
104
+ *
105
+ * The other variants are Button's, for a call to action that navigates. It is
106
+ * still a link: announced as one, activated with Enter, and openable in a new
107
+ * tab.
108
+ *
109
+ * `external` marks a link that leaves the app — it adds a trailing icon, opens
110
+ * a new tab, and tells assistive technology that it will.
111
+ *
112
+ * Pass `render` to hand the markup to a router's own link component so
113
+ * client-side navigation works.
114
+ *
115
+ * @example
116
+ * <Typography as="p">
117
+ * Released under the <Link href="https://opensource.org/license/mit" external>MIT licence</Link>.
118
+ * </Typography>
119
+ *
120
+ * <Link href="/dashboard" variant="primary" render={<NextLink href="/dashboard" />}>
121
+ * Open dashboard
122
+ * </Link>
123
+ */
124
+ export declare function Link({ href, variant, size, with: typeStyle, underline, external, icon, iconPosition, render, className, children, ref, ...props }: LinkProps): import('react').ReactElement<unknown, string | import('react').JSXElementConstructor<any>>;
125
+ export {};
@@ -0,0 +1,2 @@
1
+ export { ListItem } from './listitem';
2
+ export type { ListItemProps, ListItemOwnProps, ListItemElement, ListItemSize } from './listitem';
@@ -0,0 +1,92 @@
1
+ import { MouseEventHandler, ReactNode } from 'react';
2
+ import { IconName } from '../icon';
3
+ import { PolymorphicProps } from '../polymorphic';
4
+ /**
5
+ * The elements a ListItem is willing to render as.
6
+ *
7
+ * Two, and only two. `li` is the default because a nav list is the case that
8
+ * needs the semantics: a real `li` inside a list gets its position and count
9
+ * computed by the browser, which is what produces "3 of 8". `div` is the
10
+ * escape hatch for a row that is not in a list — a settings row, a card body —
11
+ * and a caller who takes it owns `aria-setsize` and `aria-posinset` from then
12
+ * on.
13
+ *
14
+ * This union is why `ListItem` has an `as` prop at all when the rule is that
15
+ * polymorphism stays on layout and typography components. Decided in
16
+ * apps/docs/decisions/0014-sidebar-navigation.html (D2), which amends that
17
+ * rule to "layout and typography components, plus ListItem".
18
+ */
19
+ export type ListItemElement = 'li' | 'div';
20
+ export type ListItemSize = 'sm' | 'md' | 'lg';
21
+ /** ListItem's own props. The element's own attributes are added by PolymorphicProps. */
22
+ export interface ListItemOwnProps {
23
+ /** The row's text. Truncates rather than wrapping. */
24
+ children?: ReactNode;
25
+ /**
26
+ * Content before the label — an icon, an avatar, an image, a swatch.
27
+ *
28
+ * **Non-interactive only.** It renders inside the row's anchor or button, so
29
+ * a checkbox or a button here would be an interactive descendant of one,
30
+ * which HTML forbids and browsers handle by making one of the two
31
+ * unreachable. Put interactive content in `end`, which is a sibling.
32
+ * Decided in 0014 D1.
33
+ */
34
+ start?: ReactNode;
35
+ /**
36
+ * Content after the label, outside the row's control — a count, a Token, an
37
+ * IconButton, an overflow menu. The only slot that may hold something
38
+ * interactive.
39
+ */
40
+ end?: ReactNode;
41
+ /**
42
+ * Makes the row a link. The anchor covers the indicator, `start`, the label
43
+ * and the row's padding — everything except `end`.
44
+ */
45
+ href?: string;
46
+ /** Makes the row a button. Ignored when `href` is set. */
47
+ onClick?: MouseEventHandler<HTMLElement>;
48
+ size?: ListItemSize;
49
+ /**
50
+ * Marks the row as the current one: the ghost active fill, plus
51
+ * `aria-current="page"` on the link when there is one.
52
+ */
53
+ selected?: boolean;
54
+ /**
55
+ * An icon shown only while the row is selected, in a gutter at the leading
56
+ * edge that every row reserves whether selected or not — so the labels form
57
+ * one column instead of shifting as the selection moves.
58
+ *
59
+ * **Set it consistently across a list.** The gutter is reserved per row, so
60
+ * a list where only some rows pass it will not line up. Nothing in the type
61
+ * can enforce that. Decided in 0014 D3.
62
+ */
63
+ selectedIcon?: IconName | false;
64
+ /** Disables a button row. Has no effect on a link — see Link's note (0009). */
65
+ disabled?: boolean;
66
+ }
67
+ export type ListItemProps<E extends ListItemElement = 'li'> = PolymorphicProps<E, ListItemOwnProps>;
68
+ /**
69
+ * A row: `start`, a label, and `end`.
70
+ *
71
+ * The whole row is the link when `href` is set — everything except the `end`
72
+ * slot, which sits outside it so it can hold a button. That split is the
73
+ * component's central rule: **`start` takes non-interactive content, `end` is
74
+ * the interactive one.** Nesting a button inside a link is invalid HTML and
75
+ * leaves one of the two unreachable.
76
+ *
77
+ * `selected` marks the current row. Pair it with `selectedIcon` for a tick in
78
+ * a reserved leading gutter, set consistently across the list so the labels
79
+ * line up.
80
+ *
81
+ * Renders an `<li>`, for a list. Pass `as="div"` for a row that is not in one.
82
+ *
83
+ * @example
84
+ * <ListItem href="/docs/tokens" start={<Icon icon="star" />} selected selectedIcon="check">
85
+ * Tokens
86
+ * </ListItem>
87
+ *
88
+ * <ListItem start={<Icon icon="bell" />} end={<IconButton icon="x" label="Dismiss" />}>
89
+ * Notifications
90
+ * </ListItem>
91
+ */
92
+ export declare function ListItem<E extends ListItemElement = 'li'>({ as, children, start, end, href, onClick, size, selected, selectedIcon, disabled, className, ...props }: ListItemProps<E>): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,31 @@
1
+ import { ComponentPropsWithoutRef, ComponentRef, ElementType, Ref } from 'react';
2
+ /**
3
+ * Props for a component that renders as one of a *restricted* set of elements.
4
+ *
5
+ * `E` is deliberately constrained by each component to its own union of
6
+ * legitimate tags rather than left open as `ElementType`. Arbitrary
7
+ * polymorphism would let a Stack render as a `<span>` or Adorn as a `<div>`,
8
+ * and would promise a flexibility the implementation never had.
9
+ *
10
+ * What this adds over declaring `as`, `HTMLAttributes<HTMLElement>` and `ref`
11
+ * by hand is *correlation*: the props and the ref follow the chosen element.
12
+ * `Typography as="label"` accepts `htmlFor`, `as="blockquote"` accepts `cite`,
13
+ * `Stack as="ol"` accepts `start` and `reversed`, and each gets a precise ref
14
+ * (`HTMLLabelElement`, `HTMLQuoteElement`, `HTMLOListElement`) instead of a
15
+ * blanket `HTMLElement`. All of those were type errors under the previous
16
+ * hand-declared pattern.
17
+ *
18
+ * `Own` wins on collision — `Omit`ting it from the element's attributes is
19
+ * what lets Stack define its own `spacing` without `HTMLAttributes` fighting
20
+ * it. `as` is omitted from the same side so it cannot be doubly declared.
21
+ *
22
+ * @example
23
+ * export type StackProps<E extends StackElement = 'div'> =
24
+ * PolymorphicProps<E, StackOwnProps>;
25
+ *
26
+ * export function Stack<E extends StackElement = 'div'>(props: StackProps<E>) {}
27
+ */
28
+ export type PolymorphicProps<E extends ElementType, Own> = Own & Omit<ComponentPropsWithoutRef<E>, keyof Own | 'as'> & {
29
+ as?: E;
30
+ ref?: Ref<ComponentRef<E>>;
31
+ };
package/dist/reset.css ADDED
@@ -0,0 +1,4 @@
1
+ @layer jig.reset, jig.tokens, jig.base, jig.components;
2
+
3
+ @layer jig.reset{:root{box-sizing:border-box}html,body{margin:0;padding:0}h1,h2,h3,h4,h5,h6,p{font-weight:400;font-size:inherit;margin:0;padding:0;font-style:normal}}
4
+ /*$vite$:1*/
@@ -0,0 +1,10 @@
1
+ import { Breakpoint } from './breakpoints';
2
+ /**
3
+ * A responsive prop value — either a plain value applied at all breakpoints,
4
+ * or an object mapping breakpoints to values (mobile-first, min-width).
5
+ *
6
+ * @example
7
+ * direction="column"
8
+ * direction={{ xs: 'column', lg: 'row' }}
9
+ */
10
+ export type Responsive<T> = T | Partial<Record<Breakpoint, T>>;
@@ -0,0 +1,2 @@
1
+ export { ScrollArea } from './scrollarea';
2
+ export type { ScrollAreaProps } from './scrollarea';
@@ -0,0 +1,26 @@
1
+ import { HTMLAttributes, ReactNode, Ref } from 'react';
2
+ export interface ScrollAreaProps extends Omit<HTMLAttributes<HTMLDivElement>, 'className'> {
3
+ /** The scrolling content. */
4
+ children?: ReactNode;
5
+ /** Applied to the root — the element whose height constrains the scroll. */
6
+ className?: string;
7
+ ref?: Ref<HTMLDivElement>;
8
+ }
9
+ /**
10
+ * A region that scrolls, with a styled scrollbar in place of the platform's.
11
+ *
12
+ * The height is yours to set: it only scrolls once something constrains it, so
13
+ * give it a `maxHeight`, or put it in a flex or grid parent that bounds it
14
+ * (remembering `min-height: 0` on the flex child above it).
15
+ *
16
+ * No chrome at rest. The scrollbar appears on hover, on focus within, and
17
+ * while scrolling; a gradient mask at the cropped edges shows there is more in
18
+ * the meantime. Space for the scrollbar is always reserved, so content does not
19
+ * shift when it appears.
20
+ *
21
+ * @example
22
+ * <ScrollArea style={{ maxHeight: '20rem' }}>
23
+ * {messages.map((m) => <Message key={m.id} {...m} />)}
24
+ * </ScrollArea>
25
+ */
26
+ export declare function ScrollArea({ className, children, ref, ...props }: ScrollAreaProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,2 @@
1
+ export { Separator } from './separator';
2
+ export type { SeparatorProps, SeparatorOrientation } from './separator';
@@ -0,0 +1,48 @@
1
+ import { CSSProperties, Ref } from 'react';
2
+ export type SeparatorOrientation = 'horizontal' | 'vertical';
3
+ export interface SeparatorProps {
4
+ /**
5
+ * Which way the rule runs. A vertical separator takes its length from the
6
+ * flex or grid row it sits in, so it renders as nothing outside one.
7
+ */
8
+ orientation?: SeparatorOrientation;
9
+ /**
10
+ * Hides the rule from assistive technology, for a divider that is decoration
11
+ * rather than a boundary.
12
+ *
13
+ * Reach for it wherever the structure already exists in the markup — between
14
+ * buttons in a labelled toolbar, or between items in a list. Leave it off
15
+ * where the rule itself is the only thing marking a boundary, which is when
16
+ * a screen reader user needs to hear about it.
17
+ */
18
+ decorative?: boolean;
19
+ className?: string;
20
+ style?: CSSProperties;
21
+ ref?: Ref<HTMLDivElement>;
22
+ }
23
+ /**
24
+ * A rule that divides content.
25
+ *
26
+ * `orientation="vertical"` takes its length from the flex or grid row it sits
27
+ * in — it has no height of its own, so give it a parent that has one.
28
+ *
29
+ * By default it is announced as a separator. Pass `decorative` where the rule
30
+ * is only visual and the structure is already carried by a labelled group, a
31
+ * list or a heading, so it is not read out as noise.
32
+ *
33
+ * Spacing around it comes from the parent, like every other component.
34
+ *
35
+ * @example
36
+ * <Stack spacing="500">
37
+ * <Typography as="h2" with="heading04">Ingredients</Typography>
38
+ * <Separator />
39
+ * <Typography as="h2" with="heading04">Method</Typography>
40
+ * </Stack>
41
+ *
42
+ * <Stack direction="row" spacing="300" align="center">
43
+ * <ToggleButton value="bold" isIconOnly icon="star" label="Bold" />
44
+ * <Separator orientation="vertical" decorative />
45
+ * <ToggleButton value="italic" isIconOnly icon="heart" label="Italic" />
46
+ * </Stack>
47
+ */
48
+ export declare function Separator({ orientation, decorative, className, style, ref, }: SeparatorProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,2 @@
1
+ export { SideNav } from './sidenav';
2
+ export type { SideNavProps } from './sidenav';
@@ -0,0 +1,35 @@
1
+ import { HTMLAttributes, ReactNode, Ref } from 'react';
2
+ export interface SideNavProps extends Omit<HTMLAttributes<HTMLElement>, 'children' | 'title'> {
3
+ /** The sections and rows. Normally `SideNavSection`s. */
4
+ children?: ReactNode;
5
+ /** Pinned above the scrolling area — a product mark, a search field. */
6
+ header?: ReactNode;
7
+ /** Pinned below it — an account row, a theme switch. */
8
+ footer?: ReactNode;
9
+ /**
10
+ * The accessible name. Required in practice: a page with two navigation
11
+ * landmarks and no names leaves a screen reader user choosing between
12
+ * "navigation" and "navigation". A missing one logs a development warning.
13
+ */
14
+ 'aria-label'?: string;
15
+ className?: string;
16
+ ref?: Ref<HTMLElement>;
17
+ }
18
+ /**
19
+ * A sidebar navigation region.
20
+ *
21
+ * Renders a `<nav>` and takes its accessible name from `aria-label`. `header`
22
+ * and `footer` are pinned; whatever is between them scrolls in a `ScrollArea`
23
+ * when it overflows.
24
+ *
25
+ * It has no width of its own — that belongs to the layout around it, so give
26
+ * it one with `style` or a parent grid column.
27
+ *
28
+ * @example
29
+ * <SideNav aria-label="Docs" header={<Search />} footer={<AccountRow />} style={{ width: '16rem' }}>
30
+ * <SideNavSection label="Getting started" collapsible defaultOpen>
31
+ * <ListItem href="/docs/install">Installation</ListItem>
32
+ * </SideNavSection>
33
+ * </SideNav>
34
+ */
35
+ export declare function SideNav({ children, header, footer, className, ref, ...props }: SideNavProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,2 @@
1
+ export { SideNavSection } from './sidenavsection';
2
+ export type { SideNavSectionProps } from './sidenavsection';
@@ -0,0 +1,44 @@
1
+ import { CSSProperties, HTMLAttributes, ReactNode, Ref } from 'react';
2
+ export interface SideNavSectionProps extends Omit<HTMLAttributes<HTMLDivElement>, 'className' | 'style' | 'children'> {
3
+ /**
4
+ * The section's heading. Optional — a section with no label is just a
5
+ * grouped list, which is how ungrouped items get their list semantics.
6
+ */
7
+ label?: ReactNode;
8
+ /** The rows. Normally `ListItem`s. */
9
+ children?: ReactNode;
10
+ /**
11
+ * Lets the section be folded away. Requires `label`, which becomes the
12
+ * disclosure trigger — there is nothing else to press.
13
+ *
14
+ * Uses `Collapsible` rather than a disclosure of its own (0014 D4), so it
15
+ * inherits the measured-height animation, the reduced-motion guard and the
16
+ * `plus`/`minus` indicator 0013 D3 chose.
17
+ */
18
+ collapsible?: boolean;
19
+ /** Open state for a collapsing section. Omit to let it manage its own. */
20
+ open?: boolean;
21
+ defaultOpen?: boolean;
22
+ onOpenChange?: (open: boolean) => void;
23
+ className?: string;
24
+ style?: CSSProperties;
25
+ ref?: Ref<HTMLDivElement>;
26
+ }
27
+ /**
28
+ * A labelled group of rows inside a `SideNav`.
29
+ *
30
+ * `label` is optional; without one the section is a bare list, which is how a
31
+ * run of ungrouped items still gets its list semantics. With `collapsible` the
32
+ * label becomes a disclosure trigger and the rows fold away.
33
+ *
34
+ * The rows are wrapped in a `<ul role="list">` — the role as well as the
35
+ * element, because WebKit drops list semantics from a `ul` styled with
36
+ * `list-style: none`.
37
+ *
38
+ * @example
39
+ * <SideNavSection label="Components" collapsible defaultOpen>
40
+ * <ListItem href="/docs/button">Button</ListItem>
41
+ * <ListItem href="/docs/combobox">Combobox</ListItem>
42
+ * </SideNavSection>
43
+ */
44
+ export declare function SideNavSection({ label, children, collapsible, open, defaultOpen, onOpenChange, className, style, ref, ...props }: SideNavSectionProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,2 @@
1
+ export { Slider } from './slider';
2
+ export type { SliderProps, SliderSize } from './slider';