@kanso-labs/kanso-ui 0.8.2 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -49,6 +49,31 @@ StyleX compiles the library's own rules into a CSS `@layer`, and your app's
49
49
  stylesheet is unlayered, so your rules win the cascade wherever the two meet —
50
50
  no specificity contest, and no `!important`.
51
51
 
52
+ ### Layout
53
+
54
+ `Container` centres content at a measure, and `Stack` puts one gap from the
55
+ spacing scale between a row or a column of children. Between them they cover
56
+ page measure, section rhythm, and the ordinary rows and columns that would
57
+ otherwise be bespoke CSS in every consuming app:
58
+
59
+ ```tsx
60
+ <Container>
61
+ <Stack gap="xl">
62
+ <Stack align="center" direction="row" justify="between">
63
+ <Text variant="titleLarge">Headline</Text>
64
+ <Button>Save changes</Button>
65
+ </Stack>
66
+ <Feed minItemWidth="260px">{items}</Feed>
67
+ </Stack>
68
+ </Container>
69
+ ```
70
+
71
+ Both are layout only: they paint no surface and wrap no child. `Stack` is why no
72
+ component here carries a margin of its own, since the space between two things
73
+ belongs to whatever holds both of them. For the page-level layouts — a list
74
+ beside a detail pane, a main pane with a companion — reach for `ListDetail` and
75
+ `SupportingPane` instead.
76
+
52
77
  ### Rendering as a different element
53
78
 
54
79
  `render` swaps the element a component produces, keeping its styling:
@@ -0,0 +1,36 @@
1
+ import { useRender } from "@base-ui/react/use-render";
2
+ //#region src/components/container/index.d.ts
3
+ type ContainerProps = useRender.ComponentProps<'div'> & {
4
+ /**
5
+ * How wide the content may run before it stops growing. The container is
6
+ * centred in whatever space is left over.
7
+ *
8
+ * Worth setting. The default suits a page of mixed components; prose wants
9
+ * a measure in `ch`, since what makes a line hard to read is how many
10
+ * characters it holds rather than how many pixels.
11
+ * @default '960px'
12
+ */
13
+ maxInlineSize?: string;
14
+ /**
15
+ * Inline padding, which is what keeps the content off the edge of the
16
+ * window once it is narrower than the measure. `none` is for a container
17
+ * nested inside one that already has it.
18
+ * @default 'default'
19
+ */
20
+ padding?: 'default' | 'none';
21
+ };
22
+ /**
23
+ * A centred measure for a page or a section of one: content grows to a width
24
+ * and stops, with the leftover space split evenly either side.
25
+ *
26
+ * Layout only — it paints no surface and gives its children no container of
27
+ * their own, which is what separates it from Card. It sets no gaps either, so
28
+ * reach for Stack inside it for the rhythm between sections.
29
+ *
30
+ * `render` swaps the element, for a container that should be a `<main>` or a
31
+ * `<section>` rather than a `<div>`.
32
+ */
33
+ declare function Container({ maxInlineSize, padding, render, ...props }: ContainerProps): import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
34
+ //#endregion
35
+ export { type ContainerProps, Container as default };
36
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,49 @@
1
+ import { props } from "../../node_modules/@stylexjs/stylex/lib/es/stylex.js";
2
+ import { mergeStyles } from "../../styles/merge.js";
3
+ import { useRender } from "@base-ui/react/use-render";
4
+ //#region src/components/container/index.tsx
5
+ const DEFAULT_MAX_INLINE_SIZE = "960px";
6
+ const _temp = {
7
+ kB7OPa: "x9f619",
8
+ kzqmXN: "xh8yej3",
9
+ kUOVxO: "xvueqy4",
10
+ ks0D6T: "x13i5qev",
11
+ "$$css": true
12
+ };
13
+ const styles = {
14
+ paddingDefault: {
15
+ kg3NbH: "xg0ps1x",
16
+ $$css: true
17
+ },
18
+ paddingNone: {
19
+ kg3NbH: "xnjsko4",
20
+ $$css: true
21
+ },
22
+ root: (maxInlineSize) => [_temp, { "--x-maxInlineSize": ((val) => typeof val === "number" ? val + "px" : val != null ? val : void 0)(maxInlineSize) }]
23
+ };
24
+ /**
25
+ * A centred measure for a page or a section of one: content grows to a width
26
+ * and stops, with the leftover space split evenly either side.
27
+ *
28
+ * Layout only — it paints no surface and gives its children no container of
29
+ * their own, which is what separates it from Card. It sets no gaps either, so
30
+ * reach for Stack inside it for the rhythm between sections.
31
+ *
32
+ * `render` swaps the element, for a container that should be a `<main>` or a
33
+ * `<section>` rather than a `<div>`.
34
+ */
35
+ function Container({ maxInlineSize = DEFAULT_MAX_INLINE_SIZE, padding = "default", render, ...props$1 }) {
36
+ const padded = padding === "none" ? styles.paddingNone : styles.paddingDefault;
37
+ return useRender({
38
+ defaultTagName: "div",
39
+ props: {
40
+ ...props$1,
41
+ ...mergeStyles(props(styles.root(maxInlineSize), padded), props$1)
42
+ },
43
+ render
44
+ });
45
+ }
46
+ //#endregion
47
+ export { Container as default };
48
+
49
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../src/components/container/index.tsx"],"sourcesContent":["import { useRender } from '@base-ui/react/use-render';\nimport * as stylex from '@stylexjs/stylex';\nimport { mergeStyles } from '../../styles/merge';\nimport '../../tokens/design.tokens.stylex';\nimport { spacing } from '../../tokens/design.tokens.stylex';\n\n// The width fourteen of this library's own story files already centre their\n// page on, which is what makes it the default rather than a number picked\n// here. A measure is a property of the content: 960px suits a page of mixed\n// components, and prose wants something nearer 58ch, which is what the story\n// files that hold prose use. Say which one you mean rather than taking this.\nconst DEFAULT_MAX_INLINE_SIZE = '960px';\n\n// A dynamic style rather than a static one, for the same reason Feed's is:\n// the measure comes from the call site and StyleX compiles its classes ahead\n// of time, so the value is written to a custom property inline instead.\nconst _temp = {\n kB7OPa: \"x9f619\",\n kzqmXN: \"xh8yej3\",\n kUOVxO: \"xvueqy4\",\n ks0D6T: \"x13i5qev\",\n \"$$css\": true\n};\nconst styles = {\n paddingDefault: {\n kg3NbH: \"xg0ps1x\",\n $$css: true\n },\n paddingNone: {\n kg3NbH: \"xnjsko4\",\n $$css: true\n },\n root: (maxInlineSize: string) => [_temp, {\n \"--x-maxInlineSize\": (val => typeof val === \"number\" ? val + \"px\" : val != null ? val : undefined)(maxInlineSize)\n }]\n};\ntype ContainerProps = useRender.ComponentProps<'div'> & {\n /**\n * How wide the content may run before it stops growing. The container is\n * centred in whatever space is left over.\n *\n * Worth setting. The default suits a page of mixed components; prose wants\n * a measure in `ch`, since what makes a line hard to read is how many\n * characters it holds rather than how many pixels.\n * @default '960px'\n */\n maxInlineSize?: string;\n /**\n * Inline padding, which is what keeps the content off the edge of the\n * window once it is narrower than the measure. `none` is for a container\n * nested inside one that already has it.\n * @default 'default'\n */\n padding?: 'default' | 'none';\n};\n\n/**\n * A centred measure for a page or a section of one: content grows to a width\n * and stops, with the leftover space split evenly either side.\n *\n * Layout only — it paints no surface and gives its children no container of\n * their own, which is what separates it from Card. It sets no gaps either, so\n * reach for Stack inside it for the rhythm between sections.\n *\n * `render` swaps the element, for a container that should be a `<main>` or a\n * `<section>` rather than a `<div>`.\n */\nfunction Container({\n maxInlineSize = DEFAULT_MAX_INLINE_SIZE,\n padding = 'default',\n render,\n ...props\n}: ContainerProps) {\n const padded = padding === 'none' ? styles.paddingNone : styles.paddingDefault;\n return useRender({\n defaultTagName: 'div',\n props: {\n ...props,\n ...mergeStyles(stylex.props(styles.root(maxInlineSize), padded), props)\n },\n render\n });\n}\nexport type { ContainerProps };\nexport default Container;"],"mappings":";;;;AAWA,MAAM,0BAA0B;AAKhC,MAAM,QAAQ;CACZ,QAAQ;CACR,QAAQ;CACR,QAAQ;CACR,QAAQ;CACR,SAAS;AACX;AACA,MAAM,SAAS;CACb,gBAAgB;EACd,QAAQ;EACR,OAAO;CACT;CACA,aAAa;EACX,QAAQ;EACR,OAAO;CACT;CACA,OAAO,kBAA0B,CAAC,OAAO,EACvC,uBAAsB,QAAO,OAAO,QAAQ,WAAW,MAAM,OAAO,OAAO,OAAO,MAAM,KAAA,EAAA,CAAW,aAAa,EAClH,CAAC;AACH;;;;;;;;;;;;AAgCA,SAAS,UAAU,EACjB,gBAAgB,yBAChB,UAAU,WACV,QACA,GAAG,WACc;CACjB,MAAM,SAAS,YAAY,SAAS,OAAO,cAAc,OAAO;CAChE,OAAO,UAAU;EACf,gBAAgB;EAChB,OAAO;GACL,GAAG;GACH,GAAG,YAAY,MAAa,OAAO,KAAK,aAAa,GAAG,MAAM,GAAG,OAAK;EACxE;EACA;CACF,CAAC;AACH"}
@@ -5,6 +5,7 @@ import Button, { ButtonProps } from "./button/index.js";
5
5
  import Card, { CardProps } from "./card/index.js";
6
6
  import Chip, { ChipProps } from "./chip/index.js";
7
7
  import Code, { CodeProps } from "./code/index.js";
8
+ import Container, { ContainerProps } from "./container/index.js";
8
9
  import CopyField, { CopyFieldProps } from "./copy-field/index.js";
9
10
  import Currency, { CurrencyProps } from "./currency/index.js";
10
11
  import Feed, { FeedProps } from "./feed/index.js";
@@ -16,8 +17,9 @@ import ListItem, { ListItemProps } from "./list-item/index.js";
16
17
  import ProductIcon, { ProductIconProps } from "./product-icon/index.js";
17
18
  import Separator, { SeparatorProps } from "./separator/index.js";
18
19
  import Sheet, { SheetProps } from "./sheet/index.js";
20
+ import Stack, { StackAlign, StackGap, StackJustify, StackProps } from "./stack/index.js";
19
21
  import SupportingPane, { SupportingPaneProps } from "./supporting-pane/index.js";
20
22
  import Tabs, { TabsProps } from "./tabs/index.js";
21
23
  import Text, { TextProps } from "./text/index.js";
22
24
  import TextField, { TextFieldProps } from "./text-field/index.js";
23
- export { AppBar, type AppBarProps, Avatar, type AvatarProps, Badge, type BadgeProps, Button, type ButtonProps, Card, type CardProps, Chip, type ChipProps, Code, type CodeProps, CopyField, type CopyFieldProps, Currency, type CurrencyProps, Feed, type FeedProps, IconButton, type IconButtonProps, Keycap, type KeycapProps, Link, type LinkProps, ListDetail, type ListDetailProps, ListItem, type ListItemProps, ProductIcon, type ProductIconProps, Separator, type SeparatorProps, Sheet, type SheetProps, SupportingPane, type SupportingPaneProps, Tabs, type TabsProps, Text, TextField, type TextFieldProps, type TextProps };
25
+ export { AppBar, type AppBarProps, Avatar, type AvatarProps, Badge, type BadgeProps, Button, type ButtonProps, Card, type CardProps, Chip, type ChipProps, Code, type CodeProps, Container, type ContainerProps, CopyField, type CopyFieldProps, Currency, type CurrencyProps, Feed, type FeedProps, IconButton, type IconButtonProps, Keycap, type KeycapProps, Link, type LinkProps, ListDetail, type ListDetailProps, ListItem, type ListItemProps, ProductIcon, type ProductIconProps, Separator, type SeparatorProps, Sheet, type SheetProps, Stack, type StackAlign, type StackGap, type StackJustify, type StackProps, SupportingPane, type SupportingPaneProps, Tabs, type TabsProps, Text, TextField, type TextFieldProps, type TextProps };
@@ -0,0 +1,60 @@
1
+ import { useRender } from "@base-ui/react/use-render";
2
+ //#region src/components/stack/index.d.ts
3
+ type StackAlign = 'baseline' | 'center' | 'end' | 'start' | 'stretch';
4
+ type StackGap = 'lg' | 'md' | 'none' | 'sm' | 'xl' | 'xs' | 'xxl' | 'xxs' | 'xxxl';
5
+ type StackJustify = 'around' | 'between' | 'center' | 'end' | 'start';
6
+ type StackProps = {
7
+ /**
8
+ * How the children line up across the stack: down the inline axis of a
9
+ * column, down the block axis of a row. Left unset, they stretch, which is
10
+ * what makes every card in a column the same width.
11
+ *
12
+ * `start` is what an inline-sized child needs in a column — a Badge or a
13
+ * Chip spans the whole width otherwise.
14
+ */
15
+ align?: StackAlign;
16
+ /**
17
+ * Which way the children run.
18
+ * @default 'column'
19
+ */
20
+ direction?: 'column' | 'row';
21
+ /**
22
+ * The space between children, as a step of the spacing scale. `none` closes
23
+ * it entirely.
24
+ *
25
+ * Worth setting. The default is a middle step, and how much air a group of
26
+ * things wants is the one thing a stack cannot work out for itself.
27
+ * @default 'md'
28
+ */
29
+ gap?: StackGap;
30
+ /**
31
+ * How leftover space is distributed along the stack. Left unset, the
32
+ * children sit at the start and the space collects after them.
33
+ *
34
+ * `between` is the one that puts a headline at one end of a row and its
35
+ * actions at the other.
36
+ */
37
+ justify?: StackJustify;
38
+ /**
39
+ * Lets a row wrap onto further lines rather than overflowing. Has no effect
40
+ * on a column, which has as many lines as it has children.
41
+ * @default false
42
+ */
43
+ wrap?: boolean;
44
+ } & useRender.ComponentProps<'div'>;
45
+ /**
46
+ * A row or a column of children with one gap between them, taken from the
47
+ * spacing scale.
48
+ *
49
+ * Layout only — it paints no surface and wraps no child, so each child is a
50
+ * flex item exactly as it was written. It is the answer to spacing a group of
51
+ * things, which is why no component here carries a margin of its own: the
52
+ * space between two things belongs to whatever holds both of them.
53
+ *
54
+ * `render` swaps the element, for a stack that should be a `<ul>`, a `<nav>`,
55
+ * or a `<section>` rather than a `<div>`.
56
+ */
57
+ declare function Stack({ align, direction, gap, justify, render, wrap, ...props }: StackProps): import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
58
+ //#endregion
59
+ export { type StackAlign, type StackGap, type StackJustify, type StackProps, Stack as default };
60
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,131 @@
1
+ import { props } from "../../node_modules/@stylexjs/stylex/lib/es/stylex.js";
2
+ import { mergeStyles } from "../../styles/merge.js";
3
+ import { useRender } from "@base-ui/react/use-render";
4
+ //#region src/components/stack/index.tsx
5
+ const alignments = {
6
+ baseline: {
7
+ kGNEyG: "x1pha0wt",
8
+ $$css: true
9
+ },
10
+ center: {
11
+ kGNEyG: "x6s0dn4",
12
+ $$css: true
13
+ },
14
+ end: {
15
+ kGNEyG: "xuk3077",
16
+ $$css: true
17
+ },
18
+ start: {
19
+ kGNEyG: "x1cy8zhl",
20
+ $$css: true
21
+ },
22
+ stretch: {
23
+ kGNEyG: "x1qjc9v5",
24
+ $$css: true
25
+ }
26
+ };
27
+ const gaps = {
28
+ lg: {
29
+ kOIVth: "xxj4525",
30
+ $$css: true
31
+ },
32
+ md: {
33
+ kOIVth: "x1gka490",
34
+ $$css: true
35
+ },
36
+ none: {
37
+ kOIVth: "xxhr3t",
38
+ $$css: true
39
+ },
40
+ sm: {
41
+ kOIVth: "x126z3so",
42
+ $$css: true
43
+ },
44
+ xl: {
45
+ kOIVth: "xj2l1yv",
46
+ $$css: true
47
+ },
48
+ xs: {
49
+ kOIVth: "xzoy561",
50
+ $$css: true
51
+ },
52
+ xxl: {
53
+ kOIVth: "xghv2kt",
54
+ $$css: true
55
+ },
56
+ xxs: {
57
+ kOIVth: "x14qo01y",
58
+ $$css: true
59
+ },
60
+ xxxl: {
61
+ kOIVth: "xvm9ira",
62
+ $$css: true
63
+ }
64
+ };
65
+ const justifications = {
66
+ around: {
67
+ kjj79g: "x1l1ennw",
68
+ $$css: true
69
+ },
70
+ between: {
71
+ kjj79g: "x1qughib",
72
+ $$css: true
73
+ },
74
+ center: {
75
+ kjj79g: "xl56j7k",
76
+ $$css: true
77
+ },
78
+ end: {
79
+ kjj79g: "x13a6bvl",
80
+ $$css: true
81
+ },
82
+ start: {
83
+ kjj79g: "x1nhvcw1",
84
+ $$css: true
85
+ }
86
+ };
87
+ const styles = {
88
+ base: {
89
+ kB7OPa: "x9f619",
90
+ k1xSpc: "x78zum5",
91
+ $$css: true
92
+ },
93
+ column: {
94
+ kXwgrk: "xdt5ytf",
95
+ $$css: true
96
+ },
97
+ row: {
98
+ kXwgrk: "x1q0g3np",
99
+ $$css: true
100
+ },
101
+ wrap: {
102
+ kwnvtZ: "x1a02dak",
103
+ $$css: true
104
+ }
105
+ };
106
+ /**
107
+ * A row or a column of children with one gap between them, taken from the
108
+ * spacing scale.
109
+ *
110
+ * Layout only — it paints no surface and wraps no child, so each child is a
111
+ * flex item exactly as it was written. It is the answer to spacing a group of
112
+ * things, which is why no component here carries a margin of its own: the
113
+ * space between two things belongs to whatever holds both of them.
114
+ *
115
+ * `render` swaps the element, for a stack that should be a `<ul>`, a `<nav>`,
116
+ * or a `<section>` rather than a `<div>`.
117
+ */
118
+ function Stack({ align, direction = "column", gap = "md", justify, render, wrap = false, ...props$1 }) {
119
+ return useRender({
120
+ defaultTagName: "div",
121
+ props: {
122
+ ...props$1,
123
+ ...mergeStyles(props(styles.base, styles[direction], gaps[gap], align !== void 0 && alignments[align], justify !== void 0 && justifications[justify], wrap && styles.wrap), props$1)
124
+ },
125
+ render
126
+ });
127
+ }
128
+ //#endregion
129
+ export { Stack as default };
130
+
131
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../src/components/stack/index.tsx"],"sourcesContent":["import { useRender } from '@base-ui/react/use-render';\nimport * as stylex from '@stylexjs/stylex';\nimport { mergeStyles } from '../../styles/merge';\nimport '../../tokens/design.tokens.stylex';\nimport { spacing } from '../../tokens/design.tokens.stylex';\n\n// Short names rather than the CSS values they map to, so a call site reads\n// `align=\"start\"` instead of `align=\"flex-start\"`. A lookup is unavoidable\n// either way — `alignItems` takes `flex-start` and `justifyContent` takes\n// `space-between`, neither of which is a word anyone wants in a prop.\nconst alignments = {\n baseline: {\n kGNEyG: \"x1pha0wt\",\n $$css: true\n },\n center: {\n kGNEyG: \"x6s0dn4\",\n $$css: true\n },\n end: {\n kGNEyG: \"xuk3077\",\n $$css: true\n },\n start: {\n kGNEyG: \"x1cy8zhl\",\n $$css: true\n },\n stretch: {\n kGNEyG: \"x1qjc9v5\",\n $$css: true\n }\n};\n\n// One key per step of the spacing scale, named exactly as the token group\n// names it, so `gaps[gap]` indexes straight off the prop with no lookup table\n// to keep in sync — the same arrangement Text's type scale uses.\n//\n// `none` is the one key with no token behind it, and deliberately so: zero is\n// the absence of a spacing decision rather than a step of the scale, so there\n// is nothing for the scale to name. It exists because a stack that only wants\n// the direction and the alignment is otherwise a plain flex container written\n// out by hand.\nconst gaps = {\n lg: {\n kOIVth: \"xxj4525\",\n $$css: true\n },\n md: {\n kOIVth: \"x1gka490\",\n $$css: true\n },\n none: {\n kOIVth: \"xxhr3t\",\n $$css: true\n },\n sm: {\n kOIVth: \"x126z3so\",\n $$css: true\n },\n xl: {\n kOIVth: \"xj2l1yv\",\n $$css: true\n },\n xs: {\n kOIVth: \"xzoy561\",\n $$css: true\n },\n xxl: {\n kOIVth: \"xghv2kt\",\n $$css: true\n },\n xxs: {\n kOIVth: \"x14qo01y\",\n $$css: true\n },\n xxxl: {\n kOIVth: \"xvm9ira\",\n $$css: true\n }\n};\nconst justifications = {\n around: {\n kjj79g: \"x1l1ennw\",\n $$css: true\n },\n between: {\n kjj79g: \"x1qughib\",\n $$css: true\n },\n center: {\n kjj79g: \"xl56j7k\",\n $$css: true\n },\n end: {\n kjj79g: \"x13a6bvl\",\n $$css: true\n },\n start: {\n kjj79g: \"x1nhvcw1\",\n $$css: true\n }\n};\nconst styles = {\n base: {\n kB7OPa: \"x9f619\",\n k1xSpc: \"x78zum5\",\n $$css: true\n },\n column: {\n kXwgrk: \"xdt5ytf\",\n $$css: true\n },\n row: {\n kXwgrk: \"x1q0g3np\",\n $$css: true\n },\n wrap: {\n kwnvtZ: \"x1a02dak\",\n $$css: true\n }\n};\ntype StackAlign = 'baseline' | 'center' | 'end' | 'start' | 'stretch';\ntype StackGap = 'lg' | 'md' | 'none' | 'sm' | 'xl' | 'xs' | 'xxl' | 'xxs' | 'xxxl';\ntype StackJustify = 'around' | 'between' | 'center' | 'end' | 'start';\ntype StackProps = {\n /**\n * How the children line up across the stack: down the inline axis of a\n * column, down the block axis of a row. Left unset, they stretch, which is\n * what makes every card in a column the same width.\n *\n * `start` is what an inline-sized child needs in a column — a Badge or a\n * Chip spans the whole width otherwise.\n */\n align?: StackAlign;\n /**\n * Which way the children run.\n * @default 'column'\n */\n direction?: 'column' | 'row';\n /**\n * The space between children, as a step of the spacing scale. `none` closes\n * it entirely.\n *\n * Worth setting. The default is a middle step, and how much air a group of\n * things wants is the one thing a stack cannot work out for itself.\n * @default 'md'\n */\n gap?: StackGap;\n /**\n * How leftover space is distributed along the stack. Left unset, the\n * children sit at the start and the space collects after them.\n *\n * `between` is the one that puts a headline at one end of a row and its\n * actions at the other.\n */\n justify?: StackJustify;\n /**\n * Lets a row wrap onto further lines rather than overflowing. Has no effect\n * on a column, which has as many lines as it has children.\n * @default false\n */\n wrap?: boolean;\n} & useRender.ComponentProps<'div'>;\n\n/**\n * A row or a column of children with one gap between them, taken from the\n * spacing scale.\n *\n * Layout only — it paints no surface and wraps no child, so each child is a\n * flex item exactly as it was written. It is the answer to spacing a group of\n * things, which is why no component here carries a margin of its own: the\n * space between two things belongs to whatever holds both of them.\n *\n * `render` swaps the element, for a stack that should be a `<ul>`, a `<nav>`,\n * or a `<section>` rather than a `<div>`.\n */\nfunction Stack({\n align,\n direction = 'column',\n gap = 'md',\n justify,\n render,\n wrap = false,\n ...props\n}: StackProps) {\n return useRender({\n defaultTagName: 'div',\n props: {\n ...props,\n ...mergeStyles(stylex.props(styles.base, styles[direction], gaps[gap], align !== undefined && alignments[align], justify !== undefined && justifications[justify], wrap && styles.wrap), props)\n },\n render\n });\n}\nexport type { StackAlign, StackGap, StackJustify, StackProps };\nexport default Stack;"],"mappings":";;;;AAUA,MAAM,aAAa;CACjB,UAAU;EACR,QAAQ;EACR,OAAO;CACT;CACA,QAAQ;EACN,QAAQ;EACR,OAAO;CACT;CACA,KAAK;EACH,QAAQ;EACR,OAAO;CACT;CACA,OAAO;EACL,QAAQ;EACR,OAAO;CACT;CACA,SAAS;EACP,QAAQ;EACR,OAAO;CACT;AACF;AAWA,MAAM,OAAO;CACX,IAAI;EACF,QAAQ;EACR,OAAO;CACT;CACA,IAAI;EACF,QAAQ;EACR,OAAO;CACT;CACA,MAAM;EACJ,QAAQ;EACR,OAAO;CACT;CACA,IAAI;EACF,QAAQ;EACR,OAAO;CACT;CACA,IAAI;EACF,QAAQ;EACR,OAAO;CACT;CACA,IAAI;EACF,QAAQ;EACR,OAAO;CACT;CACA,KAAK;EACH,QAAQ;EACR,OAAO;CACT;CACA,KAAK;EACH,QAAQ;EACR,OAAO;CACT;CACA,MAAM;EACJ,QAAQ;EACR,OAAO;CACT;AACF;AACA,MAAM,iBAAiB;CACrB,QAAQ;EACN,QAAQ;EACR,OAAO;CACT;CACA,SAAS;EACP,QAAQ;EACR,OAAO;CACT;CACA,QAAQ;EACN,QAAQ;EACR,OAAO;CACT;CACA,KAAK;EACH,QAAQ;EACR,OAAO;CACT;CACA,OAAO;EACL,QAAQ;EACR,OAAO;CACT;AACF;AACA,MAAM,SAAS;CACb,MAAM;EACJ,QAAQ;EACR,QAAQ;EACR,OAAO;CACT;CACA,QAAQ;EACN,QAAQ;EACR,OAAO;CACT;CACA,KAAK;EACH,QAAQ;EACR,OAAO;CACT;CACA,MAAM;EACJ,QAAQ;EACR,OAAO;CACT;AACF;;;;;;;;;;;;;AAwDA,SAAS,MAAM,EACb,OACA,YAAY,UACZ,MAAM,MACN,SACA,QACA,OAAO,OACP,GAAG,WACU;CACb,OAAO,UAAU;EACf,gBAAgB;EAChB,OAAO;GACL,GAAG;GACH,GAAG,YAAY,MAAa,OAAO,MAAM,OAAO,YAAY,KAAK,MAAM,UAAU,KAAA,KAAa,WAAW,QAAQ,YAAY,KAAA,KAAa,eAAe,UAAU,QAAQ,OAAO,IAAI,GAAG,OAAK;EAChM;EACA;CACF,CAAC;AACH"}
package/dist/index.d.ts CHANGED
@@ -5,6 +5,7 @@ import Button, { ButtonProps } from "./components/button/index.js";
5
5
  import Card, { CardProps } from "./components/card/index.js";
6
6
  import Chip, { ChipProps } from "./components/chip/index.js";
7
7
  import Code, { CodeProps } from "./components/code/index.js";
8
+ import Container, { ContainerProps } from "./components/container/index.js";
8
9
  import CopyField, { CopyFieldProps } from "./components/copy-field/index.js";
9
10
  import Currency, { CurrencyProps } from "./components/currency/index.js";
10
11
  import Feed, { FeedProps } from "./components/feed/index.js";
@@ -16,10 +17,11 @@ import ListItem, { ListItemProps } from "./components/list-item/index.js";
16
17
  import ProductIcon, { ProductIconProps } from "./components/product-icon/index.js";
17
18
  import Separator, { SeparatorProps } from "./components/separator/index.js";
18
19
  import Sheet, { SheetProps } from "./components/sheet/index.js";
20
+ import Stack, { StackAlign, StackGap, StackJustify, StackProps } from "./components/stack/index.js";
19
21
  import SupportingPane, { SupportingPaneProps } from "./components/supporting-pane/index.js";
20
22
  import Tabs, { TabsProps } from "./components/tabs/index.js";
21
23
  import Text, { TextProps } from "./components/text/index.js";
22
24
  import TextField, { TextFieldProps } from "./components/text-field/index.js";
23
25
  import "./components/index.js";
24
26
  import "./styles.css";
25
- export { AppBar, type AppBarProps, Avatar, type AvatarProps, Badge, type BadgeProps, Button, type ButtonProps, Card, type CardProps, Chip, type ChipProps, Code, type CodeProps, CopyField, type CopyFieldProps, Currency, type CurrencyProps, Feed, type FeedProps, IconButton, type IconButtonProps, Keycap, type KeycapProps, Link, type LinkProps, ListDetail, type ListDetailProps, ListItem, type ListItemProps, ProductIcon, type ProductIconProps, Separator, type SeparatorProps, Sheet, type SheetProps, SupportingPane, type SupportingPaneProps, Tabs, type TabsProps, Text, TextField, type TextFieldProps, type TextProps };
27
+ export { AppBar, type AppBarProps, Avatar, type AvatarProps, Badge, type BadgeProps, Button, type ButtonProps, Card, type CardProps, Chip, type ChipProps, Code, type CodeProps, Container, type ContainerProps, CopyField, type CopyFieldProps, Currency, type CurrencyProps, Feed, type FeedProps, IconButton, type IconButtonProps, Keycap, type KeycapProps, Link, type LinkProps, ListDetail, type ListDetailProps, ListItem, type ListItemProps, ProductIcon, type ProductIconProps, Separator, type SeparatorProps, Sheet, type SheetProps, Stack, type StackAlign, type StackGap, type StackJustify, type StackProps, SupportingPane, type SupportingPaneProps, Tabs, type TabsProps, Text, TextField, type TextFieldProps, type TextProps };
package/dist/index.js CHANGED
@@ -6,6 +6,7 @@ import Button from "./components/button/index.js";
6
6
  import Card from "./components/card/index.js";
7
7
  import Chip from "./components/chip/index.js";
8
8
  import Code from "./components/code/index.js";
9
+ import Container from "./components/container/index.js";
9
10
  import CopyField from "./components/copy-field/index.js";
10
11
  import Currency from "./components/currency/index.js";
11
12
  import Feed from "./components/feed/index.js";
@@ -17,8 +18,9 @@ import ListItem from "./components/list-item/index.js";
17
18
  import ProductIcon from "./components/product-icon/index.js";
18
19
  import Separator from "./components/separator/index.js";
19
20
  import Sheet from "./components/sheet/index.js";
21
+ import Stack from "./components/stack/index.js";
20
22
  import SupportingPane from "./components/supporting-pane/index.js";
21
23
  import Tabs from "./components/tabs/index.js";
22
24
  import TextField from "./components/text-field/index.js";
23
25
  import "./styles.css";
24
- export { AppBar, Avatar, Badge, Button, Card, Chip, Code, CopyField, Currency, Feed, IconButton, Keycap, Link, ListDetail, ListItem, ProductIcon, Separator, Sheet, SupportingPane, Tabs, Text, TextField };
26
+ export { AppBar, Avatar, Badge, Button, Card, Chip, Code, Container, CopyField, Currency, Feed, IconButton, Keycap, Link, ListDetail, ListItem, ProductIcon, Separator, Sheet, Stack, SupportingPane, Tabs, Text, TextField };
package/dist/styles.css CHANGED
@@ -79,6 +79,10 @@
79
79
  border-width: 1px;
80
80
  }
81
81
 
82
+ .xxhr3t {
83
+ gap: 0;
84
+ }
85
+
82
86
  .xj2l1yv {
83
87
  gap: var(--x196ey9q);
84
88
  }
@@ -99,14 +103,26 @@
99
103
  gap: var(--xbmbo34);
100
104
  }
101
105
 
106
+ .xghv2kt {
107
+ gap: var(--xi3mssk);
108
+ }
109
+
102
110
  .x126z3so {
103
111
  gap: var(--xod9tvo);
104
112
  }
105
113
 
114
+ .xvm9ira {
115
+ gap: var(--xqgx294);
116
+ }
117
+
106
118
  .x10im51j {
107
119
  margin-block: 0;
108
120
  }
109
121
 
122
+ .xvueqy4 {
123
+ margin-inline: auto;
124
+ }
125
+
110
126
  .xboopgi {
111
127
  margin-inline: var(--x3km7fe);
112
128
  }
@@ -135,6 +151,10 @@
135
151
  padding-block: var(--xod9tvo);
136
152
  }
137
153
 
154
+ .xnjsko4 {
155
+ padding-inline: 0;
156
+ }
157
+
138
158
  .x1sdxjpb {
139
159
  padding-inline: 48px;
140
160
  }
@@ -181,10 +201,26 @@
181
201
  }
182
202
 
183
203
  @layer priority4 {
204
+ .x1pha0wt {
205
+ align-items: baseline;
206
+ }
207
+
184
208
  .x6s0dn4 {
185
209
  align-items: center;
186
210
  }
187
211
 
212
+ .xuk3077 {
213
+ align-items: flex-end;
214
+ }
215
+
216
+ .x1cy8zhl {
217
+ align-items: flex-start;
218
+ }
219
+
220
+ .x1qjc9v5 {
221
+ align-items: stretch;
222
+ }
223
+
188
224
  .xkh2ocl {
189
225
  align-self: stretch;
190
226
  }
@@ -425,6 +461,10 @@
425
461
  flex-direction: column;
426
462
  }
427
463
 
464
+ .x1q0g3np {
465
+ flex-direction: row;
466
+ }
467
+
428
468
  .x1iyjqo2 {
429
469
  flex-grow: 1;
430
470
  }
@@ -433,6 +473,10 @@
433
473
  flex-shrink: 0;
434
474
  }
435
475
 
476
+ .x1a02dak {
477
+ flex-wrap: wrap;
478
+ }
479
+
436
480
  .xjaampf {
437
481
  font-family: var(--x134eq0n);
438
482
  }
@@ -673,6 +717,14 @@
673
717
  justify-content: flex-end;
674
718
  }
675
719
 
720
+ .x1nhvcw1 {
721
+ justify-content: flex-start;
722
+ }
723
+
724
+ .x1l1ennw {
725
+ justify-content: space-around;
726
+ }
727
+
676
728
  .x1qughib {
677
729
  justify-content: space-between;
678
730
  }
@@ -1189,6 +1241,10 @@
1189
1241
  max-height: none;
1190
1242
  }
1191
1243
 
1244
+ .x13i5qev {
1245
+ max-width: var(--x-maxInlineSize);
1246
+ }
1247
+
1192
1248
  .xbktkl8 {
1193
1249
  min-height: 56px;
1194
1250
  }
@@ -1329,6 +1385,11 @@
1329
1385
  inherits: false
1330
1386
  }
1331
1387
 
1388
+ @property --x-maxInlineSize {
1389
+ syntax: "*";
1390
+ inherits: false
1391
+ }
1392
+
1332
1393
  @property --x-minBlockSize {
1333
1394
  syntax: "*";
1334
1395
  inherits: false
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kanso-labs/kanso-ui",
3
- "version": "0.8.2",
3
+ "version": "0.9.0",
4
4
  "description": "A React component library built on Base UI primitives and styled with StyleX, with design tokens sourced from a single W3C DTCG file and compiled via Style Dictionary",
5
5
  "keywords": [
6
6
  "react",